題目原本出處﹕http://www.tango.idv.tw/study-area/read.php?f=1&i=200&t=200


***********************************


作者: netman (---.n203-95-150.eranet.net)
日期:   01/05/26 20:33


假設﹕
1) NAT 上有三張網路卡﹕
eth0 接外部網路﹐201.1.2.3
eth1 接 DMZ﹐10.1.2.3
eth 2 接內部網路﹐192.168.0.254
2) DMZ 內有一台主機﹐10.1.2.6﹐打算提供 FTP 服務(port 21 和 port 20)

問題﹕

1) 假設 DMZ 和外部網路的路由是通的﹐NAT 上面只進行單純的封包過濾而沒修改
packet﹐而且其預設 policy 都是 DENY。請設定所有必須的規則﹐讓 FTP 能順利向
外部提供服務。
2) 假設 DMZ 和外部網路的路由是不通的﹐我們用如下命令將 eth0 的 port 21和 的
連線請求轉至 10.1.2.6 的 port 21﹕
ipmasqadm portfw -a -P tcp -L 201.1.2.3 21 -R 10.1.2.6 21
而且 NAT 上的預設 policy 也全部為 DENY。請設定所有必須的規則﹐讓 FTP 能順利
向外提供服務。

要求﹕
請先提供答案﹐不管是否完整﹐日後我們再回來討論。



***********************************



 Re: NAT 的 FTP 設定命題 
作者: swbai (---.hinet.net)
日期:   01/05/30 20:44

我先交卷吧!
1.
ipchains -A input -i eth0 -p TCP -d 10.1.2.6 21 -j ACCEPT
ipchains -A forward -p TCP -d 10.1.2.6 21 -j ACCEPT
ipchains -A output -i eth1 -p TCP -d 10.1.2.6 21 -j ACCEPT
ipchains -A input -i eth1 -p TCP -s 10.1.2.6 21 -j ACCEPT
ipchains -A forward -p TCP -s 10.1.2.6 21 -j ACCEPT
ipchains -A output -i eth0 -p TCP -s 10.1.2.6 21 -j ACCEPT
ipchains -A input -i eth0 -p TCP -d 10.1.2.6 20 -j ACCEPT
ipchains -A forward -p TCP -d 10.1.2.6 20 -j ACCEPT
ipchains -A output -i eth1 -p TCP -d 10.1.2.6 20 -j ACCEPT
ipchains -A input -i eth1 -p TCP -s 10.1.2.6 20 -j ACCEPT
ipchains -A forward -p TCP -s 10.1.2.6 20 -j ACCEPT
ipchains -A output -i eth0 -p TCP -s 10.1.2.6 20 -j ACCEPT

2.
ipchains -A input -i eth0 -p TCP -d 201.1.2.3 21 -j ACCEPT
ipchains -A forward -p TCP -d 201.1.2.3 21 -j MASQ
ipchains -A output -i eth1 -p TCP -d 10.1.2.6 21 -j ACCEPT
ipchains -A input -i eth1 -p TCP -s 10.1.2.6 21 -j ACCEPT
ipchains -A forward -p TCP -s 10.1.2.6 21 -j MASQ
ipchains -A output -i eth0 -p TCP -s 201.1.2.3 21 -j ACCEPT
ipmasqadm portfw -a -P tcp -L 201.1.2.3 20 -R 10.1.2.6 20
ipchains -A input -i eth0 -p TCP -d 201.1.2.3 20 -j ACCEPT
ipchains -A forward -p TCP -d 10.1.2.6 20 -j MASQ
ipchains -A output -i eth1 -p TCP -d 10.1.2.6 20 -j ACCEPT
ipchains -A input -i eth1 -p TCP -s 10.1.2.6 20 -j ACCEPT
ipchains -A forward -p TCP -s 10.1.2.6 20 -j MASQ
ipchains -A output -i eth0 -p TCP -s 201.1.2.3 20 -j ACCEPT


 
 
***********************************

 Re: NAT 的 FTP 設定命題 (答案篇) 
作者: netman (---.seed.net.tw)
日期:   01/06/08 16:14


