VSFTPD與iptables NAT的設置詳解(申精)

火星人 @ 2014-03-04 , reply:0
←手機掃碼閱讀

VSFTPD與iptables NAT的設置詳解(申精)

FTP協議的特點就是數據流埠與控制流埠分離,這使得管理員在設置防火牆規則時,需要多考慮一些因素.同時由於FTP伺服器本身的重要性和不安全性,許多管理員想將其置於防火牆機器后,這樣一來就更麻煩了.通常是客戶端能登錄上伺服器,但無法列出目錄,無法傳輸數據等等,讓許多新手管理員摸不清頭腦,到論壇里撒分「跪求」解決辦法.其實這並不是想像的那麼難,看了本文後,你將明白這一切.


第一部分.理解FTP的主動模式與被動模式
        網上關於FTP傳輸的主被動模式的講解已很多。要想讓客戶機與伺服器之間暢通無阻的傳輸數據,必須首先理解它們的傳輸原理,這樣我們遇到問題時才可以對症下藥.我們通過抓包分析來理解其轉輸過程.

        主動模式(Port模式)
        主動模式的傳輸數據流程如下(伺服器ip:192.168.200.1,客戶端ip:192.168.200.8):
                1..192.168.200.8.55722 > 192.168.200.1.ftp: PORT 192,168,200,8,178,210
                2..192.168.200.1.ftp > 192.168.200.8.55722: 200 PORT command successful. Consider using PASV.
                3..192.168.200.8.55722 > 192.168.200.1.ftp: ......ACK
                4..192.168.200.8.55722 > 192.168.200.1.ftp: LIST
                5..192.168.200.1.ftp-data > 192.168.200.8.45778:......SYN
                6..192.168.200.8.45778 > 192.168.200.1.ftp-data: ......SYN.ACK
                7..192.168.200.1.ftp-data > 192.168.200.8.45778: ......ACK
                8..192.168.200.1.ftp > 192.168.200.8.55722: 150 Here comes the directory listing.
                9..192.168.200.1.ftp-data > 192.168.200.8.45778:
                        -rw-r--r--    1 0        0               6 Mar 23 08:53 filetest
                        drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
        從上面的數據得出主動模式的傳輸過程如下:
                A.(第1行)客戶端向伺服器申請PORT模式的數據傳輸,並通過PORT命令告知伺服器"我的IP是192.168.200.8,我開放埠45778等你".
                        (45778是通過PORT命令后的最後兩個數字算出來的.178*256 + 210 = 45778)
                B.(第2行)伺服器在檢查所收到的PORT命令的語法和安全性等因素后,向客戶端告知PORT命令成功,並同時建議客戶端考慮使用PASV.
                        (PASV就是我們接下來要講的被動模式)
                C.(第3行)客戶端確認收到從伺服器傳來的信息並應答.
                D.(第4行)客戶端向伺服器申請列出目錄信息的數據.
                E.(第5,6,7行)伺服器收到客戶端的申請后,主動用自己的20埠去連接客戶端的45778埠,以便傳送數據.
                        (注意:這是重要的地方,所謂主動模式,就是指伺服器從自己的數據埠主動去連接客戶端)
                F.(第8行)當伺服器與客戶端的數據流埠成功連接后,伺服器便通過控制埠21向客戶發送信息:你需要的目錄列表傳來了.
                G.(第9行)伺服器通過數據流埠,將用戶所需要的目錄數據信息發向客戶端.
        在整個通信過程中,伺服器僅用了兩個固定的低端埠,即控制埠21(ftp)和數據埠20(ftp-data),防火牆規則很好設置,只需放開這兩個埠就行.而客戶端就沒那麼幸運了,動態的開放了一個高端埠等待連接,這讓處於區域網內部,通過共享同一IP上網的用戶而言基本沒轍.但是,有其它的解決辦法么?有!就是我們接下來要談到的被動模式.

        被動模式(Passive模式)
        被動模式的傳輸數據流程如下(伺服器ip:192.168.200.1,客戶端ip:192.168.200.8):
                1..192.168.200.8.40137 > 192.168.200.1.ftp: PASV
                2..192.168.200.1.ftp > 192.168.200.8.40137: Entering Passive Mode (192,168,200,1,11,187)
                3..192.168.200.8.40137 > 192.168.200.1.ftp: ......ACK
                4..192.168.200.8.43422 > 192.168.200.1.3003: ......SYN
                5..192.168.200.1.3003 > 192.168.200.8.43422: ......SYN.ACK
                6..192.168.200.8.43422 > 192.168.200.1.3003: ......ACK
                7..192.168.200.8.40137 > 192.168.200.1.ftp: LIST
                8..192.168.200.1.ftp > 192.168.200.8.40137: 150 Here comes the directory listing.
                9..192.168.200.1.3003 > 192.168.200.8.43422:
                        -rw-r--r--    1 0        0               6 Mar 23 08:53 filetest
                        drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
        從上面的數據得出主動模式的傳輸教程如下:
                A.(第1行)客戶端向伺服器申請PASV模式的數據傳輸.
                B.(第2行)伺服器新開放一個數據流埠,進入監聽模式.並告訴客戶"你連接192.168.200.1吧,我開放了3003埠等你呢".
                        (3003埠是通過第2行最後兩個數字計算出來的,11*256 + 187 = 3003)
                C.(第3行)客戶端確認收到從伺服器傳來的信息並應答.
                D.(第4,5,6行)當客戶端獲知伺服器已新開了一個數據流埠讓自己去連接后,便從本地隨機選擇一個埠去連接伺服器指定的埠,以便傳送數據.
                        (注意:這是重要的地方,與主動模式不一樣,伺服器不會去主動連接客戶端,而是新開一個埠,被動的等客戶端來連接,這就是所謂的被動模式)
                E.(第7行)當客戶端與伺服器的數據流埠成功連接后,客戶端便向伺服器申請列出目錄信息的數據.
                F.(第8行)伺服器便通過控制埠21向客戶發送信息:你需要的目錄列表傳來了.
                G.(第9行)伺服器通過數據流埠,將用戶所需要的目錄數據信息發向客戶端.
        在整個通信過程中,客戶端都是主動去連接伺服器,並沒有開放埠被連接,這確實為客戶端的防火牆減輕了不少麻煩.但麻煩消失了么?沒有!被動模式只是把麻煩"移"到了伺服器上而已,伺服器則需要動態的開一個高端埠來傳輸數據,怎樣處理這個埠是我們面臨著的困難.不過不用怕,天才的程序員們為我們想好了一切,我們只需要按我們的要求設置參數就行.接下來讓我們分析各種可能存在的情況.


