Lightsailで独自ドメインを付けてSSL認証にする。

### 前提
あいからわず自分用メモに近い記事です。

読む方のために、スクリーンショットやコマンドを細かく記載していきますので、参考資料というより
実際にやらなくてもやったつもりになれる記事を目指していきます。

Route53で直接ドメインを取れば簡単なのかもしれませんが、今回は別のGoogleDomainsで取得中のドメインを使ってLightsail上のnginxに紐づけてrailsアプリを起動させるところまでやっていきます。

なお、モザイクや黒塗りが好きではないですが、スクリーンショットは加工してあり、
独自ドメインの部分に`mydomain.app`
静的IPのところを`99.83.154.118`と直しています。

### 現在までの状態
LightsailでAmazonLinux2インスタンスを作ります。

![AmazonLinux.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/f70ddf96-500e-6b6a-38fd-70cb6daeeb1c.jpeg)
その後AmazonLinux2インスタンスに静的IPアドレスを紐づけています。
![AmazonLinuxStaticIp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/5f557bde-4399-a47d-80a6-e2dd531669be.jpeg)

ここにSSHアクセスして、環境整備してnginxが起動できるところは省略します。

...
...
ということで
Webサーバにnginxをインストールしました。

今回の動作にはnginxだけで大丈夫なので、とりあえずアプリケーションサーバは切っていて、
静的IPアドレスでアクセスすると、nginxのエラーが出る画面となっています。

```
firefox http://99.83.154.118
```
![were sorry.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/8d671dc0-38b8-92e7-2746-03839473c73c.png)


nginxの返答が返ってきているのでWebサーバは動いていますね。



### DNSゾーンを作成しサブドメインを登録

私はGoogleDomainsで以前から取得しているドメインがあります。(ここではmydomain.appとします)
そのサブドメインの管理のみLightsailのDNSゾーンで管理します。

実質的にはRoute53のようですが、Lightsail内から操作でき、シンプルな設定内容なので初心者に優しくなっています。

今回は開発中のアプリのテストサーバーとしての用途なので、dev.mydomain.app
でホストゾーンを作成します。
作成されたら、Aレコードを追加して、サブドメインとLightsailインスタンスを紐づけします。
![Arecore.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/687dcb5b-ef22-00e4-d3ee-097ba955015e.jpeg)

### GoogleDomainsのカスタムネームレコードにRoute53で作ったホストゾーンのNSを登録する。

ではDNSが見つけてくれるよう、親ドメインへネームレコードの登録と行きます。
Lightsail上のDNSゾーンの詳細の中のネームサーバーの4行をGoogleに登録していきます。
![mydomain.appDNSzone.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/d3f97109-1ec6-1101-59f3-f978bc7869e0.jpeg)