我們還是先以 swbai 的例子來討論吧﹐因為我們個題目沒考慮其它的安全要求﹐單純
就 ftp 服務進行設定而已﹐而且以 ipchains 為主。所以﹐其它的設定﹐自己慢慢補
充吧﹐例如 DNS 等。

>1.
>ipchains -A input -i eth0 -p TCP -d 10.1.2.6 21 -j ACCEPT
>ipchains -A forward -p TCP -d 10.1.2.6 21 -j ACCEPT
>ipchains -A output -i eth1 -p TCP -d 10.1.2.6 21 -j ACCEPT
>ipchains -A input -i eth1 -p TCP -s 10.1.2.6 21 -j ACCEPT
>ipchains -A forward -p TCP -s 10.1.2.6 21 -j ACCEPT
>ipchains -A output -i eth0 -p TCP -s 10.1.2.6 21 -j ACCEPT
>ipchains -A input -i eth0 -p TCP -d 10.1.2.6 20 -j ACCEPT
>ipchains -A forward -p TCP -d 10.1.2.6 20 -j ACCEPT
>ipchains -A output -i eth1 -p TCP -d 10.1.2.6 20 -j ACCEPT
>ipchains -A input -i eth1 -p TCP -s 10.1.2.6 20 -j ACCEPT
>ipchains -A forward -p TCP -s 10.1.2.6 20 -j ACCEPT
>ipchains -A output -i eth0 -p TCP -s 10.1.2.6 20 -j ACCEPT

漂亮﹗就是這樣設定啦﹐而且思路非常清晰﹗

>2.
>ipchains -A input -i eth0 -p TCP -d 201.1.2.3 21 -j ACCEPT
這是連線建立﹐因為用 ipmasqadm 來做 DNAT (port forward)﹐所以 destination
應該是 NAT 的外部界面。

>ipchains -A forward -p TCP -d 201.1.2.3 21 -j MASQ *
嗯﹐這個就要小心了﹐因為 DNAT 的時候已經將 destinatioin socket 修改過了﹐也
就是封包 input 進來之後﹐201.1.2.3 會變為 10.1.2.6 。而且﹐我們還要了解
ipmasqadm 這支程式的特性﹕當它修改了 input packet 之後﹐就不再會受到
ipchains 的 forward 檢查﹐而是直接根據路由判斷之後進行 output。所以﹐這行是
多餘的﹐拿掉則可。(標籤 1)

>ipchains -A output -i eth1 -p TCP -d 10.1.2.6 21 -j ACCEPT
這是經過 DNAT 修改之後﹐從 NAT 主機送出到 ftp server 的封包﹐必須 ACCEPT﹐
否則連線請求沒辦法到達 server。

>ipchains -A input -i eth1 -p TCP -s 10.1.2.6 21 -j ACCEPT
這是從 ftp server 回應進來的封包﹐也一定要 ACCEPT。

>ipchains -A forward -p TCP -s 10.1.2.6 21 -j MASQ
好了﹐這裡就要非常小心了﹗因為我們假設的前提是﹕dmz 和 外面網路是不能路由
的﹐如果封包沒做 MASQ 處理﹐那麼將無法遞送。而且﹐還不要忽略﹐當初封包經過
ipmasqadm 的處理﹐這裡進行 MASQ 之後﹐出去的封包會被還原成 client 所 expect
的 socket 。如果用 ACCEPT 的話﹐是不行的﹐為什麼 ipmasqadm 不會對 ACCEPT 規
則做還原動作﹐這個我就不知道了﹐或許要請問寫程式的設計者。但﹐我們要知道﹐
只有使用 MASQ 才能將當初被 DNAT 處理過的連線正確的還原為原來的 socket﹐即
port 21。(標籤 2)

>ipchains -A output -i eth0 -p TCP -s 201.1.2.3 21 -j ACCEPT
這是還原 socket 之後﹐送回到 client 那邊的回應封包﹐所以要 ACCEPT。

