2016年6月1日水曜日

GAEでSSLの設定(Let’s Encrypt の導入備忘録)

---重要---
GAEのSSL設定は、マネージドセキュリティという仕組みが導入され、簡単になりました。
参考:Google App EngineでマネージドSSLが全ユーザーに無料提供

GAE設定の「カスタムドメイン」画面でカスタムドメインをチェックし、『マネージドセキュリティを有効にする』ボタンを押すだけで設定が完了します。また証明書の自動更新も行われます。
以下の記事のような作業は、行う必要はありません。(2017年9月14日以降)


今回はGAEのSSL設定について、備忘録を残します。

サーバにSSL証明書を導入することは、セキュリティの観点から推奨されています。しかしGAE(Google App Engine)上で導入するには、独特の費用の問題があり、簡単ではありませんでした。 しかし今では、導入のハードルはかなり下がってきています。

GAEでSSL証明書を導入する場合、以前は設定するだけ課金されました。しかし現在は、SNI 形式を利用する場合は無料で開放されています(以前は月額9ドル課金)。VIP 形式の場合は、現在でも月額39ドル課金されます。しかしSNI形式でも最近では、多くのブラウザーが対応しています。

参考
SNI は、グローバルIPに依存せず、ホスト名毎にSSL証明書を使い分けることができます。
wikipedia - Server Name Indication
VIP(仮想IP)は、アプリケーションに専用のIPアドレスを割り当てます。SSL証明書も、与えられたグローバルIPに対して割り当てられます。
GAE日本語訳 - カスタムドメインのSSL

SSL証明書自体も、年額で数万するという認識でした(グローバルサインのクイック認証SSLで、定価34800円など)。しかしSSL/TSL普及を目指す非営利団体の登場などにより、現在では無料のSSL証明書を利用することも可能になっています。

今回無料のSSL証明書である、Let’s Encrypt をGAEに導入します。この手順は既にネット上で公開されています。私もそれらの情報を参考に設定しましたが、一つ問題があります。それは Let’s Encrypt が発行する証明書の有効期限は90日と非常に短いのです。Let’s Encrypt では自動更新ツールを提供することにより、短い有効期限の問題の解決策を示していますが、現在のところGAE上ではこのツールを利用することが出来ないようです。

今回備忘録として設定方法を記事にするのは、サーバ側で何らかの解決策が示されるまで、当分定期的にSSL証明書を手動で登録更新を続ける必要があるためです。

今回参考にした記事・サイト
Let’s Encrypt
Let’s Encrypt on Google App Engine
Let's Encryptの証明書をGoogleAppEngineに設定して独自ドメインで運用する

Cloud Shell にてSSL証明書発行
Google Cloud Console から、Cloud Shell を開きます。ちなみに Cloud Shell は 2016年中は無料だそうです。

ブラウザの下部にシェルが表示されます。

次のコマンドで Let’s Encrypt モジュールのクーロンを作成します。

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

Let’s Encrypt のディレクトリに移動します。

cd letsencrypt

下のコマンドで、チャレンジ・レスポンス確認モードで動作させます(この時モジュールがインストールされるため、時間が掛かります)。

sudo ./letsencrypt-auto -a manual certonly

リカバリ用にメールアドレスを入力します。

利用規約に同意します。

独自ドメインを入力します。

マニュアルモードでの動作を確認します。

次のメッセージが表示されます。

独自ドメインの次のURLにアクセスすると、指示されたレスポンスコードを返すように設定します。

http://独自ドメイン/.well-known/acme-challenge/チャレンジコード

いろいろ方法がありますが、app.yaml に次の設定を追加するのが簡単です。

- url: /.well-known/acme-challenge/?(.{5}).*
  static_files: applications/myapp/static/letsencrypt/\1.txt
  upload: applications/myapp/static/letsencrypt/(.+)
  mime_type: text/plain

applications/myapp/static/letsencrypt/ ディレクトリに、チャレンジコードの頭5桁の名前を付けたテキストファイルの中身に、レスポンスコードを入れて、ファイルを生成します。例えば、

l1b83dAg6K-b10wHpoFguNo9b4iOIOAkiHtEkT3yhiE というチャレンジコードだったら、 l1b83.txt というファイルを作成し、中身にレスポンスコードを入れます。

これらのアプリケーションファイルのGAEへのアップロードが完了したら、ENTERキーを押して処理を続行し、正常に完了したら証明書が生成されています。

SSL証明書のセット
SSL証明書は Cloud Shell 上で、

/etc/letsencrypt/live/独自ドメイン/fullchain.pem  → 公開鍵証明書
/etc/letsencrypt/live/独自ドメイン/privkey.pem   → RSA秘密鍵

ファイルが生成されています。Cloud Consolel の「設定」→「SSL証明書」→「新しい証明書をアップロード」 で次の画面を開きます。

Cloud Shell の次のコマンドで公開鍵証明書の中身を表示します。

sudo less /etc/letsencrypt/live/独自ドメイン/fullchain.pem

-----BEGIN CERTIFICATE-----
xxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END CERTIFICATE-----

BEGINの行からENDの行までコピーして、公開鍵証明書の画面に貼り付けます。

追記(注意): fullchain.pem には、公開鍵証明書と共に中間CA証明書が追記されています。つまり、

-----BEGIN CERTIFICATE-----
公開鍵証明書
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
中間CA証明書
-----END CERTIFICATE-----

という構成になっていますので、公開鍵証明書のBEGINから中間CA証明書のENDまでコピーします。

同様にRSA秘密鍵も、

sudo openssl rsa -inform pem -in /etc/letsencrypt/live/独自ドメイン/privkey.pem -outform pem | less
で中身を表示します。

-----BEGIN RSA PRIVATE KEY-----
xxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END RSA PRIVATE KEY-----

同様にBEGINからENDの行までをコピーし、画面に貼り付けます。完了したらSSL証明書をアップロードします。

最後に、アップロードしたSSL証明書のリンクをクリックし、「次のカスタム ドメインに対して SSL を有効にします」の項目でカスタムドメインにチェックを入れて、保存ボタンを押します。これによって、SSL証明書が有効に動作します。


以上で、SSL証明書の設定は完了します。難しくはないのですが、分かり難いです。この作業を90日毎に行う必要があります(更新では証明書を生成して貼り付けるだけですが・・・)。GAEでも自動で更新するようになれば楽になります。今後に期待しています。