Let's Encrypt and nginx:DebianとUbuntuでのセットアップ

画像







突然この全体の話があなたから渡された場合、 Let's Encryptは非営利組織ISRGの認証センターであり、EFFおよび多くの企業の支援を受けて存在ます。 証明書を暗号化て、すでに1,000万を超えるドメインで使用しています







明らかに無料であることに加えて、Let's Encryptの証明書には、他の商用認証センターにはない特別な利点があります。Let's Encryptから証明書を受け取った場合、すべてが同じであれば、これは永遠に続きます。 1〜2年に1回、証明書を手動で更新する必要はありません。 証明書がどこかに存在することを覚えておく必要はありません。 受信、設定、および忘れました!







気配りのある読者はすぐに異議を申し立てます。証明書は3か月の有効期間で発行されることがわかっているので、どうしてそうなのでしょうか。 問題は、証明書の自動更新にあります。これは、人間の行動がない場合に可能です。







この記事の自動証明書更新の組織は、Let's Encryptのこの基本的な利点を十分に理解できるように細心の注意を払いました。







この記事はなぜですか



EFF Webサイトには、証明書を取得するための推奨プログラムであるCertbotの使用方法に関する簡単な説明がありますが、絶対に必要な場合にのみSSHを介してサーバーにアクセスする人に適しています。 より詳細なドキュメントもありますが、これまでのところ、すべてを読んで、本当に知っておく必要のあるすべてのものを見つけます...さらに、証明書の使用に関するいくつかの重要な戦略的問題に対処していません。







明らかに、サーバーコンソールに慣れているが、あまり時間をかけずにそれを理解したい人には、短くてわかりやすい指示が必要です。







内容



この記事から学ぶことができます...







  1. Certbotを定期的にインストールして構成する方法。
  2. nginxに必要なものと、証明書を受信するためのnginxの構成方法
  3. 証明書の取得 方法と受信した証明書の確認方法
  4. Let's Encryptの証明書をnginx にインストールする方法
  5. 証明書を自動的に更新する方法。


注意事項



SNIのすべてを知っていますか? すぐにインストールについて読んでください。







以下の手順では、サイトでSNIを使用すると想定しています。 TLSプロトコルのこの拡張により、ブラウザーは、サーバーからSSL証明書を受け取って検証する前に、目的のサイト名を通信できます。 SNIのおかげで、1つのIPでHTTPSを介して任意のサイトをホストできます。 しかし、すべてがそれほど単純ではありません-さもなければ、なぜこれについて書くのでしょうか?







原則的にSNIをサポートしない古いブラウザがいくつかあります。 これらには、 すでに放棄されたWindows XPのIEのすべてのバージョン、 2010年のAndroid 2.3および2.2の組み込みブラウザー、およびJavaバージョン1.6バージョン2.7.9までのPythonなどのよりエキゾチックなブラウザーとライブラリが含まれます







それでもWindows XPのIEでサイトを開きたい場合は、SNIを放棄してもこの問題は解決しません。 暗号を特別な方法で選択する必要があります 。すでに前方秘匿性を放棄 、SSL Labsから低い評価を得るリスクがあります。 ご想像のとおり、この問題は別の議論に値します。それは、XPのIEユーザーは同情できるからです-インターネットの半分が開かれなくなったからです!







わずか1年前、Bingなどの一部の検索ボットによるこのテクノロジーの限定的なサポートにより、SNIへの切り替えが妨げられる可能性がありましたが、SNIなしでは開かない無料のCloudflare証明書を備えた数十のサイト、Bingボット( 検証が容易 )、およびボットの出現により、 他の主要な検索エンジンは現実と一致しています。 今、このために心配することはできません。 Googlebotにはこのような問題は一度もなかったと思います。







心配するもう1つの理由は、サイトのAPIにアクセスするさまざまな方法です。 長期間APIを使用している場合、クライアントの中には古いバージョンのJavaまたはPythonを使用しているクライアントがいる可能性がわずかにあります。 持っていない場合、心配することはありません。 ある場合、私の哀conの意。







SNIに頼る方が良いのはなぜですか?



  1. 簡単です。 発行された証明書に関する事実を常に念頭に置く必要はありません。 最初に証明書が発行されたドメイン。 ドメイン追加する必要がある証明書。 など... SNIでこのようなことを考える必要はありません。







  2. 秘密は秘密のままです。 すべてのドメインに対して1つの証明書がある場合、希望に関係なく、だれでも簡単にリスト全体を表示できます。 各サイトに独自の証明書がある場合、そのような問題はありません。


