【AWS】EC2にnginxサーバー構築の備忘録



### 事前準備
 - EC2インスタンスの起動
 - ドメイン名を取得済み
 - Elastic IPの関連付け済み
 - Route53とパブリックIPアドレスの設定済み

### 設定方法
1. EC2へSSH接続する
    ```
    ssh -i "mykeypair.pem" ec2-user@ec2-********.ap-northeast-1.compute.amazonaws.com
    ```
1. Nginxとemacsのインストール
    ```
    sudo yum -y update
    sudo yum install emacs
    sudo amazon-linux-extras install nginx1
    y
    nginx -v
    ```
1. Nginxの起動
    ```
    sudo systemctl start nginx
    sudo systemctl status nginx
    sudo systemctl enable nginx
    sudo systemctl is-enabled nginx
    ```
1. サーバーの起動を確認
    ```
    ブラウザでhttp://パブリックIPにアクセス
    ```
1. OpenSSLとmod_sslをインストールする
    ```
    sudo yum install openssl
    sudo yum install mod_ssl
    ```
1. テスト用に自己署名のダミー証明書とキーを生成するためのスクリプトを実行する
    ```
    cd /etc/pki/tls/certs
    sudo ./make-dummy-cert localhost.crt
    ```
1. 新しいプライベートキーを生成する
    ```
    cd /etc/pki/tls/private/
    sudo openssl genrsa -out custom.key
    sudo chown root:root custom.key
    sudo chmod 600 custom.key
    ls -al custom.key
    ``
1. CSR(Certificate Signing Request:証明書署名要求) を作成する。
    ```
    sudo openssl req -new -key custom.key -out csr.pem
    ```
1. CAにCSRを送信する。今回はCAとして、無料の認証局であるIdenTrust 社のLet’s Encrpytを使う。
    ```
    sudo amazon-linux-extras install epel
    sudo yum install certbot
    sudo systemctl stop nginx
    sudo certbot certonly --standalone -d example.com
    ```
1. 3か月で証明書の期限が切れるので、定期実行するようにする
    ```
    $ sudo certbot renew --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"
    $ crontab -e
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    * * 1 * * sudo certbot renew --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"
    * * 1 * * sudo cp -LR /etc/letsencrypt/live/non-stock-sales-1993.com /etc/pki/tls/certs/
    * * 1 * * sudo cp /etc/pki/tls/certs/non-stock-sales-1993.com/* /etc/pki/tls/certs/
    * * 1 * * sudo systemctl restart nginx
    //次の更新はいつなのか確認できる
    $ sudo certbot renew 
    //証明書の削除
    $ sudo certbot revoke --cert-path  /etc/letsencrypt/live/example.com/cert.pem
    ```
1. 正常に終了すると、/etc/letsencrypt/live 以下に最新版の証明書へのシンボリックリンクが作成されるので、/etc/pki/tls/certsにコピーしておく
    ```
    sudo ls /etc/letsencrypt/live/example.com/
    sudo cp -LR /etc/letsencrypt/live/example.com /etc/pki/tls/certs/
    sudo cp /etc/pki/tls/certs/example.com/* /etc/pki/tls/certs/
    ```
1. /etc/nginx/nginx.confを下記を編集かなければ追加する
    ```
    sudo emacs /etc/nginx/nginx.conf
    ```
    ```
    # Settings for a TLS enabled server. 
    server {
        listen       443 ssl http2;
        listen       [::]:443 ssl http2;
        server_name  example.com;
        root         /usr/share/nginx/html;

        ssl_certificate "/etc/pki/tls/certs/cert.pem";
        ssl_certificate_key "/etc/pki/tls/certs/privkey.pem";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        #ssl_ciphers PROFILE=SYSTEM; 
        #ssl_prefer_server_ciphers on; 

        # Load configuration files for the default server block. 
        include /etc/nginx/default.d/*.conf;

        try_files $uri /index.html;

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
    ```
1. Nginxサーバーの起動
    ```
    sudo systemctl start nginx
    sudo systemctl status nginx
    ```
1. html/jsファイルの修正
    ```
    下記フォルダのファイルを修正する
    /usr/share/nginx/html/
    ```

### Fast APIの立て方

1. ライブラリをインストールする
    ```
    pip3 install fastapi uvicorn
    pip3 install pydantic
    ```
1. /etc/nginx/nginx.confを下記を追加する
    ```
    location /api {
        proxy_pass http://localhost:8000/;
        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;
    }
    ```
1. /user/share/nginx/html/myappというフォルダを作り、下記のファイルを作成する。
    ```Python:main.py
    from fastapi import FastAPI
    
    app = FastAPI()
    
    @app.get("/api")
    def read_root():
        return {"Hello": "World"}
    
    @app.get("/items/{item_id}")
    def read_item(item_id: int, q: str = None):
        return {"item_id": item_id, "q": q}
    ```
1. 下記のコマンドをmyappフォルダで実行する
    ```
    uvicorn main:app --host localhost --port 8000
    ```

### Next.jsで特定ページのURLへの遷移を有効にする
next.config.jsに下記を追記する
```
trailingSlash: true,
```

## まとめ
今回は、EC2にNginxサーバーをSSL/TLS認証済みする方法を紹介した。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/SSL-on-amazon-linux-2.html