🐡

ローカル環境オレオレ証明書からの卒業

2023/04/15に公開

背景

ローカルで以下のような設定のnginxをdockerで動かして、
httpsでアクセスできるようにしていました

$ tree

├── docker-compose.yml
└── nginx
    ├── conf.d
    │   └── default.conf
    └── ssl
        ├── server.crt
        └── server.key
# nginx/conf.d/default.conf
server {
  listen 443 ssl;
  # ここ実際は自分の開発環境用のドメイン
  # 適当なサブドメインをつけてローカルループバックアドレスにしてます
  server_name YOURDOMAIN.example.com;

  # オレオレ
  ssl_certificate /etc/nginx/ssl/server.crt;
  ssl_certificate_key /etc/nginx/ssl/server.key;


  location / {
    proxy_pass http://frontend:3000/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # for websocket
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}
# docker-compose.yml
# 実際には他に同じnetworkにいるコンテナもあります
version: '3.8'

services:
  nginx:
    image: nginx:stable-alpine
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
    ports:
      - "443:443"
    networks:
      - frontend_network
networks:
  frontend_network:
    external: true
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout nginx/ssl/server.key -out nginx/ssl/server.crt

証明書はこんな感じで適当に作ってました

でもこれだとオレオレ証明書なので、
ブラウザでなんか警告出るし嫌だったので真面目に証明書を作ろうとなりました。

作成手順

1. EC2インスタンスを建てる

無料で建てられる適当なインスタンスを立てます。
グローバルIPアドレスだけ確認しておきましょう。

後ですぐに消すのでキーペアも今回用に作っても作らなくてもいいですし、
今回用に作るようなら後ですぐに消してOKです。

2. Aレコード設定

EC2インスタンスのグローバルIPアドレスをAレコードに設定します。
これはdomainの管理画面で設定できます。
TTLは最短にしておきましょう(最短でも300sが多いです)

3. certbotのインストール

macOSの場合で書きます。

brew install certbot
sudo certbot certonly --manual --domain YOURDOMAIN.example.com

英語を読みながら適当に返答していきます。
途中よくわからん(よく分からなくない)メールを受け取るかみたいな質問もあるので気をつけてください。
最後に

Create a file containing just this data:

[ファイルの中身にしないといけない文字列 以降 XXX]

And make it available on your web server at this URL:

http://YOURDOMAIN.EXAMPLE.COM/.well-known/acme-challenge/[ファイルの名前になる文字列 以降 YYY]

みたいな表示が出るのでここ(*)で何も押さずに次の作業に移ります

4. ec2上での作業

まずEC2の管理画面からインバウンドルールを編集して80番ポートを開けます。

次にEC2インスタンスにsshで入ります。

sudo -iu root
mkdir tmp
cd tmp
mkdir -p .well-known/acme-challenge
echo XX > .well-known/acme-challenge/YY
python -m http.server 80

とします
(*)に戻ってエンターを押します。

これで多分証明書ができてると思います。
作ったEC2インスタンスはここでちゃんと消し飛ばしましょう(1敗)
あとAレコードもローカルループバックアドレスに戻しておきましょう。

5. nginxの設定

certbotを実行したときに作られた証明書をnginxの設定に反映します。
まずは証明書をコピーします。

sudo cp /etc/letsencrypt/archive/YOURDOMAIN.example.com/privkey1.pem ./privkey.pem
sudo chown YOUR_USERNAME privkey.pem
mv privkey.pem nginx/ssl/

sudo cp /etc/letsencrypt/archive/YOURDOMAIN.example.com/fullchain1.pem ./fullchain.pem
sudo chown YOUR_USERNAME fullchain.pem
mv fullchain.pem nginx/ssl/

最後にnginxの設定を変更します。

# nginx/conf.d/default.conf
-  # オレオレ
-  ssl_certificate /etc/nginx/ssl/server.crt;
-  ssl_certificate_key /etc/nginx/ssl/server.key;
+  # Let's Encrypt
+  ssl_certificate /etc/nginx/ssl/fullchain.pem;
+  ssl_certificate_key /etc/nginx/ssl/privkey.pem;

これでnginxをdocker-compose up -dしておわりです。おめでとうございます

最後に

こんなクソめんどくさいことしなくても mkcert とかでオレオレ証明書作ればいいらしいです。
ワロタです。

https://qiita.com/k_kind/items/b87777efa3d29dcc4467

Discussion