アプリケーションサーバー(EC2)をパブリックサブネットからプライベートサブネットに移動する
はじめに
ApacheサーバをリバースプロキシにしてRailsアプリと連携させる
この記事で、プロキシサーバーの設定を行いました。しかし、アプリの肝となっているアプリケーションサーバーがパブリックサブネットに存在している為、セキュリティ的に問題があります。
この記事ではアプリケーションサーバーをプライベートサブネットに配置し、プロキシサーバー経由で接続させる為の作業記録を残しておきます。
※railsサーバーを操作するには自PC -> Apacheサーバー -> railsサーバーの順にssh接続して操作します。(railsサーバーはプライベートサブネットなので、直接ssh接続できない)
# 自PCからApacheサーバーにssh
% ssh -i "~/.ssh/apache-server.pem" ec2-user@ec2-<Apacheサーバー>.ap-northeast-1.compute.amazonaws.com
# Apacheサーバーからrailsサーバーにssh
$ ssh -i "~/.ssh/app_key.pem" rails@<railsサーバー>
1.AMIの作成
EC2のインスタンスのアクションから「イメージとテンプレート」>「イメージの作成」を選択。データの齟齬がないように、EC2インスタンスは停止させた状態でAMIを作成する。
2.AMIからインスタンスを起動
自分のAMIを使用してプライベートサブネットにEC2インスタンスを起動する。当然、VPCはプロキシサーバーやデータベースサーバーと同じにする必要がある。パブリックIPの割り当ては無効化。
- 名前:application_server_private
- OSイメージ:自分のAMI
- インスタンスタイプ:t2.micro
- キーペア:application_serverのものを使用
- ネットワーク(アプリケーションと同じvpc)
- サブネット:plivate1-ap-northeast-1a
- パブリックIPの自動割り当て:無効化
- セキュリティグループ
- セキュリティグループ名:application_security_group
- インバウンドグループ(プロキシEC2からのアクセスだけ許可)
- タイプ:HTTP(80), カスタムTCP(ポート範囲3000)
- ソース:プロキシEC2のIPアドレス
- ストレージ:30GB(gp3)
3.プロキシサーバーの再設定
/etc/httpd/conf.d/rails.confを修正する。
ProxyPass / http://<railsサーバーのプライベートIP>:3000/
ProxyPassReverse / http://<railsサーバーのプライベートIP>:3000/
修正後Apacheをリロードする。
% sudo systemctl restart httpd
4.RDSを新しいEC2インスタンスに接続する
現在RDSが接続しているのはパブリックサブネットに配置しているEC2インスタンスだけです。RDSは新しくAMIで作成したプライベートサブネットにあるEC2インスタンスにも接続してあげます。
(※作業時はこの接続手順をうっかり失念しており、データベースのsocketエラーやアプリ起動エラーが立て続けに発生した。RDSを接続する事ですぐに解決できたのだが、それに気づくまでに半日近くの時間を費やしてしまった。)
AMI作成のEC2インスタンスに接続する。
5.セキュリティグループの整理
接続確認などで一時的に0.0.0.0からのアクセスを許可してしまったりしていたので、しっかりとセキュリティグループを設定しなおす。
※セキュリティグループはIPアドレスだけでなく、他のリソースに設定したセキュリティグループを送信元や送信先として設定できる。VPC内部のリソースにセキュリティグループを設定する際は、IPアドレスを設定するよりもセキュリティグループIDを設定した方が柔軟性や安全性が高く、メンテナンスしやすい。
-
webサーバー
- セキュリティグループ名:sg-proxy
- インバウンドグループ
- ポート範囲:22番ポート,80番ポート
- 送信元:マイIP(今回は自分のPCからのみのアクセスを許可する)
- アウトバウンドグループ
- ポート範囲:22番ポート,3000番ポート
- 送信先:sg-rails(セキュリティグループを指定)
- インバウンドグループ
- セキュリティグループ名:sg-proxy
-
railsサーバー
- セキュリティグループ名:sg-rails
- インバウンドグループ
- ポート範囲:22番ポート,3000番ポート
- 送信元:sg-proxy(セキュリティグループ)
- アウトバウンドグループ
- ポート範囲:5432番ポート
- 送信先:sg-psql-rails(セキュリティグループを指定)
- インバウンドグループ
- セキュリティグループ名:sg-rails
-
データベース(RDS)
- セキュリティグループ名:sg-psql-rails
- インバウンドグループ
- ポート範囲:5432番ポート
- 送信元:sg-rails(セキュリティグループ)
- アウトバウンドグループ
- ポート範囲:全てのトラフィック
- 送信先:0.0.0.0
- インバウンドグループ
- セキュリティグループ名:sg-psql-rails
6.Railsアプリケーションの起動
必要な準備は整った為、プライベートサブネットのEC2インスタンスでrailsアプリケーションを起動しする。
$ RAILS_ENV=production bundle exec rails s -b 0.0.0.0
=> Booting Puma
=> Rails 8.0.2 application starting in production
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.6.0 ("Return to Forever")
* Ruby version: ruby 3.4.4 (2025-05-14 revision a38531fd3f) +PRISM [x86_64-linux]
* Min threads: 3
* Max threads: 3
* Environment: production
* PID: 3487
* Listening on http://0.0.0.0:3000
Use Ctrl-C to stop
プロキシサーバーにhttp接続したところ、アプリケーションが無事に起動
さいごに
無事にプロキシサーバー経由でプライベートサブネットにあるrailsアプリを起動できました。RDSとEC2の接続エラーでかなり苦労しましたが、プロキシ設定の作業自体は思ったよりもシンプルだったと思います。
(エラー解決のために、セキュリティグループを見直したりデータベースの設定ファイルをいちから確認したり、ファイアウォールを確認したり...と無駄な時間をかなり費やしてしまいました。)
Discussion