Debian8でLet’sEncryptを使用してNginxを保護する方法
序章
Let’s Encryptは、無料のTLS / SSL証明書を簡単に取得してインストールできる新しい認証局(CA)であり、Webサーバーで暗号化されたHTTPSを有効にします。 ソフトウェアクライアントを提供することにより、プロセスを簡素化します。 certbot
(以前は letsencrypt
)、必要な手順のほとんど(すべてではないにしても)を自動化しようとします。 現在、証明書の取得とインストールのプロセス全体は、ApacheWebサーバーでのみ完全に自動化されています。 ただし、Let’s Encryptを使用すると、無料のSSL証明書を簡単に取得できます。この証明書は、選択したWebサーバーソフトウェアに関係なく、手動でインストールできます。
このチュートリアルでは、Let’s Encryptを使用して無料のSSL証明書を取得し、Debian8のNginxで使用する方法を示します。 また、SSL証明書を自動的に更新する方法についても説明します。 別のWebサーバーを実行している場合は、Webサーバーのドキュメントに従って、セットアップで証明書を使用する方法を学習してください。
前提条件
このチュートリアルに従う前に、いくつかのことが必要になります。
root以外のユーザーがいるDebian8サーバーが必要です。 sudo
特権。 このようなユーザーアカウントを設定する方法は、Debian8チュートリアルの初期サーバー設定に従うことで学ぶことができます。
サーバーにNginxをまだインストールしていない場合は、このガイドに従ってインストールしてください。
証明書を使用する登録済みドメイン名を所有または管理する必要があります。 まだドメイン名を登録していない場合は、そこにある多くのドメイン名レジストラの1つに登録できます(例: Namecheap、GoDaddyなど)。
まだ作成していない場合は、ドメインがサーバーのパブリックIPアドレスを指す Aレコードを作成してください(DigitalOceanのDNSを使用している場合は、このガイドに従うことができます])。 これが必要なのは、Let’s Encryptが、証明書を発行しているドメインを所有していることを検証する方法のためです。 たとえば、次の証明書を取得する場合 example.com
、検証プロセスが機能するには、そのドメインがサーバーに解決される必要があります。 私たちのセットアップは使用します example.com
と www.example.com
ドメイン名として、両方のDNSレコードが必要です。
すべての前提条件が整ったら、Let’sEncryptクライアントソフトウェアのインストールに進みましょう。
ステップ1:Let’sEncryptクライアントであるCertbotをインストールする
Let’s Encryptを使用してSSL証明書を取得するための最初のステップは、 certbot
サーバー上のクライアントを暗号化しましょう。
The certbot
Debian 8がリリースされたとき、パッケージは利用できませんでした。 アクセスするには certbot
パッケージの場合、サーバーでJessieバックポートリポジトリを有効にする必要があります。 このリポジトリを使用して、安定したリポジトリに含まれているものよりも新しいバージョンのソフトウェアをインストールできます。
次のように入力して、バックポートリポジトリをサーバーに追加します。
- echo 'deb http://ftp.debian.org/debian jessie-backports main' | sudo tee /etc/apt/sources.list.d/backports.list
新しいリポジトリを追加した後、 apt
新しいパッケージに関する情報をダウンロードするためのパッケージインデックス:
- sudo apt-get update
リポジトリが更新されたら、 certbot
バックポートリポジトリをターゲットにしてパッケージ化:
注:バックポートを使用する場合は、一般的な更新にリポジトリを使用するのではなく、必要な特定のパッケージのみをインストールすることをお勧めします。 バックポートパッケージは、メインリポジトリよりも互換性の保証が少なくなっています。
このリポジトリを使用して誤ってパッケージをインストールまたは更新しないようにするには、明示的に -t
バックポートからパッケージをインストールするためのリポジトリ名のフラグ。
- sudo apt-get install certbot -t jessie-backports
The certbot
これで、クライアントを使用する準備が整いました。
ステップ2:SSL証明書を取得する
Let’s Encryptは、さまざまなプラグインを介してSSL証明書を取得するためのさまざまな方法を提供します。 別のチュートリアルで説明されているApacheプラグインとは異なり、ほとんどのプラグインは、使用するWebサーバーを手動で構成する必要がある証明書の取得にのみ役立ちます。 証明書のみを取得し、それらをインストールしないプラグインは、サーバーに証明書を発行する必要があるかどうかを認証するために使用されるため、「認証者」と呼ばれます。
Webrootプラグインを使用してSSL証明書を取得する方法を説明します。
Webrootプラグインの使用方法
Webrootプラグインは、特別なファイルをに配置することで機能します /.well-known
検証のためにLet’sEncryptサービスによって(Webサーバーを介して)開くことができるドキュメントルート内のディレクトリ。 構成によっては、へのアクセスを明示的に許可する必要がある場合があります /.well-known
ディレクトリ。
Nginxをまだインストールしていない場合は、このチュートリアルに従ってインストールしてください。 終了したら、以下に進みます。
検証のためにLet’sEncryptがディレクトリにアクセスできることを確認するために、Nginx構成に簡単な変更を加えましょう。 デフォルトでは、次の場所にあります /etc/nginx/sites-available/default
. 使用します nano
編集するには:
- sudo nano /etc/nginx/sites-available/default
サーバーブロック内に、次のロケーションブロックを追加します。
location ~ /.well-known {
allow all;
}
また、を検索して、ドキュメントルートが何に設定されているかを調べることもできます。 root
Webrootプラグインを使用するにはパスが必要であるため、ディレクティブ。 デフォルトの構成ファイルを使用している場合、ルートは次のようになります。 /var/www/html
.
保存して終了。
構文エラーがないか構成を確認してください。
- sudo nginx -t
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
エラーが見つからない場合は、次のコマンドでNginxを再起動します。
- sudo systemctl restart nginx
今、私たちは私たちを知っています webroot-path
、Webrootプラグインを使用して、これらのコマンドでSSL証明書を要求できます。 ここでは、ドメイン名も指定しています -d
オプション。 単一の証明書を複数のドメイン名で機能させる場合(例: example.com
と www.example.com
)、必ずすべてを含めてください。 また、強調表示された部分を適切なWebルートパスとドメイン名に置き換えてください。
- sudo certbot certonly -a webroot --webroot-path=/var/www/html -d example.com -d www.example.com
後 certbot
初期化すると、メールアドレスを入力してLet’sEncryptの利用規約に同意するよう求められます。 その後、チャレンジが実行されます。 すべてが成功した場合は、次のような出力メッセージが表示されます。
Output:IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/example.com/fullchain.pem. Your cert
will expire on 2017-09-05. To obtain a new or tweaked version of
this certificate in the future, simply run certbot again. To
non-interactively renew *all* of your certificates, run "certbot
renew"
- If you lose your account credentials, you can recover through
e-mails sent to [email protected].
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
出力例で強調表示されている証明書のパスと有効期限をメモしておく必要があります。
ファイアウォール注:次のようなエラーが発生した場合 Failed to connect to host for DVSNI challenge
、ポートでTCPトラフィックを許可するようにサーバーのファイアウォールを構成する必要がある場合があります 80
と 443
.
注:ドメインがCloudFlareなどのDNSサービスを介してルーティングされている場合は、証明書を取得するまで一時的に無効にする必要があります。
証明書ファイル
証明書を取得すると、次のPEMエンコードファイルが作成されます。
- cert.pem:ドメインの証明書
- chain.pem:Let’sEncryptチェーン証明書
- fullchain.pem:
cert.pem
とchain.pem
結合 - privkey.pem:証明書の秘密鍵
作成したばかりの証明書ファイルの場所を知っておくことが重要です。これにより、Webサーバー構成でそれらを使用できるようになります。 ファイル自体は、のサブディレクトリに配置されます /etc/letsencrypt/archive
. ただし、Let’s Encryptは、最新の証明書ファイルへのシンボリックリンクを作成します。 /etc/letsencrypt/live/your_domain_name
ディレクトリ。 リンクは常に最新の証明書ファイルを指すため、これは証明書ファイルを参照するために使用する必要があるパスです。
次のコマンドを実行して、ファイルが存在することを確認できます(ドメイン名に置き換えてください)。
- sudo ls -l /etc/letsencrypt/live/your_domain_name
出力は、前述の4つの証明書ファイルである必要があります。 すぐに、使用するようにWebサーバーを構成します fullchain.pem
証明書ファイルとして、および privkey.pem
証明書キーファイルとして。
強力なDiffie-Hellmanグループを生成する
セキュリティをさらに強化するには、強力なDiffie-Hellmanグループも生成する必要があります。 2048ビットのグループを生成するには、次のコマンドを使用します。
- sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
これには数分かかる場合がありますが、完了すると、強力なDHグループが作成されます。 /etc/ssl/certs/dhparam.pem
.
手順3:Webサーバー(Nginx)でTLS/SSLを構成する
SSL証明書を取得したので、それを使用するようにNginxWebサーバーを構成する必要があります。
構成にいくつかの調整を加えます。
- SSLキーと証明書ファイルの場所を含む構成スニペットを作成します。
- 将来的に任意の証明書で使用できる強力なSSL設定を含む構成スニペットを作成します。
- Nginxサーバーブロックを調整してSSLリクエストを処理し、上記の2つのスニペットを使用します。
Nginxを構成するこの方法により、サーバーブロックをクリーンに保ち、共通の構成セグメントを再利用可能なモジュールに配置できます。
SSLキーと証明書を指す構成スニペットを作成する
まず、新しいNginx構成スニペットを作成しましょう /etc/nginx/snippets
ディレクトリ。
このファイルの目的を正しく区別するために、名前を付けます ssl-
ドメイン名、ドメイン名、 .conf
終わりに:
- sudo nano /etc/nginx/snippets/ssl-example.com.conf
このファイル内で、 ssl_certificate
証明書ファイルへのディレクティブと ssl_certificate_key
関連するキーに。 私たちの場合、これは次のようになります。
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
これらの行を追加したら、ファイルを保存して閉じます。
強力な暗号化設定を使用して構成スニペットを作成する
次に、いくつかのSSL設定を定義する別のスニペットを作成します。 これにより、Nginxに強力なSSL暗号スイートが設定され、サーバーの安全性を維持するのに役立ついくつかの高度な機能が有効になります。
設定するパラメーターは、将来のNginx構成で再利用できるため、ファイルに一般的な名前を付けます。
- sudo nano /etc/nginx/snippets/ssl-params.conf
Nginx SSLを安全にセットアップするために、Cipherli.stサイトのRemyvanElstによる推奨事項を使用します。 このサイトは、人気のあるソフトウェアの使いやすい暗号化設定を提供するように設計されています。 Nginxの選択に関する彼の決定について詳しくは、こちらをご覧ください。
注: Cipherli.st のデフォルトの推奨設定は、強力なセキュリティを提供します。 場合によっては、これにはクライアントの互換性が向上するという犠牲が伴います。 古いクライアントをサポートする必要がある場合は、「はい、レガシー/古いソフトウェアで動作する暗号スイートを教えてください」というラベルの付いたリンクのリンクをクリックしてアクセスできる代替リストがあります。
以下の構成では、デフォルトの提案の代わりに互換性リストを使用できます。 使用する構成の選択は、サポートする必要があるものに大きく依存します。
私たちの目的のために、提供された設定全体をコピーすることができます。 いくつかの小さな変更を加える必要があります。
まず、アップストリームリクエスト用に優先DNSリゾルバーを追加します。 このガイドではGoogleを使用します。 また、先に進み、 ssl_dhparam
以前に生成したDiffie-Hellmanファイルを指すように設定します。
最後に、 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構成を調整する
スニペットができたので、Nginx構成を調整してSSLを有効にすることができます。
このガイドでは、 default
のサーバーブロックファイル /etc/nginx/sites-available
ディレクトリ。 別のサーバーブロックファイルを使用している場合は、以下のコマンドでその名前に置き換えてください。
先に進む前に、現在のサーバーブロックファイルをバックアップしましょう。
- 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
ディレクティブ、追加します server_name
ディレクティブ。サーバーのドメイン名に設定します。 次に、作成する2番目のサーバーブロックへのリダイレクトを設定します。 その後、この短いブロックを閉じます。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
. . .
次に、残りの構成を含めるために、すぐ下に新しいサーバーブロックを開始する必要があります。 2つのコメントを外すことができます listen
ポート443を使用するディレクティブ。 その後、設定した2つのスニペットファイルを含める必要があります。
注:使用できるのは1つのみです。 listen
を含むディレクティブ default_server
各IPバージョンとポートの組み合わせの修飾子。 これらのポートで他のサーバーブロックを有効にしている場合 default_server
設定すると、ブロックの1つから修飾子を削除する必要があります。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
. . .
終了したら、ファイルを保存して閉じます。
(代替構成)HTTPトラフィックとHTTPSトラフィックの両方を許可する
暗号化されたコンテンツと暗号化されていないコンテンツの両方を許可する必要がある場合は、Nginxを少し異なる方法で構成する必要があります。 これは、回避できる場合は一般的に推奨されませんが、状況によっては必要になる場合があります。 基本的に、2つの別々のサーバーブロックを1つのブロックに圧縮し、リダイレクトを削除します。
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name example.com www.example.com;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
. . .
終了したら、ファイルを保存して閉じます。
ステップ4:ファイアウォールを調整する
ファイアウォールを有効にしている場合は、SSLトラフィックを許可するように設定を調整する必要があります。 必要な手順は、使用しているファイアウォールソフトウェアによって異なります。 現在ファイアウォールが構成されていない場合は、スキップしてください。
UFW
ufw を使用している場合は、次のように入力すると現在の設定を確認できます。
- sudo ufw status
おそらく次のようになります。つまり、WebサーバーへのHTTPトラフィックのみが許可されます。
OutputStatus: active
To Action From
-- ------ ----
SSH ALLOW Anywhere
WWW ALLOW Anywhere
SSH (v6) ALLOW Anywhere (v6)
WWW (v6) ALLOW Anywhere (v6)
さらにHTTPSトラフィックを取り込むために、「WWWフル」プロファイルを許可してから、冗長な「WWW」プロファイルの許容値を削除できます。
- sudo ufw allow 'WWW Full'
- sudo ufw delete allow 'WWW'
ステータスは次のようになります。
- sudo ufw status
OutputStatus: active
To Action From
-- ------ ----
SSH ALLOW Anywhere
WWW Full ALLOW Anywhere
SSH (v6) ALLOW Anywhere (v6)
WWW Full (v6) ALLOW Anywhere (v6)
これで、HTTPSリクエストがサーバーで受け入れられるはずです。
IPTables
使用している場合 iptables
、次のように入力すると、現在のルールを確認できます。
- sudo iptables -S
ルールを有効にしている場合は、それらが表示されます。 構成例は次のようになります。
Output-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
SSLトラフィックを開くために必要なコマンドは、現在のルールによって異なります。 上記のような基本的なルールセットの場合、次のように入力してSSLアクセスを追加できます。
- sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT
ファイアウォールルールをもう一度見ると、新しいルールが表示されます。
- sudo iptables -S
Output-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
プログラムを使用して自動的に適用する場合 iptables
起動時にルールを使用する場合は、必ず新しいルールで構成を更新する必要があります。
ステップ5:Nginxでの変更を有効にする
変更を加えてファイアウォールを調整したので、Nginxを再起動して新しい変更を実装できます。
まず、ファイルに構文エラーがないことを確認する必要があります。 これを行うには、次のように入力します。
- sudo nginx -t
すべてが成功すると、次のような結果が得られます。
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
出力が上記と一致する場合、構成ファイルに構文エラーはありません。 Nginxを安全に再起動して、変更を実装できます。
- sudo systemctl restart nginx
Let’s Encrypt TLS / SSL証明書が配置され、ファイアウォールがポート80および443へのトラフィックを許可するようになりました。 この時点で、WebブラウザでHTTPS経由でドメインにアクセスして、TLS/SSL証明書が機能することをテストする必要があります。
Qualys SSL Labsレポートを使用して、サーバー構成のスコアを確認できます。
In a web browser:https://www.ssllabs.com/ssltest/analyze.html?d=example.com
これが完了するまでに数分かかる場合があります。 このガイドのSSL設定では、少なくともAの評価を報告する必要があります。
ステップ6:自動更新を設定する
Let’s Encryptの証明書は90日間有効ですが、エラーの許容範囲を確保するために、60日ごとに証明書を更新することをお勧めします。 この記事の執筆時点では、クライアント自体の機能として自動更新はまだ利用できませんが、Let’sEncryptクライアントを実行して証明書を手動で更新できます。 renew
オプション。
インストールされているすべてのドメインの更新プロセスをトリガーするには、次のコマンドを実行します。
- sudo certbot renew
最近証明書をインストールしたため、コマンドは有効期限のみを確認し、証明書がまだ更新されていないことを通知するメッセージを出力します。 出力は次のようになります。
Output:Saving debug log to /var/log/letsencrypt/example.com.log
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal
The following certs are not due for renewal yet:
/etc/letsencrypt/live/example.com/fullchain.pem (skipped)
No renewals were attempted.
複数のドメインでバンドルされた証明書を作成した場合、ベースドメイン名のみが出力に表示されますが、更新はこの証明書に含まれるすべてのドメインに対して有効である必要があることに注意してください。
証明書が古くならないようにするための実用的な方法は、自動更新コマンドを定期的に実行するcronジョブを作成することです。 更新は最初に有効期限をチェックし、証明書の有効期限が30日以内の場合にのみ更新を実行するため、たとえば、毎週または毎日実行するcronジョブを作成しても安全です。
crontabを編集して、毎週renewalコマンドを実行する新しいジョブを作成しましょう。 rootユーザーのcrontabを編集するには、次のコマンドを実行します。
- sudo crontab -e
初めて使用する場合 crontab
、お好みのテキストエディタを選択するように求められる場合があります。 強い好みがない場合は、nanoが簡単な選択です。
次の行を追加します。
crontab entry30 2 * * * /usr/bin/certbot renew --noninteractive --renew-hook "/bin/systemctl reload nginx" >> /var/log/le-renew.log
保存して終了。 これにより、を実行する新しいcronジョブが作成されます。 certbot renew
毎日午前2時30分にコマンドを実行し、証明書が更新された場合はNginxをリロードします。 コマンドによって生成された出力は、次の場所にあるログファイルにパイプされます。 /var/log/le-renewal.log
.
注: cronジョブを作成およびスケジュールする方法の詳細については、VPSガイドでCronを使用してタスクを自動化する方法を確認してください。
結論
それでおしまい! Webサーバーは、無料のLet’s Encrypt TLS / SSL証明書を使用して、HTTPSコンテンツを安全に提供しています。