CentOS6.xにLet’s Encryptをインストールする

2020.11.5更新

目次

事前準備・前提条件

今回は客先のサーバーの環境を前提条件に進めていく。

■ centosのバージョン確認
cat /etc/redhat-release
  • CentOS 6.x
  • Apache 2.2系

既存のサーバーに手を加えるに当たって気をつけておく点として、ApacheにすでにSSLが適用されている場合、再起動時にパスフレーズ入力を求められる。もしパスフレーズがわからなければApacheが起ち上がらなくなるので事前に確認する必要がある。

まずはhttpd/conf.dの中を覗いてSSLを利用している部分がないかを確認する

mod_sslが入ってなければそもそもSSLを利用していない。

■ mod_sslが入っていない場合はインストールする
$ yum -y install mod_ssl

もし、パスフレーズが必要なSSLが今回変更対象のものであればあまり気にしなくて良いのですが、そのあたりの細かい状況はケースバイケースなので、いずれにしてもきちんと把握しておく必要がある。(凡ミスをやらかしたので自分への戒めで書いてます)

certbotの準備

certbotを利用するにあたってpython2.7が必要なので、準備します。準備方法はいろいろありますが、python2.6が標準で入っていたため、依存関係崩さないように2.6と2.7を共存させる。

■ Software Collectionを更新
$ yum install centos-release-scl-rh
$ python --version
$ yum install rh-python37
$ vi /etc/profile.d/python37.sh
#!/bin/bash
 
source /opt/rh/rh-python36/enable
export X_SCLS="`scl enable rh-python36 'echo $X_SCLS'`"
■ profileを読み込む(~/.bashrcなどでもよい)
$ source ~/.profile

■ pipをupdate
$ pip install -U pip virtualenv cryptography
(もし/opt/eff.org/certbot/が既にあれば削除して再作成)
$ rm -r /opt/eff.org/certbot/

■ certbotをインストール
$ curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
curl: (35) SSL connect error

そのままcurlでインストールしようとしたらエラーが出た。どこで躓いているのかを確認してみる。

■ どこでつまづいているのかエラー内容を確認
$ curl -L --verbose https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto

* About to connect() to dl.eff.org port 443 (#0)
*   Trying 151.101.108.201... connected
* Connected to dl.eff.org (151.101.108.201) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS error -12190
* Closing connection #0
* SSL connect error

curl: (35) SSL connect error

諸々不具合が出ているようだが、まずはcurlのバージョンが古いだけの場合が多いようなのでとりあえずアップデートする。

■ curlをアップデート
$ yum update curl
$ yum update nss
■ certbotの依存関係を処理するのに使われるパッケージをアップデート
$ yum update libcurl

■ certbotをインストール(再)
$ curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto

■ certbot-autoに実行権限を与える
$ chmod 700 /usr/bin/certbot-auto

■ certbot-autoを動かすと依存パッケージが勝手にインストールされる
$ certbot-auto --version

certbot-autoに何かしらの動作をさせると初回動作時にインストールが行われるがここでエラーが出る場合も

■ certbot-autoをインストール
$ certbot-auto --version
Bootstrapping dependencies for RedHat-based OSes... (you can skip this with --no-bootstrap)
yum is /usr/bin/yum
yum is hashed (/usr/bin/yum)
Failed to set locale, defaulting to C
Loaded plugins: fastestmirror, priorities, refresh-packagekit, security
Setting up Install Process
...(中略)...
Error: Package: python-devel-2.6.6-66.el6_8.x86_64 (updates)
           Requires: python-libs(x86-64) = 2.6.6-66.el6_8
           Installed: python-libs-2.6.6-68.el6_10.x86_64 (@sl-security)
               python-libs(x86-64) = 2.6.6-68.el6_10
           Available: python-libs-2.6.6-64.el6.x86_64 (base)
               python-libs(x86-64) = 2.6.6-64.el6
           Available: python-libs-2.6.6-66.el6_8.x86_64 (updates)
               python-libs(x86-64) = 2.6.6-66.el6_8
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
Could not install OS dependencies. Aborting bootstrap!

どうやらRedHat系列のOS起動時の依存関係が云々かんぬんということらしいが、(you can skip this…)とあるのでスキップしちゃう。

$ certbot-auto --version --no-bootstrap
certbot 1.9.0

すんなりインストール完了。
これでcertbotの準備はできた。

Apache2.2の設定①

wwwディレクトリ配下の各ドメインのドキュメントルートは基本的にディレクトリ名をドメインにしているという前提で説明していきます。ディレクトリ名をドメイン名にしていない場合は適宜読み替えてください。

■ 認証用ファイルを設置するディレクトリを作成する
mkdir /var/www/certbot/(任意のドメイン名など)

■ Apacheのバーチャルホスト設定ファイルに追記する
vi /etc/httpd/conf.d/(任意のドメイン).conf
<VirtualHost *:80>
    DocumentRoot /var/www/(ドキュメントルートのディレクトリパス)
    ServerName (設定対象のドメイン名)
...
 
    # for Let's Encrypt
    Alias /.well-known /var/www/certbot/(任意のドメイン名)/.well-known
 
    <Directory /var/www/certbot/(任意のドメイン名)>
        Require all granted
    </Directory>
</VirtualHost>

バーチャルホストの設定ファイルは/etc/httpd/conf.dディレクトリ内に.conf拡張子で置いておくと勝手に読み込んでくれる。ドメイン毎に1つのファイルで書いてもいいけど、SSLの設定ファイルも細かく切り分けて管理すると便利。

■ バーチャルホストファイル構成例
example.com.conf ←ポート80の設定用
example.com.ssl.conf ←ポート443(SSL)の設定用
example.com.ssl.conf_200320  (バックアップなどは拡張子をconfから変更することで読み込まれなくなる)

バーチャルホストの設定ができたら設定をリロードする

ssl.conf内のvirtualhostディレクティブをごそっと削除

# apachectl -t
CentOS7
# systemctl reload httpd
CentOS6
# service httpd reload

Let’s Encrypt証明書を取得

証明書を取得するコマンド

certbotの準備ができたら、早速証明書を取得する。

■ 証明書を取得する
# time /usr/bin/certbot-auto certonly \
    --webroot \
    -w /var/www/certbot/sample.domain.jp \
    -d sample.domain.jp \
    --preferred-challenges http \
    -m <登録するメールアドレス>

■ メールアドレスを登録しない場合(--register-unsafely-without-email)
# time /usr/bin/certbot-auto certonly \
    --webroot \
    -w /var/www/certbot/sample.domain.jp \
    -d sample.domain.jp \
    --preferred-challenges http \
    --register-unsafely-without-email

■ 取得テストをする場合(--dry-run)
# time /usr/bin/certbot-auto certonly \
    --webroot \
    -w /var/www/certbot/sample.domain.jp \
    -d sample.domain.jp \
    --preferred-challenges http \
    --register-unsafely-without-email \
    --dry-run

■ 一つの証明書で複数ドメインを認証する場合(適宜、-w,-dを増やす)
# time /usr/bin/certbot-auto certonly \
    --webroot \
    -w /var/www/certbot/sample.domain.jp \
    -d sample.domain.jp \
    -w /var/www/certbot/sample2.domain.jp \
    -d sample2.domain.jp \
    -w /var/www/certbot/www/sample.domain.jp \
    -d www.sample.domain.jp \
    --preferred-challenges http \
    --register-unsafely-without-email

–dry-runで証明書リクエストテスト

まずは取得テスト(dry-run)を行ってから取得するようにしましょう。取得時に上手く動かなかったり変な状態で取得してしまうと同一ドメインに対する証明書リクエストの申請上限(10回くらいだった気がする)に引っかかり1週間ほど認証サーバーから拒否されて再取得ができなくなります。

そこそこ長いコマンドなので僕はシェルスクリプトに記述してそれを実行している。–dry-runの切り替えも楽。

#!/bin/bash
time /usr/bin/certbot-auto certonly \
    --webroot \
    -w /var/www/certbot/sample.domain.jp \
    -d sample.domain.jp \
    --preferred-challenges http \
    --register-unsafely-without-email \
    --dry-run

–dry-runでsuccessしたら–dry-runを削除(コメントアウト)して実行する。

■ --dry-runで実行
# bash get_sslcert.sh
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for sample.domain.jp
Using the webroot path /var/www/certbot/sample.domain.jp for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - The dry run was successful.

real    0m7.321s
user    0m2.797s
sys     0m0.286s

証明書を取得

challenge failed for domain sample.domain.jpなどと出たら認証がうまくいっていない。
考えられる原因はタイポの他に、認証用ファイルの設置ディレクトリが未作成などが考えられる。

■ 本番実行(--dry-runをコメントアウト)
# bash get_sslcert.sh
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Registering without email!

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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   ←利用規約に同意
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for sample.domain.jp
Using the webroot path /var/www/certbot/sample.domain.jp for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/sample.domain.jp/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/sample.domain.jp/privkey.pem
   Your cert will expire on 2021-02-03. 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"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - 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


real    0m11.163s
user    0m3.463s
sys     0m0.325s

「- Congratulations! Your certificate and chain have been saved at: ~」
と出力されれば、証明書の取得は成功です。
失敗した場合は、エラーメッセージや、デバッグログ /var/log/letsencrypt/letsencrypt.log を参照して解消。
取得した証明書は以下で確認できる。

# ls -l /etc/letsencrypt/live/sample.domain.jp/
  • 証明書: /etc/letsencrypt/live/sample.domain.jp/cert.pem
  • 秘密鍵: /etc/letsencrypt/live/sample.domain.jp/privkey.pem
  • 中間証明書: /etc/letsencrypt/live/sample.domain.jp/chain.pem
  • 証明書+中間証明書: /etc/letsencrypt/live/sample.domain.jp/fullchain.pem

Apache2.2の設定②

SSLのバーチャルホスト設定を追加

証明書が取得できたらいよいよバーチャルホスト設定にSSL用のものを加える

■ SSL用のバーチャルホスト設定を作成
# vi /etc/httpd/conf.d/sample.domain.jp.ssl.conf

<VirtualHost *:443>
    DocumentRoot /var/www/sample.domain.jp/public_html
    ServerName sample.domain.jp
...
    <Directory /var/www/certbot/sample.domain.jp>
        Require all granted
    </Directory>
...(↑ここまでは適宜既存の設定に合わせて設定)
...(↓ここの3行が証明書の場所を指定している)
    SSLCertificateFile /etc/letsencrypt/live/sample.domain.jp/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/sample.domain.jp/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/sample.domain.jp/chain.pem
...
</VirtualHost>
# apachectl -t
# service restart httpd

ここまででSSL化は完了。https://sample.domain.jpにアクセスすると証明書が有効になったサイトが表示される。
※Apache2.2の場合、ssl.confにNameVirtualHost *:443の記述を足しておかないとSSLでVirtualHostが効かないので注意。

常時SSL化

しかし、これだとhttp://~でアクセスしたときはSSL化されていない状態のページにもアクセスできてしまうため、http://でアクセスしてもhttps://に切り替わるように設定をする。
サイトのドキュメントルートの.htaccessの設定に次の3行を加筆する。

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

http://sample.domain.jpでアクセスしてもhttps://~に切り替わるようになっていればOK。
ページ構造内部や画像リンクなどが常時SSL化によって影響を受けて表示されない場合などがあるので表示の確認をして設定完了。

Let’s Encryptの更新設定

更新作業

Let’s Encryptは証明書の有効期限が90日と短いため更新作業が頻繁に必要になる。
更新はcertbot-auto renewで簡単に行えるが、この作業を定期的に行うのは煩雑なので、自動更新スクリプトを用意してcronに処理をさせたい。そのため、ログにもUpdateのことが残るようにちょっと装飾を加えて、httpdの再起動までセットで行う。

次のようなシェルスクリプトを用意した。
証明書の更新の部分に–dry-runをつけているので、自動化を組み込む作業時は–dry-runにて運用するのが好ましいだろう。

最後は–dry-runをコメントアウトして最終確認をして自動化させる。

#!/bin/bash

CERTBOT_CMD=/usr/bin/certbot-auto
WEBSERVER_RESTART_CMD="service httpd restart"

echo "===== Update SSL Certfile ====="
echo "`date` Update SSL Certfile start"

# 証明書の更新
${CERTBOT_CMD} renew \
  --post-hook "${WEBSERVER_RESTART_CMD}" \
  --dry-run

LE_STATUS=$?

# 証明書の取得に失敗したときはメールで通知
if [ "$LE_STATUS" != 0 ]; then
    echo "Update SSL Certfile failed"
fi

echo "`date` Update SSL Certfile end"

# EOF

自動更新スクリプト

自動化処理は先ほどのupdate_sslcert.shをcronに定期実行させるだけだ。

■ update_sslcert.shに実行権限を付与
# chmod 755 /root/bin/update_sslcert.sh ←設置した場所によってパスは適宜
0 5 * * 0 root PATH="/sbin:$PATH" /root/work/update_sslcert.sh 1>> /var/log/update_sslcert.log 2>&1

ちなみにここでは毎週月曜日の朝5時に更新確認を行うように設定。
Let’s Encryptは証明書期限が残り30日を切ると更新される。

参考

稲葉サーバーデザインLet’s EncryptによるSSLサーバー証明書の取得、自動更新設定(2019年1月版)

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URL Copied!
  • URL Copied!

りょま

本職:教える人,スキル:プログラミング,趣味:音楽

コメント

コメントする

目次
閉じる