Debian 8でLet’s Encryptを使用してNginxを保護する方法

前書き

Let’s Encryptは、無料のTLS / SSL証明書を簡単に取得してインストールする新しい認証局(CA)です。これにより、Webサーバーで暗号化されたHTTPSを有効にします。 必要な手順のほとんど(すべてではないにしても)を自動化しようとするソフトウェアクライアント + certbot +(以前は `+ letsencrypt +`と呼ばれていました)を提供することにより、プロセスを簡素化します。 現在、証明書の取得とインストールのプロセス全体は、Apache Webサーバーでのみ完全に自動化されています。 ただし、Let’s Encryptを使用すると、無料のSSL証明書を簡単に取得できます。この証明書は、ウェブサーバーソフトウェアの選択に関係なく、手動でインストールできます。

このチュートリアルでは、Let’s Encryptを使用して無料のSSL証明書を取得し、Debian 8のNginxで使用する方法を示します。 また、SSL証明書を自動的に更新する方法も示します。 別のWebサーバーを実行している場合は、Webサーバーのドキュメントに従って、セットアップで証明書を使用する方法を学習してください。

image:https://assets.digitalocean.com/articles/letsencrypt/nginx-letsencrypt.png [TLS / SSL証明書を暗号化し、自動更新するNginx]

前提条件

このチュートリアルを実行する前に、いくつかのものが必要です。

`+ sudo +`特権を持っている非rootユーザーのDebian 8サーバーが必要です。 Debian 8の初期サーバーセットアップチュートリアルに従って、このようなユーザーアカウントを設定する方法を学ぶことができます。

サーバーにNginxをまだインストールしていない場合は、https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-debian-8 [このガイド]に従ってインストールしてください。

証明書を使用する登録ドメイン名を所有または制御する必要があります。 登録済みのドメイン名をまだお持ちでない場合は、多数のドメイン名レジストラーのいずれかに登録できます(例: Namecheap、GoDaddyなど)。

まだお持ちでない場合は、サーバーのパブリックIPアドレスをドメインにポイントする* Aレコード*を作成してください(DigitalOceanのDNSを使用している場合は、https://www.digitalocean.com/communityをフォローできます/ tutorials / how-to-set-up-a-host-name-with-digitalocean [このガイド])。 これは、Let’s Encryptが証明書を発行するドメインを所有していることを検証する方法のために必要です。 たとえば、「+ example.com 」の証明書を取得する場合、検証プロセスが機能するためには、そのドメインがサーバーに解決される必要があります。 このセットアップでは、ドメイン名として「 example.com 」と「 www.example.com +」を使用するため、両方のDNSレコードが必要です

すべての前提条件が整ったら、次にLet’s Encryptクライアントソフトウェアのインストールに進みましょう。

ステップ1:Let’s Encrypt ClientであるCertbotをインストールする

Let’s Encryptを使用してSSL証明書を取得する最初のステップは、サーバーに「+ certbot +」Let’s Encryptクライアントをインストールすることです。

Debian 8のリリース時には、 `+ certbot `パッケージは利用できませんでした。 ` 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

リポジトリが更新されたら、backportsリポジトリを対象として `+ certbot +`パッケージをインストールできます。

sudo apt-get install certbot -t jessie-backports

これで、 `+ certbot +`クライアントを使用する準備ができました。

ステップ2:SSL証明書を取得する

Let’s Encryptは、さまざまなプラグインを通じてSSL証明書を取得するさまざまな方法を提供します。 https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-debian-8 [別のチュートリアル]で説明されているApacheプラグインとは異なり、ほとんどのプラグインは、使用するWebサーバーを手動で構成する必要がある証明書の取得にのみ役立ちます。 証明書を取得するだけでインストールしないプラグインは、サーバーに証明書を発行するかどうかを認証するために使用されるため、「認証者」と呼ばれます。

  • Webroot *プラグインを使用してSSL証明書を取得する方法を示します。

Webrootプラグインの使用方法

Webrootプラグインは、ドキュメントルート内の `+ /。well-known `ディレクトリに特別なファイルを配置することで機能します。これは、検証のためにLet's Encryptサービスによって(Webサーバーを介して)開くことができます。 設定によっては、 ` /。well-known +`ディレクトリへのアクセスを明示的に許可する必要がある場合があります。

Nginxをまだインストールしていない場合は、https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-debian-8 [このチュートリアル]に従ってインストールしてください。 終了したら、下に進みます。

確認のためにLet’s Encryptがディレクトリにアクセスできるようにするために、Nginxの設定を簡単に変更しましょう。 デフォルトでは、「+ / etc / nginx / sites-available / default 」にあります。 編集するには、 ` nano`を使用します。

sudo nano /etc/nginx/sites-available/default

サーバーブロック内に、次の場所ブロックを追加します。

SSLサーバーブロックに追加

       location ~ /.well-known {
               allow all;
       }

Webrootプラグインを使用するにはパスが必要なので、 `+ root `ディレクティブを検索して、ドキュメントルートに設定されているものを検索することもできます。 デフォルトの設定ファイルを使用している場合、ルートは ` / 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 +)、それらすべてを必ず含めてください。 また、強調表示された部分を適切なwebrootパスとドメイン名に置き換えてください:

