VirtualHost環境でLet’s Encryptを導入

やりたいこと

Apacheで作ったVirtualHost環境において、ドメインごとにLet’s Encryptを導入してSSL通信が可能なようにする。

参考にさせて頂いたサイト

https://weblabo.oscasierra.net/letsencrypt-2/

環境

  • CentOS 7
  • firewalld使用
  • epel導入済み。ただしデフォルトではfalseになるようにしてある。
  • Apache 2.4
  • Apacheでは/etc/httpd/conf.d/以下にドメインごとのconfを作り、VirtualHost節を書いて環境を作っている。
  • Document Rootは/home/<domain>/public_html/ 以下にしている。ここは環境次第で読み替えてもらえればと思う。

手順

  1. certbotを導入。Let’s Encryptではこのツールによって証明書の発行を全て操作することができる。一般的なSSLのようにHPにいって申し込みして証明書が送られてきて〜という手順とは違う。
  2. certbot経由でSSL証明書発行
  3. ApacheのVirtual Host部へ設定を書く
  4. 443ポートなど必要なポートをあけて接続チェック

certbot導入

# yum --enablerepo=epel install certbot python-certbot-apache

certbotで証明書発行

Let’s EncryptはドメインとHPの存在をチェックするそうなので、適当にindex.htmlを置いて80番ポートで読めるようにしておく。

# certbot certonly --webroot -w /home/<user1>/public_html/ -d <SSLを取得したいdomain名>

certbotが対話モードで色々言ってくるのでメールアドレスを入力したり対応する。

正常に終われば/etc/letsencrypt/live/<domain名>/以下に証明書が発行されているはずである。このliveにはシンボリックリンクで置いてあって、実体は/etc/letsecrypt/archive/<domain名>/以下だがこちらは触らない方がよさげ。

これを必要なドメイン分行っておく。一度発行を行えばメールアカウントは同じでいいようでパスされる。

VirtualHostの設定

VirtualHostを書いてあるconf内に443ポート版を追加すればいい。

通常ポートである80番の物と内容はほぼ同じである。追記部分は以下のようにする。流儀によるところだが、logはssl接続とsslなしで分けて置いたほうが便利かと思う。

<VirtualHost *:443>
     ErrorLog logs/<domain>_secure-error_log
     CustomLog logs/<domain>_secure-access_log combined
     ........<中略>........
     SSLCertificateFile /etc/letsencrypt/live/<domain>/cert.pem
     SSLCertificateKeyFile /etc/letsencrypt/live/<domain>/privkey.pem
     SSLCertificateChainFile /etc/letsencrypt/live/<domain>/chain.pem
    ........<中略>........
</VirtualHost>

httpdを再起動する。

# systemctl restart httpd

ApacheからSSLのエラーが出る場合の修正

Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.

# systemctl status httpd
    AH00526: Syntax error on line 118 of /etc/httpd/conf.d/ssl.conf:
    SSLCertificateChainFile: file '/etc/pki/tls/certs/server-chain.crt' does not exist or is empty

このエラーはSSLの設定が二重になってしまっているので起きているようだ。私の環境ではapacheを導入した時点でconf.d/にssl.confが作られていたので、これをrenameして読み込ませないようにすることで解消した。(※末尾が.confだとrenameしても読み込むと思うので注意)

# mv ssl.conf ssl.conf.bak

firewalldの設定

firewall-cmd --add-service=https --zone=public --permanent

zoneがpublicをデフォルトにしてない場合は適宜変更する。

ついでに443がListenしているか確認しておく

# ss -nat | grep 443
LISTEN      0      128                                                   *:443

ブラウザから確認

httpsでブラウザからつないで見てSSLで接続がされればok

通らなかったらtelnetで443叩いてみるとか、apacheがエラー吐いてないかなど確認する。場合による。

証明書の自動更新設定

crontabで毎月15日のAM4:00に更新およびhttpdの再起動をするようにする。

# crontab -e
00 04 15 * * certbot renew && systemctl restart httpd