EC2+Nginx+node.jsのWEBサーバーをLet’sEncryptでSSL化する

この手順で構築したWEBサーバーを使用する。

・ ディストリビューション: Amazon Linux 2023.1.20230825
・ インスタンスタイプ: t3a.nano
・ ボリュームサイズ: 20GB

python3の仮想環境を使用してcertbotをインストールする。
※この手順作成時はpython3.9だった

# dnf install pip
# mkdir /opt/certbot
# python3 -m venv /opt/certbot
# /opt/certbot/bin/pip install --upgrade pip
# /opt/certbot/bin/pip install certbot

ACMEチャレンジのための設定を追加する。

server {
    listen       80;
    listen       [::]:80;
    server_name  _;
    location = /.well-known/acme-challenge/ {
        root /usr/share/nginx/html/.well-known/acme-challenge/;
    }
}

証明書を取得する。
※何度も失敗すると制限がかかるので予め--dry-runオプションを指定してテストした方が良い

/opt/certbot/bin/certbot certonly --webroot -w /usr/share/nginx/html/ -d testapp.example.com

Nginxの設定ファイルを変更する。

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name testapp.example.com;
    ssl_certificate     /etc/letsencrypt/live/testapp.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/testapp.example.com/privkey.pem;
    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://localhost:3000/;
    }
}

Nginxの設定をリロードしてhttpsでの接続を確認する。

# systemctl reload nginx

cronに証明書を更新するジョブを追加する。

0 4 * * * /opt/certbot/bin/certbot renew --deploy-hook "systemctl reload nginx"

EC2をNginx+node.jsでWEBサーバーにする

・ ディストリビューション: Amazon Linux 2023.1.20230825
・ インスタンスタイプ: t3a.nano
・ ボリュームサイズ: 20GB

タイムゾーンを日本に変更する。
※使用できるタイムゾーンはlist-timezonesサブコマンドで確認できる

# timedatectl set-timezone Asia/Tokyo

メモリが512MBしかないのでスワップを追加する。
※事前にswapon –summaryで既存スワップを確認済み

# dd if=/dev/zero of=/swapfile bs=1M count=1024
# mkswap /swapfile
# swapon /swapfile

fstabの末尾にも設定を1行追加して永続化する。

/swapfile    none    swap    sw    0    0

nvmを使用してnode.jsをインストールする。
※使用できるnode.jsのバージョンはnvm ls-remoteで確認できる

# dnf install git
$ git clone https://github.com/creationix/nvm.git ~/temp-nvm
$ ~/temp-nvm/install.sh
$ rm -r ~/temp-nvm/
$ source ~/.bashrc
$ nvm install --lts

適当なWEBサーバーを作成する。

const http = require("http");
http.createServer(function(request, response) {
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.end("Hello, World!\n");
}).listen(3000);

node.jsでWEBサーバーを起動しておく。

$ node ~/testapp.js

Nginxをインストールして起動+有効化する。

# dnf install nginx
# systemctl enable --now nginx

リバースプロキシを設定してnode.jsのWEBサーバーに中継する。
※「client_max_body_size 10m」で10MBまでの画像なども受け取れる
※「proxy_set_header Host $host」でクライアントが送信したリクエストのホスト名を渡す
※「proxy_set_header X-Real-IP $remote_addr」でクライアントのIPアドレスを渡す

server {
    listen 80;
    listen [::]:80;
    server_name testapp.example.com;
    client_max_body_size 10m;
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_path http://localhost:3000/;
    }
}

Nginxの設定値を再読込する。

# systemctl reload nginx