上のLightsailのネームサーバを、親ドメインであるGoogleDomainsのカスタムレコードに追加します。
3行目の`dev.mydomain.app`が今回追加したNSレコードです。
![GoogleDomainsCustomRecord (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/832c9493-38b8-97e9-a4a8-843bcfab4384.jpeg)

ネームサーバーが一致していますね。

名前解決がされることを確認します。
![refused.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/e399624c-89b2-3c98-9281-8e43ed4b14a3.jpeg)
と表示されます。

自分が詰まったところだったのですが、今回の親ドメインがappドメインだからです。
app,devドメインは比較的新しいドメインで、SSL適用が必須のドメインとなっています。

ブラウザからのアクセスですと、ブラウザ内でURLの書き換え処理がなされ、HTTP指定をしてもアクセスがHTTPSアクセスへと変換されてしまいます。
そのため、現段階の設定では拒絶されます。

curlやdigコマンドで名前解決がなされているか確認して、それで動いていればそのままSSLを適用していきます。

```
curl http://dev.mydomain.app
```

```
<!DOCTYPE html>
<html>
<head>
  <title>We're sorry, but something went wrong (500)</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <style>
...
...
```

きちんとHTMLが返ってきましたので、独自ドメインの紐づけが完了しています。

digでも確認してみます。

```
dig http://origin.dev.mydomain.app
```

```
;; QUESTION SECTION:
;origin.dev.mydomain.app.                IN      A

;; ANSWER SECTION:
origin.dev.mydomain.app. 60      IN      A       99.83.154.118
```

lightsailで取得した静的IPが返ってきていますので、大丈夫です。

### ディストリビューションを作成する

AWSでのCloudFrontという機能なのですが、Lightsailではディストリビューションを作成するという名前で作成します。

ネットワーキングタブからディストリビューションの作成を選びます。
![distribution.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/c5a56858-4b84-b021-8c5f-2f36ffca94f6.png)

cloudfrontは、Webサーバーの直接アクセスをさせずに、cloudfrontだけがWebサーバーにアクセスをし、キャッシュを取得してから配信する仕組みです。
オリジンとなるWebサーバーにLightsailインスタンスを指定します。
![origin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/b3b61f24-a4dc-f1db-b730-28d5a439805a.png)
他の設定はあまりわかっていませんが、ディストリビューション(cloudfront)の一意の名前は
`www.dev.mydomain.app`としました。
![price.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/7becbfa7-0536-c260-16ad-0604f46bf04e.png)

作成したディストリビューション(cloudfront)でSSL証明書を作成します。

![certificate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/ca390543-e99c-6af7-50f2-531419ceadfe.jpeg)

LightsailのDNSゾーンにCNAMEレコードを追加することで所有者の確認と証明書の付与がなされます。
名前に当たるところに末尾の`dev.mydomain.app`も入っているので、注意して入力します。

![ce (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/61bbc6f5-f764-8fe7-2f96-0883b74f9266.jpeg)

証明書側とDNSゾーン側でコピペする項目名が違うので注意が必要です。

|ディストリビューション側|DNSゾーン側|
|---|---|
|名前|サブドメイン|
|値|マップ先|

![dns.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/119b4dc2-a914-8c58-f6c2-48fe64ddb0fd.jpeg)

CNAMEを登録しての、所有の確認による検証には結構時間がかかります。
一旦ここで休憩をいれます。
<hr>
10分ほどで反映されると読んだのですが、40分ほどかかりました。


検証が済み、ディストリビューションに用意されたアドレスでのアクセスでSSLが適用されました。
![デフォルトのドメイン名.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/1e6ac19b-aeaa-7998-67da-03f38625059c.jpeg)

j35ggtd784fpdj.cloudfront.netのリンクをクリックして
保護マークがついていることを確認します。
![went wrong.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/b6c3ad49-c781-013a-949e-0ad4ae635e56.jpeg)

最後にディストリビューションがカスタムドメイン使うことを有効にします。
![無効.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/b4921ac5-4a1c-d501-a065-7a8aff28d139.png)
![有効.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/029af2fb-3e15-e2e8-0128-4469f5269755.jpeg)



### DNSゾーンでCNAMEの関連付け

最後にDNSゾーン(dev.mydomain.app)に戻って、
`www.dev.mydomain.app`、`dev.mydomain.app`のアドレスレコードをディストリビューションに紐づけます。

![Arecord1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/67f46204-6474-7a09-ae3a-4ca10c2c23eb.jpeg)
![Arecord2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/86c2f4fe-6668-968a-9434-0d62945bcaea.jpeg)

ここではAレコードとして解決先を登録していますが、ディストリビューションがしっかりプルダウンで出てきますので、選択することでアドレスレコードとしてではなく、エイリアスレコードになるようです。

ここでも10分~40分ほど待てばOKでしょうか？

<hr>

今回は10分ほどで完了しました。

![finish.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/208ec6c6-22cb-de90-d915-e78ab90b2464.jpeg)


なお、nginx⇔ディストリビューション(cloudfront)間の通信は初期設定のままHTTPとして設定しました。

なので、この後pumaをproductionで起動させてみたのですが、リダイレクトループが起こりました。
pumaの設定force-sslをコメントアウトにすることで解決できました。

```config/environments/production.rb
# config.force_ssl = true
```

一度リダイレクトループが起こってわけがわかりませんでした。
これから開発でまたSSL関連でエラーに合うかもしれませんが、とりあえずはVPS、SSLが最安級で設定できていると思っています。

|Lightsailサービス|値段|
|---|---|
|Lightsailインスタンス|$3.5|
|静的IP紐づけインスタンス|$0.0|
|DNSゾーン(Lightsail版Route53)|$0.0(予定)|
|ディストリビューション(Lightsail版cloudfront)|$2.5まで|
|合計|$6.0|

DNSサービスにRoute53では料金がかかっていたので、もしかしたらLightsailDNSゾーンでも料金がかかっているかもしれないので、その場合はまた追記します。

ロードバランサーを入れないことでSSLが安くできたので、よかったなと思います。


#### 参考にしたサイト

[Google Domainsで管理しているドメインのサブドメインをRoute53で作成する](https://dev.classmethod.jp/articles/create-subdomain-on-route53/)
[【目指せ最安Webサイト】AWS+LightSailのディストリビューションを使ってWordPressをSSL化する方法。注意点・ACMの良い所](https://andes-melon.com/distributiononligitsail/)
[Lightsail が CloudFront をサポートしたようなので試してみた。](https://doc-sin.life/?p=1555#)
[.devドメインと.appドメインがHTTPSを強制する仕組み](https://qiita.com/tomoyk/items/187aa6723e80e1bba675)