Let’s Encryptの更新方法と更新の自動化

この投稿でLet’s Encryptで無料でSSL証明書を作りましたが有効期限が切れそうなので更新します。
環境は、サーバはさくらのVPS、OSはUbuntu16.04、webサーバはnginxです。

更新方法

参考:https://certbot.eff.org/#ubuntuxenial-nginx

Automating renewal

有効期限が切れる前に自動的に証明書を更新するようにCertbotを設定することができます。 Let’s Encrypt Encryptは90日間使用できるので、この機能を利用することをお勧めします。このコマンドを実行すると、証明書の自動更新をテストできます。

$ letsencrypt renew --dry-run --agree-tos

Ubuntu Xenial上のCertbotのバージョンに「電子メールなしで登録する!」という警告が表示されるバグがあります。以前にCertbotに電子メールを送っていたとしても。これが起こっても心配しないでください。更新には影響しません。それが正しく動作していると思われる場合は、以下を実行するcronまたはsystemdジョブを追加して自動更新を手配できます

$ letsencrypt renew

更新する

更新はNginxをとめないといけません。止めずにrenewコマンドを実行すると、エラーがでます。

The program nginx (process ID 22394) is already listening on TCP port 80. This
will prevent us from binding to that port. Please stop the nginx program
temporarily and then try again. For automated renewal, you may want to use a
script that stops and starts your webserver. You can find an example at
https://letsencrypt.org/howitworks/#writing-your-own-renewal-script.
Alternatively you can use the webroot plugin to renew without needing to stop
and start your webserver.

手動で更新する

Nginxを停止したのちに、renewコマンドを実行して、Nginxを再開するか、webrootプラグインを利用して、renewコマンドを実行する必要があります。webrootプラグインを利用する場合、80ポートにアクセスしてNot Foundとかにならないようにする必要があるようです。私の場合、httpsでしか接続できない(httpの場合強制的にhttpsにリダイレクトさせる)ようにしてあるので、webrootは使えませんでした。Nginx停止&再開をrenewコマンドの前後でやってみます。

$ sudo systemctl stop nginx.service
$ letsencrypt renew
$ sudo systemctl start nginx.service

自動更新させる

自動更新はcronを使います。

$ cd 
$ vim .crontab

.crontabの中身を下記のようにします。

0 3 15 * * systemctl stop nginx.service; letsencrypt renew; systemctl start nginx.service

あるいは、ログを残しておく場合は下記のようにします。

0 3 15 * * systemctl stop nginx.service; letsencrypt renew > /var/log/cron.log 2>&1; systemctl start nginx.service

crontabに反映させます。

$ crontab .crontab
$ crontab -l
0 3 15 * * systemctl stop nginx.service; letsencrypt renew; systemctl start nginx.service

設定がうまく反映できているかの確認をしたい場合、一旦上記cronの実行頻度を変更してすぐに実行させるようにしつつ、下記のような感じでログ出力したらいいと思います。

* * * * * systemctl stop nginx.service; letsencrypt renew >> /var/log/cron.log 2>&1; systemctl start nginx.service

Let’s EncryptでSSL証明書を無料で作る

Let’s Encryptで無料でSSL証明書を作成します。
certbotというのを使って作ります。

Ubuntu + Nginxの場合は下記になります。
参考:https://certbot.eff.org/#ubuntuxenial-nginx

$ sudo apt-get install letsencrypt 
$ letsencrypt certonly --standalone -d hoge.com -d www.hoge.com

–standalone だと、nginxを一回とめないといけない。
—-webroot だと、とめなくていいけど、80ポートで登録するサイトにアクセスできる必要があるみたい。まだないサブドメインとかを事前登録したい場合は、standaloneを使えばいいのかな。

登録完了すると、下記ディレクトリに格納される。
/etc/letsencrypt/live/hoge.com/cert.pem
/etc/letsencrypt/live/hoge.com/fullchain.pem
/etc/letsencrypt/live/hoge.com/privkey.pem

nginxの設定では、下記のようにする。

listen 443;
ssl on;
ssl_certificate /etc/letsencrypt/live/hoge.com/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/hoge.com/privkey.pem;
server_name hoge.com;

複数のドメインを一気に登録したりすると、cert.pemじゃなくて、fullchain.pem使うみたい。

SSL証明書の設定(AWS)

何をやるかちょっと忘れた。

参考:
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/InstallCert.html#InstallSSL-managing-server-certs

sshでサーバに入ります。
opensslが入ってるか確認します。

sudo yum update openssl

プライベートキーを作成します。

openssl genrsa 2048 > private-key.pem

CSR(証明書署名要求)を作成する。

openssl req -new -key private-key.pem -out csr.pem
Country Nameは、日本の場合、JP
State or Province Nameは、都道府県なので、Tokyoとか。
Locality Name (eg, city)は、市区町村。Shibuya-kuとか。
Organization Nameは、会社名。Logicky Inc.など。
Organizational Unit Nameは、組織名(オプション)。
Common Nameは、ドメイン。logicky.comなど。(ワイルドカードを使ってサブドメインに対応させる場合は、*.logicky.comとする)
Email Addressは、メアド(オプション。空でいいらしい。)

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: これは、空でいいらしい。
An optional company name []: これは、空でいいらしい。

これで完成。

netowl.jpというところでSSL証明書を買ったんだけど、CSR入力後にSSL証明書発行したら、承認メールが送られてくるようになっていて、SSL証明を使うドメインのメールアドレスに承認メールが送られてくるので、メール受信可能な状態にしないといけない。AWSでメール受信設定するのもめんどくさいので、google mailを使うことにした。

証明書を発行したら、AWSのiamというのにアップロードしたら便利らしい。iamとか使わなくてもこの前で来たけどやってみる。

aws iam upload-server-certificate --server-certificate-name certificate_object_name --certificate-body file://public_key_certificate_file --private-key file://privatekey.pem --certificate-chain file://certificate_chain_file

Unable to locate credentials. You can configure credentials by running “aws configure”.

おお、使えない。

sudo yum install python-pip
sudo pip install awscli

Unable to locate credentials. You can configure credentials by running “aws configure”.
まだ使えない。AccessKeyとSecretKeyが必要で、それを設定する必要があるらしい。このKeyはIAMから取得できるらしい。IAMってなんだ。まあ、今いらないからいいや。

単純にアップして、httpd.conf(ssl.conf)を設定したら反映された。
chromeは、キャッシュしているらしく、正常に反映した後でも、URLバーが赤い状態になっていたが、ブラウザを再起動したら緑になった。

cakephp1.3 – SSL接続

1.3の場合セキュリティコンポーネントが微妙な挙動をするらしく、使わずにSSL接続や、CSRF対策などをやることが多いらしい。
SSL接続は、SSLコンポーネントというものが便利らしい。

SSL Component

簡単に設定できた。常時SSL接続の場合の設定方法はよくわからないが、本体ソースのssled関数で全部trueを返すようにしたらとりあえずできる。

参考:CakePHPのSSL Componentでhttpとhttpsを切り替える

cakePHP – httpsとhttpの接続強制処理

