nginxでHTTPSサーバーを構成する

なぜこれを書いているのですか?


最近、多くの要因(NSA、 広告付きDPIなど)により、妄想が起き始め、私の小さなサイトを完全にhttpsに移行しようと考えました。 ハブにはSSL / TLSの技術的な詳細が記載された記事いくつかありましたが、https Webサーバーの構成に関する情報を探していると、記事の伝統的な区分が見つかりました-これらは「Do it like like」記事です。これらはさまざまな使用パターンを説明する理論上の大きな記事ですが、実用的な既製オプションはありません。 ハブのセットアップに関する記事がありましたが DHエンコードに関する情報はなく、一部のパラメーターは説明されていません。 記事として見つかったものを注文する価値があると思いました。これは、httpsをサーバーに展開したいが、SSLの世界に深く入り込まない人に役立ちます。

ナレーションは、nginxがWebサーバーとして機能するという事実を考慮して行われます(1つの場所にphp-fpmのパラメーターがあります)。

証明書


すでにStartSSLから証明書を取得しました。 彼らはすでにハブで彼について書いているので、私はこのステップにとどまりません。 最初の2、3日の間、サーバー上の証明書をチェックするブラウザーはそれを誓うことができます(これはOpera 12とFirefoxで起こりました)。明らかにStartComでは有効な証明書のキャッシュはそれほど頻繁に更新されません。 インストールについては、以下で説明します

カスタマイズオプションについて


新しいバージョンのNginxはすぐに使用できますが、実際には関連性がありますが、まだ洗練されたパラメーターが必要ですが、実際のパラメーターはそれほど前に標準構成に現れなかったため、場合によっては構成内のHTTPSサーバーの標準例は関連しません。

一般に、現在関連する2つの構成オプションがあります-Forward Secrecyありとなし。 セットアップ時の違いはエンコーディングのセット(ssl_ciphersディレクティブ)のみですが、ここではhttpsから何を望むかを検討する価値があります。

Forward Secrecyについては、 こちらをご覧ください 。 一言で言えば、一番下の行は、現在関連するRC4アルゴリズムの場合、サーバーの秘密キーに基づいてセッションキーが生成されるということです。 したがって、秘密鍵が危険にさらされた場合、すべてのセッションを復号化することができます(記録されている場合)。 DHエンコードを使用する場合、各セッションには独自のキーのセットがあり、これらのセッションはプライベートキーにまったく依存しません。 ただし、この場合、ハンドシェイクにはるかに多くのプロセッサ時間が費やされ、負荷とページを開くのにかかる時間が増加します。

ここでは、サイトでhttpsが特に必要な理由を検討する価値があります。 多数の訪問者がいる場合、DH暗号化アルゴリズムを使用すると、負荷が適切に増加する可能性があります(HTTPSに切り替えると、いずれにせよ増加します)。場合によっては、VDSなどの関税を引き上げる必要があります。 ほとんどの場合、RC4で十分ですが、多くはRC4を「トップクラス」にしたいので、リソースが許せばRC4にしませんか。

Nginxのセットアップ


設定の結果として、私はほぼそのような構成を形成しました。以下にパラメーターの本質を説明します。

httpセクションで、次を追加する必要があります。
ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; ssl_prefer_server_ciphers on; ssl_stapling on; resolver 8.8.8.8; 


