概要
Linuxで、あるwebサーバの「ホスト名:ポート番号」を「別のホスト:ポート番号」へ転送(つまりポートフォワーディング)する方法について記載。実現にはCentOSやUbuntu等に標準搭載されている「iptables」を利用。
今回紹介する内容は、おそらくCentOS7以降にデフォルトで入っているfirewalldなどでも実現できるが、極力環境に依存せずにポートフォワーディングする方法を模索した結果、iptablesを使うことにした。
iptablesでのポートフォワーディング方法を紹介する記事はそれなりにあるが、それらの方法を素直に試しても上手くいかず、実現までにかなりハマったので本記事で改めてまとめる。
本例でのご紹介はHTTP(HTTPS)のみだが、SSHでも動作確認済。またTCP通信であれば他のプロトコルでも動くはず。
サンプルソース(23/07/09追加)
GitHubにシェルスクリプトのサンプルを追加しました。
実現したい構成
- webサーバ(転送先)のIPアドレスは
23.45.67.89
、ポートは80
- ポートフォワーディングの設定を行う転送元サーバのIPアドレスは
192.168.1.4
- クライアントから転送元サーバに
http://192.168.1.4:10080
をリクエストすると、転送元サーバがwebサーバにポートフォワーディングして、http://23.45.67.89:80
のサイトへリクエスト。 - リクエスト送信後、webサーバが返すレスポンスをクライアントで閲覧可能
iptablesによる実装
転送元サーバで、以下のコマンドを実行
(1) PREROUTINGチェイン
- クライアントから入ってくるリクエストで、宛先のIPアドレスとポートを変換
-
--dport
: 変換前の宛先ポート番号 -
--to-destination
: 変換後の「宛先IP : ポート番号」
-
$ sudo iptables -t nat -A PREROUTING -p tcp \
--dport 10080 -j DNAT \
--to-destination 23.45.67.89:80
(2) POSTROUTINGチェイン
- 転送元サーバから外に出ていくパケットに関する記述
-
-d
: 変換後のIPアドレス -
--dport
: 変換後の宛先ポート番号 -
-j MASQUERADE
: IPマスカレードを行う
-
$ sudo iptables -t nat -A POSTROUTING -p tcp \
-d 23.45.67.89 --dport 80 \
-j MASQUERADE
- IPマスカレードで具体的にやっていることは、送信元のIPアドレスを「クライアント」から「転送元サーバ(192.168.1.4)」に変換する処理。ポート番号は通信の度に任意の値(例:51720、52369等)が付与される。
(3) FORWARDチェイン
-
クライアントから送信したパケットの通過を許可するために必要な記述。
-
TCP通信の場合、3way-handshakeと呼ばれる方法で双方向通信が行われるため、両方の通信を許可するための設定が必要
- 参考サイト : Linuxで作るファイアウォール[パケットフィルタリング設定編]
-
「クライアント → webサーバ」へのパケット通過を許可するコマンドが下記
$ sudo iptables -A FORWARD -p tcp \
-d 23.45.67.89 --dport 80 \
-j ACCEPT
- 一方で「webサーバ → クライアント」へのパケット通過を許可するコマンドが下記
- 逆方向の設定なので、webサーバのIPアドレスとポートを記載したオプションが「
-s
: 送信元アドレス」「--sport
: 送信元ポート番号」になっていることに注意 - 2行目の記述「
! --syn -m state --state ESTABLISHED
」は特定の条件を満たした通信のみ許可するための記述。セキュリティを気にしなければ省略しても問題ないはず。
- 逆方向の設定なので、webサーバのIPアドレスとポートを記載したオプションが「
$ sudo iptables -A FORWARD -p tcp \
! --syn -m state --state ESTABLISHED \
-s 23.45.67.89 --sport 80 \
-j ACCEPT
(4) OUTPUTチェイン
- 転送元サーバからのリクエストもポートフォワーディングしたい場合に記載
- 書き方はチェイン名をOUTPUTとする以外は(1)のPREROUTINGと同じ
$ sudo iptables -t nat -A OUTPUT -p tcp \
--dport 10080 -j DNAT \
--to-destination 23.45.67.89:80