owned mediaウェブ制作に役立つコンテンツを発信中!

CentOS8 + Apache + Nginx + MariaDBでVPSサーバーに環境構築をする(#7:SSL証明書のインストールと設定)

最終更新日: Update!!
最近のウェブサイト運用では常時SSL化が当然のようになっています。そこでVPSサーバーにSSL証明書をインストールして、SSL対応のウェブサイトを運用できる環境を構築していきたいと思います。SSL対応をすることでセキュリティだけでなく、SEOにもメリットがあります。今回は無料で手軽に使える「Let's Encrypt」を利用したSSL証明書をインストールしていきます。また必要なSSLの設定なども合わせて進めていきます。  
1. SSL証明書のインストール
まずSSL証明書を導入する上で「mod_ssl」というものが必要になります。下記コマンドで「mod_ssl」がインストールされているか確認します、なければインストールしていきます。
# dnf list installed | grep mod_ssl
mod_ssl.x86_64
  mod_sslがApacheのモジュールとして有効化されているかを「ssl_module (shared)」の表示で確認します。
# httpd -M
..............
ssl_module (shared)
  さらに念の為、httpsのプロトコルがFirewallで開放されているかも確認しておきます、httpsの表記があればOKです。
# firewall-cmd --list-all
..............
services: cockpit dhcpv6-client ftp http https ssh
  SSL証明書インストールに必要となるクライアントツールの「certbot-auto」をインストールしていきます。あとで移動させるのでtmpディレクトリに入ってから、下記のコマンドを実行してインストールを進めていきます。
# cd /tmp
# wget https://dl.eff.org/certbot-auto
  tmpディレクトリにインストールしたcertbot-autoファイルを「/usr/local/bin/」配下に移動させ、所有者とパーミッションを変更します。
# mv certbot-auto /usr/local/bin/certbot-auto
# cd /usr/local/bin/
# chown root certbot-auto
# chmod 0755 certbot-auto
  下記のコマンドでSSL証明書を発行していきます。SSL証明書の発行方法はいくつかありますが、ここでは「--webroot」のオプションを使った方法になります。ドキュメントルートに認証用のファイルを配置させるので「-w」オプションの後にドメインに対応するドキュメントルートのパスを、「-d」オプションの後に、ドキュメントルートに紐づくドメインを指定します。
# certbot-auto certonly --webroot -w [DOCUMENTROOT] -d [DOMAINNAME]
  (補足)サブドメインなどが複数ある場合には、それぞれのドキュメントルートとドメインの指定を続けて記述する形になります。
# certbot-auto certonly --webroot -w directory-com -d example.com -d site1.example.com
  SSL証明書や関連パッケージのインストールが始まり、途中で下記のように質問されるので答えながら進めていきます。
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): メールアドレスを入力

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
  しばらくするとドメイン所有者の検証が始まります。この時に、実行しているサーバーのIPアドレスがドメインのAレコードに登録されていないとエラーとなり、進めることができません。また、http通信で検証するので、firewallでhttpのプロトコルが解放されている必要があります。エラーが出るようであれば、そのあたりを確認しましょう。
Performing the following challenges:
  http-01 challenge for example.com
  http-01 challenge for site1.example.com
  http-01 challenge for site2.example.com
  ..............
  下記のメッセージが表示されると、無事にSSL証明書がサーバーにインストールされました。
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example.com/privkey.pem
Your cert will expire on 2020-10-15. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew *all* of your certificates, run
"certbot-auto renew"
- If you like Certbot, please consider supporting our work by:
  (補足)別ドメインにわたる場合には各ドメインごとに上記作業を行う方が証明書が分かれて管理がしやすいのでお勧めです。
# certbot-auto certonly --webroot -w directory-com -d example.com
# certbot-auto certonly --webroot -w directory-net -d example.net
# certbot-auto certonly --webroot -w directory-jp -d example.jp
  念の為、インストールされた証明書を確認しておきます。それぞれのドメインごとに証明書関係のファイルが作成されています。