サーバーセクションは、おおよそ次のようになります。
 server { listen 443 ssl; server_name www.site.ru; ....... keepalive_timeout 60; ssl_certificate certificate_bundled.crt; ssl_certificate_key privatekey.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "HIGH:!RC4:!aNULL:!MD5:!kEDH"; add_header Strict-Transport-Security 'max-age=604800'; ....... location ~ \.php$ { ....... fastcgi_param HTTPS on; #  php-fpm ....... } } 


この例では、DHアルゴリズムは使用されていません。 前方秘密はありません。 ここでの改善のうち、SSLv3サポートを省略(ssl_ciphersから削除)することができます。したがって、TLSをサポートしないため、IE 6以下はサポートされなくなります。
SSLv3を使用しない場合、この設定はSSLテストで100-95-100-90のスコアを与えます。

パラメーターを見てみましょう


ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
「セッションパラメータを保存するためのキャッシュのタイプとサイズを設定します。」(Nginx.org)キャッシュはセッションキーを再利用するために必要なので、新しい接続を確立するために古いキーが使用されます。 ハンドシェイクは再現されません。 キャッシュが存在しない場合、すべての要素でのページの読み込み時間が大幅に増加するため、DHEエンコーディングを使用する場合(たとえばOpera 12ブラウザーで)、特に関連性が高くなります。 共有パラメーターは、すべてのワークフローに共通のnginxキャッシュを設定します。10m-キャッシュサイズ(10 MB、1 MB〜4000セッション、これらの設定では最大4万セッションまで保存可能)、5m-キャッシュのセッションタイムアウト(5分) 。

ssl_prefer_server_ciphers on;
「SSLv3およびTLSプロトコルを使用する場合、サーバー暗号をクライアント暗号よりも優先するように指定します。」(Nginx.org)-クライアント暗号(CBC)は特定の種類の攻撃に対して脆弱です。

ssl_stapling on;
サーバーがOCSP応答を添付できるようにして、ユーザーのページ読み込み時間を短縮します。 ここでは、証明書の有効性についての回答を意味します(失効を確認する場合)。 ユーザーのセキュリティの観点から、誰が回答を送信するかは問題ではありません-WebサーバーまたはCAサーバー-結局、回答はいずれの場合でも署名され、応答の有効性も確認でき、回答には有効期限が含まれます。
この機能を機能させるには、リゾルバーディレクティブによって行われるDNSサーバーを指定する必要があります。

keepalive_timeout-説明を必要とせず、オフにしたり、接続を再確立するために負荷を減らすために小さくしすぎたりしないでください。

ssl_certificatessl_certificate_keyは、証明書ファイルとその秘密鍵ファイルを指します。 StartSSLからの証明書の例について説明しているので、ここで証明書をインストールするためのStartSSLの指示について少しコメントします-一般的な証明書ファイルにルートCA証明書を追加する必要はありません。データ。 ファイルに個人証明書と中間証明機関の証明書があれば十分です。 (StartSSL証明書用の)nginxの完成した証明書ファイルは、次のコマンドで取得できます。
 cat certificate.crt sub.class1.server.ca.pem > certificate_bundled.crt 

証明書がcertificate.crtであり、中間証明書がwww.startssl.com/certs/sub.class1.server.ca.pemである場合

add_header Strict-Transport-Security 'max-age = 604800';
Strict-Transport-Secutiry-サイトにhttps経由でのみアクセスできることをブラウザに伝えるヘッダー。 これにより、暗号化されていない接続を介した後続の攻撃のためにhttpバージョンに戻る可能性がなくなります。 ところで、このパラメーターは、ページコードにhttpを介した同じサイトからの「忘れられた」リソース接続(画像/スクリプト/スタイル/ ...)がある場合、ブラウザー自体がhttpsバージョンに移動し、部分的に暗号化されていないことを誓わないという点でも便利です接続。 もちろん、これは外部リソースでは機能しません。 時間は1週間です。 多くの場合、1年に設定することをお勧めしますが、将来httpsを使用しないことにした場合、これは一部のユーザーに問題を引き起こす可能性があります。 時間は、このヘッダーの送信ごとに更新されます。 サイトを訪れるたびに。

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
サポートされているプロトコルを示します。 SSLv2およびv3には重大な脆弱性があります。

ssl_ciphers "高:!RC4 :! aNULL :! MD5 :! kEDH";
使用される暗号を示します。 実際、暗号スイートの変更により、Forward Secrecyが設定されています。 これは、nginxが提供する標準セットとはKEDHパラメーターのみが異なります。

前方秘匿


Forward Secrecyを有効にするには、たとえば次の暗号スイートを使用できます。
 ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; 


さらに、OpenSSL暗号の優先度を設定する必要があります。
 openssl ciphers -V 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA256 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA EECDH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS' 

このオプションは、一部のブラウザーとの互換性を維持するためにRC4を使用することを禁止しませんが、実装するのは実際には困難ですが、それ以前に脆弱性が発見されました

暗号化を強化するには、DH暗号のパラメーターのファイルを作成することでDH暗号の強度を高めることができます(ファイルの作成には時間がかかります)。
 openssl dhparam -out dh4096.pem 4096 

そして、nginx設定にディレクティブを追加します
 ssl_dhparam dh4096.pem; 

これは、たとえば、Webベースのサーバー/サービス管理インターフェースに対して実行できますが、ハンドシェイクにはさらに時間がかかるため、通常のサイトでは実行しないでください。

CDNサービスについて


Forward Secrecyのセットアップ手順の説明で、少なくともAmazon CloudFrontのCDNはサーバーとのDH暗号化交換をサポートしていないことに気づきました。RC4は少し悪いようです。 他のCDNでもすべてが完璧というわけではありませんが、個人的にはまだそれらに出会っていないので、何も言えません。

便利なリンク


https Webサーバー設定のテスト
Forward SecrecyのApacheおよびnginx設定

Source: https://habr.com/ru/post/J195808/


All Articles