カスタムドメイン取得とLet's Encrypt証明書とHeroku SSLと

Herokuへの証明書アップロード手順の確認のために、カスタムドメイン・証明書の取得から試してみた。
長い記事になりますが、備忘録として。

ドメインの取得

無料で独自ドメインを取得出来るという、 freenomを使用する。
(やはり無料だけあって色々とデメリットがあげられたりしているので、ご利用は自己責任で)
取得できるドメインは5種類で、 .tk/.ml/.ga/.cf/.gq となっている。

詳しい登録方法などは以下を参考にさせてもらいました。

今回は .tk のドメインで取得した。
ちなみに、.tkのドメインは90日間で25アクセス以下だった場合には登録が削除されるらしいので運用の際は注意。

以下のドメインで取得してみた。(もうドメイン登録はキャンセル済み)

ssl-sni-test.tk

ユーザー登録はメールアドレスからの登録にしたが、住所や名前などは必須となっていた。
以下が必須だった項目。

  • first name
  • last name
  • address1
  • city
  • state
  • postcode
  • phone number
  • password

登録すれば同時にドメインの申請も完了。

ネームサーバとDNS

freenomには無料で利用できるDNSサーバが用意されているのでそれを利用する。

上部メニューから Services -> My Domains を選択。
編集したいドメインの、 Manage Domainをクリック。

タブメニューの Management Tools -> Nameserversを選択。
Use default nameserversを選択して、Change Nameserversをクリック。
これで、freenomのネームサーバを使う設定に変更できた。
(デフォルトではfreenomのネームサーバを使うように設定されていないため、DNSの設定が出来なかった。)

あとは、タブメニューの Manage Freenom DNSを選択。
ここで、DNSの設定が可能となる。

証明書の取得

