さくらのVPSに無料SSL「Let’s encrypt」を導入してみた記録

無料SSL発行サービス「Let’s encrypt」を利用し、さくらのVPS上のサーバをSSL(https)対応しました。
色々引っかかりながらも、複数の独自ドメイン用証明書を取得し、運用することができています。
また同じようなことをする日が来るかもしれませんので、作業記録を残しておきます。

まずは公式の使い方を見ます。
それだけでスムースに完了した方はこの記事を見る必要はありません…。

Certbotクライアントをダウンロード

SSL/TLS サーバ証明書の取更新作業を自動化できる、CertbotクライアントをさくらのVPS上にダウンロードします。

まずは自分のホームディレクトリに移動

$ pwd
/home/XXX

git を使用してCertbot クライアントをダウンロード

gitをインストールしていない場合は、公式のヘルプを参考にインストールしておく

$ git clone https://github.com/certbot/certbot

・git を使用して Certbot クライアントをダウンロード

git clone https://github.com/certbot/certbot

Initialized empty Git repository in /home/XXX/certbot/.git/
remote: Counting objects: 40999, done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 40999 (delta 10), reused 0 (delta 0), pack-reused 40975
Receiving objects: 100% (40999/40999), 11.30 MiB | 2.03 MiB/s, done.
Resolving deltas: 100% (29209/29209), done.

Certbotのテストを実行する

// Certbotディレクトリに移動してから
$ cd certbot/

// Certbotを実行する
$ sudo ./certbot-auto

足りないシステムがある場合、下記のようにインストール確認が表示されます。

トランザクションの要約
================================================================================================================
インストール        12 パッケージ
アップグレード      17 パッケージ

総ダウンロード容量: 44 M
これでいいですか? [y/N]

「y」を入力すると、足りないものが色々ダウンロードされます。
必要なものが全てダウンロードされると、Certbotクライアントを起動することができます。
起動すると青い画面が出るのですが、「No」を(Tabで)選択して、一度終了させます。

サーバ証明書を取得する

SSLサーバ証明書の取得に進みます。

Certbotを実行する

$ ./certbot-auto certonly --standalone -d lima.world -d diary.lima.world -d l.lima.world -d www.lima.world

Certbotを起動する際に、サーバで使用しているドメイン、サブドメインをオプションに並べて行きます。
続けてドメインを入力していくことで、複数のドメインを一つの証明書にまとめることもできます。


E-mail入力画面が開くので、緊急時の連絡メールアドレスを入力します。
ここに入力したアドレスに、各種お知らせ(サーバ証明書が期限切れになりそうな時のお知らせも)が送られてきます。
規約に同意すると次の画面に進みますが…。

ウェブサーバを一度停止する


Apacheなどの80ポートを使用するプロセスがすでに走っていると、このようなエラー画面が出てしまいましたので、停止させます。

$ sudo /etc/rc.d/init.d/httpd stop

もう一度入力すると…

./certbot-auto certonly --standalone -d lima.world -d diary.lima.world -d l.lima.world

Failed authorization procedure. lima.world (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to XXXX.XXX.XXX.XXX:443 for TLS-SNI-01 challenge, l.lima.world (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to XXXX.XXX.XXX.XXX:443 for TLS-SNI-01 challenge, diary.lima.world (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to XXXX.XXX.XXX.XXX:443 for TLS-SNI-01 challenge

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: lima.world
   Type:   connection
   Detail: Failed to connect to XXXX.XXX.XXX.XXX:443 for TLS-SNI-01
   challenge

   //省略

   To fix these errors, please make sure that your domain name was entered correctly and the DNS A record(s) for that domain contain(s) the right IP address. Additionally, please check that your computer has a publicly routable IP address and that no firewalls are preventing the server from communicating with the client. If you're using the webroot plugin, you should also verify that you are serving files from the webroot path you provided.

443ポートを通じてサーバに接続することができなかったため、エラーになってしまっています。
それもそのはず、ファイアウォールのiptablesにて指定外のポートはブロックした状態になっています。
接続できるように、443ポートを開ける必要があります。

SSL通信用の443ポートを解放する

// Super userになって
$ su -
// sysconfigディレクトリに移動し
$ cd /etc/sysconfig
$ vi iptables

// iptablesの適当な位置に、この一行を追加する
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT

// iptablesを再起動する
$ service iptables restart

iptablesの設定を変更してから、再度実行すると、無事に証明書の取得が完了しました。

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/lima.world/fullchain.pem. Your cert will
   expire on 2017-01-04. 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:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

/etc/letsencrypt/live/(ドメイン名)/の中を確認すると、4つのpemファイルが追加されていることが確認できます。

Apacheの設定を変更する

SSL接続できるように、Apacheのバーチャルホスト設定を変更します。

// バーチャルホスト設定ファイルを開く
$ sudo vi /etc/httpd/conf.d/vhost.conf

「NameVirtualHost *:443」を冒頭に追加します。

その後は、現在すでに書き込まれている80ポートにアクセスした際の設定に加える形で、
443ポートにアクセスされた際の設定を各ドメインごとに行っていきます。

またhttp(80ポート)を見に来た人をhttpsにリダイレクトさせる設定を既存の設定に加えることができますが、
無事にhttpsで接続できることを確認してから追記する方が良いかと思います。

NameVirtualHost *:80
#この一行を追加する
NameVirtualHost *:443

# 省略
<VirtualHost *:80>
DocumentRoot /var/www/lima
ServerName lima.world
<Directory "/var/www/lima">
AllowOverride All
</Directory>
# httpで来たらmod_rewriteでhttpsにリダイレクトさせる設定
  <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
  </IfModule>
</VirtualHost>

# 新規追加する設定
<VirtualHost *:443>
DocumentRoot /var/www/lima
ServerName   lima.world

# 証明書を設定
SSLEngine on
# 証明書ファイルを設定
SSLCertificateFile      /etc/letsencrypt/live/lima.world/cert.pem 
SSLCertificateKeyFile   /etc/letsencrypt/live/lima.world/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/lima.world/chain.pem
<Directory "/var/www/lima">
AllowOverride All
</Directory>
</VirtualHost>
# 省略

Apacheを再起動する

先にconfigtestを行なってから、start(restart)します。

$ sudo service httpd configtest
Syntax OK
$ sudo service httpd start

httpsで接続できるかどうか、ブラウザから接続確認を行います。

Let’s Encryptを自動更新させる

Let’s encryptの証明書の有効期限は3ヶ月です。
Certbotをインストールしたディレクトリで更新コマンドを打つことで更新できます。

$ ./certbot-auto renew

3ヶ月おきにこのコマンドを手動で打つのも面倒(忘れそう)ですので、自動的に証明書を更新できるようにします。

cronを使った定期的更新のためのメモを参考にしました。

上記のページを参考に、cron-renew-letsencrypt-certificatesというスクリプトを用意します。
まずはdry-runオプション(実際には更新しない、テストモード)をつけて試してみます。

#!/bin/bash

/etc/rc.d/init.d/httpd stop
cd /home/lima/certbot
/home/lima/certbot/certbot-auto renew --dry-run > /var/log/certbot.renew.log 2>&1
/etc/rc.d/init.d/httpd start

「cron-renew-letsencrypt-certificates」を実行します。
処理が終わるまでに時間がかかる場合があります。

$ su -
$ ./cron-renew-letsencrypt-certificates
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [  OK  ]

その後、ログを見てみます。
最下部に「Congratulations, all renewals succeeded.」と表示されていれば、成功です。

$ vi /var/log/certbot.renew.log
#省略
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/lima.world.conf
-------------------------------------------------------------------------------
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/lima.world/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)

このままではdry-runのままですので、実際に実行できるようにスクリプト書き換えます。

#!/bin/bash

/etc/rc.d/init.d/httpd stop
cd /home/lima/certbot
/home/lima/certbot/certbot-auto renew > /var/log/certbot.renew.log 2>&1
/etc/rc.d/init.d/httpd cstart

あとは、crontabでこのスクリプトを定期的に起動するように設定します。

crontabを設定

まだcronをインストールしていない場合は、下記のコマンドでインストールします。

$ yum install crontabs


cronの設定を開き、スクリプトが起動するよう追記します。


$ sudo crontab -u root -e
13 13 13 * * /home/lima/cron/cron-renew-letsencrypt-certificates

これは毎月1回、13日の13時13分に実行する設定です。何時でもOKですが、なんとなく。
毎日実行させても良いとは思いますが、証明書は3ヶ月間有効ですので、月1回ぐらい起動させておけば良いかと思います。

あとは、スクリプトに実行権限を与えておきます。

chmod +x /home/lima/cron/cron-renew-letsencrypt-certificates

これで設定完了です。

無事に実行された場合のログは、このようなものでした。

$ sudo vi /var/log/certbot.renew.log


Upgrading certbot-auto 0.9.2 to 0.9.3...
Replacing certbot-auto...
Creating virtual environment...
Installing Python packages...
Installation succeeded.
/root/.local/share/letsencrypt/lib/python2.6/site-packages/cryptography/__init__.py:26: DeprecationWarning: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of cryptography will drop support for Python 2.6
  DeprecationWarning
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Cert not yet due for renewal

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/lima.world.conf
-------------------------------------------------------------------------------

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/lima.world/fullchain.pem (skipped)
No renewals were attempted.

まだ有効期限が迫っていない場合、更新も実行されません。
そのため「The following certs are not due for renewal yet」という形で終わっています。

また、上記と同様の理由で、自動更新を設定しているにもかかわらずLet’s Encryptから「certificate expiration notice(有効期限切れのお知らせ)」が届くこともあります。
放っておけばそのうち更新されますが、心配な場合は、cronでの起動頻度をもっと多くすると良いでしょう。



この記事にコメントする

メールアドレスは公開されません。コメントは管理者による承認後に公開されます。

関連記事

DEVONthinkのデータベース同期用に、さくらのVPSにWebDAV入れてみたら5分でおわった。
続きを読む

外部(本番)サーバにはphpMyAdminをインストールしたくない!でも、本番環境データベースへの外部からの接続は許可したくない…そんな時に便利なデータベースへの接続方法です!
続きを読む

さくらのレンタルサーバでは、サーバコントロールパネルからCRON(CRONTAB)を最大5つまで設定できる。
このCRONを使用することで、指定した時間に自動的にウェブページを書き換えることができる。
実は、SSHでログインすれば、6つ以上のCRONを設定することも可能だ。
ここまで書けば情報としては十分な気もするけれど、一応、手順も書いておく。
続きを読む

「さくらのレンタルサーバ スタンダード」から「さくらのマネージドサーバ」への移行作業をした。

その際に、phpMyAdminを利用してMySQLに接続し、データのエクスポート→移転先サーバでのインポートを試みたところ、移転先サーバで文字化けしてしまった。
文字エンコーディングはどちらもUTF-8 (utf8_general_ci) にしてあるにもかかわらず。
結論としては「phpMyAdminだけでなく、コマンドラインを使ってデータを取り出す」方法で無事に移行できたものの、2時間ぐらいハマってしまった。

続きを読む