>ipmasqadm portfw -a -P tcp -L 201.1.2.3 20 -R 10.1.2.6 20 *
照理說﹐ftp-data 連線應該是從 port 20 出去的﹐換句話說﹐基本上第一個 syn 的
連線封包是 output 而不是 input 。好了﹐這樣的話﹐要能成功的將回應封包(不是
起始封包) forward 到 ftp server 去﹐要看 client 那邊是否知道 ftp-data 的建
立 socket 會在 server 端的 port 20 上面﹐也就是取決於 dmz 的 server 經過
SNAT 之後是否能夠成功的用 port 20 來起始 ftp-data 通道。請參考後面的解釋。
(標籤 3)

>ipchains -A input -i eth0 -p TCP -d 201.1.2.3 20 -j ACCEPT *
只有上一句的條件成立的時候﹐這行才用用。

>ipchains -A forward -p TCP -d 10.1.2.6 20 -j MASQ *
這行和“標籤 1”那行的道理一樣﹐如果用“標籤 3”那行處理之後﹐那這行就無需
使用了。

>ipchains -A output -i eth1 -p TCP -d 10.1.2.6 20 -j ACCEPT
這行是必須的﹐不管“標籤 3”和上一句是否被執行﹐這行仍是必須的﹐因為對於
dmz 的 ftp server 來說﹐不管 NAT 那邊怎麼處理﹐用來做 ftp-data 的 port 還是
20。

>ipchains -A input -i eth1 -p TCP -s 10.1.2.6 20 -j ACCEPT
這也是必須的﹐理由同上。

>ipchains -A forward -p TCP -s 10.1.2.6 20 -j MASQ
這行是整個命題的重點﹗因為 ftp-data 的連線﹐是從 server 端起始的﹐也就是﹐
當 dmz 的 ftp server 要建立 ftp-data 連線的時候﹐因為無法路由﹐所以一定要用
MASQ。但比較“標籤 2”那行﹐因為那行的連線﹐之前已經被 ipmasqadm 處理過﹐所
以能正確的還原到原來的 socket (port 21)。但這裡﹐因為這是第一個連線封包﹐當
初不可能被 ipmasaqdm 處理過(我在名題的時候﹐就沒處理 port 20 的 DNAT﹐因為
做了也是白做)﹐是不可能會被還原為 port 20 的﹐取而代之的是﹐ipchains 會根據
MASQ 的要求﹐重新建立一個對外的 socket﹐而 port 則是隨機產生的﹐也就是說﹐
在 1024:65535 之間。好了﹐請記住這個特性﹐我們必須要相對的為這個特性付出代
價﹐也就是必須增加這兩行規則﹕
ipchains -A output -i eth0 -p TCP -s 201.1.2.3 1024:65355 -d 0/0
1024:65535 -j ACCEPT
ipchains -A input -i eth0 -p TCP -s 0/0 1024:65535 -d 201.1.2.3
1024:65535 -j ACCEPT

這樣的話﹐我們可以看到的結果是﹕1024 以上的 port 都打開接受連線了﹗這是非常
危險的一個動作﹐因為開放的範圍太大了。起碼﹐我們也應該將來自外面的第一個
syn 封包攔下來﹐所以上面的 input 我們可以修改為﹕
ipchains -A input -i eth0 -p TCP -s 0/0 1024:65535 -d 201.1.2.3 1024:65355
! -y -j ACCEPT

所以﹐“標籤 3”和其後緊接著的兩行﹐也就沒什麼作用了﹐拿掉則可。

>ipchains -A output -i eth0 -p TCP -s 201.1.2.3 20 -j ACCEPT *
同樣﹐swbai 的最後一行也可以不設了﹐因為是多餘的﹐事實上﹐ ftp-data 的
socket﹐從 NAT 主機出去 client 那邊的時候﹐是不會使用到 port 20 的。

這裡﹐我們並沒有使用 passive 模式﹐所有被 * 標識的句子﹐事實上都可以拿掉。
不知道 passive 模式在設定﹐可否作為下一個命題來討論呢﹖我是非常歡迎大家來探
討探討的﹗
 
 

----------
 
NAT 的 FTP 設定命題 (iptables) 
作者: netman (---.seed.net.tw)
日期:   01/06/30 17:25 
 

大家好﹗

自從上次公佈了 NAT 的 FTP 設定命題 之後﹐陸續收到一些朋友問起 iptables 的設
定如何﹖今天花了點時間試了試﹐茲將我自己的設定供大家參考一下。

原命題詳見﹕

