7. 特殊協議
有些協定是並不想要做 NAT 的。對於每一個這樣的協議而言﹐有兩個延伸設定(extension)是必須要寫清楚的:一個是關於協議之聯機追蹤﹐另一個關於實際的 NAT。
在 netfilter 發行套件裏面﹐有一些關於 ftp 的現行模塊﹕ip_conntrack_ftp.o 與 ip_nat_ftp.o 。如果您把這些插入到您的核心裏面(或您永久性的編譯它們)﹐那麼要在 ftp 聯機上做任何種類的 NAT 都是可行的。如果您不這樣的話﹐那您可以使用被動模式 ftp﹐不過如果您要做一些動作甚於簡單 Source NAT 的話﹐這就可能不那麼可靠了。
8. NAT 的一些限制 (caveats)
如果在一個聯機上做 NAT﹐所有 雙向 (傳出和傳入) 的封包﹐都必須要通過 NAT 主機才 行﹐否則並不可靠。尤其在聯機追蹤程序重組碎片 (fragments)的時候﹐也就是說﹐不但聯機追蹤會不可能﹐而且您的封包根本就不能通過﹐因爲碎片會被擋下。
如果您要做 SNAT﹐您會想要確定經過 SNAT 封包所傳給的主機會將響應送回給 NAT 主機。例如﹐如果您映對某些傳出封包到來源地址 1.2.3.4 之上﹐那麼� 部的路由器就必須知道要將響應封包(目的地爲 1.2.3.4 )送回給該主機。這可以用如下方法做到﹕
1. 如果您要在主機自己的地址(路由和其它所有運作皆正常)上面做 SNAT﹐您無需做任何動作。
2. 如果您要在一個在本機網絡上尚未使用的地址做 SNAT(例如﹐映對到在 1.2.3.0/24 網絡上的一個可用 IP 1.2.3.99)﹐您的 NAT 主機就需要響應關於該地址的 ARP 請求﹐一如它自己本身的一樣﹕最簡單的方法就是建立 IP alias﹐例如﹕
3. # ip address add 1.2.3.99 dev eth0
4. 如果您要在一個完全不同的地址上做 SNAT﹐您就要確定 SNAT 封包抵達的機器能夠路由回該 NAT 主機。如果 NAT 主機是它們的默認網關的話﹐是可以做到的﹐否則﹐您就要廣告(advertize )一個路由(如果跑路由協議的話)﹐或是手工的在每一臺參與機器上增規則
10. 在同一網絡上的 Destination NAT
如果您要做 portforwarding 回到同一個網絡﹐您要確定前向和響應封包雙方都經過該 NAT 主機(這樣它們� 能被修改)。NAT 程序從現在開始(2.4.0-test6以後)﹐會擋掉後面情形所產生的傳出 ICMP 重導向﹕那些已經 NAT 的封包以它所進入的相同界面傳出﹐而接收端服務器仍嘗試直接響應到客戶端(不認可該響應)。
經典的情形是內部人員嘗試連接到您的 `公有(public)' 網站服務器﹐實際上是從公有地址(1.2.3.4) DNAT 到一個內部的機器(192.168.1.1)去﹐就像這樣﹕
# iptables -t nat -A PREROUTING -d 1.2.3.4 \
-p tcp --dport 80 -j DNAT --to 192.168.1.1
一個方法是跑一臺內部 DNS 服務器﹐它知道您的公有網站的真正(內部) IP 地址﹐而將其它請求轉傳給� 部的 DNS 服務器。換而言之﹐關於您網站服務器的記錄會正確地顯示爲內部 IP 地址。
而另一個方法是同時讓這臺 NAT 主機將該等聯機之來源 IP 地址映對爲它自己的地址﹐我們可以像如下那樣做(假設 NAT 主機之內部 IP 地址爲 192.168.1.250)﹕
# iptables -t nat -A POSTROUTING -d 192.168.1.1 -s 192.168.1.0/24 \
-p tcp --dport 80 -j SNAT --to 192.168.1.250
因爲 PREROUTING 規則是最先執行的﹐對內部網站服務器而言﹐封包就已經被定向好了﹕我們可以內定好哪個爲來源 IP 地址。
11. 感謝
首先感謝在我工作期間相信 netfilter 的構想並支持我的 WatchGuard 和 David Bonn。
以及所有其他幫我指正 NAT 之不足的朋友﹐尤其是那些讀過我的日記的。
Rusty.