いつきコンテンツ

ヘルプ

カウンター


2016-06-15 Let's encrypt使って暗号化してみた

ポートが1つ(https/443)しか使えないワシの場合用メモ。

一般的な場合は、Let’s EncryptでSSL証明書を無料取得&自動更新しよう - D2CSolutions Weblog - デジタル・マーケティングの技術&事例ブログあたりを見ながらやれば良いと思う。letsencrypt-autoは、certbot-autoになってて入手先も違うけど。

対象はCentOS 6系です。他の環境でも一部変更すれば使えると思うよ!

[日記][Linux][Unix] Let's encryptで暗号化

まず前提として、1つしかポートが使えない状態(httpsの443のみ使える状態)です(いやまぁ、開けることはできるんだけど、セキュリティ上開けたくなかったのよ……)

最初はwebrootプラグイン使って認証出来ないかなぁと色々試してみたが、どうやら出来ない模様(将来的には出来るかもしれん)

理想は……

Let's Encrypt側 - インターネット - サーバー(nginx/port443)

だったのだが、webrootプラグインではどうも443にいきなりアクセスして/.well-known/をつついてもらうことは出来ないっぽい(問答無用でhttp/80にアクセスが来た。http/80を開けてるなら、webroot使うと良いかもしれない)

しょうがないので妥協案

Let's Encrypt側 - インターネット - Let's Encryptクライアント(port443/旧名:letsencrypt-auto。使ったのは、cartbot-auto)

にして、Let's Encryptクライアント(以下、certbot)が起動している間は、nginxをシャットダウンさせるという方法。まぁ、こうすれば443ポートが空くので、certbotがstandaloneで使えるようになる。

欠点は、certbotが起動している間(数秒程度だが)httpsのアクセスが出来なくなるところ……。まあこの辺は、ポート空けるか、リロードする間止めるかのトレードオフになりそう。


と言う訳で、前置きが長くなりましたが、方法を。

CentOS 6の場合、どうやらユーザー権限ではなく、rootじゃないと無理っぽいので、全部rootで実行です。

まず、CentOS 6で必要なおまじないをします。

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

1行目は、CentOS 6でSCL(CentOSで、複数のバージョンのバイナリを動かすためのツールみたいなもん)をインストールしています。

何故かというと、certbotはpython 2.7系じゃ無いと警告(まれにエラーも)が出るからです。ちなみにCentOS 6系は、python 2.6が入っています。2.7にすることは出来ません(´・ω・`)

で、2行目は、python 2.7(と、ツール)をインストールします。SCLのおかげで、これをインストールしてもOS標準のpythonは書き換わりません。要するに、python依存のツールはそのまま使えます。

んじゃぁ、どうやってpython 2.7を使うかというと、次のコマンドを入力します

scl enable python27 bash

これを使うと、python27(python 2.7)が有効な状態の、bashが起動します(つまり、この端末から元の環境に戻るためには一回exitしないとだめです)

以降はこのbash上から実行することになります。

複数端末を起動している場合は、入力先を間違わないように注意。

ちなみに、pythonが2.6か2.7かは、

python -V

(Vは大文字)とやるとバージョンが分かるので、sclコマンド入力前後で確かめると良いでしょう。

これで準備はOK。以下はCentOS 6以外でも共通です。


まず、certbotをダウンロードするディレクトリを決めましょう。今回は、/usr/local/certbotとします。*1

そのディレクトリを作成して、移動*2します。

mkdir /usr/local/certbot
cd /usr/local/certbot

次に、certbot本体(certbot-auto)をダウンロードして、実行権限をつけます。

wget https://dl.eff.org/certbot-auto
chmod 700 certbot-auto

この状態で、

./certbot-auto --help

とやると、必要なものをモリモリインストールしてくれます。

次に、standaloneモードで起動するため、一度nginxを閉じます。

service nginx stop

これで443ポートが使えるようになります。

あとは、certbotを起動するだけ!

./certbot-auto

現在、最初に「何モードで起動するか」を聞いてきます。

今回はstandaloneモード(certbot自体にサーバーもやらせる)ので、standaloneを選びます。

次に、緊急時のメールアドレスを聞いてきますので、入力します。何かあったときはこのアドレス宛に何かクルらしいです。よく分からないが、英語を読め(笑)

で、その次に利用規約へ同意するかどうかを聞いてきますので、大丈夫ならagreeを選びます。

そうすると、「ドメイン名入れてね」みたいな事を言われますので、httpsサーバーにするドメイン名(=今動かそうとしているサーバーを指しているドメイン名)を入力します。

で、OKを押すと、勝手にドメインに対する証明書を作ってくれます。

証明書自体は、最新のものが

/etc/letsencrypt/live/ドメイン名/fullchain.pem
/etc/letsencrypt/live/ドメイン名/privkey.pem

に置かれます(それぞれ、証明書のフルチェインと鍵です。Apacheに設定するときは、同じディレクトリのcert.pemやらchain.pemを使います)

ちなみにこれらのファイルはシンボリックリンクになっていて、/etc/letsencrypt/archive/ドメイン名/fullchain1.pemとかにリンクされています。全部/etc/letsencrypt以下に出来ますので、そこは安心。

この時点で、今まで入れた設定が/etc/letsencrypt以下にも保存されています。

後は、何らかの方法でwebサーバーにこの証明書を教えてやればOKです。

ちなみに、nginxの場合は、こんな感じ(/etc/nginx/conf.d/ssl.conf)

server {
listen 443;
server_name サーバー名;
(省略)
ssl on;
ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem;
(以下省略)

これで、service nginx startとか入力してやれば、認証済みの証明書を使ったhttpsサーバーが起動します。

ヨカッタネ!


さて、最後に更新の問題です。

Let's encryptは、更新期間が90日と非常に短くなっています。

まぁ、90日後前後に再入力してやれば良いのですが、めんどくさいので、自動化しましょう。

その前に、更新方法を。

今回はstandaloneモードなので、nginxを止めた状態で

./certbot-auto renew

としてやれば、必要ならば勝手に更新されます。

なので、centos6のSCLを有効にしたうえでrenewするには、

scl enable  python27  'bash -c "cd /usr/local/certbot && /etc/init.d/nginx stop && ./certbot-auto renew && /etc/init.d/nginx start"'

と書いてやれば良いことになります。

順に、SCLでpython27を有効にする。bashを起動して、以下のコマンドを実行する。/usr/local/certbotへ移動する。nginxを止める。certbotを使って更新する。nginxを起動する。というコマンドです。1行で書いて下さい。

さて、少しだけ改良してログをとるようにしましょう。

scl enable  python27  'bash -c "cd /usr/local/certbot && /etc/init.d/nginx stop >> /root/cert-renew.log 2>&1 &&  ./certbot-auto renew >> /root/cert-renew.log 2>&1  && /etc/init.d/nginx start >> /root/cert-renew.log 2>&1"'

これで、更新ログが/root/cert-renew.logにとられるようになります。

あとはこれをcronあたりで実行してやればいいわけです。

上のサイトを参考にして、rootでcrontab -eを実行し、こんな行を付け足しました。

10 0 1 * * scl enable  python27  'bash -c "cd /usr/local/certbot && /etc/init.d/nginx stop >> /root/cert-renew.log 2>&1 &&  ./certbot-auto renew >> /root/cert-renew.log 2>&1  && /etc/init.d/nginx start >> /root/cert-renew.log 2>&1"'

これで毎月1日、0時10分に証明書を更新しようともくろむようになります。

一応注意なのですが、これだと、証明書が古いままの期間がまれに出ます。

nginxを止めている時間が毎日ある程度確保できているなら、

10 0 * * * scl~

とした方が良いかもしれません。

もしくは、./certbot-auto renewを、

./certbot-auto certonly --renew-by-default --standalone --standalone-supported-challenges tls-sni-01 --domains ドメイン名

として強制更新するのも手ではあります。これはまぁ、お好みで。


とまぁ、こんな感じで某所は更新させています。

本来はwebrootプラグインを使ってやったほうが良いのですが、443しか使えないという制約があったので……(;´Д`)

*1 ちなみに、/root以下に作ってしまい、「パーミッションが足りねぇ!」と怒られたアホがこちらになります。

*2 何処で判断してるのかまでは突き止めていませんが、どうも/usr/local/certbotのディレクトリは保存されているっぽく、このディレクトリで実行しないと文句を言われるようになります。イヤなら/rootとかにcdしても良いです

Last Update: 2016-06-15 15:23:20

カレンダー

2003|04|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|07|08|11|
2013|03|05|08|
2014|01|
2015|04|05|06|07|09|10|12|
2016|01|03|05|06|10|11|
Generated by tDiary version 4.1.2 + amazon(DB Patch 0.2.1) + counter(DB Patch 0.2) + IKPatch version beta 4.0.1.
Powered by Ruby version 2.1.5-p273 with ruby-fcgi