http://www.tango.idv.tw/study-area/read.php?f=1&i=200&t=200

假設﹕
1) NAT 上有三張網路卡﹕
eth0 接外部網路﹐201.1.2.3
eth1 接 DMZ﹐10.1.2.3
eth 2 接內部網路﹐192.168.0.254
2) DMZ 內有一台主機﹐10.1.2.6﹐打算提供 FTP 服務(port 21 和 port 20)

問題﹕

1) 假設 DMZ 和外部網路的路由是通的﹐NAT 上面只進行單純的封包過濾而沒修改
packet﹐而且其預設 policy 都是 DENY。請設定所有必須的規則﹐讓 FTP 能順利向外
部提供服務。
2) 假設 DMZ 和外部網路的路由是不通的﹐我們用如下命令將 eth0 的 port 21和 的
連線請求轉至 10.1.2.6 的 port 21﹕
ipmasqadm portfw -a -P tcp -L 201.1.2.3 21 -R 10.1.2.6 21
而且 NAT 上的預設 policy 也全部為 DENY。請設定所有必須的規則﹐讓 FTP 能順利
向外提供服務。

(註﹕因為這次使用 iptables﹐所有原假設 2 中的 ipmasqadm 命令行就無需執行了)


我的 iptables 設定﹕

***************************************
假設 1)﹕

# Generated by iptables-save v1.2.1a on Thu Jun 28 14:45:26 2001
*nat
:PREROUTING DROP [3:144]
:POSTROUTING ACCEPT [2:108]
:OUTPUT ACCEPT [4:948]
-A PREROUTING -p udp -m udp --dport 53 -j ACCEPT
-A PREROUTING -p udp -m udp --sport 53 -j ACCEPT
-A PREROUTING -p tcp -m tcp --dport 113 -j ACCEPT
-A PREROUTING -p tcp -m tcp --sport 113 -j ACCEPT
-A PREROUTING -p icmp -j ACCEPT
-A PREROUTING -d 10.1.2.6 -i eth0 -p tcp -m tcp --dport 21 -j ACCEPT
-A PREROUTING -s 10.1.2.6 -i eth1 -p tcp -m tcp --sport 20 -j ACCEPT
COMMIT
# Completed on Thu Jun 28 14:45:26 2001
# Generated by iptables-save v1.2.1a on Thu Jun 28 14:45:26 2001
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [4:948]
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --sport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 113 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 113 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A FORWARD -p tcp -m tcp --sport 53 -j ACCEPT
-A FORWARD -p tcp -m tcp --dport 53 -j ACCEPT
-A FORWARD -s 10.1.2.6 -i eth1 -p tcp -m tcp --sport 21 -j ACCEPT
-A FORWARD -d 10.1.2.6 -i eth0 -p tcp -m tcp --dport 21 -j ACCEPT
-A FORWARD -s 10.1.2.6 -o eth0 -p tcp -m tcp --sport 20 -j ACCEPT
-A FORWARD -d 10.1.2.6 -o eth1 -p tcp -m tcp --dport 20 -j ACCEPT
-A FORWARD -p icmp -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p udp -m udp --sport 53 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 113 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 113 -j ACCEPT
COMMIT
# Completed on Thu Jun 28 14:45:26 2001


***************************************
假設 2)﹕

