11
13

More than 3 years have passed since last update.

【ほぼ無料】FreenomとLet's Encryptを使って0円でドメインとSSL証明書を手に入れて、AWS EC2にdockerを入れてnginxコンテナを起動してドメインで繋がるHTTPS WEBサービスを立ち上げる方法

Last updated at Posted at 2020-11-24

経緯

何か業務で使う技術や新しい技術を試したいときにAWS上にWebサーバーを立ててAPIとかテストページとか用意して、ローカルのChromeやAndroid端末からhttpで繋いでごにょごにょやるってのを結構やる。
RestAPIの疎通確認ぐらいならそれでいいんだけど、WebRTCやWebSocketの検証で使いたい場合、SSL化されたサイトでないとエラーになって接続できないため動作確認が出来ない問題があった。
どうにかこうにか安価でオレオレ証明書じゃないWebサーバーを立てられないかなーと調べたところ、FreenomとLet's Encryptを使えばほぼ無料で独自ドメインのhttpsサーバーを立てられそうだと判明。

Freenomでのドメイン取得方法やLet's EncryptでのSSL証明書取得方法、それらをAWSで設定するやり方等は探せば断片的にはあるけど、全部まとまった記事は無かったので、備忘録もかねてここに残しておく。

やること

  1. 【無料】Freenomで無料ドメインを取得する
  2. 【条件付無料】AWS EC2インスタンスを作成してdockerをインストールする
  3. 【条件付無料】AWS Elastic IPで静的IPアドレスを発行してEC2インスタンスに関連付ける
  4. 【ほぼ無料】AWS Route53でDNS設定を行いドメイン名でEC2インスタンスに繋がるようにする
  5. 【無料】dockerでEC2インスタンスにnginxコンテナを立ち上げる
  6. 【無料】Let's Encryptで無料SSL証明書を取得してhttpsで繋がるようにする

無料の条件とほぼ無料の詳細

  • AWS EC2インスタンスは無料利用枠を使用する
    • 無料利用枠と記載のあるAmazonマシンイメージ(AMI)は月に750時間無料で使える。今回はそれを使うことで無料とする
  • ElasticIPで割り当てたEC2インスタンスは起動したままにしておく
    • ElasticIPで発行したIPアドレスがEC2インスタンスに関連付けされていない場合は課金が発生する。いくら課金されるかは調べていないがわずかであるらしい。こういう仕組みになっているのは無駄にIPアドレスを確保されるのを防ぐためだろう。
  • AWS Route53では月に0.5$課金される
    • 下記は公式(2020年11月現在)から抜粋してきたもの。まあこのくらいなら缶コーヒー半分くらいだし、いいよね。
      image.png

1. 【無料】Freenomで無料ドメインを取得する

早速やっていきます。ドメインはFreenomというサービスを使って取得します。Freenomとは、ドメインを無料で取得出来る海外のサービスです。ドメイン名は、XXXX.tkやXXXX.ml、XXXX.ga等が無料で取得できます。
https://www.freenom.com/ja/index.html

ドメインが使えることを確認し、チェックアウトする

好きなドメインを取得することが出来ますので、取得したいドメインを入力しましょう。利用可能か調べてくれて利用可能であれば以下のような画面になりますので「今すぐ入手!」を押下した後、「チェックアウト」を押下します。

image.png


image.png

使用期間を選択する

12ヵ月まで無料で使えるようですので、最大限使用させていただきましょう。Periodで「12 Months @ FREE」を選択して「Continue」を押下します。

image.png

ユーザー登録 or ログイン

金額が$0.00USD(無料)なのを確認します。問題なければ購入のためログインします。
私の場合は既に登録済みなので、普通にGoogleでログインします。
初回登録してないと、いろいろ登録しないといけないかもしれません。
image.png

規約に同意して購入

再度、金額が$0.00USD(無料)なのを確認してから、規約に同意のチェックを入れ、「Complete Order」を押下します。

image.png


image.png


image.png

これにてドメインの取得は完了しました。

2. 【条件付無料】AWS EC2インスタンスを作成してdockerをインストールする

こちらは私が書いた別の記事がそのまま使用できますので、こちら↓を参照ください。

AWS EC2インスタンスにdockerとdocker-composeをインストールして簡単なWEBサービスを立ち上げる方法

3. AWS Elastic IPで静的IPアドレスを発行してEC2インスタンスに関連付ける

静的IPアドレス(固定IPアドレス)を取得し、上記で起動したEC2インスタンスにそのIPアドレスを割り当てます。こうすることで、EC2を再起動したりしてもIPアドレスが変わることは無くなります。

静的IPアドレスを取得する

まずは画面操作して静的IPアドレスを取得します。
「Elastic IP」を押下し、
image.png
次の画面で「Elastic IP アドレスの割り当て」を押下します。
image.png
次の画面で「割り当て」を押下します。
image.png
静的IPアドレスが取得できました。
image.png

EC2インスタンスに静的IPアドレスを関連付ける

割り当てられたIPアドレスを選択状態にして「アクション」内の「Elastic IPアドレスの関連付け」を押下します。
image.png
インスタンスには、先ほど作成したEC2のインスタンスIDを入力します。
入力したら「関連付ける」を押下します。
image.png

EC2インスタンスと静的IPアドレスの関連付けが完了しました。
image.png

4. 【ほぼ無料】AWS Route53でDNS設定を行いドメイン名でEC2インスタンスに繋がるようにする

ドメイン名で繋がるようにDNS設定を行います。
ホストゾーン作成→Aレコード登録→FreenomでNameserver設定という手順になります。

ホストゾーンの作成

Route53の画面に行き、
image.png
「ホストゾーン」を押下します。
image.png
「ホストゾーンの作成」を押下します。
image.png
Freenomで取得したドメインを入力して「ホストゾーンの作成」を押下します。
image.png
ホストゾーンの作成が完了しました。
image.png