たとえば、Thematic Media証明書でドメインを確認できます。







true | openssl s_client -showcerts -connect habrahabr.ru:443 2>&1 | openssl x509 -text | grep -o 'DNS:[^,]*' | cut -f2 -d:
      
      





執筆時点で、このコマンドはすべての可能なTMドメインの詳細なリストを表示します。







 habrastorage.org api.geektimes.ru api.habrahabr.ru geektimes.ru habrahabr.ru id.tmtm.ru lab.geektimes.ru m.geektimes.ru m.habrahabr.ru special.geektimes.ru special.habrahabr.ru www.geektimes.ru www.habrahabr.ru
      
      





秘密も秘密もありません。 これが欲しい?







Certbotをインストールする



Certbotがすでに資格や免責事項のないDebian安定版とUbuntuにある未来からこのテキストを読んでいるなら、すべてが簡単です:







 apt-get install certbot
      
      





配布にはaptitude



または別のパッケージマネージャーを使用してください。







Jessieでのインストール



2016年末の時点でまだDebian安定版「jessie」を使用している場合、すべてが少し複雑です。







  1. /etc/apt/sources.list



    次の行を追加して、Debianバックポートを有効にする必要があります。







     deb http://ftp.debian.org/debian/ jessie-backports main contrib non-free
          
          





  2. これで、ソースを使用してインストールできます。







     apt-get update apt-get install certbot -t jessie-backports
          
          





    (このセクションは、 ストレッチのみが安定するまで関連します。)









16.10(yakkety)以下のUbuntuバージョン



 sudo add-apt-repository ppa:certbot/certbot sudo apt-get update sudo apt-get install --upgrade letsencrypt
      
      





さらに、 certbot



代わりにcertbot



使用してletsencrypt









別の分布



他のディストリビューションがある場合は、追加のインストール手順がCertbotの公式Webサイトにあります。 パッケージマネージャーを使用しない場合、通常、インストールは...







 wget -O /usr/local/bin/certbot-auto https://dl.eff.org/certbot-auto chmod +x /usr/local/bin/certbot-auto ln -s /usr/local/bin/certbot-auto /usr/local/bin/certbot
      
      





以下では、 certbot



コマンドの代わりにcertbot-auto



コマンドを使用できます。







Certbotとwebroot



Webサーバーを再構成または停止せずにwebrootメソッドを使用して証明書を受け取ります。つまり、nginxです。 certbot



がファイルを書き込むディレクトリが必要であり、 ACMEプロトコルに従ってネットワークから認証サーバーにアクセスできる必要があります。







オプションの長い行を毎回書き込まないように、またはそれらを思い出さないようにするために、 /etc/letsencrypt/cli.ini



見つけることを期待する構成ファイルにメイン設定を書き込みます。







 authenticator = webroot webroot-path = /var/www/html post-hook = service nginx reload text = True
      
      





最後のディレクティブは、ncursesの魅力と美しさから私たちを救うために必要です。これは、ここ、この記事、そして自宅でコマンドの出力を比較できるようにするために必要です。







また、証明書を正常に更新する場合、nginxを(サービスを中断することなく)穏やかに再起動する必要があります。 受信した証明書を同時に使用するPostfixなどの他のサービスの再起動を妨げるものはありません。 コマンドはセミコロンで区切られます。







セミコロンがエラーを引き起こす場合

このエラーが表示される場合:







 letsencrypt: error: Unexpected line 14 in /etc/letsencrypt/cli.ini: post-hook = service nginx reload; service postfix reload
      
      





次に、 python-configargparse



を更新する必要があります。 エラーは0.11.0修正されました







Certbotが行うこと



certbot



は、指定された階層の下のサブディレクトリでドメイン権限をチェックするために必要なファイルを作成することが期待されています。 これらのように思われる:







 /var/www/html/.well-known/acme-challenge/example.html
      
      





これらのファイルは、少なくともHTTPを介して、ターゲットドメイン上のネットワークからアクセスできる必要があります。







 http://www.example.com/.well-known/acme-challenge/example.html
      
      





次のチェックのために、ある種のファイルを作成します。







 mkdir -p /var/www/html/.well-known/acme-challenge echo Success > /var/www/html/.well-known/acme-challenge/example.html
      
      





Let's Encryptに参加する



登録は一度だけ行う必要があります:







 certbot register --email me@example.com
      
      





ここで複雑なことはありません。







証明書用にnginxを準備する



一般に、証明書を取得するには、すべてのserver



ブロックのすべてのlocation



ブロックに次のブロックを追加する必要がありserver









 location /.well-known { root /var/www/html; }
      
      





各サイトにそのようなブロックを明示的に入力するのは/etc/nginx/acme



であることは明らかです。したがって、上記のブロックの内容でファイル/etc/nginx/acme



を作成します。







 # cat /etc/nginx/acme location /.well-known { root /var/www/html; }
      
      





次に、証明書を取得するドメインとサブドメインごとに、 server



ブロックで、すべてのlocation



ブロックの前に次のようにlocation



ます。







 include acme;
      
      





リダイレクトされたホスト(たとえば、裸のドメインからwwwへ)はスキップできます。 ACMEサーバーは、標準転送を考慮する必要があります。 詳細については、以下をご覧ください。







nginxを再起動し、テストファイルが表示されることを確認します。







 # service nginx reload # curl -L http://www.example.com/.well-known/acme-challenge/example.html Success
      
      





チェック後、テストファイルを削除することをおcertbot



ますcertbot



certbot



なものをすべて削除するのが好きで、そのようなファイルは干渉してエラーメッセージ(チャレンジディレクトリをクリーンアップできません)を引き起こします。







 rm /var/www/html/.well-known/acme-challenge/example.html
      
      





これで、最初の証明書受け取る準備ができました。







転送コード301および302について



すでに述べたように、ACME Boulderサーバーはコード301および302での転送許可しています 。 この意味で、最終的には、チェックに合格するために必要なファイルがどこにあるかは問題ではありません。 最終的なHTTPまたはHTTPSプロトコルの制限なしに、 非標準ポートにでも転送できます。 ドメイン権限をチェックするための単一ポイントを作成するためにリダイレクトを使用することをお勧めします







10個のリダイレクトを制限してcurl



を使用してこれらのファイルを取得できる場合、ボールダーはこれらのファイルを表示します。 IPアドレスに制限はないはずです。







 curl --location --max-redirs 10 http://example.com/.well-known/acme-challenge/example.html
      
      





これは、異なるバージョンのサイト間に複雑なリダイレクト構造がある場合に便利です。 そのブロックをメインサイトのみのlocation



に接続して、他の全員の証明書を取得するだけで十分なはずです。







 $ curl --head --silent --location --max-redirs 10 http://somewhere.example.net/... | grep ^HTTP HTTP/1.1 301 Moved Permanently HTTP/1.1 301 Moved Permanently HTTP/1.1 200 OK
      
      





検証は常に、ポート80のHTTPプロトコル要求で開始されます。







すべてがすでに暗号化されている場合...



既にすべてのサイトがHTTPSで動作している場合、ポート80で転送サーバーを構成すると、スキーム全体が機能し、応答で$request_uri



が保存されます。







もう1つのことは、パスを短くして、ブロックをHTTPSへの転送を行うポート80のデフォルトサーバーのlocation



に接続できることです。 その後、個々のサイトの構成に何かを追加する必要はありません。







このようなオールインワンからHTTPSサーバーへの転送の構成例:







 server { listen server.example.com:80 default_server; include acme; location / { return 301 https://$host$request_uri; } }
      
      





そのような構成は、特定のサイトの構成とは別に、 /etc/nginx/conf.d/default.conf



で定義する必要があります。







Apacheを別のポートに再構成しないように、外部IPでサーバーを明示的に起動します。 これが問題にならない場合は、 listen



ディレクティブでサーバー名の指定をスキップできます。







サイトのないドメインの証明書を取得する必要がある場合...



典型的な例は、サイトがまったくないSMTPまたはIMAP専用サーバーの証明書です。 より高いユニバーサルリダイレクタを使用するか、...







 server { server_name smtp.example.com imap.example.com; listen server.example.com:80; include acme; location / { return 404; } }
      
      





残念ながら、ACMEプロトコルでは、各テスト中にそのようなサーバーが使用可能である必要があります。 これは、サーバーを再起動せずに証明書を取得および更新する必要があるため、継続的な可用性とほぼ同等です。 証明書を受け取った後、そのような構成を削除しないでください。







Apache2しかない場合...



Apache2があるが、お気に入りのnginxに切り替える方法がない場合は、次の行を/etc/apache2/conf-available/certbot.conf



追加します。







 Alias /.well-known/ /var/www/html/.well-known/ <Directory /var/www/html/.well-known/> Satisfy any </Directory>
      
      





それから







 a2enconf certbot mkdir -p /var/www/html/.well-known service apache2 reload
      
      





そして、このように確認してください:







 mkdir -p /var/www/html/.well-known/acme-challenge echo Success > /var/www/html/.well-known/acme-challenge/example.html curl -L http://localhost/.well-known/acme-challenge/example.html && rm /var/www/html/.well-known/acme-challenge/example.html
      
      





Apache2でこのようなスキームが機能しない理由はたくさんあります。 テキスト画面のペアでは、それらすべてを説明するのに十分ではありません。 怒らないでください-nginxに関する記事。







証明書を取得します



Let's Encryptには証明書のリクエスト数に制限があるため、まずテストモードで必要な証明書を取得してください。







 certbot certonly --dry-run -d example.com -d www.example.com
      
      





最後に、プログラムは成功した作業について報告する必要があります。







 The dry run was successful.
      
      





これで、実際に証明書を安全に取得できます。 wwwなど、必要なすべてのサブドメインを明示的に指定してください。







 # certbot certonly -d example.com -d www.example.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org Obtaining a new certificate Performing the following challenges: http-01 challenge for example.com http-01 challenge for www.example.com Using the webroot path /var/www/html for all unmatched domains. Waiting for verification... Cleaning up challenges Generating key (2048 bits): /etc/letsencrypt/keys/0001_key-certbot.pem Creating CSR: /etc/letsencrypt/csr/0001_csr-certbot.pem IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2017-04-01. 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"
      
      





やった! 証明書の受け取りが完了しました!







証明書にサブドメインまたはドメインを追加する必要がある場合



突然www



サブドメインを指定するのを忘れた場合、または証明書に別のドメインまたはサブドメインを追加する必要がある場合( 1つの証明書で最大100 )、証明書を受け取った後にこれを行うのは簡単です。 必要な名前を追加して、コマンドを再度実行するだけです。







 certbot certonly -d example.com -d www.example.com -d shop.example.com
      
      





このドメインを証明書に追加するための代替手段はありません。 質問を避けたい場合は、この動作を承認するキーをすぐに指定できます。







 certbot certonly --expand -d example.com -d www.example.com -d shop.example.com
      
      





操作を繰り返すことができます。







受信した証明書を確認する



受け取った証明書が必要なものであることを確認してください。







 # openssl x509 -text -in /etc/letsencrypt/live/example.com/cert.pem Certificate: Signature Algorithm: ... Validity Not Before: Jan 3 06:00:00 2017 GMT Not After : Apr 3 06:00:00 2017 GMT X509v3 extensions: ... X509v3 Subject Alternative Name: DNS:example.com, DNS:www.example.com
      
      





または、詳細が必要ない場合:







 cat /etc/letsencrypt/live/*/cert.pem | openssl x509 -text | grep -o 'DNS:[^,]*' | cut -f2 -d:
      
      





チームは、証明書にドメインをリストする必要があります。







証明書をインストールして使用する



Certbotは証明書を書き換えませんが、最初の証明書ドメイン( CN



)と同じ名前の特定のディレクトリにある最新の証明書オプションへのリンクに置き換えます。







どんな種類のファイルがあるのか​​見てみましょう。







  # find /etc/letsencrypt/live/ -type l /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/chain.pem /etc/letsencrypt/live/example.com/privkey.pem /etc/letsencrypt/live/example.com/cert.pem
      
      





この知識があれば、nginxのSSL設定を設定できます。







 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
      
      





ご覧のとおり、 cert.pem



は構成内のどこでも使用されておらず、これはエラーではありません。 nginxの場合、必要ありません。







完全に機能するサンプル設定:







 server { server_name www.example.com; listen www.example.com:443 ssl; # default_server; #    default_server    SNI ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; ssl_stapling on; ssl_stapling_verify on; resolver 127.0.0.1 8.8.8.8; #    http-  add_header Strict-Transport-Security "max-age=31536000"; #  ""    http:// add_header Content-Security-Policy "img-src https: data:; upgrade-insecure-requests"; #       #location / { # proxy_pass ...; #} }
      
      





wwwなしでベアドメインからリダイレクトするように構成します。







 server { server_name example.com; listen example.com:443 ssl; access_log off; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; ssl_stapling on; ssl_stapling_verify on; resolver 127.0.0.1 8.8.8.8; add_header Strict-Transport-Security "max-age=31536000"; expires max; return 301 https://www.example.com$request_uri; }
      
      





何らかの種類のローカルサーバーを使用してDNSクエリをキャッシュしていることがわかります。 そうでない場合は、 resolver



ディレクティブの127.0.0.1



を使用するDNSサーバーのIPに置き換える必要があります。







暗号設定など( ssl_dhparam



ssl_session_cache



)を個々のサーバーの構成外にssl_dhparam



をおssl_session_cache



ます。







完全な秘密



Certbotがオープンソースコードにもかかわらず証明書のキーを盗むことを心配している場合、理論的には、一部の悪人がすべてのトラフィックを解読できることを意味します。 サイトへの接続にDHEおよびECDHEファミリーの暗号が使用されている場合、キーリークによりトラフィックの復号化が許可されません。 これらの暗号では、証明書キーは認証にのみ使用され、暗号化のキーとしては使用されません。 最新のブラウザはすべて、これらの暗号をサポートしています。







ECDHEの楕円曲線で何もする必要がない場合、拡張パラメーターをDHEに使用できます。 DHEを完全に無効にすることをお勧めします。







何らかの理由でDHEなしではできない場合

何らかの理由でDHEなしではできない場合は、最初にパラメーターを作成します。







 openssl dhparam -out /etc/ssl/private/dhparam.pem 2048
      
      





次に、 /etc/nginx/conf.d/ssl_dhparam.conf



1行/etc/nginx/conf.d/ssl_dhparam.conf



書き込みます。







 ssl_dhparam /etc/ssl/private/dhparam.pem;
      
      





証明書の更新



証明書は3か月間発行さます。 半年も、1年も、3か月だけではありません。 当然、これにより疑問が生じます。 3か月でこの手順全体を実行する必要がありますか? 数世紀の終わりまでこれを行うことは常に必要ですか? たぶん、あなたはそれをすべて忘れて、数年を覚えていないために、まだ支払われた証明書に投資するべきですか?







しかし、いや、支払い手段を探すために急いではいけません! 記事の冒頭で約束したように、証明書の更新に問題はありません。







Debianを使用している場合は、 --allow-subset-of-names



キーを/etc/cron.d/certbot



--allow-subset-of-names



呼び出しに追加するだけです。







 #    /etc/cron.d/certbot #  certbot -q renew,   certbot -q renew --allow-subset-of-names
      
      





Debianとsystemdを使用している場合は、 これらの手順を確認してください







Debianがない場合、またはファイルがない場合は、 root



からcrontab



1行だけ追加します( sudo crontab -e



):







 42 */12 * * * certbot renew --quiet --allow-subset-of-names
      
      





Let's Encryptで推奨されているように、証明書を1日に2回更新するようにしてください。 その時間のランダムに選択された分でこれを行う必要があります。つまり、この行の42



を0〜59の範囲の別の数値に置き換える必要があります。 または、/ /etc/cron.d/certbot



で行われている/etc/cron.d/certbot



実行できます。







仕組み



このコマンドでは、 --allow-subset-of-names



がドメインの部分セットの証明書を取得しようとするために、キー--allow-subset-of-names



必要です。







たとえば、サーバーサイトにwww.example.comshop.example.comがあり 、1つの証明書の下を通過しましたが、 shop.example.comを別のサーバーに転送しました。 そのようなキーを指定しない場合、Certbotは失敗し、証明書をまったく受け取らずにshop.example.comの所有権を確認しようとします。 証明書の有効期限が切れ、サイトがオフラインになります。 このキーを使用すると、少なくとも一部のドメインセットの証明書を受け取り、サイトをネットワーク上に残します。







それだけです



tee



およびsed



精通している場合は、 hostname



正しく構成されていれば、 Let's Encryptおよびnginxバンドルをセットアップするためのはるかに短い指示 hostname



ます。 コマンドをコピーして貼り付けるだけです。










間違いを見つけましたか? 個人的に書いてください。








All Articles