自宅鯖を間違ってsudo rm -rf /
してしまったので、再度certbotでLet's Encryptの設定を行った。公式サイトにOSとhttpdごとの設定方法が載ってるが、portsでは更にFreeBSDの定期ジョブ設定による更新が行える。
certbotをpkgでサクッとインストールする。webrootモードで更新したいのでapache用のプラグインも入れる。
$ sudo pkg install py38-certbot py38-certbot-apache (略) ===== Message from py38-certbot-1.14.0,1: -- This port installs the "standalone" client only, which does not use and is not the certbot-auto bootstrap/wrapper script. The simplest form of usage to obtain certificates is: # sudo certbot certonly --standalone -d <domain>, [domain2, ... domainN]> NOTE: The client requires the ability to bind on TCP port 80 or 443 (depending on the --preferred-challenges option used). If a server is running on that port, it will need to be temporarily stopped so that the standalone server can listen on that port to complete the challenge authentication process. For more information on the 'standalone' mode, see: https://certbot.eff.org/docs/using.html#standalone The certbot plugins to support apache and nginx certificate installation will be made available in the following ports: * Apache plugin: security/py-certbot-apache * Nginx plugin: security/py-certbot-nginx In order to automatically renew the certificates, add this line to /etc/periodic.conf: weekly_certbot_enable="YES" More config details in the certbot periodic script: /usr/local/etc/periodic/weekly/500.certbot-3.8
certbotにはStandaloneとWebrootの2つのモードがあり、前者はその名の通りcertbot単体で、後者は他のサービスと連携して証明書の取得&更新を行うモードとのこと。
certbotで証明書の取得を行う。
-w
にApacheのドキュメントルート、-d
に証明を受けるドメインのFQDNを指定する。初回のみメールアドレス関連のあれこれが聞かれるので、適切に回答する。
Webrootモードでの認証は、certbotが-wで指定したディレクトリに.well-known/acme-challenge/xxxyyyzzz
という認証用ファイルを作成し、Let's Encrypt側からそのファイルへアクセスすることで、ドメインの正当性が検証される。
証明書は/usr/local/etc/letsencrypt/live/指定したFQDN/
の下に置かれる。
$ sudo certbot certonly --webroot -w /usr/home/www/ -d hoge.example.com Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator webroot, Installer None Requesting a certificate for hoge.example.com IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /usr/local/etc/letsencrypt/live/hoge.example.com/fullchain.pem Your key file has been saved at: /usr/local/etc/letsencrypt/live/hoge.example.com/privkey.pem Your certificate will expire on 2021-08-02. 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 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
ApacheのSSLの設定を行う。Mozilla SSL Configuration Generatorで生成したものを使う方が確実かも…。
サンプルファイルをコピー。
$ cd /usr/local/etc/apache24 $ sudo cp extra/httpd-ssl.conf Includes/ $ sudo emacs Includes/httpd-ssl.conf
重要なのはSSLCertificateFile
とSSLCertificateKeyFile
。
SSLRandomSeed startup file:/dev/random 512 SSLRandomSeed connect file:/dev/random 512 Listen 443 SSLCipherSuite !3DES:!aNULL:EDH+HIGH:ECDH+HIGH:-AES128:-3DES:-DSS:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA SSLProxyCipherSuite !3DES:!aNULL:EDH+HIGH:ECDH+HIGH:-AES128:-3DES:-DSS:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA SSLHonorCipherOrder on SSLProtocol all -SSLv2 -SSLv3 SSLProxyProtocol all -SSLv2 -SSLv3 SSLPassPhraseDialog builtin SSLSessionCache "shmcb:/var/run/ssl_scache(512000)" SSLSessionCacheTimeout 300 <VirtualHost _default_:443> DocumentRoot "/usr/home/www" ServerName hoge.example.com:443 ServerAdmin you@example.com ErrorLog "/var/log/httpd-error.log" TransferLog "/var/log/httpd-access.log" SSLEngine on SSLCertificateFile "/usr/local/etc/letsencrypt/live/hoge.example.com/fullchain.pem" SSLCertificateKeyFile "/usr/local/etc/letsencrypt/live/hoge.example.com/privkey.pem" <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory "/usr/local/www/apache24/cgi-bin"> SSLOptions +StdEnvVars </Directory> BrowserMatch "MSIE [2-5]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog "/var/log/httpd-ssl_request.log" \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost>
Let's Encryptの証明書は有効期限が90日なので、忘れずに自動更新設定を行う。
証明書の更新はHTTP経由で行われる。HTTPSじゃなくてHTTPね。ここ、重要。
外部からHTTPでhttp://対象ドメイン/.well-known/acme-challenge/
に到達できるよう、ルータのポートフォワードやらApacheのVirtualHostやらを適切に設定のこと。宅内DNSで、宅内では対象ドメインにプライベートIPアドレスを割り当ててたりすると、宅内の作業PCからはhttpアクセスできるように見えて、外部からは到達不可で証明書の更新が行えないなんていう事も起こりうるので要注意(実際にハマった。)
まずはテスト。
$ sudo certbot --dry-run renew Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /usr/local/etc/letsencrypt/renewal/hoge.example.com.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert not due for renewal, but simulating renewal for dry run Plugins selected: Authenticator webroot, Installer None Simulating renewal of an existing certificate for hoge.example.com Performing the following challenges: http-01 challenge for hoge.example.com Using the webroot path /usr/home/www for all unmatched domains. Waiting for verification... Cleaning up challenges - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - new certificate deployed without reload, fullchain is /usr/local/etc/letsencrypt/live/hoge.example.com/fullchain.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations, all simulated renewals succeeded: /usr/local/etc/letsencrypt/live/hoge.example.com/fullchain.pem (success) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
問題なさそうなので、/etc/periodic.conf
に追加。
# echo 'weekly_certbot_enable="YES"' >> /etc/periodic.conf
更新済みの証明書をApacheでリロードする。これをしないと、古い証明書が使われ続ける挙句、httpdがCPUに100%張り付くという残念なことになる。参考:certbot renewでApacheがCPU 100%に張り付くでござるの巻き
certbotは良くできていて、証明書更新時にフックスクリプトを実行できるようになっている。/usr/local/etc/letsencrypt/renewal-hooks/deploy/
にservice apache24 reload
を呼ぶスクリプトを配置する。
#!/bin/sh service `echo $0|sed -e 's/.*\/\(.*\)_\(.*\).sh/\2 \1/'`
ファイル名から対象のサービスとコマンドを切り出す形なので、中身は同一でファイル名を変えるだけで様々なサービスに対応できる。それこそハードリンクで良い感じに処理できるかも?