質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

1124閲覧

リバースプロキシによる転送のやり方がわかりません;;

watasida

総合スコア6

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

1グッド

0クリップ

投稿2023/03/17 19:24

実現したいこと

AWSのパブリックサブネットに設置したEC2インスタンス(webサーバ)へのHTTPリクエストを、プライベートサブネットに設置したEC2インスタンス(APサーバ)にリバースプロキシで転送したい。
web、AP、DBサーバの3層構造が一般的であり、セキュリティ的にAP,、 DBはプライベートサブネットに設置すると良いらしい(自分調べ)とのことで、AWSの勉強のためにこのような手法を試してます(実務で扱っているわけではありません)。
バキバキの初心者です。用語の使い方等が間違っていたら教えてください。

前提

色々試してみた結果ごちゃごちゃしてしまい、必要な情報が書けていないかもしれません。
不足している情報があれば言ってください。

以下のような設計を考えています。
イメージ説明

今のところ、以下の通信はうまくいっていると思います。

  • ホストマシンからwebサーバへのhttp接続(ブラウザからパブリックIPでnginxのページが表示される)
  • ホストマシンからwebサーバへのssh接続
  • ホストマシンからwebサーバを踏み台にしたAPサーバへのssh接続
  • APサーバからDBサーバへのTCP3306接続
  • APサーバからエンドポイントを介したS3への接続

ホストマシンからhttpでwebサーバにアクセスした際に、リバースプロキシでAPサーバの3000番ポートに転送されるように、webサーバのnginxの設定ファイル、APサーバのapacheの設定ファイルを書き換えてみたのですが、接続できません。

  • nginxの設定ファイル

こちらを参考に、/etc/nginx/conf.d/proxy.confを作成し、以下のように書き込みました。
rootに書いてあるのはAPサーバのlaravelプロジェクトのドキュメントルートです(これをapacheの設定ファイルにも書き込んでいます)