# cd /etc/letsencrypt/live/
# ls
example.com example.net ........
# cd example.com
# ls
cert.pem chain.pem fullchain.pem privkey.pem README
  これでサーバー内にSSLの証明書がインストールできました。引き続きSSLの設定を行なっていきます。  
2. ウェブサーバー、リバースプロキシサーバー、バーチャルホストのSSL設定
まずはウェブサーバーのSSL設定を行います。「/etc/httpd/conf/」に移動し、httpdのSSL設定ファイルである「ssl.conf」にSSL設定を追記していきます。あらかじめバックアップをとっておくといいですね。
# cd /etc/httpd/conf.d/
# cp ssl.conf ssl.conf.copy
# vim ssl.conf
  ウェブサーバー用のSSL設定ファイルに下記のように変更を加えます。リバースプロキシサーバーを使う形になるので、ポート番号を被らないように変えておきます。 【etc/httpd/conf.d/ssl.conf】
// 変更前
Listen 443 https
..............
<VirtualHost _default_:443>
↓
// 変更後
Listen 8443 https
..............
<VirtualHost _default_:8443>
  続けて「/etc/httpd/conf.d/」に移動し、httpdのバーチャルホスト設定ファイルの「vhost.conf」にSSL設定を追記していきます。こちらもあらかじめバックアップをとっておきましょう。
# cd /etc/httpd/conf.d/
# cp vhost.conf vhost.conf.copy
# vim vhost.conf
  http通信用のバーチャルホスト設定と同じように、ドメイン(サブドメイン含む)に合わせて、下記のようにSSLのバーチャルホスト設定を行います。なお下記はリバースプロキシに対応したものになります。 【etc/httpd/conf.d/vhost.conf】
..............
<IfModule mod_ssl.c>
  <VirtualHost *:8443>
    SSLEngine on
    ServerName example.com
    DirectoryIndex index.php index.html
    AddDefaultCharset UTF-8
    DocumentRoot /var/www/html/directory-1
    ServerAlias www.example.com
    <Directory "/var/www/html/directory-1">
      Require all granted
    </Directory>
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
  </VirtualHost>
</IfModule>
..............
  設定ファイルを保存したら、下記コマンドで記述ミスがないかをチェックします。
# httpd -t
Syntax OK
  下記コマンドでhttpdを再起動させて、設定を反映させます。
# systemctl restart httpd
  最後にリバースプロキシサーバーの設定ファイルである「reverse_proxy.conf」を編集していきます。「/etc/nginx/conf.d/」に移動し、Nginxの設定ファイルにSSL設定を追記します。同じくあらかじめバックアップをとっておきます。
# /etc/nginx/conf.d/
# cp reverse_proxy.conf reverse_proxy.conf.copy
# vim reverse_proxy.conf
  下記のようにバーチャルホストの設定をSSLに対応させていきます。必要なドメインごとに行なっていきます。この時にhttpからhttpsへのリダイレクトやwwwサブドメインの有無統一なども合わせて済ませておくことで常時SSL化にすることができます。 【reverse_proxy.conf】
server {
  listen 80;
  server_name example.com;
  return 301 https://example.com$request_uri;
}
server {
  listen 80;
  server_name www.example.com;
  return 301 https://example.com$request_uri;
}
..............
server {
  listen 443 ssl;
  server_name example.com;
  server_name www.example.com;
  ..............
  ssl on;
  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  ssl_protocols TLSv1 TLSv1.1 TLSV1.2;
  ssl_ciphers HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers on;
  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 10m;
  client_max_body_size 20M;
  location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
    proxy_redirect off;
  }
}
..............
  設定ファイルを保存したら、下記コマンドで記述ミスがないかをチェックします。
# nginx -t
syntax is ok
  下記コマンドでnginxを再起動させて、設定を反映させます。