参考:CakePHP2.xでSSL接続(https://)を強制させる
参考:CakePHP 2.xのSecurityコンポーネントを使う際の注意点

Secutiryコンポーネントを使用すると、POST時に下記のような挙動をするため、Ajaxとか使ってるとエラーになるので注意が必要。

・Formヘルパーによって動的に生成されたTokenがhidden要素としてフォームに自動追加される。
・POSTされたフォームのTokenを確認して、問題があるとThe request has been black-holedとして処理され、$this->request->dataは空になる。

上記の動作を無効にするには、コントローラのbeforeFilter()に
$this->Security->validatePost = false;

AWSにジオトラストのSSLを設定する

Apache + OpenSSL ジオトラスト クイックSSL プレミアム インストール手順 (新規)

このとおりやったんですが、うまくいかない。httpsでアクセスするとこのウェブページにアクセスできませんってエラーになる。

環境は、下記です。
・Amazon Linux AMI release 2013.09
・Apache/2.2.26 (Unix)
・OpenSSL 1.0.1e-fips 11 Feb 2013

netstat -a | grep https

とかやってみるってどこかに書いてあったからやったけど、下記のようなの出てくるし、他のサーバでhttpsでアクセスできるやつでも同じ結果だから問題なさげ。

tcp 0 0 *:https *:* LISTEN

wget https://localhost

とやってみると、下記のようなのが出てくるので443に接続できてるし、証明書も読み込まれているっぽい。

–2014-02-12 16:03:39– https://localhost/
localhost (localhost) をDNSに問いあわせています… 127.0.0.1
localhost (localhost)|127.0.0.1|:443 に接続しています… 接続しました。
エラー: 証明書に記載されている別名とホスト名 `localhost’ が一致しません
localhost に安全の確認をしないで接続するには、`–no-check-certificate’ を使ってください。

wget https://ホスト名

ってやると、タイムアウトで接続できなかった。

AmazonEC2のサーバにSSLを設定する手順を見てたら、下記のように書いてあった。

ec2の管理画面のセキュリティーグループを修正
SSLには443ポートを使うので、インスタンスのセキュリティーグループをチェックし、そのセキュリティーグループのInboundの443番を解放する。

AmazonEC2サーバの443ポートをあける

参考:セキュリティーグループにルールを追加する (サーバーのポートを開放する)

このサイトのとおりに443あけたらできた。
(リージョン毎に表示されるインスタンスとか違うのか)

さくらVPS CentOS6.5でSSLをつかってみる

さくらサーバでSSLつかってみましょう。環境は下記になります。

・FreeBSD 9.1-RELEASE-p7 amd64
・さくらのレンタルサーバ スタンダード
・Apache/2.2.25

あら独自SSLを使えるのは、ビジネスプロ以降らしい。http://www.sakura.ne.jp/
では、VPSを使ってやってみよう。環境は下記になります。

・CentOS release 6.5 (Final)
・Apache/2.2.15 (Unix)
・OpenSSL 1.0.1e-fips 11 Feb 2013

mod_sslをインストールする

$ yum -y install mod_ssl

mod_ssl.x86_64 1:2.2.15-29.el6.centosというのがインストールされた。

CA用秘密鍵(ca.key)の作成

$ openssl genrsa -des3 -out /etc/httpd/conf/ca.key -rand rand.dat 1024

CA用証明書(ca.crt)の作成

$ openssl req -new -x509 -days 365 -key /etc/httpd/conf/ca.key -out /etc/httpd/conf/ca.crt

サーバ用秘密鍵(server.key)の作成

$ openssl genrsa -des3 -out /etc/httpd/conf/server.key -rand rand.dat 1024

署名要求書(server.csr)の作成

$ openssl req -new -key /etc/httpd/conf/server.key -out /etc/httpd/conf/server.csr

サーバ用秘密鍵(server.key)からのパスフレーズ削除

オリジナルをバックアップしてから、server.keyからのパスフレーズ削除

$ cp /etc/httpd/conf/server.key /etc/httpd/conf/server.key.bak
$ openssl rsa -in /etc/httpd/conf/server.key.bak -out /etc/httpd/conf/server.key

サーバ用証明書(server.crt)の作成

$ openssl x509 -req -signkey /etc/httpd/conf/server.key -days 3650 -in /etc/httpd/conf/server.csr -out /etc/httpd/conf/server.crt

ssl設定ファイル(ssl.conf)の変更

$ vim /etc/httpd/conf.d/ssl.conf

100 #   Server Certificate:
101 # Point SSLCertificateFile at a PEM encoded certificate.  If
102 # the certificate is encrypted, then you will be prompted for a
103 # pass phrase.  Note that a kill -HUP will prompt again.  A new
104 # certificate can be generated using the genkey(1) command.
105 
106 #SSLCertificateFile /etc/pki/tls/certs/localhost.crt
107 SSLCertificateFile /etc/httpd/conf/server.crt #<--これに変更
108 
109 #   Server Private Key:
110 #   If the key is not combined with the certificate, use this
111 #   directive to point at the key file.  Keep in mind that if
112 #   you've both a RSA and a DSA private key you can configure
113 #   both in parallel (to also allow the use of DSA ciphers, etc.)
114 
115 #SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
116 SSLCertificateKeyFile /etc/httpd/conf/server.key #<--これに変更

Apache再起動

/etc/rc.d/init.d/httpd restart

これでhttpsでアクセスすると反映されてた。

参考:はじめての自宅サーバ構築 – Fedora/CentOS –

AWSでCSRを作成する

AWSサーバに入るための鍵がppkという拡張子になっている。下記を見ながら変更してみる。
Putty の鍵ファイル .ppk を Linux ssh 用に変換してみる

yumが使えないから、下記を見ながらやってみる。
Run Putty on Mac OS X 10.6.8

sudo port install puttyってやっても、下記のエラーになった。
Error: Processing of port putty failed

sudo port selfupdateでportをアップデートしてみた。
テザリングでやってるから超おそい。
そもそもputtyとはなにか?

Windows OSで稼働するSSHクライアント。TTSSHとは異なり,SSHプロトコルversion2にも対応している。さらに,ファイル転送のためのscpや公開鍵認証のためのagentなど,UNIX版SSHクライアントの機能を多数サポートしている。

これがMacでも使えるらしい。SSHクライアントなんていらないんだけどな。やっぱり変換したい。
それにしてもUpdating the ports treeから動かない。諦めるか。一回とめてもう一回やってみる。やっぱり動かない。

そもそも変換したいわけだから、Putty自体は不要だし、どうもputtygenというのがあればいいらしい。
MacでPutty形式の秘密鍵を変換するこれみてもう一度やってみる。
brew install putty
おお出来たっぽい。

ppkを下記で変換できた。

puttygen putty_key.ppk -O private-openssh -o ~/.ssh/from_putty_key_rsa

SSHで接続しようとしてもPermission denied (publickey).ってでてエラーになる!
おーできた。ユーザ名指定してなかった笑

■CSRの作成(ジオトラスト)
サーバー証明書の作成、アップロード、削除
CSRの生成方法

CSRとは?企業の社会的責任ではない。CSRとは、お客様が生成し、認証局に提出する署名リクエスト(Certificate Signing Request)です。

ここで一旦お昼ご飯にする。