# Generated by iptables-save v1.2.1a on Sat Jun 30 16:35:09 2001
*nat
:PREROUTING DROP [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p udp -m udp --dport 53 -j ACCEPT
-A PREROUTING -p udp -m udp --sport 53 -j ACCEPT
-A PREROUTING -p tcp -m tcp --dport 113 -j ACCEPT
-A PREROUTING -p tcp -m tcp --sport 113 -j ACCEPT
-A PREROUTING -p icmp -j ACCEPT
-A PREROUTING -d 201.1.2.3 -i eth0 -p tcp -m tcp --dport 21 -j
DNAT --to-destination 10.1.2.6:21

# (註一)﹕思考一下為什麼不用為 port 20 做 DNAT﹖

-A PREROUTING -s 10.1.2.6 -i eth1 -p tcp -m tcp --sport 21 -j ACCEPT
-A PREROUTING -s 10.1.2.6 -i eth1 -p tcp -m tcp --sport 20 -j ACCEPT
-A POSTROUTING -p tcp -m tcp -s 10.1.2.6 --sport 20 -j MASQUERADE

# (註二)﹕請留意上一行﹐在 ipchains 中也有相同的設計。

COMMIT
# Completed on Sat Jun 30 16:35:09 2001
# Generated by iptables-save v1.2.1a on Sat Jun 30 16:35:09 2001
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --sport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 113 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 113 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A FORWARD -p udp -m udp --sport 53 -j ACCEPT
-A FORWARD -p udp -m udp --dport 53 -j ACCEPT
-A FORWARD -s 10.1.2.6 -i eth1 -p tcp -m tcp --sport 21 -j ACCEPT
-A FORWARD -d 10.1.2.6 -i eth0 -p tcp -m tcp --dport 21 -j ACCEPT
-A FORWARD -s 10.1.2.6 -o eth0 -p tcp -m tcp --sport 20 -j ACCEPT
-A FORWARD -d 10.1.2.6 -o eth1 -p tcp -m tcp --dport 20 -j ACCEPT
-A FORWARD -p icmp -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p udp -m udp --sport 53 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 113 -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 113 -j ACCEPT
COMMIT
# Completed on Sat Jun 30 16:35:09 2001


***************************************

以我自己觀察﹐在此命題中﹐iptables 和 ipchains 的最大分別﹐是對那個來自 ftp
server 的 ftp-data 封包的處理上。
如果用 ipchains﹐在 masq 之後會另外建一個 source socket﹐但卻不是使用 port
20 ﹔
如果用 iptables﹐在 masq 之後也會另建一個 source socket﹐但卻保留原來的 port
20。
因為連線是從 server 端由內至外建立的﹐所以在 NAT 上已經有這個連線的 masq 記
錄存在﹐所以我們也就無須為 port 20 做 DNAT 了。

不過﹐在進行 passive 模式測試的時候﹐盡管將 ip_nat_ftp 模組載入﹐還是不能建
立 ftp-data 的連線。
抓幾個封包就可以發現﹕client 端從 command channel 中接收 server 的 port 命令
之後﹐會嘗試直接以 ftp server 的 IP 來做 destination﹐卻不是以 NAT 的外部界
面為目標。所以連線無法建立。

推論﹕如果 server 和 client 兩端都各自躲在 NAT 背後﹐無論用 ipchains 和
iptalbes 都無法用 passive 模式來建立 data channel。解決的方法﹐只能在 client
端的 NAT 上﹐將 ip_nat_ftp 的模組載入(ipchains 是用 ip_masq_ftp 模組)﹐而
server 端使用標準的 port 20 和 21 來提供 FTP 服務。


以上僅為個人測試心得﹐未必與實際的運作相符。同時很歡迎大家的指教﹐謝謝﹗


--

不過﹐參考下面的文章﹐如果知道 ftp-data 的 port 號碼的話﹐應該可以這樣玩﹕

"絕對クバ人間"  撰寫於郵件 news:3i1ZkY$GzJ@BirdNest.infoX.Net...
> ※ 引述《rick.bbs@bbs.cm.nctu.edu.tw (Rick)》之銘言:
> : 我已經 IP_masq_ftp
> : 正常port 21的ftp 可以連~~
> : 但現在的問題是`
> : 我想連一個非port 21 的~就是進不去~~
> : 不管有沒有開pasv mode~~(對方用warftp)
> : 請問這倒底怎麼解決`???`
> 
>   假設對方的 ftp 開在 1999
> 
>   /sbin/modprobe ip_masq_ftp ports=21,1999


-------------------------
補充 2002/02/04 by 網中人﹕

在最近的測試中﹐我發現 netfilter 所帶來的 ip_conntrack_ftp 以及 ip_nat_ftp 模組
已經能夠成功的進行 server 端與 client 端的連線轉換。

換而言之﹐我之前所提到的過濾﹕
    client 與 server 雙方都在 NAT 之後是否能連線﹖
現在已經不是問題了﹗實在非常感謝 netfilter 的工作者們。

p.s. 我所測試的核心為 2.4.16 以及 iptables-1.2.1a-1 。