Ubuntu16.04でNginxの自己署名SSL証明書を作成する方法
序章
TLS 、つまりトランスポート層セキュリティ、およびその前身である SSL は、セキュアソケットレイヤーの略で、通常のトラフィックを保護された暗号化ラッパーでラップするために使用されるWebプロトコルです。
このテクノロジーを使用すると、サーバーは、メッセージが外部の関係者によって傍受される可能性なしに、サーバーとクライアントの間でトラフィックを安全に送信できます。 証明書システムは、ユーザーが接続しているサイトのIDを確認するのにも役立ちます。
このガイドでは、Ubuntu16.04サーバー上のNginxWebサーバーで使用するための自己署名SSL証明書を設定する方法を示します。
注:自己署名証明書は、サーバーとクライアント間の通信を暗号化します。 ただし、Webブラウザに含まれている信頼できる認証局によって署名されていないため、ユーザーは証明書を使用してサーバーのIDを自動的に検証することはできません。
サーバーにドメイン名が関連付けられていない場合や、暗号化されたWebインターフェイスがユーザー向けでない場合は、自己署名証明書が適切な場合があります。 do にドメイン名がある場合、多くの場合、CA署名付き証明書を使用することをお勧めします。 Let’sEncryptプロジェクトここで無料の信頼できる証明書を設定する方法を見つけることができます。
前提条件
始める前に、root以外のユーザーにsudo
権限を設定しておく必要があります。 Ubuntu 16.04 の初期サーバー設定に従うことで、このようなユーザーアカウントを設定する方法を学ぶことができます。
また、NginxWebサーバーをインストールする必要があります。 LEMPスタック全体(Linux、Nginx、MySQL、PHP)をサーバーにインストールする場合は、 Ubuntu16.04でのLEMPのセットアップに関するガイドに従ってください。
Nginx Webサーバーが必要な場合は、代わりに Ubuntu16.04へのNginxのインストールに関するガイドに従うことができます。
前提条件を完了したら、以下に進みます。
ステップ1:SSL証明書を作成する
TLS / SSLは、公開証明書と秘密鍵の組み合わせを使用して機能します。 SSLキーはサーバー上で秘密にされます。 クライアントに送信されるコンテンツを暗号化するために使用されます。 SSL証明書は、コンテンツを要求するすべての人と公に共有されます。 これは、関連付けられたSSLキーによって署名されたコンテンツを復号化するために使用できます。
1つのコマンドで、OpenSSLを使用して自己署名キーと証明書のペアを作成できます。
- sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
一連の質問があります。 それを説明する前に、発行しているコマンドで何が起こっているかを見てみましょう。
- openssl :これは、OpenSSL証明書、キー、およびその他のファイルを作成および管理するための基本的なコマンドラインツールです。
- req :このサブコマンドは、X.509証明書署名要求(CSR)管理を使用することを指定します。 「X.509」は、SSLおよびTLSが鍵および証明書の管理のために準拠している公開鍵インフラストラクチャ標準です。 新しいX.509証明書を作成したいので、このサブコマンドを使用しています。
- -x509 :これは、通常行われるように証明書署名要求を生成するのではなく、自己署名証明書を作成することをユーティリティに通知することにより、前のサブコマンドをさらに変更します。
- -nodes :これは、パスフレーズで証明書を保護するオプションをスキップするようにOpenSSLに指示します。 サーバーの起動時に、ユーザーの介入なしにNginxがファイルを読み取れるようにする必要があります。 パスフレーズは、再起動するたびに入力する必要があるため、これが発生するのを防ぎます。
- -365日:このオプションは、証明書が有効であると見なされる期間を設定します。 ここで1年間設定しました。
- -newkey rsa:2048 :これは、新しい証明書と新しいキーを同時に生成することを指定します。 前の手順で証明書に署名するために必要なキーを作成しなかったため、証明書と一緒に作成する必要があります。
rsa:2048
部分は、2048ビット長のRSAキーを作成するように指示します。 - -keyout :この行は、作成している生成された秘密鍵ファイルを配置する場所をOpenSSLに指示します。
- -out :これはOpenSSLに作成する証明書を配置する場所を指示します。
上で述べたように、これらのオプションはキーファイルと証明書の両方を作成します。 情報を証明書に正しく埋め込むために、サーバーについていくつか質問があります。
プロンプトに適切に記入します。
プロンプト全体は次のようになります。
OutputCountry Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc.
Organizational Unit Name (eg, section) []:Ministry of Water Slides
Common Name (e.g. server FQDN or YOUR name) []:server_IP_address
Email Address []:admin@your_domain.com
作成した両方のファイルは、/etc/ssl
ディレクトリの適切なサブディレクトリに配置されます。
OpenSSLを使用している間、クライアントとの Perfect ForwardSecrecyのネゴシエーションに使用される強力なDiffie-Hellmanグループも作成する必要があります。
これを行うには、次のように入力します。
- sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
これには数分かかる場合がありますが、完了すると、構成で使用できる/etc/ssl/certs/dhparam.pem
に強力なDHグループが作成されます。
ステップ2:SSLを使用するようにNginxを構成する
/etc/ssl
ディレクトリの下にキーファイルと証明書ファイルを作成しました。 これらを利用するには、Nginx構成を変更する必要があります。
構成にいくつかの調整を加えます。
- SSLキーと証明書ファイルの場所を含む構成スニペットを作成します。
- 将来的に任意の証明書で使用できる強力なSSL設定を含む構成スニペットを作成します。
- Nginxサーバーブロックを調整してSSLリクエストを処理し、上記の2つのスニペットを使用します。
Nginxを構成するこの方法により、サーバーブロックをクリーンに保ち、共通の構成セグメントを再利用可能なモジュールに配置できます。
SSLキーと証明書を指す構成スニペットを作成する
まず、/etc/nginx/snippets
ディレクトリに新しいNginx構成スニペットを作成しましょう。
このファイルの目的を正しく区別するために、self-signed.conf
と呼びましょう。
- sudo nano /etc/nginx/snippets/self-signed.conf
このファイル内で、ssl_certificate
ディレクティブを証明書ファイルに設定し、ssl_certificate_key
を関連するキーに設定する必要があります。 私たちの場合、これは次のようになります。
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
これらの行を追加したら、ファイルを保存して閉じます。
強力な暗号化設定を使用して構成スニペットを作成する
次に、いくつかのSSL設定を定義する別のスニペットを作成します。 これにより、Nginxに強力なSSL暗号スイートが設定され、サーバーの安全性を維持するのに役立ついくつかの高度な機能が有効になります。
設定するパラメーターは、将来のNginx構成で再利用できるため、ファイルに一般的な名前を付けます。
- sudo nano /etc/nginx/snippets/ssl-params.conf
Nginx SSLを安全にセットアップするために、Cipherli.stサイトのRemyvanElstによる推奨事項を使用します。 このサイトは、人気のあるソフトウェアの使いやすい暗号化設定を提供するように設計されています。 Nginxの選択に関する彼の決定について詳しくは、こちらをご覧ください。
上記にリンクされているサイトで推奨される設定は、強力なセキュリティを提供します。 場合によっては、これにはクライアントの互換性が向上するという犠牲が伴います。 古いクライアントをサポートする必要がある場合は、「はい、レガシー/古いソフトウェアで動作する暗号スイートを教えてください」というラベルの付いたページのリンクをクリックしてアクセスできる代替リストがあります。 そのリストは、以下にコピーされたアイテムの代わりに使用できます。
使用する構成の選択は、サポートする必要があるものに大きく依存します。 どちらも優れたセキュリティを提供します。
私たちの目的のために、提供された設定全体をコピーすることができます。 いくつかの小さな変更を加える必要があります。
まず、アップストリームリクエスト用に優先DNSリゾルバーを追加します。 このガイドではGoogleを使用します。 また、先に生成したDiffie-Hellmanファイルを指すようにssl_dhparam
設定を設定します。
最後に、 HTTP Strict Transport Security(HSTS )、特に「プリロード」機能についてお読みください。 HSTSをプリロードするとセキュリティが向上しますが、誤って有効にした場合や誤って有効にした場合は、広範囲に及ぶ結果が生じる可能性があります。 このガイドでは、設定をプリロードしませんが、影響を確実に理解している場合は、設定を変更できます。
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now. You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
自己署名証明書を使用しているため、SSLステープルは使用されません。 Nginxは単に警告を出力し、自己署名証明書のステープルを無効にして、正常に動作し続けます。
終了したら、ファイルを保存して閉じます。
SSLを使用するようにNginx構成を調整する
スニペットができたので、Nginx構成を調整してSSLを有効にすることができます。
このガイドでは、/etc/nginx/sites-available
ディレクトリにあるdefault
サーバーブロックファイルを使用していることを前提としています。 別のサーバーブロックファイルを使用している場合は、以下のコマンドでその名前に置き換えてください。
先に進む前に、現在のサーバーブロックファイルをバックアップしましょう。
- sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
次に、サーバーブロックファイルを開いて調整します。
- sudo nano /etc/nginx/sites-available/default
内部では、サーバーブロックはおそらく次のように始まります。
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .
暗号化されていないHTTPリクエストが暗号化されたHTTPSに自動的にリダイレクトされるように、この構成を変更します。 これは私たちのサイトに最高のセキュリティを提供します。 HTTPトラフィックとHTTPSトラフィックの両方を許可する場合は、次の代替構成を使用します。
構成を2つの別々のブロックに分割します。 最初の2つのlisten
ディレクティブの後に、サーバーのドメイン名またはおそらくIPアドレスに設定されたserver_name
ディレクティブを追加します。 次に、作成する2番目のサーバーブロックへのリダイレクトを設定します。 その後、この短いブロックを閉じます。
注:すべてが正しく機能していることを確認するまで、302リダイレクトを使用します。 その後、これを永続的な301リダイレクトに変更できます。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
}
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .
次に、残りの構成を含めるために、すぐ下に新しいサーバーブロックを開始する必要があります。 ポート443を使用する2つのlisten
ディレクティブのコメントを解除できます。 このブロック内でHTTP/2を有効にするために、これらの行にhttp2
を追加できます。 その後、設定した2つのスニペットファイルを含める必要があります。
注:IPバージョンとポートの組み合わせごとにdefault_server
修飾子を含むone listen
ディレクティブのみを使用できます。 default_server
が設定されているこれらのポートに対して他のサーバーブロックを有効にしている場合は、ブロックの1つから修飾子を削除する必要があります。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 302 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
. . .
終了したら、ファイルを保存して閉じます。
(代替構成)HTTPトラフィックとHTTPSトラフィックの両方を許可する
暗号化されたコンテンツと暗号化されていないコンテンツの両方を許可する必要がある場合は、Nginxを少し異なる方法で構成する必要があります。 これは、回避できる場合は一般的に推奨されませんが、状況によっては必要になる場合があります。 基本的に、2つの別々のサーバーブロックを1つのブロックに圧縮し、リダイレクトを削除します。
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name server_domain_or_IP;
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
. . .
終了したら、ファイルを保存して閉じます。
ステップ3:ファイアウォールを調整する
前提条件ガイドで推奨されているように、ufw
ファイアウォールを有効にしている場合は、SSLトラフィックを許可するように設定を調整する必要があります。 幸い、Nginxはインストール時にufw
にいくつかのプロファイルを登録します。
次のように入力すると、使用可能なプロファイルを確認できます。
- sudo ufw app list
次のようなリストが表示されます。
OutputAvailable applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
次のように入力すると、現在の設定を確認できます。
- sudo ufw status
おそらく次のようになります。つまり、WebサーバーへのHTTPトラフィックのみが許可されます。
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
さらにHTTPSトラフィックを取り込むために、「Nginx Full」プロファイルを許可してから、冗長な「NginxHTTP」プロファイルの許可を削除できます。
- sudo ufw allow 'Nginx Full'
- sudo ufw delete allow 'Nginx HTTP'
ステータスは次のようになります。
- sudo ufw status
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx Full (v6) ALLOW Anywhere (v6)
ステップ4:Nginxで変更を有効にする
変更を加えてファイアウォールを調整したので、Nginxを再起動して新しい変更を実装できます。
まず、ファイルに構文エラーがないことを確認する必要があります。 これを行うには、次のように入力します。
- sudo nginx -t
すべてが成功すると、次のような結果が得られます。
Outputnginx: [warn] "ssl_stapling" ignored, issuer certificate not found
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
最初の警告に注意してください。 前述のように、自己署名証明書はSSLステープルを使用できないため、この特定の設定は警告をスローします。 これは予想されることであり、サーバーは接続を正しく暗号化できます。
出力が上記と一致する場合、構成ファイルに構文エラーはありません。 Nginxを安全に再起動して、変更を実装できます。
- sudo systemctl restart nginx
ステップ5:暗号化をテストする
これで、SSLサーバーをテストする準備が整いました。
Webブラウザーを開き、https://
に続けて、サーバーのドメイン名またはIPをアドレスバーに入力します。
https://server_domain_or_IP
作成した証明書は、ブラウザの信頼できる認証局の1つによって署名されていないため、次のような恐ろしい警告が表示される可能性があります。
これは予想された正常なことです。 証明書の暗号化の側面にのみ関心があり、ホストの信頼性のサードパーティによる検証には関心がありません。 「詳細」をクリックしてから、提供されたリンクをクリックして、とにかくホストに進みます。
あなたはあなたのサイトに連れて行かれるべきです。 ブラウザのアドレスバーを見ると、「x」が付いたロックが表示されます。 この場合、これは単に証明書を検証できないことを意味します。 それはまだあなたの接続を暗号化しています。
2つのサーバーブロックでNginxを構成し、HTTPコンテンツをHTTPSに自動的にリダイレクトする場合は、リダイレクトが正しく機能するかどうかを確認することもできます。
http://server_domain_or_IP
これで同じアイコンが表示される場合は、リダイレクトが正しく機能したことを意味します。
ステップ6:永続的なリダイレクトに変更する
リダイレクトが正しく機能し、暗号化されたトラフィックのみを許可する場合は、Nginx構成を変更してリダイレクトを永続的にする必要があります。
サーバーブロック構成ファイルを再度開きます。
- sudo nano /etc/nginx/sites-available/default
return 302
を見つけて、return 301
に変更します。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name server_domain_or_IP;
return 301 https://$server_name$request_uri;
}
. . .
ファイルを保存して閉じます。
構文エラーがないか構成を確認してください。
- sudo nginx -t
準備ができたら、Nginxを再起動して、リダイレクトを永続的にします。
- sudo systemctl restart nginx
結論
クライアント接続に強力な暗号化を使用するようにNginxサーバーを構成しました。 これにより、リクエストを安全に処理できるようになり、外部の関係者がトラフィックを読み取るのを防ぐことができます。