# systemctl restart nginx
  これで「https://ドメイン」にアクセスするとSSLでの通信が確認できます。念の為、リダイレクトが機能しているかも試しておきましょう。  
3. SSL証明書の自動更新登録
Let's EncryptのSSL証明書では有効期限が90日間となっているため、定期的に証明書の有効期限を更新する作業が必要になります。まだ証明書の更新は期限日より30日前にならないと実行できません。そこで、こういった条件のもと証明書の更新を忘れないようにcronを使って自動更新を行うようにします。   まずは、下記のコマンドでSSL証明書が問題なく更新できるかのテストを行います。
# certbot-auto renew --dry-run
  実行後、問題なく成功すると下記のメッセージが表示されます。これでいつでも証明書を更新することができます。
Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
  /etc/letsencrypt/live/example.net/fullchain.pem (success)
  ...........
  続けて、SSL証明書の更新タスクを「cron」に登録していきます。cronの設定ファイルを開いていきます。
# cd /etc/
# vim crontab
  cronの設定ファイルへ下記のように自動化のコマンドとスケジュールを追加し保存します。(下記は毎日午前1時30分と2時30分に証明書更新が実行されるようにしています) 【etc/crontab】
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

// 下記を追加
30 1 * * * root certbot-auto renew --quiet
30 2 * * * root certbot-auto renew --quiet
  環境によってはサーバーの再読み込みを行わないと更新済みの新しい証明書が適用されないということもあるようです。そんな時には「certbot-auto renew」コマンドの「--post-hook」オプションを使って、更新直後に続けて実行するコマンドを指定できます。ここではNginxを再読み込みさせる例をあげています。
30 1 * * * root certbot-auto renew --post-hook "systemctl reload nginx" --quiet 
30 2 * * * root certbot-auto renew --post-hook "systemctl reload nginx" --quiet
  保存したら設定を反映させるために下記コマンドでcrondを再起動します。
# systemctl restart crond
  これだけでcronを使ったSSL証明書の自動更新登録が完了です。実際にcronが動作しているかはログに記録されるので確認しておきましょう。  
4. ドメイン変更や削除に伴うSSL証明書の操作
ドメインが変わったり、削除されたり、また新たなサブドメインが追加になったりと、サイトを運用しているとそのようなケースに遭遇します。その際にはSSL証明書の内容を書き換えたり、失効したのち証明書を削除するといった作業が必要になります。   まず、これまでのSSL証明書に新たなサブドメインが追加になる場合には、下記のように「--expand」オプションをつけることで、その名の通りこれまでのドメインを引き継ぎながら、対象となるドメインが拡張されるように追加することができます。
# certbot-auto certonly --expand --webroot -w directory-com -d example.com -d site1.example.com add1.example.com add2.example.com ......
  また、ドメインの廃止や別のドメインに変更となる場合には、下記の方法で既存の証明書を失効させてから新たに証明書を発行する形となります。証明書の失効に合わせて関連する証明書ファイルも全て削除されます。
# certbot-auto revoke --cert-path=/etc/letsencrypt/archive/example.com/cert1.pem
  「revoke」コマンドで、直後に対象となる証明書のパスを指定します。削除後は先ほどと同じようにSSL証明書を変更後の内容に合わせて新規で作成していきます。  
  今回はサーバーにSSL証明書をインストールして、設定を行うところまでをまとめてみました。これでSSL対応のサイトやアプリケーションを運用することができます。今回は無料で使えるLet's Encryptを利用しましたが、一般のサイトであれば十分ですので利用しない手は無いですよね。是非導入の際は参考にしてみてください。
  • はてなブックマーク
  • Pocket
  • Linkedin
  • Feedly

この記事を書いた人

Twitter

sponserd

    keyword search

    recent posts

    • Twitter
    • Github
    contact usscroll to top
      • Facebook
      • Twitter
      • Github
      • Instagram