iptablesのnatでリダイレクト先ポートを外から直接アクセスできないようにする
やりたいこと
わかりづらいタイトルですがやりたいことは以下。
例えば、8080番ポートでwebサーバを立てた時、80番でもアクセスしたい場合に
# iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
としますよね?
そうすると、外から見えるポートはこんなかんじ。
$ nmap [targetIP] Starting Nmap 7.70 ( https://nmap.org ) at 2018-06-15 20:18 JST Nmap scan report for [targetIP] Host is up (0.067s latency). Not shown: 996 closed ports PORT STATE SERVICE 80/tcp open http 8080/tcp open http-proxy Nmap done: 1 IP address (1 host up) scanned in 6.62 seconds
ポートスキャナのNmapでスキャンしてみました。
80番と8080番が空いています。繋いでみると、どちらも8080番に繋がります。
通常の使い方だとこれで良いのですが、ハニーポットなどでroot権限でプログラムを動かすのを避けるためにポートフォワーディングしている場合、80番だけを外に見せていたくなります。ポートスキャンしたときに2つも同じサービスが動いているのは怪しまれる材料になりますからね。
というわけでプログラムを8080番で動かしつつ、80番だけでサービスを動かすiptablesを設定します。
最初に大部分で参考にさせてもらった記事を載せておきます
iptablesルール一部抜粋
*filter # 80番からフォワードされた8080の接続を許可(解説1) -A INPUT -p tcp -m tcp --dport 8080 -m conntrack --ctorigdstport 80 -j ACCEPT # 他の接続は拒否 (解説2) -A INPUT -j DROP COMMIT *nat # ポートフォワード 80→8080 -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080 COMMIT
解説1
-A INPUT -p tcp -m tcp --dport 8080 -m conntrack --ctorigdstport 80 -j ACCEPT
-m conntrack
はConntrackマッチオプションを使うために記述します。
Conntrackとはiptablesのコネクション追跡機能のことで、パケットのステートをルールに使用できます。
--ctorigdstport
でポートに基づいたコネクション追跡機能のルールを指定します。
このルールだと、80番に接続して8080番にポートフォワードされた場合に接続を許可することになります。
参考
機能などの詳細は以下を参照すると良いでしょう。
Iptablesチュートリアル 1.2.2 - Chapter 7. ステート機構
Iptablesチュートリアル 1.2.2 - 10.3.5. Conntrackマッチ
解説2
-A INPUT -j DROP
ご存知その他の接続は全部破棄するやつです。 8080番だけにDROPさせたい場合は以下のようにします。(需要ないと思うけど)
-A INPUT -p tcp -m tcp --dport 8080 -j REJECT --reject-with tcp-reset
8080への接続を破棄します。
--reject-with
でREJECT時に相手にメッセージを送信します。
tcp-reset
は上記--reject-with
でRSTパケットを送信します。
つまり、このルールでは8080版に直接アクセスした場合にRSTパケットを送信し、接続を終了します。
DROPでない理由は、DROPを個別に指定するとnmapにfilteredで検知扱いされるためです。
参考
Iptablesチュートリアル 1.2.2 - 11.19. REJECTターゲット
結果
上記2つのルールを設定して再度nmapでポートスキャンをかけてみます。
$ nmap [targetIP] Starting Nmap 7.70 ( https://nmap.org ) at 2018-06-15 20:18 JST Nmap scan report for [targetIP] Host is up (0.067s latency). Not shown: 996 closed ports PORT STATE SERVICE 80/tcp open http Nmap done: 1 IP address (1 host up) scanned in 6.62 seconds
80番だけ開いてる!
で、接続してみるとしっかり8080番ポートに繋がります。
他参考情報
↑--state
使う方法でもおそらく意味は一緒ですね
Iptablesチュートリアル 1.2.2
Man page of iptables-extensions
余談
積年の悩みがこれで取れました。参考記事の焼き増しみたいになってしまったけどw
Twitterでiptablesの話をしていたら割と時代遅れっぽい。。。
だから割とこの記事も時代遅れかもしれないので、ufwやfirewalldで同じようなことができたら教えてください。
ファイアウォールをもっとよく知ることができたらきっともっと自由にハニポが楽しめるのになー