第二部分.伺服器相關設置實戰
        (注:本文所有例子均採用RHEL5+VSFTPD伺服器,且默認客戶端無防火牆.)
        機器布局如下:
                |客戶機|:::::::::::::::::|LINUX網關|------|VSFTPD伺服器|
                客戶機的IP: 10.10.10.10/8
                LINUX網關IP: 10.10.10.20/8,  192.168.1.1
                VSFTPD伺服器IP: 192.168.1.8/24

        1.配置VSFTPD伺服器,配置文件如下:
                listen=yes
                anonymous_enable=yes

                port_enable=yes
                connect_from_port_20=yes

                pasv_enable=yes
                pasv_min_port=10000
                pasv_max_port=10100
        這是一個簡單的VSFTPD配置,第一部分允許匿名用戶訪問,第二部分聲明允許主動模式,第三部分聲明允許被動模式,並把伺服器開放的被動連接的埠限制在10000-10100範圍以內,以便我們設置相應的防火牆規則.我在內網測試了,可以正常使用,更詳細的VSFTPD配置可查看man文檔或訪問http://blog.chinaunix.net/u3/94705/showart_1917230.html.

        2.網關設置
        首先開啟轉發功能.
                #echo 1 > /proc/sys/net/ipv4/ip_forward
        再設置相關NAT規則.
                #iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.8 --sport 20:21 -j SNAT --to 10.10.10.20
                #iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.8 --sport 10000:10100 -j SNAT --to 10.10.10.20
                #iptables -t nat -A PREROUTING -p tcp -d 10.10.10.20 --dport 21 -j DNAT --to-destination 192.168.1.8
                #iptables -t nat -A PREROUTING -p tcp -d 10.10.10.20 --dport 10000:10100 -j DNAT --to-destination 192.168.1.8
        前兩條規則把內網的FTP伺服器的相關埠的數據轉發出去.
        后兩條規則把外網對網關的相關埠的數據轉發給FTP伺服器.

        3.客戶端登錄測試
        登錄10.10.10.10,測試結果如下:
                # ftp 10.10.10.20
                Connected to 10.10.10.20 (10.10.10.20).
                220 (vsFTPd 2.0.5)
                Name (10.10.10.20:root): anonymous
                331 Please specify the password.
                Password:
                230 Login successful.
                Remote system type is UNIX.
                Using binary mode to transfer files.
                ftp> passive //關掉被動模式,我們先測試主動模式.
                Passive mode off.
                ftp> ls
                200 PORT command successful. Consider using PASV.
                150 Here comes the directory listing.
                -rw-r--r--    1 0        0              13 May 06 20:24 filetest
                drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
                226 Directory send OK.
        (到此,我們發現主動模式是配置無誤了,可以成功連接.可是在上部分我們說過,主動模式的可應用性不高,接著我們再測試一下被動模式)
                ftp> passive
                Passive mode on.
                ftp> ls
                227 Entering Passive Mode (192,168,1,8,39,109)
                ftp: connect: Connection timed out
        當我輸入ls命令后,系統返回了一條信息"227 Entering Passive Mode (192,168,1,8,39,109)".接著我等啊等,等來的是不幸的消息,系統提醒我連接超時了.
        這是怎麼回事兒?回過頭去看看第一部分被動模式傳輸過程就知道了,原來我們是"第D步"失敗了!
        當然會失敗啊!伺服器告訴我們,可以去連接192.168.1.8的39*256+109=10093埠以便傳輸數據,可是192.168.1.8對客戶端10.10.10.10來說是不可見的,它在10.10.10.20後面躲貓貓呢.
        此時,我們的解決辦法有兩個.其一,截獲伺服器傳向客戶端的數據(被動模式傳輸過程的第B步),修改相關數據,以欺騙客戶端讓它連接伺服器的網關10.10.10.20,因為伺服器192.168.1.8在10.10.10.20背後,對客戶端來說是不可見的.其二,由伺服器親自出面發布"假"信息欺騙客戶端,達到同樣的效果.
        這兩種解決辦法都很好實現,關於第一種,我們在網關伺服器上載入兩個模塊,以截獲並修改數據.登錄10.10.10.20操作如下:
                #modprobe ip_nat_ftp
                #modprobe ip_conntrack_ftp
        然後我們再在客戶端上測試.
                ftp> ls
                227 Entering Passive Mode (10,10,10,20,39,108)
                150 Here comes the directory listing.
                -rw-r--r--    1 0        0              13 May 06 20:24 filetest
                drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
                226 Directory send OK.
        怎麼樣,一次性就成功了吧.我們看到第二行的信息,ip已被修改成10.10.10.20,客戶端在收到這信息后,就會去連接10.10.10.20,然後經過10.10.10.20的轉發,於是我們理所當然的成功了.
        再看看第二種解決辦法,我們怎樣讓伺服器出面發布"假"消息去欺騙客戶端呢?vsftp的作者早想到這點了,我們只需要在vsftpd的配置文件中加入如下兩行即可.
                pasv_addr_resolve=yes        //允許vsftpd去欺騙客戶
                pasv_address=10.10.10.20        //讓vsftpd以這個地址去欺騙客戶
        重啟vsftpd后,我們再從客戶端測試發現也可以正常使用.

        4.如果使用了xinetd的redirect怎麼辦?
        就在我以為這篇挫文完成了的時候,一個朋友在QQ群里尋求幫助,他的情況是沒有使用NAT,而是使用了xined的redirect(重定向)功能,始終沒有調試成功.他在網關上做了如下的事情.
        A.打開轉發功能
                 #echo 1 > /proc/sys/net/ipv4/ip_forward
        B.添加了/etc/xinetd.d/vsftpd文件,內容如下:
                service ftp
                {
                        disable         = no
                        wait            = no
                        socket_type     = stream
                        user            = root
                        log_on_failure  += USERID
                        log_on_success  += PID HOST EXIT
                        bind            = 10.10.10.20
                        redirect        = 192.168.1.8 21
                }
        並啟動xinetd監聽相應的埠.
        C.然後在客戶端測試.
                # ftp 10.10.10.20
                Connected to 10.10.10.20 (10.10.10.20).
                220 (vsFTPd 2.0.5)
                Name (10.10.10.20:root): anonymous
                331 Please specify the password.
                Password:
                230 Login successful.
                Remote system type is UNIX.
                Using binary mode to transfer files.
                ftp> passive
                Passive mode off.
                ftp> ls
                500 Illegal PORT command.
                ftp: bind: Address already in use
                ftp> passive
                Passive mode on.
                ftp> ls
                227 Entering Passive Mode (192,168,1,8,39,65)
                ftp: connect: Connection timed out
        正如你所看到的那樣,客戶端能成功連接到伺服器,可是當想從伺服器列出數據的時候,無論主動模式還是被動模式都失敗了.這是正常的,我們只用xinetd重定向了21埠,卻沒有對可能要開啟的數據埠做仍何操作,所以,我們還得藉助NAT把數據埠的事兒搞定.登錄10.10.10.20,執行如下操作
                #iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.8 --sport 20 -j SNAT --to 10.10.10.20
                #iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.8 --sport 10000:10100 -j SNAT --to 10.10.10.20
                #iptables -t nat -A PREROUTING -p tcp -d 10.10.10.20 --dport 10000:10100 -j DNAT --to-destination 192.168.1.8
        再登錄客戶端連接測試.鬱悶,與先前的測試一樣,不論是主動模式還是被動模式,都失敗.
        控制埠能連接上,數據埠按我們設置的規則也能連接上,可為什麼還是失敗?難道xinetd的redirect有什麼特殊的地方,上網關伺服器一看,還真是有特殊的情況.
        在10.10.10.20上執行netstat -antup,顯示結果如下:
                tcp        0      0 10.10.10.20:21              10.10.10.10:43039           ESTABLISHED 2303/xinetd
                tcp        0      0 192.168.1.1:45459           192.168.1.8:21              ESTABLISHED 2303/xinetd
        原來xinetd的轉發機制是:先開啟21埠讓客戶機連接,自己再開啟一個埠去連接內部網路的FTP伺服器,然後自己做中間人,中轉數據.
        如果這樣的話,vsftpd伺服器會"發現"是192.168.1.1(網關伺服器的內網ip)在與它連接併發送控制指令的,這在接下來進行數據傳輸的時候會遇到困難,請看第一部分主動模式傳輸過程的第B步.客戶端通過網關xinetd模式向伺服器轉達的PORT命令,通不過vsftpd的安全性檢查,因為vsftpd伺服器只知道192.168.1.1在與它連接.就好像張三給你說,你把這份重要的數據給李四送去吧,這可是十分不安全的啊,vsftpd伺服器號稱最安全的FTP伺服器,可不是那麼"笨"的.不過我們可以將它變"笨",只需給它加個參數,讓它不檢查安全性即可.
        我們在vsftpd的配置文件中加上如下一行:
                port_promiscuous=yes
        重啟vsftpd伺服器,接著在客戶端測試:
                ftp> passive
                Passive mode off.
                ftp> ls
                200 PORT command successful. Consider using PASV.
                150 Here comes the directory listing.
                -rw-r--r--    1 0        0              13 May 06 20:24 filetest
                drwxr-xr-x    2 0        0            4096 Dec 13  2007 pub
        主動模式測試成功,可被動模式還是不行,原因上一小節已經講了.由於xinetd的redirect機制與NAT沒關係,先前的第一種通過截獲數據並修改數據包的做法行不通了,只得改改伺服器的參數,讓伺服器去忽悠客戶端吧.
        同樣,在伺服器上加上這兩行參數:
                pasv_addr_resolve=yes        //允許vsftpd去欺騙客戶
                pasv_address=10.10.10.20        //讓vsftpd以這個地址去欺騙客戶
        重啟vsftpd伺服器,在客戶端用被動模式測試連接.
                ftp> ls
                227 Entering Passive Mode (10,10,10,20,39,21)
                425 Security: Bad IP connecting.
        崩潰了吧,仍然不能連接.看到Security這個提示信息,我們就明白了,仍然是vsftpd的安全選項在作怪.它正在與192.168.1.1交流著呢,突然來了一個10.10.10.10要來連接它,它當然不願意啦,前文已說過,號稱最安全的FTP伺服器,可不是那麼"笨"的.沒辦法,再次將它變笨吧.給它再設置一個參數,在vsftpd的配置文件中加上如下一行:
                pasv_promiscuous=yes
        再登錄客戶端測試一下,發現可以正常使用了,大功告成.
        
        5.寫在最後
        FTP是在70年代設計出來的,當時的互聯網是一個封閉的網路,與現代網路環境還是有很大的差異,現代網路中不管你使用Port模式還是Passive模式,都可能產生問題.看完本文後,希望你能有所收穫,如果發現本文有錯誤,請回復或者直接加我QQ(864235428)聯繫.同時我再說下,xinetd的redirect是一個很優秀的功能,但他不適合用來處理FTP,數據埠是動態的,它無能為力,還得需要iptables,相反,由於它需要建立兩個連接的這種機制,使得我們一再要更改vsftpd關於安全性的參數,確實有點兒得不償失,如果你看完我的建議,仍然堅持要使用它,那祝你好運.

        歡迎訪問http://huabo2008.cublog.cn/
        (原創文章,歡迎轉載,轉載請保留上面這行.)
《解決方案》

不錯,寫的很詳細。

支持原創。:mrgreen:
《解決方案》

/etc/xinetd.d/vsftpd
呀,你這是哪個版本的呀?
麻煩LZ說明操作系統版本及vsftpd版本。
謝謝。
《解決方案》

文中有這句話

注:本文所有例子均採用RHEL5+VSFTPD伺服器,且默認客戶端無防火牆.

還有那個文件是是自己新建的。
《解決方案》

哦,看到了,你不說我還真注意不到。
《解決方案》

寫得很詳細,支持原創




[火星人 via ] VSFTPD與iptables NAT的設置詳解(申精)已經有368次圍觀

http://www.coctec.com/docs/service/show-post-13899.html