161
169

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

80番ポートへ届いたパケットをiptablesでローカルの上位ポートに転送する

Last updated at Posted at 2013-10-09

例えばNode.jsとかで作ったWEBサービスを外部に公開しようとした時に、80番ポートで公開したいけど一般ユーザだと1024番より上のポートしか使えない、かと言ってrootで実行はしたくない。そんなときは iptables でREDIRECTまたはDNATしてしまうのが便利です。

雑然としたメモレベルだけど備忘録として書いておく。

簡単な例

3000番ポートで動かしているサービスを80番で公開する例はこんなコマンドを打てはOK。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000

設定ファイルに保存する場合はfilterとは別にnatテーブルの設定を追加して↓こんなふうに書けばよいです。

/etc/sysconfig/iptables
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# filter settings here...
COMMIT

service iptables restart とかしてやれば反映される。

複数IPが割り当てられてるサーバで受けたIPによって転送先のローカルポートを変える例

例えば 10.0.0.80 と 10.0.0.81 のIPを持っていた場合に、10.0.0.81に来たパケットは3001番ポートへ転送、それ以外のIPで受けた場合は3000番ポートへ転送とかする場合は↓こんな風に書けばいいです。

/etc/sysconfig/iptables
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp -d 10.0.0.81 --dport 80 -j REDIRECT --to-port 3001
-A PREROUTING -p tcp              --dport 80 -j REDIRECT --to-port 3000
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# filter settings here...
COMMIT

こうすることで1台のサーバで開発環境と本番環境を別ポートで使い分けつつ、ポート指定無しのURLでアクセスが出来るようになります。

ローカルプロセスからの通信にも対応する場合はOUTPUTチェーンで書き換える

上述の設定だと外からきたパケットに対しては上手く働くけどローカルのプロセスで発生したパケットには効きません。ローカルプロセスで発生したパケットはPREROUTINGチェインを通らないからです。代わりにOUTEPUTチェインを通ります。なので外からとローカルからの両方対応しようとすると↓こうなります。

/etc/sysconfig/iptables
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp -d 10.0.0.81 --dport 80 -j REDIRECT --to-port 3001
-A OUTPUT     -p tcp -d 10.0.0.81 --dport 80 -j REDIRECT --to-port 3001
-A PREROUTING -p tcp -d 10.0.0.80 --dport 80 -j REDIRECT --to-port 3000
-A OUTPUT     -p tcp -d 10.0.0.80 --dport 80 -j REDIRECT --to-port 3000
-A OUTPUT     -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-port 3000
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# filter settings here...
COMMIT

OUTPUTチェーンで80版を全部書き換えてしまうと外部へのhttpアクセスもできなくなってしまうので、面倒ですが-dで自分のIP全てを列挙した書き換えを行ってやる必要があります。

DNATでも出来る

DNATの場合は↓こうなる。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination :3000

またDNATの場合はポートと一緒にIPも書き換えることが出来るという違いがある。

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.0.0.90:3000

参考

natテーブルのPREROUTINGチェインがどこに効くかとかは↓このへんの図とかが分かりやすいです。
r10fig01.jpg

161
169
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
161
169

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?