sudo certbot certonly -a webroot --webroot-path= -d  -d

`+ certbot +`が初期化されると、メールを入力してLet’s Encryptの利用規約に同意するよう求められます。 その後、チャレンジが実行されます。 すべてが成功した場合、次のような出力メッセージが表示されます。

Output:IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
  fullchain.pem. Your cert
  will expire on . 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

出力例で強調表示された証明書のパスと有効期限に注意してください。

証明書ファイル

証明書を取得すると、次のPEMエンコードファイルが作成されます。

  • * cert.pem:*ドメインの証明書

  • * chain.pem:* Let’s Encryptチェーン証明書

  • * fullchain.pem:* `+ cert.pem `と ` chain.pem +`の組み合わせ

  • * privkey.pem:*証明書の秘密鍵

作成したばかりの証明書ファイルの場所を知っておくことは重要です。そのため、それらをWebサーバーの構成で使用できます。 ファイル自体は、 `+ / etc / letsencrypt / archive `のサブディレクトリに配置されます。 ただし、Let’s Encryptは、 ` / etc / letsencrypt / live / +`ディレクトリに最新の証明書ファイルへのシンボリックリンクを作成します。 リンクは常に最新の証明書ファイルを指すため、これは証明書ファイルを参照するために使用する必要があるパスです。

次のコマンドを実行して(ドメイン名に置き換えて)ファイルが存在することを確認できます。

sudo ls -l /etc/letsencrypt/live/

出力は、前述の4つの証明書ファイルになります。 すぐに、証明書ファイルとして「+ fullchain.pem 」、証明書キーファイルとして「 privkey.pem +」を使用するようにウェブサーバーを設定します。

強いDiffie-Hellmanグループを生成する

セキュリティをさらに高めるには、強力なDiffie-Hellmanグループも生成する必要があります。 2048ビットグループを生成するには、次のコマンドを使用します。

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

これには数分かかる場合がありますが、完了すると「+ / etc / ssl / certs / dhparam.pem +」に強力なDHグループが作成されます。

ステップ3:Webサーバー(Nginx)でTLS / SSLを構成する

SSL証明書を取得したので、それを使用するようにNginx Webサーバーを構成する必要があります。

構成をいくつか調整します。

  1. SSLキーと証明書ファイルの場所を含む構成スニペットを作成します。

  2. 将来的に任意の証明書で使用できる強力なSSL設定を含む構成スニペットを作成します。

  3. Nginxサーバーブロックを調整してSSLリクエストを処理し、上記の2つのスニペットを使用します。

このNginxの設定方法により、サーバーブロックをクリーンに保ち、共通の設定セグメントを再利用可能なモジュールに配置できます。

SSLキーと証明書を指す構成スニペットを作成する

最初に、 `+ / etc / nginx / snippets +`ディレクトリに新しいNginx設定スニペットを作成しましょう。

このファイルの目的を適切に区別するために、 `+ ssl- `にドメイン名、最後に ` .conf +`を付けて名前を付けます。

sudo nano /etc/nginx/snippets/ssl-.conf

このファイル内で、証明書ファイルに + ssl_certificate`ディレクティブを設定し、関連キーに + ssl_certificate_key`を設定するだけです。 私たちの場合、これは次のようになります。

/etc/nginx/snippets/ssl-example.com.conf

ssl_certificate /etc/letsencrypt/live//fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live//privkey.pem;

これらの行を追加したら、ファイルを保存して閉じます。

強力な暗号化設定で構成スニペットを作成する

次に、SSL設定を定義する別のスニペットを作成します。 これにより、Nginxに強力なSSL暗号スイートが設定され、サーバーのセキュリティを維持するのに役立ついくつかの高度な機能が有効になります。

設定するパラメーターは、将来のNginx構成で再利用できるため、ファイルに一般的な名前を付けます。

sudo nano /etc/nginx/snippets/ssl-params.conf

Nginx SSLを安全にセットアップするには、https://cipherli.st [Cipherli.st]サイトでhttps://raymii.org/s/static/About.html[Remy van Elst]の推奨事項を使用します。 このサイトは、一般的なソフトウェアの使いやすい暗号化設定を提供するように設計されています。 Nginxの選択肢に関する彼の決定については、https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html [こちら]をご覧ください。

