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

試して学ぶiptablse、ポートフォワード

iptablesでポートフォワードを試してみたいと思います。

手元で試したいのでちょっと構成は特殊ですが以下です。

image.png

  • LAN(192.168.0.0/24)内にスマホとノートPCがあります。
  • ノートPC上にはwebサーバーをたて、4000番ポートで待ち受けさせます。
  • 図の簡略化のためLAN内のルーターは省略しています。

達成したいことはスマホのブラウザからノートPC(192.168.0.9)にアクセスした際に、
4000番ポートのサーバに応答させることです。

TODO

パケットの流れを下図でおさらいしながらTODOを洗い出します。
参考:Iptablesチュートリアル 1.2.2 Chapter 6.1

スマホブラウザのGETリクエストのパケットはDestination IPが192.168.0.9、Destination Portが80で、図の「NETWORK」から流れてきます。
サーバーは図の「Local Process」です。

よって、以下を実施すればリクエストのパケットはサーバーに到達できます。

  1. 図の「nat PREROUTING」でDestination IPを127.0.0.1に、Destination Portを4000に書き変える
    ※宛先がローカルホストのため、Routing Decisionでパケットは図の「INPUT」の流れに振り分けられます。
  2. 図の「filter INPUT」でそのパケットの通過を許可する

検証

初期状態は以下です。

# iptables -L        
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

デフォルトポリシーの設定

ホワイトリスト方式にします。

# iptables -P INPUT DROP
# iptables -P FORWARD DROP

ノートPC上のWEBサーバーへのアクセスを許可

TODOの順序と逆になりますが、まずノートPCのブラウザでサーバにアクセスできるようにします。

# iptables -A INPUT -d 127.0.0.1 -p tcp --dport 4000 -j ACCEPT
# iptables -A INPUT -s 127.0.0.1 -p tcp --sport 4000 -j ACCEPT

ローカルなのでややこしいですが、設定とパケットは以下のように対応します

# iptables -A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 4000 -j ACCEPT

上記がブラウザからサーバー向かうパケットを許可

# iptables -A INPUT -s 127.0.0.1/32 -p tcp -m tcp --sport 4000 -j ACCEPT

上記がサーバーからブラウザへ向かうパケットを許可

スマホからのhttpアクセスをノートPC上のサーバーへ振る

スマホ(192.168.0.2)からのリクエストのdesinationをNAPT(Network Address Port Translation)します。

# iptables -t nat -A PREROUTING -s 192.168.0.2 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:4000

LAN内のスマホ以外からもアクセスさせるには以下のようにします。

# iptables -t nat -A PREROUTING ! -s 192.168.0.9 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:4000

DNATターゲットを使うことでDestination IPとDestination Portの書き変えを行っています。





上記で動きそうですが動きませんでした。

外部からlocalhostへはデフォルトでは繋がらないようです。
localhostは外界から隔絶されているべきだからでしょう。

今回は手元で検証するためなので設定を変更します。

# sysctl -w net.ipv4.conf.eth0.route_localnet=1

※eth0はスマホからのパケットが通るNICの名前に読み替えること

これでアクセスできました!

「サーバーからの応答パケットのSNATをする必要はないのか?」という疑問をもちましたか?僕は持ちました。
結論は必要ありません。DNAT, SNATは一方向の変換を定義してやれば逆方向は自動でおこないます。
※参考: DNATターゲット

設定の確認

最終的な設定は以下です。

root@X1-Carbon-6th:~# iptables-save 
# Generated by iptables-save v1.6.1 on Sat Dec 28 14:15:30 2019
*nat
:PREROUTING ACCEPT [167:28771]
:INPUT ACCEPT [10:624]
:OUTPUT ACCEPT [314:29752]
:POSTROUTING ACCEPT [314:29752]
-A PREROUTING -s 192.168.0.2/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 127.0.0.1:4000
COMMIT
# Completed on Sat Dec 28 14:15:30 2019
# Generated by iptables-save v1.6.1 on Sat Dec 28 14:15:30 2019
*filter
:INPUT DROP [3377:278628]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [3560:414379]
-A INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 4000 -j ACCEPT
-A INPUT -s 127.0.0.1/32 -p tcp -m tcp --sport 4000 -j ACCEPT
COMMIT
# Completed on Sat Dec 28 14:15:30 2019
root@X1-Carbon-6th:~# sysctl -n net.ipv4.conf.enx7cc3a186ea62.route_localnet 
1 

片付け

片付けるときは以下に気をつけてください。

  • table毎に-Fオプションでルールを消すこと、ポリシーを元に戻すこと
  • 今回の特殊対応した設定をsysctlで戻すこと
# iptables -F && iptables -F -t nat
# iptables -P INPUT ACCEPT && iptables -P FORWARD ACCEPT
# sysctl -w net.ipv4.conf.enx7cc3a186ea62.route_localnet=0

まとめ

手元の環境でポートフォワードを試しました。
パケットの流れの図がとても優秀で、見ながら考えれば十分に設定ができることを確認しました。

「いいね」よろしくお願いします。:wink:

fukuokaex
エンジニア/企業向けにElixirプロダクト開発・SI案件開発を支援する福岡のコミュニティ
https://fukuokaex.fun/
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
ユーザーは見つかりませんでした