Aレコードの作成

「レコードの作成」を押下します。
image.png
シンプルルーティングがデフォルト選択されているのを確認して「次へ」を押下します。
image.png
「シンプルなレコードを定義」を押下します。
image.png
値/トラフィックのルーティング先で「レコードタイプに応じたIPアドレスまたは別の値」を選択した後、先ほど取得した静的IPアドレスを入力して、「シンプルなレコードを定義」を押下します。
image.png
レコードの作成を押下します。
image.png
レコードの作成が完了しました。
image.png

Nameserverの設定

今度はFreenomでNameserverの設定を行います。

「My Domains」を押下し、次の画面で「Manage Domain」を押下します。

image.png


image.png
「Management Tools」の「Nameservers」を押下します。
image.png
「Use custom nameservers(enter below)」を選択、Nameserver欄にはRoute53 ホストゾーンのNSレコードの値をコピペします。
入力したら「Change Nameservers」を押下します。
image.png

この時点で数分経過すると、DNSが浸透して行って「http://ドメイン名」でサイトが表示されるようになっているかと思います。
image.png

5. 【無料】dockerでEC2インスタンスにnginxコンテナを立ち上げる

6. 【無料】Let's Encryptで無料SSL証明書を取得してhttpsで繋がるようにする

5と6は一気にやっちゃいます。
いろいろやり方はあるかと思いますが、以下構成でdockerを使用してやってみます。

  • reverse-proxyコンテナをインターネットに公開し、https通信を受け付けます。
  • reverse-proxyコンテナからwebコンテナへ通信を転送、webコンテナではreverse-proxyからhttp通信を受け付けます。

Untitled Diagram.png

全てのdockerを停止しておく

誤動作防止のため、作業前に一度全てのdockerコンテナを止めて、dockerオブジェクトも全部削除しておくといいでしょう。

docker stop $(docker ps -q)
docker system prune -a

webコンテナの作成と起動

homeディレクトリ配下にwebディレクトリを作成し、必要な構成ファイルを作成します。

cd
mkdir web

ディレクトリ配下とファイルの内容は以下のような構成にしました。

ディレクトリ構成
web
  - html
      - index.html # hogeとでも書いておく
  - docker-compose.yml
docker-compose.yml
version: '3'

services:
  web:
    image: nginx:latest
    container_name: web
    volumes:
      - ./html:/usr/share/nginx/html

作成が終わったらdockerコンテナを起動します。

docker-compose up -d --build

起動したことを確認します。

docker-compose ps
Name              Command               State   Ports
------------------------------------------------------
web    /docker-entrypoint.sh ngin ...   Up      80/tcp

reverse-proxyコンテナの作成と起動

homeディレクトリ配下にreverse-proxyディレクトリを作成し、必要な構成ファイルを作成します。

cd
mkdir reverse-proxy

ディレクトリ配下とファイルの内容は、悪戦苦闘の結果、以下のような構成にしました。

ディレクトリ構成
reverse-proxy
  - reverse-proxy
    - default.conf
    - Dockerfile
    - entrypoint.sh
  - docker-compose.yml
default.conf
server{

    server_name y-do.tk;

    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location / {
      proxy_pass     http://web/;
    }

}
Dockerfile
FROM nginx

COPY default.conf /etc/nginx/conf.d/default.conf

RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

RUN apt-get update && apt-get install -y \
  wget cron && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/*

ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it.sh
RUN chmod +x /usr/local/bin/wait-for-it.sh

ADD https://dl.eff.org/certbot-auto /usr/local/bin/certbot-auto
RUN chmod a+x /usr/local/bin/certbot-auto
RUN certbot-auto --os-packages-only -n

COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["entrypoint.sh"]
entrypoint.sh
#!/bin/bash

# hogehoge@example.comはメールアドレス
certbot-auto --nginx -d y-do.tk -m hogehoge@example.com --agree-tos -n
certbot-auto renew

# cron job settings
# Let's Encrypt automatic Renew
echo '0 8 * * * certbot-auto renew --post-hook "nginx -s reload"' >> /cron-tmpfile
crontab /cron-tmpfile
rm /cron-tmpfile

# cron start
/etc/init.d/cron start

/bin/bash
docker-compose.yml
version: '3'

services:
  reverse-proxy:
    build: ./reverse-proxy
    tty: true
    container_name: reverse-proxy
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - '/srv/letsencrypt:/etc/letsencrypt'
    command: ["wait-for-it.sh", "web:80"]
    networks:
      - default
      - web_default

networks:
  web_default:
    external: true

作成が終わったらdockerコンテナを起動します。

docker-compose up -d --build

起動したことを確認します。

docker-compose ps
    Name                   Command               State                    Ports
-------------------------------------------------------------------------------------------------
reverse-proxy   entrypoint.sh wait-for-it. ...   Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp

インターネットからhttpsで繋がるようにAWSでセキュリティグループを更新する

FWで弾かれているため、まだインターネットからhttps通信を受け付けることが出来ません。
AWSのセキュリティグループのインバウンドルールを修正します。

ルールを追加して、タイプ「HTTPS」、ソースは「0.0.0.0/0」を入力します。
入力したら「ルールを保存」を押下します。

image.png

動作確認

ここまでやってやっとhttpsで通信が出来るようになっているはずです。アクセスしてみます。

image.png


image.png

アクセス出来た!!!

結果

月額0.5USDで独自ドメインのSSLサイトが運用できる。
ただし、ドメインは12ヵ月、SSL証明書は3か月で有効期限が切れる(無料だから文句は言えない)ので、今後は自動更新の仕組みを導入したい

11
13
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13