【ipfw】NATルールの除外設定【iptables】

インターネットへの疎通を行うためにファイアウォールでSNAT設定を行うことがあると思います。 インターネットへの疎通であるため宛先は指定せず、 0.0.0.0/0 や Interfaceを通過するすべての通信を対象にSNAT設定を行いますが、例えばVPNを利用していると特定のセグメントのみ、SNATルールを適用させたくない場合などがあると思います。(特にVPNルータでのNAT設定)
今回FreeBSDのipfwとLinuxのiptablesでNATの除外設定を行ったのでメモとして残しておきます。

FreeBSDの場合

まずFreeBSDでnat設定をする場合、 natdが紹介されている事が多いのですが、ipfwでもNAT設定が可能です。私は基本ipfwでファイアウォールを使っているため、今回はipfwでNAT設定を行いました。
用途としてはjailで作成したインスタンスの通信を、SNATでインターネットへ疎通出来るようにしています。今回LANを 192.0.2.0/25、 VPN接続先を 192.0.2.128/25 を例にipfwのnatルール設定を記載します。

nat 1 config ip {SNAT後IPアドレス}
# SNAT除外設定
add allow all from 192.0.2.0/24 to 192.0.2.0/24
add 2000 nat 1 ip from 192.0.2.0/25 to any
add 2001 nat 1 ip from any to {SNAT後IPアドレス} via {SNAT後IPアドレス}

ポイントなのがallowルールでLAN==VPN接続先のセグメント間を許可している点です。
ipfwはルールの番号通りルールマッチをしていくため、 NATルールの2000,2001の前にallowルールに合致すれば該当するトラフィックはNATされません。
例ではallowルールで明示的なルール番号を指定していませんが、自動的にルール番号が採番されNATルールより先に適用されています。適用されているルール、ルールの採番の確認は ipfw -a list で確認出来ます。
また冒頭のNATルールの確認は ipfw nat 1 show config などのコマンドで確認出来ます。

Linuxの場合

Linuxの場合はiptablesで同じくSNATルールに加え、除外ルールを書けば可能です。
今回OpenWrtでルールを書きました。VPNルータとしてSNATとVPNトラフィックを共存させるケースです。

今回も同じくLANを 192.0.2.0/25、 VPN接続先を 192.0.2.128/25 として記載しています。

iptables -t nat -I POSTROUTING 1 -s 192.0.2.0/25 -d 192.0.2.128/25 -j RETURN
iptables -t nat -I POSTROUTING 2 -s 192.0.2.0/25 -j SNAT --to-source {SNAT後IPアドレス}

ポイントは以下2つです。

  • SNATをスキップさせるためにRETURNを使う
  • -I オプションでルール番号を指定させ、SNATルール前にRETURNルールを設定する

OpenWrtの場合、 POSTROUTING ではなくLAN I/Fでは zone_lan_prerouting のチェーンになっており、かつLuCIのバージョンが古いせいかRETURNルールはUIから設定出来なかったので Custom Rules で設定しました。(反映させるのに/etc/init.d/firewall restart とかが必要でした。)
基本的にはFreeBSDと同じく、ルール順に処理されていくのでSNATルールの前にRETURNルールを入れてあげる所が大事ですね。

まとめ

今回FreeBSDのipfw, LinuxのiptablesでNATルールの除外ルール設定方法を紹介しました。
設定としてはシンプルなのですが、私自身結構苦戦しました 😇 VPNルータを構成する場合、この様なNAT除外設定が必要になってくるので参考になれば幸いです。

Share Comments
comments powered by Disqus