ウェブサイト及びサーバー監視の プレミアム製品

Server Densityについて

Author Archives: Norio Hasegawa

  1. Puppetの使用方法 ーインフラ、設定、フェイルオーバー、配備

    Comments Off on Puppetの使用方法 ーインフラ、設定、フェイルオーバー、配備

    当社ではここ数年間Server Densityのインフラを管理するためにPuppetを使用してきました。それにより、いろいろな利点があり、標準設定管理として使用しています。実際には自社での使用は約25%程度です。

    当社では主にインフラ、設定、フェイルオーバー、配備の4つの分野でPuppetを使用しています。ここではそれぞれの分野について説明させて頂きます。まずはインフラでのPuppetの使用方法です。

    Puppetの使用方法 ーインフラ

    当社は自社の環境をSoftlayerに移管した時にPuppetを使用し始めました。この環境ではメタルサーバーやパブリッククラウドインスタンスなどが混在しておりその数は約75-100あります。このように設定された際には、Softlayerからサーバーを調達して、自社のマニフェストを適用して設定を行う前にマニュアルでPuppetをインストールしました。

    当社は最近、共同の場所のデーターセンター内の自社の運用環境の移行を検討し、 自社の環境をSoftlayerからGoogle Cloudに移行することを決定しました。私自身の見解としては長期的に見れば、共同の場所のデーターセンターの方がかなりコストが低いはずですが、 初期投資にかかる費用を抑えたいと思いました。また、BigQueryのようなGoogleの製品を利用したいと思いました。

    私はこの点について、今後移行を完了するにあたり、更に詳細に述べていきます。また私は– 6月19日にBay Area 及び 7月2日ロンドンで 発表もさせて頂きます。

    Google Cloud (特に, Google Compute Engine)か他の主要などのクラウドのプロバイダーを使用する場合には、自社のコードのリソースを定義するためにPuppetのモジュールを使用できます。コントロールパネルからマニュアルでオーダーをするのではなく、Puppetのマニフェストの中で設定と共に定義できます。当社ではgce computeモジュール を使用していますが、Amazon や他のモジュールもあります。

    例えば、F 200GB のボリュームのインスタンスを定義する場合、

    
    gce_instance { 'mms-app1':
    ensure         => present,
    machine_type   => 'n1-highmem-2',
    zone           => 'us-central1-a',
    network        => 'private',
    tags           => ['mms-app', 'mongodb'],
    image          => 'projects/debian-cloud/global/images/backports-debian-7-wheezy-v20140605',
    }
    
    gce_disk { 'mms-app1-var-lib-mongodb':
    ensure      => present,
    description => 'mms-app1:/var/lib/mongodb',
    size_gb     => '200',
    zone        => 'us-central1-a',
    }
    

    ここで重要なのは、当社がコード内でインスタンスとそれらの上で稼働している設定を定義することができ、Puppetにその作業をさせるということです。

    Puppetの使用方法 ー 設定管理

    これはPuppetのオリジナルのユースケースです。– それは単一の場所で自社のサーバーにインストールしたすべてを定義できます。そのため、新規のサーバーを配備しやすく、すべて一貫性があります。

    またこれは異常な変化、修正や微調整が完全にバージョンで制御、ドキュメント化されていて、時間が経過しても失うことはないことを意味します。例えば、時間をかけてまたは様々なサポートの要望で積み重なってきた問題を回避したり、最適化するために多岐にわたる MongoDBの修正が出てきますが、これはすべてPuppetでドキュメント化されています。

    当社ではPuppet Labsが推奨する標準のモジュールレイアウトを使用しています。これは, Github レポの中に含まれて、コミットする前にpuppet lintでチェックされます。そのため、設定についての記述されたきっちり構築されたライブラリーができています。変更については、通常のコードのリビューのプロセスを経ており、Puppet Masterを配備により、変更点をすべて吸い上げてくれます。

    以前はすべてを記述するために自社で独自のカスタムモジュールを書いていましたが、今ではPuppet Forgeのモジュールをできるだけ使用しています。それはPuppet Forgeがより多くのオプションをサポートしていて、自社のカスタムモジュールよりも標準化されているためです。例えば、, MongoDBのモジュール はサーバーとクライアントのインストール、オプションの設定、レプリカの設定のなどを可能にしてくれます。

    
    include site::mongodb_org
    
    class {'::mongodb::server':
    ensure    => present,
    bind_ip   => '',
    replset   => 'mms-app',
    }
    
    mount {'/var/lib/mongodb':
    ensure  => mounted,
    atboot  => true,
    device  => '/dev/sdb',
    fstype  => 'ext4',
    options => 'defaults,noatime',
    require => Class['::mongodb::server'],
    }
    
    mongodb_replset { 'mms-app':
    ensure  => present,
    members => ['mms-app1:27017', 'mms-app2:27017', 'mms-app3:27017']
    }
    

    当社では同じバージョンを常にインストールされることを確認するために特定のパッケージのバージョンを固定し、アップグレードを管理することができます。これはデータベースなどの重要なパッケージの突然のアップグレードなどを避けるためにも重要です!

    Server Density のモニターリングのエージェントもPuppet Forge moduleでは利用することができます。 それにより、自動的にエージェントをインストールしたり、登録したり、独自のアラートも設定できます。

    すべてを組合せて、当社の MongoDBバックアップはGoogle Compute Engineの上で稼働しており、, deployed using Puppet を使用して配備され、Server Densityでモニターされていることになります。

    mms

    Puppetの使用方法 ー フェイルオーバー

    当社はロードバランサーとしてNginx を使用しており、 proxyプールのメンバーをリスト化するためPuppetの変数を使用しています。これはPuppet Forge nginxモジュールを使用して、配備されていており、当社はその改善に貢献しています。

    ロードバランサーのローテーションからノードを削除する必要がある時には、マニュアルのプロセスで Puppet web UI かAPIを使用して、それが実現できます。 UIは人的なエラーの可能性を最小限に抑えて、変更を適用することができます。  API により一つのノードに障害が発生した場合など特定の条件でフェイルオーバーを自動化することができます。

    Puppetの使用方法 ー 配備

    これは通常Puppetを使うやり方ではないですが、配備のメカニズムの一部の構築に専念することを手助けしてくれます。この方法では、すでにサーバーで稼働しているPuppet agentを利用します。これにより、カスタムの SSHコマンドを使用したり、独自にエージェントを書いたり、自社の要望に合うためのワークフローをカスタマイズするといったこと必要なくなります。

    これは以下のような仕組みです。:

    • コードはGithubの中でマスターにコミットされる。 (通常はプルリクエストを合わせることですが、これは自社のコードリビューするやり方です。).
    • テストを行うBuildbot によって新しいビルドが引き起こされ、ビルドのアーチファクトを作成する。 – 必要最低限のコードが実際にプロダクションサーバーにコピーされる。
    • 社内のコントールパネル内の配備のボタンを押して、どのサーバーに配備されるか(枝分かれした配備も可能)選択して、実際に配備されるものを反映して内部のバージョン番号がアップデートされる。
    • /opt/puppet/bin/mco puppetd runonce -Iが特定のホストによって引き起こされ、Puppet が配備されたバージョンがリクエストされたバージョンと違うことを通知する。
    • 新規のビルドがサーバーにコピーされる。

    buildbot

    ステータスのメッセージがこのプロセスの期間中 Hipchatにポスティングされ、どのエンジニアもいつでもコードを配備できます。しかしながら、当社ではウイークデーの5時以降と金曜日の3時以降重要ではない変更を行わないことをルール化しています。

    このためにPuppetの使用により不利な点もいくつかあります。 まず初めにPuppet エージェントは低いスペックのハードではかなり遅いことです。当社の世界中のリモート監視のノードは一般的に低電力のノードであるために、エージェントは非常にゆっくり実行されます。また最終的には配備は必ずしも同時に起きず、配備するコードにそのことを頭に入れておく必要がるので、一貫性があります。

    Puppetがほとんどのドキュメンテーション

    これら4つのユースケースは当社のインフラの設定とほとんどがテキストファイルに含まれることを意味します。これにより以下のようないくつかの利点があります。:

    • バージョンが管理されている-誰でも変更点を確認でき、すべてリビュープロセスの一環である。
    • 誰でも見ることができる– もし、どのように機能しているか知りたい場合には、マニフェストを読めばすぐに理解することができる。
    • すべてに一貫性がある– 真実はすべて一つのソースからであり、一つの場所ですべてが定義されている。

    それは 当社のすべてのドキュメントではありません。, しかしながら、使用されていてライブの状態にあるので大部分であるということがいえます。皆さんもご存知のように、すべてのドキュメントをアップデートをしておくは嫌なことです!

  2. PuppetでのNginxの展開

    Comments Off on PuppetでのNginxの展開

    当社のCEO デイビット・ミィトンは5月に開催れたPuppet Camp Tokyoのイベントで Server Densityの監視インフラをいかに管理するかについての講演をしました。この内容に沿って、サーバー間でどのようにPuppeでNginxを展開するかについて説明したいと思います。

    当社は1年以上、100台近くのサーバーのインフラをPuppetを使用して管理してきました。当初は、Terremarkでの古いホスト環境にマッチするようにマニュアルで設定をして、 Softlayerに移行しやすいようにしていました。ここ数ヶ月間で、当社はForge のモジュールを使うようにリファクタリングして、サーバーの数を減らすためにいくつかのサーバーの役割を統合しました。Forge のモジュールを使用することにより、自分たちですべてを再実装するのではなく、コミュニティーコードを再利用できるようになりました。

    PuppetでのNginxの展開

    Puppet ソリューションの追求

    選択肢は自分たちでマニフェストを書き込むか(新たに一つやり方を追加することになりますが)、コミュニティーに接触して、このような問題が既に解決されたかを確認して、既存の解決方法を(または少なくとも何とかできるキックスタートの方法)を再び作り込むようなことをやめることでした。

    当社では自分たちで実行するより再利用が有効であると信じており、Forge のサイトに行くことが不可欠でした。

    セットアップについて

    • 当社は 数カ月間後導入されるServer Densityのバージョン2のインフラが準備できるまでに、Puppet Enterpriseを運用しました。そして、十分に考慮が必要なのはロードバランサでした。当社では現在Poundを使用していますが、新製品に必要な追加機能は Nginxにのみありました.
    • Nginxはイベント起動型のWebサーバーであり、プロキシーやロードバランスの機能が備わっています。またIt has inbuilt native support for FCGI や uWSGIのプロトコルのサポートが備わっており、 uWSGIなどの高速アプリサーバーで Python WSGIのアプリを運用することができます。
    • PoundやVarnishとは違い, 新規の NginxはWebSocketsやGoogle’s SPDY のスタンダードのサポートだけではなく、サードパーティーのTCP/IPソケットをフルにハンドルするためのモジュールもサポートしているため、 非同期のWebSocket Python のアプリとアップストリームの Node.js プロキシーを選んで混ぜることができます。
    • これは明らかにPuppetを通じて展開及び構成することができなければなりません。
    • 当社独自のマニフェストを使用。 これらはpuppet masterにより Gihub repoを引き出されます。
    • Puppet Console やLive Managementは集中的に使用され、スイッチのフェイルオーバーなどの一過性の変化を誘発するために使用されます。 (PuppetConf 2012のビデオ).

    すべての統合

    Puppetlabs nginxのモジュールを選択しましたが, 当社はそれをPuppet Enterprise (PE) の設定に追加することが必要でした。. そのためにはA) 実際のコードが必要で、 B)既存のノードでそれを運用できることが必要でした。

    A)を実行するには2つの方法があります。:

    1. puppet モジュールのインストール  puppetlabs/nginx
    2. git サブモジュール  既存のpuppet master モジュールのフォルダーに https://github.com/puppetlabs/puppetlabs-nginx.git を追加。

    この決定はモジュールを確認して、それの強化を実現することで簡単にできました。当社はこれらの変更をpuppetlabs-nginxでフォークしており, フォークをpuppet masterに組み込む最善の方法は gitサブモジュールを得ることです。

    B)に関しては、 PE コンソールがこのようにパラメータ化クラをサポートしていないことがすぐに解りました。そこで当社のサイトのpp.(実際には何もなし)とコンソールを統合するオプションしか残されていませんでした。それは ENC であり、すべてでした。しかし、それでは前述のように過渡の変化を起こすようにコンソールを使用することができなくなります。当社は、site.ppではなくコンソール上でノードパラメータを継続して管理することを望んでいます。 完全性のために、ノードの継承を使用することもできますが、おそらく大変なことになると思われます。

    その解決方法として、クラス階層を設定することにしました。:


    class serverdensity-nginx
    {
    class { 'nginx': }
    nginx::resource::upstream {
    'socky_rack':
    ensure => present,
    members => $lbTargetHosts,
    }

    PE コンソールによって当社独自のserverdensity-nginx が使用され、nginx のクラスを含むので、コンソールコードパラメータと nginx モジュールの機能を使用できるようになります。

    コンソールを使用して一過性の変化を引き起こす

    このソリューションの長所の一つは、制御インターフェースのnginxの欠如を克服し、Poundで慣れている操作の機能性を維持できることです。

    Nginxは変更するのに設定ファイルを必要として、リロードの際に設定をロードします。 To, eg. はロードバランサーのローテーションから一つのノードを取り除くので、, それに相応する設定アファイルを修正して、nginxのリロードを引き起こします。

    Puppetでは、これはコンソールを使用してノードやグループ、パ ラメータ を 変更することで実現し、実行するノードを起動します。Puppetはそれからnginxをリロードします。最善の場合には、リロードで切断されるこはありません。

    代替の方法、他にどのように実行すればいいか?

    後にPuppet Labs Nginx モジュールはJames Frymanのモジュール.に由来することを知ります。

    2011年6月30日以降、Puppet Labsのモジュールはアップデートされていないので、その名前で呼んだ方がいいかもしれません。明らかに、Puppet Labs`はForgeのにPuppet Labsの名前空間内のすべてのモジュールが最高クラスで、積極的に維持されることを保証したいのである。彼らは2013年初めにもこのプロジェクトをキックオフしたいと言っていました。

    当社はモジュールに変更を加えました。

    • SSL の改善 Qalys SSL Labs!に感謝します
    • 追加のカスタムログ
    • バグの修正と美化

    そして、 フォークはGithubで確認できます。

  3. Webアプリケーションを保護する方法

    Comments Off on Webアプリケーションを保護する方法

    100%セキュリティーを確保することは不可能ですが、皆さん自身、Webアプリ、また顧客への様々なタイプの攻撃を軽減するために、Webアプリを保護するためのステップはあります。Server Density バージョン2ではこれらを製品をできるだけ強化した上で実践しようとしています。

    これらのヒントは、SQLインジェクションからの保護、フィルタリング、セッション処理、およびXSRF保護になどのセキュリティのベストプラクティスに追加されるものです。以下の提案を実践する前に基本をご理解頂くために、OWASPのチートシートとOWASP チートシートをご確認下さい。:

    SSL のみ

    私が2009年にServer Densityを設立した当初は、できるだけ簡単にセットアップをするために、アクセスと監視エージェントのポストバックは、HTTPやHTTPS経由で許可されていました。ほとんどのサーバーがアウトバウンドポート80を常に許可していました。また、デフォルトを少し前にHTTPSに変更したので、これは考えていたほど問題にはなりませんでした。SSLは一般的にはパフォーマンス上でもボトルネックと考えられがちですが、それは決して正しい解釈ではなく、すべての接続先にSSLを強制しない理由は実際にはありません。

    Server Density バージョン2では、新しいエージェントの導入とWeb UIへのアクセスの両方にSSLを強制できるように、新しいURLを使用しています。当社はまだ非SSLの下での古いドメインのエンドポイントをサポートしていますが、最終的には、それをリタイアさせます。

    実装の状況を確認するための優れたレポートと今後のセキュリティのための推薦項目を取得するために、 Qualys SSLサーバーのテストを皆さんのURLで実行して下さい。

    Server Density SSL

    当社はまだRC4の脆弱性を解決するための最善の方法を検討中ですが、TLS1.2.のみサポートすることが適切だと思われます。しかしながら、 ブラウザーの開発バージョンでのみ現在はサポートしています。当社はブラウザーのオプションとして提供しており、ブラウザーのサポートが改善すれば、おそらく旧バージョンは無効にします。

    完全な前方秘匿性のあるSSLのサポート

    通常では、SSLへのすべての接続はURLは単一のプライベートキーにて暗号化されています。もし誰かがすべてのトラフィックをキャプチャした場合に、彼らは皆さんのキーにアクセスすれば、復号化される可能性があります。完全な前方秘匿性 はすべてのセッションにおいて新しいキーを交渉することでこれに対応します。つまり、一つのキーの妥協は、そのセッションのデータのみに影響を与えます。

    もし、これを実行したい場合には、Webサーバーの設定の特定の暗号スイートを許可する必要があります。ECDHE-RSA-AES128-SHA:AES128-SHA:RC4-SHA はほとんどのブラウザーと互換性があります。理論と実装の詳細は、このブログの記事に記載されています

    当社はnginx load balancersでSSLを終了し、これらの設定でSSLを実装します。

      
    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers   on;
    # prefer RC4-SHA to avoid BEAST
    ssl_ciphers ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH;
    
    

    Google Chromeで接続状況の詳細を確認して、ECDHE_RSAを見つけることで、暗号タイプで完全な前方秘匿性を使用して接続しているかどうか分かります。:

    server-density-perfect-forward-secrecy1

    厳格なトランスポートセキュリティの使用

    SSLの強制はHTTPの厳格なトランスポートセキュリティ と一緒に組み合わされるべきです。さもなければ、ユーザーがプロトコルなしで、例えばhttps://example.comではなくexample.comとタイプして、リダイレクトされる形で自身のドメインに入り込んでくるリスクがあります。HTTP経由のコミュニケーションでは短時間しかないので、リダレクトはセキュリティーホールを開けることになります。

    このような事象は、返信と共にSTSヘッダを送信することで解決されます。それはブラウザーに記憶していて、リクエストを実際に発行せずに、強制的にhttpからhttpsに変換されるためです。これは再度チェックされる前に、ブラウザーが設定を記憶する時間のヘッダを送信することよりアーカイブされます。:

    
    strict-transport-security:max-age=315360000; includeSubdomains
    
    

    ヘッダは10年間に設定され、それぞれのアカウントが例えば、example.serverdensity.io.というような独自のURLを取得するためにサブドメインも含まれます。

    ブラウザーのベンダーに厳格なトランスポートセキュリティの設定を送信

    まだ、STSヘッダにも潜在的な欠点があります。それは初めのリクエストがあってから送信されるためです。これと組み合わせるためにはURLをブラウザーのベンダーに送信してsubmit your URL to browser vendors ブラウザーがSSL経由でURLにアクセスするように強制します。

    これがクロームでどのように機能するかはFirefox seedsクロームのリストからURLを送信することで分かります。

    コンテンツのセキュリティポリシーの強制

    最も一般的なセキュリティ上の脆弱性の中でトップ10の中で, クロスサイトスクリプティングは3番目となっています。これはリモートコードが通常正しくないかもしくは良くないフィルタリングにより、サイトに注入されし、実行されるものです。

    これに対処するための正しい方法は、許可されたリモートリソースのホワイトリストを提供することです。もしスクリプトURLがこのリストとマッチしない場合は、ブラウザーはブロックします。 これはすべてをブロックでき、その後で追加機能で特定のURを開くことができるので、新製品で実行する方が簡単です。しかしながら、ブラウザー開発ツールを使用する場合は、どのリモートホストが呼び出されているか簡単に確認することができます。

    当社が使用しているCSP:

    
    content-security-policy:script-src 'self' 'unsafe-eval' https://maps.google.com https://*.gstatic.com https://*.googleapis.com https://*.mixpanel.com https://*.mxpnl.com; connect-src 'self' https://maps.google.com https://*.gstatic.com https://*.googleapis.com https://*.mixpanel.com https://*.mxpnl.com; frame-src 'self' https://maps.google.com https://*.gstatic.com https://*.googleapis.com https://*.mixpanel.com https://*.mxpnl.com; object-src 'none
    
    

    当社はこれを必要とするサードパーティの複数のライブラリをリライトするように、ここでは特別に安全ではない評価をしました。

    すべてのコンテンツをホストすることができるドメインのワイルドカードの使用に注意して下さい。例えば、*.cloudfront.netにワイルドカードを使用する場合には、誰でもファイルをアップロードできるAmazonのCDNなので、誰もが任意のスクリプトをホストできるようになります!

    またContent-Security-Policyは 標準のヘッダですが、 Firefox や IE は X-Content-Security-Policyのみサポートします。ヘッダの名前や指令についての詳細の情報はOWASPのドキュメントご覧下さい。 またこの入門編としてこのチュートリアルをチェックしてみて下さい。.

    その他のHTTP セキリュティーヘッダ

    またブラウザーによっては、その他のリスポンスヘッダの設定により、さらに追加のセキリュティ機能が可能になります。 それらは全般的にサポートされておらず、別の階層の(わずかの)保護だけですが、検討の価値はあります。:

    パスワード、リメンバー・ミー、ログインリセットを正しく使用

    これはアプリへのメインのゲートウェイであるので、ロギングする際のすべての段階を正しく実行しているか確認する必要あります。リサーチまた安全なプロセスをデザインするのに必要な時間はわずかです。

    それから OWASPのチートシートと照らし合わせて認証プロセスを見直して下さい。.

    マルチファクター認証を提供

    server-density-mfa

    もし、アプリが些細な消費者向の製品以上であると考えるのであれば、ユーザーがログインする前に、彼らが持っているものを使用して認証するマルチファクタ認証を提供する必要があります。 Google Authenticator のスタンダードを使用して下さい。なぜならば、それは 、すべてのプラットフォームで利用可能な認証のアプリがあり、ほとんどすべてのプラットフォーム用のライブラリを持っていからです。 カスタムでインストールするのは非常に厄介であり、独自アプリは皆さん自身のシステムを実装してくれません!

    MFAトークンを追加/削除のようなものを再認証するようにして下さい。ユーザーがパスワードの変更などほとんどのアクションでその都度認証しなければならないことで不満を感じないように、当社は、すべてのユーザー·プロファイルの変更のためにこれを実行し、タイムアウトを持つことにしました。しかしながら、新たにトークンを追加したり、既存のトークンを削除する場合には、その都度認証が必要になります。

    MFA は重要なアプリにとって、アカウントのハイジャックからの保護のために非常に重要です。

    セキュリティ監査の実施

    誰も完璧ではありません、皆さんが、正しく物事をやっていることを確認する唯一の方法は、それを壊すことによって、サードパーティにセキュリティを確認してもらうことです。

    当社は、コードレビューと実装プロセス(コードを細かに確認)の一環として内部で自身のセキュリティレビューを行うだけでなく、外部のセキュリティコンサルタントからの定期的なレビューを受けています。当社のレビューは the guys at &yet (through lift security)によって行われますが、 Matasano も知知名度が高いです。私は、一つの会社が監査を行って、修正を施した後で別の会社に変更点を監査してもらうことをお勧めします。

    継続的な改善

    セキュリティとは攻撃のリスクを軽減するためにレイヤを追加していくということす。しかし、キーワードはリスクの軽減です。. 新たな脅威は、常に浮上しており、継続的にセキュリティをを施す必要があります。つまり、すべての既存の施策の定期的な見直し、新たな防御機構をチェックし、セキュリティのアナウンスに注意を払うことを意味します。