Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
168
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@kawaz

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

例えば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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
168
Help us understand the problem. What are the problem?