GAE 公式で Let's encrypt に対応!
2017年9月より、GAE自体がLet's encrypt に対応しました。 これにより、コンソールからの簡単操作でSSL証明書が導入できるようになりました。 しかも Google が自動的に証明書も更新してくれます。 今から設定する人は、そちらを使いましょう。
無料でSSL/TLS証明書が発行できるLets' Encryptプロジェクトが、2016年4月、ついにベータ版から正式版になりました。
無料といっても、MozillaやGoogle, Facebookなどのウェブ企業や、シスコやアカマイなどのネットワーク関係の大御所も支援しているプロジェクトなので、審査がなく全自動で発行されるタイプの1,000-2,000円くらいの有料のSSL証明書と全く遜色ありません*1。
業界的にウェブの暗号化に向けてこのようなプロジェクトを動かしているのは素晴らしいですね。
GAEへのSSL/TLS証明書の導入
さて、独自ドメイン運用をしているGoogle App Engine(GAE)のサイトをSSL/TLS対応をしてみましょう。
Let's Encrypt では、証明書発行の際に、ドメインの所有の確認のため、指定されたURLにファイルをアップロードする必要があります。よくあるプロセスですね。
通常のサーバーの場合は、この確認用のファイルの設定や、Apache/nginxなどの設定もcertbotというプログラムが証明書の取得とあわせてやってくれるのですが、GAEの場合証明書の設定はGUIでしかできません。
そこで、証明書の取得のみ行うmanual
モードで行います。なのでこのためにわざわざサーバーを立てる必要はありません。以下では Mac OSX 10.11.4で作業しました。
1. 独自ドメインの設定を終えておく
まずは、独自ドメインがGAEで表示できる状態にしておきます。 あとのステップで、Let's Encrypt から取得しようとする証明書用のサーバーにリクエストが来て所有の確認が行われるので、DNSの設定などは済ませておく必要があります。
2. 証明書の取得
まずは、Let's Encrypt のクライアントのインストールを行います。
cloneします。10MBほどあるので、そこそこ時間かかります。
$ git clone https://github.com/certbot/certbot $ cd certbot
それでは早速証明書を取得してみましょう。初回は必要なプログラムのインストールが行われるので、時間がかかります。 また環境のrootのPWを求められる場合があります。
初回のみ、メールアドレスを聞かれるのと、利用規約への同意を求められます。
ちなみにこのcert-only
のonlyというのは、インストールも行うrun
に対して、インストールはしない、という意味です。
また以前は、letsencrypt-auto
でしたが、2016年5月からcertbot-auto
に変更になったそうです。
$ ./certbot-auto certonly --manual # PWを求められるかも
必要なミドルウェアのインストールが終わると、次のような画面になります。 ここに取得予定のドメインを入力します。カンマ区切りスペース区切りで複数可。
次にクライアントのIPアドレスがログに記録され公開されることに対する同意確認画面。Yesで進みます。
次に以下のようなメッセージが表示されます。
Make sure your web server displays the following content at http://cheetahapp.net/.well-known/acme-challenge/gTIjcnRpydLV5lcRDD-b-2TcTRh4YyZC26jDSZOx2ck before continuing: gTIjcnRpydLV5lcRDD-b-2TcTRh4YyZC26jDSZOx2ck.5Hvrmt1oBopQ03IDSAdTZRRoXZACheMnLi_Y272bLx4 If you don't have HTTP server configured, you can run the following command on the target server (as root): mkdir -p /tmp/certbot/public_html/.well-known/acme-challenge cd /tmp/certbot/public_html printf "%s" gTIjcnRpydLV5lcRDD-b-2TcTRh4YyZC26jDSZOx2ck.5Hvrmt1oBopQ03IDSAdTZRRoXZACheMnLi_Y272bLx4 > .well-known/acme-challenge/gTIjcnRpydLV5lcRDD-b-2TcTRh4YyZC26jDSZOx2ck # run only once per server: $(command -v python2 || command -v python2.7 || command -v python2.6) -c \ "import BaseHTTPServer, SimpleHTTPServer; \ s = BaseHTTPServer.HTTPServer(('', 80), SimpleHTTPServer.SimpleHTTPRequestHandler); \ s.serve_forever()" Press ENTER to continue
ここははやる気持ちを抑えてまだENTERは押しません!!
指示どおりに、Let's Encryptからのメッセージの存在確認用URLにテキストを置きます。 上記の場合は、以下のURLで以下が表示されるようにします。
URL: http://cheetahapp.net/.well-known/acme-challenge/gTIjcnRpydLV5lcRDD-b-2TcTRh4YyZC26jDSZOx2ck
内容: gTIjcnRpydLV5lcRDD-b-2TcTRh4YyZC26jDSZOx2ck.5Hvrmt1oBopQ03IDSAdTZRRoXZACheMnLi_Y272bLx4
GAEでは以下の様に設定します。
lets_encrypt.txt
:
gTIjcnRpydLV5lcRDD-b-2TcTRh4YyZC26jDSZOx2ck.5Hvrmt1oBopQ03IDSAdTZRRoXZACheMnLi_Y272bLx4
app.yaml
:
- url: /.well-known/acme-challenge/gTIjcnRpydLV5lcRDD-b-2TcTRh4YyZC26jDSZOx2ck static_files: lets_encrypt.txt upload: lets_encrypt.txt
デプロイします。
$ appcfg update .
さっきのURLをクリックして内容が表示されることを確認したら、エンターを押します。
しばらくすると、以下のような内容が表示されて無事証明書が取得できました。
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/cheetahapp.net/fullchain.pem. Your cert will expire on 2016-08-31. 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 ceriticates, 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/[domain_name]
にあります。
$ sudo ls /etc/letsencrypt/live/cheetahapp.net cert.pem chain.pem fullchain.pem privkey.pem
秘密鍵を復号化します。
$ sudo openssl rsa -in /etc/letsencrypt/live/[domain_name]/privkey.pem -out /etc/letsencrypt/live/[domain_name]/privkey_no_pass.pem
3. GAEへの登録
GCPのコンソールから、GAE→設定→SSL 証明書→新しい証明書をアップロードの順に開きます。
「PEM でエンコードされた X.509 公開鍵証明書」の欄に、fullchain.pem
を、
「復号化された PEM でエンコードされた RSA 秘密鍵」の欄にprivkey_no_pass.pem
をペーストします。
ここで復号化を忘れると選択した秘密鍵は有効ではないようです。
というエラーメッセージが表示されます。これ結構はまりましたw
4. 動作確認
無事に設定できると、以下のようにアドレスバーが緑になります。やった!!
課題 証明書が3ヶ月で切れてしまう
SSL証明書は3ヶ月で切れてしまいます。通常年単位での更新なのでこれはちょっと面倒です。
サーバー自体にcertbotを入れれば、/etc/letsencrypt/live/[domain_name]
に常に最新に証明書のシンボリックリンクが貼られるので手間はないのですが、GAEだとそうはいきません。
証明書の再取得はコマンドできるのですが、GAEへの証明書の送信はAPIなどあるのでしょうか。軽く探したところは見つかりませんでした。
3ヶ月おきにフォーム行くのは地味に面倒なので、そこに1000円払うと割りきって既存のSSL業者を使う、というのもありかもしれません。
証明書の更新 (2016/11/1 追記)
早速3か月経ったので、証明書の更新を行いました。 更新でもファイルをアップロードする必要がありますが、アップロードするURLとファイル内容は同じなので、コマンド押していけば簡単に新しい証明書を取得できます。 コマンドさえメモっておけば5分もあれば更新完了するので、そんなに手間でもありませんね。
ただまあGAEとかに関してはこの作業完全自動化してくれたら嬉しいんですけどねー。。
まとめ
GAEのSSL対応、これがあれば5分くらいで終わってしまいますね。 いつもSSL対応は、秘密鍵作ってそれでCSR作って会社のサイトのフォームに行って発行依頼して、メールクリックして、証明書DLしてなど複雑な手順だったので、かなり簡単になりました。 しかも全部無料、提供しているのがシスコ・アカマイ、Google、Facebookなので割と安心、ということで、銀行などが使っているアドレスバーに緑の組織名が表示されるEV SSL以外はどんどん移行が進むんじゃないでしょうか。
参考
qiita.com 秘密鍵の復号化で同じはまりをされていた方w
qiita.com 同様のことをGCEのインスタンスで行った事例。
*1:どちらも改ざんと盗聴には効果がありますが、なりすましには無力です。