AWS EC2 + SpringBoot + Nginx + Let’s EncryptでHTTPS対応
前回、EC2 + SpringBoot + Let’s Encryptの構成で、完全無料でSSL対応する方法を書きましたが、今回は、webサーバにNginxを使った場合の設定方法をまとめます。
webサーバを使った方がいい理由
SpringBootでアプリを動かしていれば、webサーバを別に用意することなく、手軽に動かせますが、細かな設定ができません。
また、外部と通信するのはwebサーバになるので、SpringBootでアプリが動いていることを秘匿できたり、アクセス制御をアプリ側で実装する必要がなかったりと、セキュリティ面でも実装コスト面でもメリットがあります。
SpingBootを使ったことはないけど、ApacheやNginxを使ったことがあるという人は多いと思うので、そういった人にもミドルウェアが切り離されていた方がとっつきやすいはずです。
ApacheとNginxどっちがいいか
webサーバといえば、ApacheとNginxの2択だと思いますが、最近の主流はNginxになっているようです。
Apacheと比較してNginxの方が、少量プロセスで太陽のリクエストを処理でき、処理性能は、1.47倍高くパフォーマンスがいいそうです。
そういうわけでNginxを使っていこうと思います。
Apache | Nginx | |
同時・複数アクセスへの対処の仕方 | 1アクセスに対して、1つの対応 | 複数のアクセスに対して、1つの対応にまとまる |
---|---|---|
アクセス急増時のサーバーへの負荷 | いっきに負荷増 | アクセスに比例して負荷は急激に増えない |
その結果Webサーバーの動き | 遅くなり、ダウンしやすくなる | 処理速度は維持し、ダウンしにくい |
出典:カゴヤのサーバ研究室
参考
https://www.kagoya.jp/howto/rentalserver/nginx/
https://qiita.com/kamihork/items/49e2a363da7d840a4149
HTTPS対応手順
Nginxインストール
Amazon Linuxでパッケージをインストールするには、amazon-linux-extras リポジトリからインストールすることができます。
amazon-linux-extrasについてはこちらを参考にしてください。
# amazon-linux-extrasでインストールできるパッケージの確認
$ amazon-linux-extras
0 ansible2 available [ =2.4.2 =2.4.6 =2.8 =stable ]
2 httpd_modules available [ =1.0 =stable ]
3 memcached1.5 available [ =1.5.1 =1.5.16 =1.5.17 ]
...
38 nginx1 available [ =stable ]
39 ruby2.6 available [ =2.6 =stable ]
40 mock available [ =stable ]
# nginxのインストール
$ sudo amazon-linux-extras install nginx1
$ nginx -v
nginx version: nginx/1.18.0
# 起動&動作確認
$ sudo systemctl start nginx
$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2021-05-01 16:47:03 JST; 3h 7min ago
Process: 19586 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Process: 19584 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 19582 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 19589 (nginx)
CGroup: /system.slice/nginx.service
├─19589 nginx: master process /usr/sbin/nginx
└─19591 nginx: worker process
これだけです、簡単ですね。
インスタンス起動時にNginxを自動で起動させたければ、これもやっておきましょう。
$ sudo systemctl enable nginx
http://{EC2のIPもしくはドメイン}
でアクセスして、動作確認できます。
SSL証明書の取得
次に、Let’s EncryptでSSL証明書を取得します。
Let’s Encryptについては、前回の記事に書いてあるので、どんなものなのか知りたい人はこちらを参考にしてください。
取得していきましょう。
# yumのepelリポジトリ設定
$ cd ~
$ sudo wget -r --no-parent -A 'epel-release-*.rpm' http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/
$ sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm
$ sudo yum-config-manager --enable epel*
Nginx用に簡単に設定できるツール(certbot-nginx)があるので、それを使っていきます。
4回入力を求められるので、入力していくだけで作成されます。
- メールアドレス → メールアドレスを入力
- 利用規約に同意するか → YES
- メールアドレスを共有していいか → NO
- どのドメインをhttpsにするか → httpsにしたいドメイン入力 (hoge.example.com)
$ sudo yum install certbot-nginx
# nginxが動いていないとここでエラーになる
$ sudo certbot --nginx
## 1つ目 メールアドレス hoge@hoge.example.com
## 2つ目 利用規約同意 yes
## 3つ目 メールアドレスを共有して良いか NO
## 4つ目 どのドメインをhttpsにするか hoge.example.com
こんな感じで証明証が発行されます。
IMPORTANT NOTES:
- Unable to install the certificate
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/hoge.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/hoge.example.com/privkey.pem
Your certificate will expire on 2021-07-23. To obtain a new or
tweaked version of this certificate in the future, simply run
certbot again with the "certonly" option. To non-interactively
renew *all* of your certificates, run "certbot renew"
注意点ですが、Let’s Encryptは3ヶ月で証明書の有効期限が切れます。
certbot renewを実行すれば更新してくれます。
$ sudo certbot renew --no-self-upgrade
手動で上を打ってもいいですが、cronに登録しておいた方がいいです。
# (例)毎日3時に実行
$ sudo crontab -e
0 3 * * * root certbot renew --no-self-upgrade
$ sudo systemctl restart crond
参考
Spring bootでSSL(HTTPS)を有効にするならnginxを使え
SpringBootアプリの設定
Nginxの設定をしたいところですが、先にSpringBootの設定をしておきます。
application.properties (もしくはyml)をこんな感じにします。
server.port=8080
endpoints.enabled=false
management.add-application-context-header=false
ポート番号は、8080でなくてもいいです。好きなポートで。
endpoints.enabledとmanagement.add-application-context-headerの設定は好みです。
どちらも「余計な情報をユーザーに見られないようにする」効果があります。
NginxのSSL設定
次に、Nginxに設定していきます。
# DH交換鍵を作る $ sudo mkdir /etc/nginx/ssl $ cd /etc/nginx/ssl $ sudo openssl dhparam 2048 -out dhparam.pem
Nginxのデフォルトの設定ファイルは、/etc/nginx/nginx.conf ですが、自分で設定を追加していく場合は、以下の設定ファイルを新しく作って書いていった方がいいです。
# 設定ファイル作成
$ cd /etc/nginx/conf.d
$ sudo vim default.conf
/etc/nginx/conf.d/default.conf はこんな感じにしておきます。
# httpはhttpsにリダイレクト
server {
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
# httpsはローカルホストの8080に飛ばす(springbootアプリをこのポートで動かしておく)
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/hoge.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hoge.example.com/privkey.pem;
ssl on;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!DSS;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/hoge.example.com/fullchain.pem;
resolver 8.8.8.8;
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;';
server_name hoge.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
中身を説明してきます。
ここは、http(80ポート)をhttps(443ポート)にリダイレクトさせる設定です。(そのままですが)
リダイレクトさせたくなければなくても大丈夫です。
# httpはhttpsにリダイレクト
server {
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
こっちが、httpsの設定です。
Nginxの細かな設定部分の省略しますが、ドメインを自分のドメインに書き換えてください。
# httpsはローカルホストの8080に飛ばす(springbootアプリをこのポートで動かしておく)
server {
listen 443 ssl;
listen [::]:443 ssl;
〜略〜
}
httpsで受けたリクエストをどこに飛ばすか設定している箇所です。
server_name geotube.amusia-web.com;
location / {
proxy_pass http://127.0.0.1:8080;
}
今回は、SpingBootアプリを8080ポートで動かしている想定なので、ローカルホストの8080ポートに飛ばしてあげればアプリにリクエストできます。
ローカルホストのアクセスはポート解放必要ないので、EC2のポート設定で8080を解放しておく必要はないです。
設定が完了したら、nginxをリスタートします。
$ sudo systemctl restart nginx
SpringBootアプリケーションが動いていないと、Nginxが起動しないので、アプリを起動させておいてください。
以上です。
これで、http, httpsどちらでアクセスしてもhttpsで表示されるようになりました。
Nginxのアクセスとエラーログ確認
Nginxのアクセスログとエラーログはここにあります。
- /var/log/nginx/access.log
- /var/log/nginx/error.log
デフォルトだと毎日ログローテーションしてgz圧縮されます。
ここを見てリクエストが来ていれば大丈夫です。
まとめ
今回は、AWS EC2 + SpringBoot + Nginx + Let’s EncryptでHTTPS対応する方法でした。
次回は、Nginxのセキュリティ設定をしていこうと思います。
DDoS対策とか、外部からAPIを叩けないようにするとか。
この辺りの設定が簡単にできるので、webサーバを別に立てた方がいいですね。
本日のオススメの書籍
こちらは、AWSについての基本を網羅的に知ることができます。
こちらは、SpringBootで開発したい人にオススメ。
私も本業でSpringBoot使っていますが、この本のおかげでだいぶ理解が進みました。
コメント