この目的のために、提供された設定全体をコピーできます。 少し修正するだけです。

まず、アップストリームリクエストに優先DNSリゾルバを追加します。 このガイドではGoogleを使用します。 また、先に生成したDiffie-Hellmanファイルを指すように `+ ssl_dhparam +`設定を設定します。

最後に、https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security [HTTP Strict Transport Security、またはHSTS]、特にhttps://hstspreload.appspot.com/ [ 「プリロード」機能]。 HSTSをプリロードするとセキュリティが向上しますが、誤って有効にしたり誤って有効にしたりすると、広範囲に及ぶ結果を招く可能性があります。 このガイドでは、設定をプリロードしませんが、その意味を理解していることが確実な場合は変更できます。

/etc/nginx/snippets/ssl-params.conf

# 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  valid=300s;
resolver_timeout 5s;


add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

完了したら、ファイルを保存して閉じます。

Nginx構成を調整してSSLを使用する

スニペットができたので、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

内部では、サーバーブロックはおそらく次のように始まります。

/ 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番目のサーバーブロックへのリダイレクトを設定します。 その後、この短いブロックを閉じます。

/ etc / nginx / sites-available / default

server {
   listen 80 default_server;
   listen [::]:80 default_server;
   server_name  www.;



   # SSL configuration

   # listen 443 ssl default_server;
   # listen [::]:443 ssl default_server;

   . . .

次に、すぐ下に新しいサーバーブロックを起動して、残りの構成を含める必要があります。 ポート443を使用する2つの `+ listen +`ディレクティブのコメントを外すことができます。 その後、設定した2つのスニペットファイルを含めるだけです。

/ etc / nginx / sites-available / default

server {
   listen 80 default_server;
   listen [::]:80 default_server;
   server_name  www.;
   return 301 https://$server_name$request_uri;
}



   # SSL configuration






   . . .

完了したら、ファイルを保存して閉じます。

(代替構成)HTTPおよびHTTPSトラフィックの両方を許可する

暗号化されたコンテンツと暗号化されていないコンテンツの両方を許可する必要がある場合、またはNginxを少し異なるように構成する必要があります。 これは、回避できる場合は一般的に推奨されませんが、状況によっては必要になる場合があります。 基本的に、2つの個別のサーバーブロックを1つのブロックに圧縮し、リダイレクトを削除します。

/ etc / nginx / sites-available / default

server {
   listen 80 default_server;
   listen [::]:80 default_server;



   server_name  www.;



   . . .

完了したら、ファイルを保存して閉じます。

ステップ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 Full」プロファイルを許可してから、冗長な「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 -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=

これには数分かかる場合があります。 このガイドのSSLセットアップは、少なくとも* A *の評価を報告する必要があります。

ステップ6:自動更新を設定する

Let’s Encrypt証明書は90日間有効ですが、エラーを許容するために60日ごとに証明書を更新することをお勧めします。 この記事の執筆時点では、クライアント自体の機能として自動更新はまだ使用できませんが、「+ renew +」オプションを使用してLet’s Encryptクライアントを実行することにより、手動で証明書を更新できます。

インストールされているすべてのドメインの更新プロセスをトリガーするには、次のコマンドを実行します。

sudo certbot renew

証明書を最近インストールしたため、コマンドは有効期限を確認するだけで、証明書がまだ更新されていないことを通知するメッセージを出力します。 出力は次のようになります。

Output:Saving debug log to /var/log/letsencrypt/.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

The following certs are not due for renewal yet:
 /etc/letsencrypt/live//fullchain.pem (skipped)
No renewals were attempted.

複数のドメインを含むバンドルされた証明書を作成した場合、ベースドメイン名のみが出力に表示されますが、更新はこの証明書に含まれるすべてのドメインに対して有効であることに注意してください。

証明書が古くなることのないようにするための実用的な方法は、自動更新コマンドを定期的に実行するcronジョブを作成することです。 更新は最初に有効期限をチェックし、証明書の有効期限が30日以内の場合にのみ更新を実行するため、たとえば毎週または毎日実行されるcronジョブを作成しても安全です。

crontabを編集して、毎週更新コマンドを実行する新しいジョブを作成しましょう。 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

保存して終了。 これにより、毎日午前2:30に `+ certbot renew `コマンドを実行する新しいcronジョブが作成され、証明書が更新されるとNginxがリロードされます。 コマンドによって生成された出力は、 ` / var / log / le-renewal.log +`にあるログファイルにパイプされます。

結論

それでおしまい! Webサーバーは、無料のLet’s Encrypt TLS / SSL証明書を使用してHTTPSコンテンツを安全に提供しています。

Related