Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

例えば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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした