マルチドメイン化とLet's Encrypt証明書導入

お客様先のWebサーバについて、

* マルチドメイン化
* **wwwなし** のアクセスを **wwwあり** に統一（例：`example.co.jp` を `www.example.co.jp` に転送）
* 常時SSL化
* それまでの有料SSLサーバ証明書を**Let's Encrypt**に移行

とする機会があったので、自分用にメモ。

# 前提環境
```console
# cat /etc/redhat-release 
CentOS release 6.10 (Final)

# httpd -v
Server version: Apache/2.2.15 (Unix)
```

# マルチドメイン化
## Apache2定義ファイル編集

バーチャルホストで `www.example.co.jp` と `www.example2.co.jp` に分割する。

```apache:/etc/httpd/conf.d/www.example.co.jp.conf
<VirtualHost *:80>
    ServerName www.example.co.jp
    DocumentRoot /var/www/html
    CustomLog logs/www.example.co.jp_access.log combined
    ErrorLog logs/www.example.co.jp_error.log
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.co.jp
    DocumentRoot /var/www/html
    TransferLog logs/www.example.co.jp_ssl_access_log
    ErrorLog logs/www.example.co.jp_ssl_error_log
    SSLEngine on

    # 有料証明書のコメントアウト
    #SSLCertificateFile /etc/httpd/conf/ssl/www.example.co.jp.crt
    #SSLCertificateKeyFile /etc/httpd/conf/ssl/www.example.co.jp.key
    #SSLCACertificateFile /etc/httpd/conf/ssl/dvcacert.cer

    # Let's Encrypt証明書パスを追加
    SSLCertificateFile /etc/letsencrypt/live/www.example.co.jp/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/www.example.co.jp/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/www.example.co.jp/fullchain.pem
</VirtualHost>
```

```apache:/etc/httpd/conf.d/www.example2.jp.conf
<VirtualHost *:80>
    ServerName www.example2.jp
    DocumentRoot /var/www/html2/www.example2.jp
    CustomLog logs/www.example2.jp_access.log combined
    ErrorLog logs/www.example2.jp_error.log

    # 常時SSL化
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
    </IfModule>
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example2.jp
    DocumentRoot /var/www/html2/www.example2.jp
    TransferLog logs/www.example2.jp_ssl_access_log
    ErrorLog logs/www.example2.jp_ssl_error_log
    SSLEngine on

    # Let's Encrypt証明書パスを追加
    SSLCertificateFile /etc/letsencrypt/live/www.example2.jp/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/www.example2.jp/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/www.example2.jp/fullchain.pem
</VirtualHost>
```
環境によっては `ssl.conf` の `VirtualHost`ディレクティブをごっそり削除する必要があるかも。

## DNSゾーンファイル編集

`www.example2.jp` としてもアクセス可能とする。
プロバイダがDNSサーバを管理している場合はDNSレコード編集画面を提供しているはずなので、それに従おう。

```conf:/usr/local/etc/namedb/master/example2.jp.zone
$TTL 1800
$ORIGIN example2.jp.
@       IN      SOA     AAA.BBB.co.jp. (
        2018080101      ; Serial
        43200           ; Refresh after 12 hours
        3600            ; Retry after one hour
        2419200         ; Expire after 4 weeks
        1200 )          ; Negative cache TTL of 20 minutes
;
; Authoritative name servers
;
        IN      NS      XXX.YYY.co.jp.
;
; Hosts
;
www     120     IN      A       nnn.nnn.nnn.nnn   ; 追加
```

# Let's Encrypt導入

```:EPELリポジトリの追加
yum -y install epel-release
```

証明書の更新にはPython2.7以上が必要なのだが、CentOS6の標準リポジトリには無いので、RedHat系の**Software Collections**（SCL）を使う。

```
yum -y install centos-release-scl
yum -y install python27 python27-python-tools
```

```
cd /usr/bin
wget https://dl.eff.org/certbot-auto
chmod 755 certbot-auto
```

SCLが効いているシェルの配下で証明書を取得してみる。

```shell-session
# python -V
Python 2.6.6

# scl enable python27 bash
# python -V
Python 2.7.13

# certbot-auto certonly --webroot -w /var/www/html2/www.example2.jp -d www.example2.jp -m xxxxx@mail.aaa.co.jp --agree-tos --no-eff-email --redirect
# certbot-auto certonly --webroot -w /var/www/html -d www.example.co.jp,example.co.jp -m xxxxx@mail.aaa.co.jp --agree-tos --no-eff-email --redirect
```
`www.example.co.jp` と `example.co.jp` はひとつの証明書とする。

* **失効**は `certbot-auto revoke --cert-pat=/etc/letsencrypt/live/www.example2.jp/cert.pem`
* **強制更新**は `certbot-auto renew --force-renew`

## 再起動

```
service httpd restart
```

## cron定義
証明書の有効期限が90日で切れるため、自動更新の設定をする。

```:毎週土曜日の午前3時に更新チェック
# crontab -l
00 03 * * 5 scl enable python27 "bash -c \"certbot-auto renew --post-hook '/sbin/service httpd restart'\"" > /var/log/certbot.log 2>&1
```

# wwwありなしの統一と常時SSL化

```apache:httpd.conf
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_HOST} ^example\.co\.jp$
  RewriteRule ^(.*)$ http://www.example.co.jp/$1 [R=301,L]
  RewriteCond %{HTTPS} off
  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</IfModule>
```

WordPressを使っている場合は以下も必要。
もし、**WordPress HTTPS プラグイン** を使っていたなら、*Force SSL Exclusively* のチェックを外すのを忘れずに。

```apache:httpd.conf
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /wp/
  RewriteRule ^index\.php$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /wp/index.php [L]
</IfModule>
```

最後に、wwwのありなしが別々とサイトとしてGoogleに認識されるとSEO的に不利になる場合があるので、**Google Search Console**でも、wwwありに統一しておくと良いだろう。