server { listen 80; server_name .*; root /var/www/laravel-project/AWS-EC2-laravel/public; location / { try_files $uri @app; } location @app { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://APサーバのプライベートIP:3000; } }
  • apacheの設定ファイル

こちらや、こちらを参考にして、/etc/httpd/conf/httpd.confを以下のように書き換えました。

# DocumentRoot: The directory out of which you will serve your # documents. By default, all requests are taken from this directory, but # symbolic links and aliases may be used to point to other locations. # DocumentRoot "/var/www/laravel-project/AWS-EC2-laravel/public" # 書き換え # # Relax access to content within /var/www. # <Directory "/var/www/laravel-project/AWS-EC2-laravel/public"> # 書き換え AllowOverride All # NoneからAllに書き換え # Allow open access: Require all granted </Directory>

発生している問題・エラーメッセージ

ブラウザから、http://webサーバのパブリックIPにアクセスすると、502 Bad Gatewayというエラー(nginxのエラーページ)が表示されます。

試したこと

webサーバからの3000番ポートへのリクエストを受けつけるため/etc/httpd/conf/httpd.conf

Listen webサーバのプライベートIP:3000 # 80から書き換え

と書き換え、apacheを再起動すると、

(99)Cannot assign requested address: AH00072: make_sock: could not bind to address webサーバのプライベートIP

というエラーになりました。

補足情報

APサーバにはapacheに加えてphp-fpmというPHP用のアプリケーションサーバ(?)も入っています。何の目的で入れたのかもあまり理解していないのですが、これの設定ファイルを書き換える必要もあるのでしょうか?

gusachan3を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gusachan3

2023/03/18 09:30

AWS EC2 Laravelプロジェクトを表示させたいがApacheのドキュメントルートを変えてもテストページから変わらない。 https://teratail.com/questions/jihmgmkplssp00 AmazonLinux2にPHP8.1とLaravel9を導入して開発環境を作ってみる https://dev.classmethod.jp/articles/ec2-php81-laravel9/ システムの起動時に httpd.service が起動できず Cannot assign requested address: AH00072: make_sock: could not bind to address エラーが発生する - Red Hat Customer Portal https://access.redhat.com/ja/solutions/3154131 nginxのエラーの詳細が分かりませんが以下のコマンドは試しましたか。 setsebool -P httpd_can_network_connect 1
watasida

2023/03/18 13:19

今webサーバのパブリックIPにアクセスすると、nginxのエラーログ(`/var/log/nginx/error.log`)には以下のように出力されていました。 ``` 2023/03/18 13:03:56 [error] 3266#3266: *2223 connect() failed (111: Connection refused) while connecting to upstream, client: 15.164.98.242, server: *, request: "POST /round HTTP/1.1", upstream: "http://APサーバのプライベートIP:3000/round", host: "webサーバのパブリックP" ``` nginxのリバースプロキシの設定はできているけどAPサーバがリクエストを受け取れていないということでしょうか? また、`setsebool -P httpd_can_network_connect 1`を実行すると、`setsebool: SELinux is disabled.`と表示されました。
watasida

2023/03/18 14:01

まだ解決かどうかわからないのですが、`/etc/httpd/conf/httpd.conf`を`Listen IP:3000`からListen 3000`にすると、webサーバのIPアドレスからlaravelの初期画面が表示されました。 ただ、この状態だとwebサーバ以外のIPからの3000番ポートへのリクエストも受け入れてしまうような気がします。webサーバのIPのみ受け入れるにはどのような設定が必要でしょうか?
gusachan3

2023/03/18 18:29

/etc/httpd/conf.d/proxy.confの設定は以下のサイトが参考になりませんか。 Akward delay to connect Apache's proxy request to a node.js App https://serverfault.com/questions/262036/akward-delay-to-connect-apaches-proxy-request-to-a-node-js-app Apache proxypass and webrick redirect https://www.apachelounge.com/viewtopic.php?t=4963 例えば・・・。 <VirtualHost *:80> ServerName proxy.example.com DocumentRoot //var/www/laravel-project/AWS-EC2-laravel/public ErrorLog logs/proxy.example-error_log CustomLog logs/proxy.example.com-access_log combined env=!no_log RewriteEngine on RewriteRule "^/(.*)" "https://%{HTTP_HOST}/$1" <Directory //var/www/laravel-project/AWS-EC2-laravel/public> AllowOverride All </Directory> </VirtualHost> <Proxy *> Require all granted </Proxy> ProxyPreserveHost on ProxyRequests off ProxyPass "/" "http://127.0.0.1:3000/" ProxyPassReverse "/" "http://127.0.0.1:3000/" </VirtualHost>
gusachan3

2023/03/18 18:33

訂正)タイポミス恐縮です <VirtualHost *:80> ServerName proxy.example.com DocumentRoot /var/www/laravel-project/AWS-EC2-laravel/public ErrorLog logs/proxy.example-error_log CustomLog logs/proxy.example.com-access_log combined env=!no_log RewriteEngine on RewriteRule "^/(.*)" "https://%{HTTP_HOST}/$1" <Directory /var/www/laravel-project/AWS-EC2-laravel/public> AllowOverride All Require all granted </Directory> <Proxy *> Require all granted </Proxy> ProxyPreserveHost on ProxyRequests off ProxyPass "/" "http://127.0.0.1:3000/" ProxyPassReverse "/" "http://127.0.0.1:3000/" </VirtualHost>
watasida

2023/03/20 05:53

ありがとうございます。 ご提示いただいた内容ですと、APサーバは80番ポートのリクエスト(=HTTP)を自身の3000番ポートにリバースプロキシで転送するということでしょうか? 書き方がわるかったかもしれないのですが、自分としては Webサーバのnginxで80番ポートのリクエストを受け、APサーバの3000番ポートにリバースプロキシで転送したいです。
yu_1985

2023/03/20 06:40

ALBではなくEC2インスタンスでnginxを使う理由は何でしょう? 用途を考えるとALBを使えば十分かと思うのですが…。
watasida

2023/03/20 11:39

ありがとうございます。 おっしゃる通り、ALBでリバースプロキシと同様のことができたり、CloudFrontで静的コンテンツを配信できたりする、ということをつい最近知りまして、じゃあwebサーバいらないんじゃ?とも思ったのですが、最初の質問に書いたように勉強のためにやってみているという感じです。 WebサーバとALBの使い分けもいまいちわかっていなくて、、、 ざっくりでいいんですけども、どんな場合にはwebサーバ、どんな場合にはALBと、使い分けがありましたら教えて欲しいです。
yu_1985

2023/03/20 11:59

リバースプロキシとして使うならそれはWEBサーバーと呼ぶべきか微妙ですね。 図だとアプリケーションサーバー内にApacheを使っているので、それがWEBサーバーの役割をしています。 前段に置いているWEBサーバーと呼んでいるものはリバースプロキシとしてしか使っていません。 ALBでできないような細かいルール分けをしたり、あるいはALBよりも安いインスタンスでプロキシとして使いたい(当然スペックも低くなりますが、それで十分な場合)というならnginxでリバースプロキシを作るのもなくはないですが、多くの場合ALBを使えば必要十分です。 ところで、まずアプリケーションサーバーのApacheはちゃんと3000番ポートをListenしていますか? そうでないならリバースプロキシが3000番ポートにリクエストを送ったら当然エラーになります。 質問に書いてあることを読むに、まずリバースプロキシがどうとかは置いといてAPサーバーと呼んでいるサーバーをパブリックサブネットできちんと動かしてみてはどうでしょうか。
watasida

2023/03/20 13:51

ALBとWebsサーバについての説明ありがとうございます。最初はALBを使い、細かい設定をしたくなったらwebサーバを設置するのが一般的なんですね。 パブリックサブネットでの動作は確認しています。 最初はパブリックサブネットにAPサーバ、プライベートサブネットにDBサーバという構成で動かして、そこから今の構成に変更した、という経緯です。 APサーバが3000番ポートをListenしているか?、については ・APサーバのセキュリティグループのインバウンドルールとして、TCP3000番ポートの、ソースがWebサーバのセキュリティグループを設定 ・Webサーバのセキュリティグループのアウトバウンドルールとして、TCP3000番ポートの、ソースがAPサーバのセキュリティグループを設定 (あとSSH接続のために22番ポートは開けています)している状態で、webサーバにアクセスして、APサーバで設定したlaravelの画面が表示される、ということから、Listenしているものと考えてました、、、が、、、 netstat -an でリッスンしているポート番号を調べてみると(見づらくてすみません)、 ``` Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN ←?? tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN ←SSH tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN ←SMTP tcp 0 208 APサーバのIP:22 WebサーバのIP:42310 ESTABLISHED ← SSH tcp6 0 0 :::111 :::* LISTEN tcp6 0 0 :::22 :::* LISTEN tcp6 0 0 :::3000 :::* LISTEN  ← IPv4ではなくIPv6?? ``` となって、IPv6の3000番をlistenしている??? 調べてみると、以下のような記事が出てきて、 > :::80というのは0.0.0.0:80のIPv4-mapped IPv6アドレスであり、 らしいので、正直よくわからないんですが、まあいいのかな、、、という感じです。 https://qiita.com/fetaro/items/d5164ba8271114d8a0c8
watasida

2023/03/20 14:02

だいぶ色々と書いてしまったのですが、質問としては、 APサーバのapacheの設定で、「webサーバのIPからの3000番ポートへのリクエストのみをListenする設定にする方法はあるか?」 というかそもそも、AWSのセキュリティグループでIPとポートの設定をしてwebサーバとAPサーバ間の通信を制限すれば、apacheでの設定は必要ないのでしょうか? です。 色々聞いてしまってすみません。
yu_1985

2023/03/20 15:36

> 最初はALBを使い、細かい設定をしたくなったらwebサーバを設置するのが一般的なんですね。 いいえ、そういうわけではありません。 そもそも今回WEBサーバーと呼んでいるものはただのリバースプロキシなので、そこの認識を改める必要があります。 今回WEBサーバーとして動作しているものはApacheです。(nginxもWEBサーバーとして動作するミドルウェアですが、今回図中の役割では単なるリバースプロキシです) nginxをリバースプロキシとして使う場合をあえて考えるならよほどnginxに細かいことをさせたい場合ですが、そんなケースはほぼなく、またリバースプロキシ自体がボトルネックになりかねないので素直にALBを使ったほうが良いです。 サーバーの役割が減ってシンプルな構成になります。 逆に、例えばほとんどアクセスがないのでALBよりも安価なインスタンスを使って転送したいというのであれば使う意味はあります。 > AWSのセキュリティグループでIPとポートの設定をしてwebサーバとAPサーバ間の通信を制限すれば、apacheでの設定は必要ないのでしょうか? セキュリティグループはリソース間の通信の許可設定をするものなので、サーバー上で何がListenしているかとは関係がありません。 そもそも、なぜ3000番ポートである必要があるかなのですが、それは自分で3000番ポートにリクエストを転送するように設定しているからで、実際は別に80番(Apacheのデフォルト)のままでも問題ありません。(80番ポートに転送するようにすればいいだけ) ApacheのListenのところが80のままなのであればApacheが使用しているのは80番ポートなので、3000番ポートを使用する設定に直すか、またはそもそもわざわざ3000番ポートに転送せず80番ポートに送るようにしましょう。 その場合は当然セキュリティグループも修正が必要です。
yu_1985

2023/03/20 15:38

特定のポートをどのプロセスが使用しているか確認するにはlsofコマンドを使うといいです。 https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/664useportps.html ※root権限が必要な場合がほとんどなのでsudoを使ってください。 > APサーバが3000番ポートをListenしているか?、については ・APサーバのセキュリティグループのインバウンドルールとして、TCP3000番ポートの、ソースがWebサーバのセキュリティグループを設定 ・Webサーバのセキュリティグループのアウトバウンドルールとして、TCP3000番ポートの、ソースがAPサーバのセキュリティグループを設定 (あとSSH接続のために22番ポートは開けています)している状態で、webサーバにアクセスして、APサーバで設定したlaravelの画面が表示される、ということから、Listenしているものと考えてました、、、が、、、 その時ちゃんと3000番ポートを指定してアクセスしましたか?
watasida

2023/03/21 14:21

なるほど、Webサーバのつもりで設置していたEC2は、今回の設計ではwebサーバとして機能していないということですかね(なのでALBで十分と)。 nginxの設定では、最初の質問に書いたようにリバースプロキシの設定をし、APサーバの3000番に転送するよう設定しています。 また、APサーバでapacheの設定ファイル(/etc/httpd/conf/httpd.conf)で、 Listen 3000 に書き換えています(元々80だった)。 APサーバで sudo lsof -i:3000 を実行すると COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME httpd 2951 root 4u IPv6 17485 0t0 TCP *:hbci (LISTEN) httpd 2982 apache 4u IPv6 17485 0t0 TCP *:hbci (LISTEN) httpd 2983 apache 4u IPv6 17485 0t0 TCP *:hbci (LISTEN) httpd 2984 apache 4u IPv6 17485 0t0 TCP *:hbci (LISTEN) httpd 2985 apache 4u IPv6 17485 0t0 TCP *:hbci (LISTEN) httpd 3022 apache 4u IPv6 17485 0t0 TCP *:hbci (LISTEN) と表示され,Listenできているようです。
yu_1985

2023/03/22 01:49

> Webサーバのつもりで設置していたEC2は、今回の設計ではwebサーバとして機能していない 機能していないというか、単なるリバースプロキシとしてリクエストを転送しているだけなので、それならALBを使ったほうが楽だし性能の心配をすることもない、ということです。 > nginxの設定では、最初の質問に書いたようにリバースプロキシの設定をし、APサーバの3000番に転送するよう設定しています。 はい、それは把握しています。 正直わざわざ3000番ポートを使う意味はあんまりないですが…。 apacheの再起動時のエラーについては解消されたのでしょうか? ↑に貼られているログを見るにApacheがきちんと立ち上げられてない可能性がそこそこ高そうに思えるのですが…。
watasida

2023/03/22 02:31

> apacheの再起動時のエラーについては解消されたのでしょうか? > ↑に貼られているログを見るにApacheがきちんと立ち上げられてない可能性がそこそこ高そうに思えるのですが…。 再起動のエラーについてはおそらく解消していると思います。 Listen WebサーバのプライベートIP:3000 としていたものを Listen 3000に直して起動すると、statusで active(running)と表示されています。 他にチェックすべき項目があれば教えていただけるとありがたいです。
watasida

2023/03/22 04:08

そのコマンドでは、いずれもlaravelの初期画面(welcome.blade.php)の中身が表示されました。
yu_1985

2023/03/22 07:15

よくよく考えたら、今回nginxはリバースプロキシとしてのみ動作させたいので設定内容が誤っているのではないでしょうか。 nginxを入れているサーバー上に実際のソースが存在しないのでrootを指定したらおかしなことになりそうです。 根本的にはproxy_passだけでも十分で、他の設定は必要があれば入れるくらいではないでしょうか。 以下の記事が参考になるかと思います。 https://qiita.com/OPySPGcLYpJE0Tc/items/1f4219a51980a75696b5#4-%E3%83%AA%E3%83%90%E3%83%BC%E3%82%B9%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E6%A7%8B%E7%AF%89
watasida

2023/03/23 15:02

> 根本的にはproxy_passだけでも十分で、他の設定は必要があれば入れるくらいではないでしょうか。 root等を削除してproxy_passだけでもできました。 rootに関しては自分も疑問だったんですが、なぜ動いていたのかは謎です... 今回、勉強のためにwebサーバ(のつもりで設置したもの)にnginxを入れてリバースプロキシということをしてみたんですが、かなり冗長(というか無駄)な構成で、役割的にはALBで全然十分で、逆に設定で余計な手間がかかってしまうということがわかりました。 nginxの設定など、まだ謎が残っていますが、長くなってしまったので勝手ながらここで区切らせてもらいます。答えてくださったお二方、ありがとうございました。自分の中でもう少し整理してからまた質問するかもしれませんので、その時はお願いいたします。
guest

回答1

0

自己解決

以下のように設定すると、ブラウザからwebサーバのIPにアクセスして、laravelの画面が表示されました。
APサーバの/etc/httpd/conf/httpd.conf

Listen 3000 # 80から書き換え

Webサーバの/etc/nginx/nginx.confserverの中に以下のように追記

location / { proxy_pass http://APサーバのIP:3000/; }

投稿2023/03/23 15:12

watasida

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問