Let’s Encrypt + Apache

Let’s Encryptを使ってApacheをHTTPS化し、ついでにHTTP/2対応した手順のメモ。

環境

  • さくらのVPS v3(2G)
  • FreeBSD 10.3
  • Apache 2.4
  • 同一IP上に複数サイト

手順

認証取得

  1. 認証取得クライアントのCertbotをインストール。
    Let’s Encryptのクライアントにはいろいろな言語で実装されたものがあり、Let’s Encrypt Wikiに一覧が掲載されている。CertbotはEFF推奨のクライアント。
    portsからsecurity/py-certbotをインストールする。(当初はsecurity/py-letsencryptというパッケージだったが、名称変更された。)

    # sudo portmaster security/py-certbot

    依存パッケージが山ほどあるので、すべて一緒にインストールしておく。

    なお、certbotのサイトにはApache用のプラグインがあると書かれているが、インストール後のメッセージによると「近日実装」とのこと。

    The letsencrypt plugins to support apache and nginx certificate installation
    will be made available soon in the following ports:

    * Apache plugin: security/py-letsencrypt-apache
    * Nginx plugin: security/py-letsencrypt-nginx

    近日っていつ頃なのだろう。とにかく現時点では未実装なので、手動で設定することに。

  2. コマンドラインから、認証を取得。
    # sudo certbot certonly --webroot --email webmaster@mydomain.tld -w /usr/local/www/domain1 -d domain1.mydomain.tld
    # sudo certbot certonly --webroot --email webmaster@mydomain.tld -w /usr/local/www/domain2 -d domain2.mydomain.tld

    複数あるサイトすべてについて、認証を取得しておく。取得した認証は、/usr/local/etc/letsencrypt/live/[サーバ名]/ の下に置かれる。live以下はシステム管理者以外参照できない設定になっている。

    # sudo ls /usr/local/etc/letsencrypt/live/
    domain1.mydomain.tld   domain2.mydomain.tld
    # sudo ls /usr/local/etc/letsencrypt/live/domain1.mydomain.tld
    cert.pem chain.pem fullchain.pem privkey.pem
  3. cronに自動更新用のコマンドを登録。
    # sudo crontab -e

    次の行を追加。実行時間は適宜変更。

    30 3 * * * /usr/local/bin/certbot renew --quiet

    有効期限が30日を切ると自動更新される。

Apacheの設定

  1. SSLとHTTP/2のオプションを追加してApacheをビルドし直す。
    # sudo portmaster --force-config www/apache24

    nghttp2も一緒にインストールされる。

  2. /usr/local/etc/apache24/httpd.conf を次のように編集。
    • 読み込む必要のあるモジュールの行のコメントをはずす。
      LoadModule socache_shmcb_module libexec/apache24/mod_socache_shmcb.so
      LoadModule ssl_module libexec/apache24/mod_ssl.so
      LoadModule http2_module libexec/apache24/mod_http2.so
      
    • httpd-vhosts.conf の読み込みをコメントアウトし、httpd-ssl.conf の行のコメント記号を削除する。 
      #Include etc/apache24/extra/httpd-vhosts.conf
      Include etc/apache24/extra/httpd-ssl.conf
    • HTTP/2を有効にする。
      <IfModule http2_module>
      Protocols h2 http/1.1
      H2Direct on
      </IfModule>
    • 非SSL通信をすべてSSL通信に転送する設定を追加する。
      <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{HTTPS} off
      RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
      </IfModule>
  3. /usr/local/etc/apache24/extra/httpd-ssl.conf を次のように編集する。
    Listen 443
    
    SSLCipherSuite AESGCM:HIGH:MEDIUM:!MD5:!RC4
    SSLProxyCipherSuite AESGCM:HIGH:MEDIUM:!MD5:!RC4
    
    SSLHonorCipherOrder on
    
    SSLProtocol all -SSLv3
    SSLProxyProtocol all -SSLv3
    
    SSLPassPhraseDialog builtin
    
    SSLSessionCache "shmcb:/var/run/ssl_scache(512000)"
    SSLSessionCacheTimeout 300
    
    SSLStrictSNIVHostCheck off
    
    <VirtualHost _default_:443>
    <IfModule mod_rewrite.c>
     RewriteEngine On
     RewriteCond %{HTTP_HOST} !domain1.mydomain.tld
     RewriteRule ^(.*)$ https://domain1.mydomain.tld/ [R=301,L]
    </IfModule>
     ServerAdmin webmaster@mydomain.tld
     DocumentRoot "www/domain1"
     ServerName www.mydomain.tld:443
     ErrorLog "/var/log/apache/default-error.log"
     TransferLog "/var/log/apache/default-transfer.log"
     CustomLog "/var/log/apache/default-ssl-request.log" \
     "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    
     SSLEngine on
    
     SSLCertificateFile "etc/letsencrypt/live/domain1.mydomain.tld/cert.pem"
     SSLCertificateKeyFile "etc/letsencrypt/live/domain1.mydomain.tld/privkey.pem"
     SSLCertificateChainFile "etc/letsencrypt/live/domain1.mydomain.tld/chain.pem"
     <FilesMatch "\.(cgi|shtml|phtml|php)$">
     SSLOptions +StdEnvVars
     </FilesMatch>
    
     BrowserMatch "MSIE [2-5]" \
     nokeepalive ssl-unclean-shutdown \
     downgrade-1.0 force-response-1.0
    </VirtualHost>
    <VirtualHost *:443>
     DocumentRoot "www/domain2"
     ServerName domain2.mydomain.tld:443
     ServerAdmin webmaster@mydomain.tld
     ErrorLog "spool/apache/domain2.mydomain.tld-error.log"
     TransferLog "spool/apache/domain2.mydomain.tld-transfer.log"
     CustomLog "spool/apache/domain2.mydomain.tld-ssl-request.log" \
     "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    
     SSLEngine on
    
     SSLCertificateFile "etc/letsencrypt/live/domain2.mydomain.tld/cert.pem"
     SSLCertificateKeyFile "etc/letsencrypt/live/domain2.mydomain.tld/privkey.pem"
     SSLCertificateChainFile "etc/letsencrypt/live/domain2.mydomain.tld/chain.pem"
    
     <FilesMatch "\.(cgi|shtml|phtml|php)$">
     SSLOptions +StdEnvVars
     </FilesMatch>
    
     BrowserMatch "MSIE [2-5]" \
     nokeepalive ssl-unclean-shutdown \
     downgrade-1.0 force-response-1.0
    </VirtualHost>
    
    

    SSLCipherSuiteの先頭を「AESGCM」にしておかないと、Firefoxでサイトを開けなくなる。

  4. httpd.conf の内容をチェックする。
    # sudo apachectl configtest

    認証ファイルがシステム管理者にしか見えない設定のため、sudoで実行すること。一般ユーザで実行すると認証ファイルの読み込み確認でエラーとなる。

  5. Apacheを再起動。
    # sudo service apache24 restart
  6. ブラウザでサイトに接続し、アドレスバーに鍵が表示されていることを確認。
  7. SSL Server Test」(またはGlobalSignのSSL Server Test)で、サイトの設定に問題のないことを確認。
タイトルとURLをコピーしました