証明書は無料で発行出来る、 Lets Encrypt`を利用する。
証明書の発行には、ブラウザ上で発行出来るサービスがあるのでそちらを利用させてもらう。
以下に作者さんの詳しい説明があるので、そちらから。

基本、そのまま進めて問題ないが、1点だけ、秘密鍵はブラウザ上では作らずにローカルPC上で作成したものをアップした方がよさそう。
ブラウザ上で作ったものをHerokuにアップするとパスフレーズを解除しろ、と言われ、パスフレーズを解除しようとコマンドを入れるとエラーが出たりしたため、最初からパスフレーズがかかっていないものを作成し、アップロードした方が確実と思われる。

1
$ openssl genrsa 2048 > key.pem

ドメインの所有証明は、dns-01の方法を使用した。
取得したチャレンジトークンをTXTレコードとしてDNSに登録する。

登録例

Name Type TTL Target
_acme-challenge.ssl-sni-test.tk. TXT 14440 "L9Dlzt3Kzfu2mLYbmW2RTUdEzNBuNPiyyBt6yQyEjKk" |

結構すぐに反映された。
あとは証明書を発行するのみ。

Herokuへアップロード

Herokuのアプリに証明書を適用させるには2種類の方法がある。

  • SSL Endpoint : SSLアドオンを利用した方法 ($20/month)
    • Typeは sni
  • Heroku SSL : Heroku標準の機能 (無料)
    • Typeは endpoint

SSL Endpointは従来からの方法で、2016年末ごろにHeroku SSLが追加された。
なので、今後追加する場合にはHeroku SSLを利用する方がよい。

ただし、Heroku SSLはFree Dynoで利用しているアプリには使用出来ないので注意。
今回は Heroku SSLを利用する。

アップロード方法

アップロード方法は管理画面からGUI操作で行うか、Heroku CLI経由でコマンドラインから行うかの2種類がある。

管理画面からアップロードする

Settingから、Domains and certificatesセクションにある、Configure SSLをクリック。

更新方法を聞かれるので、今回はManuallyを選択。
AutomaticallyはLet’s Encryptの場合にのみ使える自動更新のオプションで、今回はLet’s Enctyptなので利用出来るのだが、普通はマニュアルになるため今回もマニュアルにした。

アップロードするウインドウが表示されるので、ファイルをドラッグ。

アップするものは以下。

  • 証明書 (+中間証明書)
  • 秘密鍵

中間証明書は、Let’s Encryptの場合だけなのかは不明だが、今回はなしでもアップすることが出来た。
通常は必要だと思われる(証明書発行会社のページには一緒にアップして下さい、とある)ので末尾に追加しておく。

無事、アップされると以下のようになる。

コマンドからのアップロード

certs:addでアップ可能。コマンドのヘルプは以下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ heroku certs:add -h
Usage: heroku certs:add CRT KEY [flags]

add an SSL certificate to an app

Flags:
 -a, --app     (required) app to run command against
 -r, --remote  git remote of app to use
 --bypass      bypass the trust chain completion step
 --domains     domains to create after certificate upload
 --type        type to create, either 'sni' or 'endpoint'

Note: certificates with PEM encoding are also valid

Example:

    $ heroku certs:add example.com.crt example.com.key

Example (Certificate Intermediary):

     $ heroku certs:add intermediary.crt example.com.crt example.com.key

アップする。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ heroku certs:add ssl-sni-test-cert.pem ssl-sni-test-server-nopass.key -a sni-test
Resolving trust chain... done
Adding SSL certificate to ⬢ sni-test... done
Certificate details:
Common Name(s): ssl-sni-test.tk
Expires At:     2017-11-02 02:12 UTC
Issuer:         /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
Starts At:      2017-08-04 02:12 UTC
Subject:        /CN=ssl-sni-test.tk
SSL certificate is verified by a root authority.
? Select domains you would like to add

=== Your certificate has been added successfully.  Add a custom domain to your app by running ⬢ heroku domains:add <yourdomain.com>

途中、ドメインの選択する箇所があったが、一つしかないしそのままエンターでいけた。

コマンドからアップ状況を確認する。

1
2
3
4
$ heroku certs -a sni-test
Name              Common Name(s)   Expires               Trusted  Type
────────────────  ───────────────  ────────────────────  ───────  ────
pteranodon-48202  ssl-sni-test.tk  2017-11-02 02:12 UTC  True     SNI

ドメインの設定

Herokuへのドメイン追加、と、DNSの設定、の2つが必要。

Herokuへのドメイン追加

証明書をアップした時と同じく、Setting画面から追加する。

追加したいドメインを登録。

登録すると以下のようになる。

もちろん、コマンドからも登録可能。

1
2
3
4
5
6
7
$ heroku domains:add ssl-sni-test.tk -a sni-test
Adding ssl-sni-test.tk to ⬢ sni-test... done
 ▸    Configure your app's DNS provider to point to the DNS Target ssl-sni-test.tk.herokudns.com.
 ▸    For help, see https://devcenter.heroku.com/articles/custom-domains

The domain ssl-sni-test.tk has been enqueued for addition
 ▸    Run heroku domains:wait 'ssl-sni-test.tk' to wait for completion

コマンドから確認すると以下のようになる。

1
2
3
4
5
6
7
8
$ heroku domains -a sni-test
=== sni-test Heroku Domain
sni-test.herokuapp.com

=== sni-test Custom Domains
Domain Name      DNS Target
───────────────  ─────────────────────────────
ssl-sni-test.tk  ssl-sni-test.tk.herokudns.com

DNSの設定

freenomからDNSの設定を行う。
Heroku側のドメイン追加で取得したDNS TargetをCNAMEとして登録する。以下のような形で追加した。

Name Type TTL Target
CNAME 14440 ssl-sni-test.tk.herokudns.com |

アクセス

httpsでアクセスすると、無事、アクセス出来た。
SSLもLet’s Encryptでちゃんと反映されていた。

2つの証明書と2つのドメイン

ここからは応用検証。
一つのHerokuアプリに2つのドメインを適用させ、それぞれに別々の証明書を適用させてみる。

サブドメインの証明書

先ほどと同じようにサブドメインの証明書を取得した。以下で取得する。

add.ssl-sni-test.tk

チャレンジトークンも変わるので、DNSレコードに2つ目のTXTレコードを追加する。

Herokuへアップ

管理画面から同じようにアップしてみたが、すでにアップされているものを置き換える事になるようで、複数の証明書をアップすることは出来なかった。
次にコマンドから追加してみるも、以下のようにエラーが出た。

1
2
3
4
$ heroku certs:add cert.pem server.key -a sni-test
Resolving trust chain... done
Adding SSL certificate to ⬢ sni-test... !
 ▸    Only one SNI endpoint is allowed per app (try certs:update instead).

どうやら証明書は一つしかアップ出来ないよう。
しかし、Only one SNI endpointとあるように、sniのタイプには証明書は一つしかアップできない、とのことのよう。

SSL Endpoint

というわけで、SSL Endpointのアドオンを追加し、試してみた。
アドオンを追加する。(有料なので注意)

1
$ heroku addons:create ssl:endpoint

証明書をアップする。その際、typeにendpointを指定する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ heroku certs:add cert.pem server.key --type endpoint -a sni-test
Resolving trust chain... done
Adding SSL certificate to ⬢ sni-test... done
⬢ sni-test now served by kanagawa-69051.herokussl.com
Certificate details:
Common Name(s): add.ssl-sni-test.tk
Expires At:     2017-11-02 02:49 UTC
Issuer:         /C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
Starts At:      2017-08-04 02:49 UTC
Subject:        /CN=add.ssl-sni-test.tk
SSL certificate is verified by a root authority.
? Select domains you would like to add

=== Your certificate has been added successfully.  Update your application's DNS settings as follows
Domain           Record Type  DNS Target
───────────────  ───────────  ─────────────────────────────
ssl-sni-test.tk  ALIAS/ANAME  ssl-sni-test.tk.herokudns.com

やはりtypeが違うのでアップすることが出来た。
証明書のアップ状況を確認してみる。

1
2
3
4
5
$ heroku certs -a sni-test
Name                 Endpoint                      Common Name(s)       Expires               Trusted  Type
───────────────────  ────────────────────────────  ───────────────────  ────────────────────  ───────  ────────
kanagawa-69051       kanagawa-69051.herokussl.com  add.ssl-sni-test.tk  2017-11-02 02:49 UTC  True     Endpoint
corythosaurus-87918  (Not applicable for SNI)      ssl-sni-test.tk      2017-11-02 02:12 UTC  True     SNI

ドメインの追加

同じく、Herokuへドメインを追加する。
登録するTarget Nameは、herokudns.comのものでもよいし、kanagawa-69051.herokussl.comのSSL Endpointで設定されているものでもどちらでもよい。

DNSには以下のように追加した。

Name Type TTL Target
add CNAME 14440 kanagawa-69051.herokussl.com |

アクセス

これで無事、 ssl-sni-test.tk と、 add.ssl-sni-test.tk の両方へアクセス出来るようになった。
さらに、どちらにも別々の証明書を適用させる事が出来た。

感想

無料ドメインと無料証明書はかなり便利そう。ドメインの方は運用に不安が残るが、全く無料で独自ドメインのHTTPSのサイトが持てるというのはちょっと驚き。(Herokuは無料では不可能)

Herokuの場合はアプリを気軽に作る事が出来るため、一つのサーバ(アプリ)での運用、というのはあまりすることがないと思われる。
そのため、sni endpoint それぞれのタイプで一つしか証明書がアップ出来ないようになっているのだと思う。それだったらアプリを分ければいいよ、との考え方だと思うので、複数アップロードの出番はまずないと思われる。

参考

   このエントリーをはてなブックマークに追加