Nginx代理FTP


1 需求

近期,需要通過Nginx代理內網FTP服務,以便外網用戶進行訪問,故針對此展開技術調研。
軟件版本:

  • Nginx: 1.18.0;
  • vsftpd: 3.0.2;
  • CentOS: CentOS Linux release 7.9.2009 (Core).

2 FTP模式

FTP具有兩個端口,分別為控制端口(完成諸如登錄,目錄查詢/切換等命令),數據端口(負責具體數據傳輸).

CentOS上安裝vsftpd后,啟動服務可發現vsftpd在21端口上監聽命令(此時無客戶端接入),具體如下圖所示:

FTP連接模式具有兩種,分別為主動模式(PORT)以及被動模式(PASV)。

主動模式:

(1)當FTP客戶端以主動模式連接服務端時,客戶端以動態選擇的端口號向服務器的命令端口發起連接;

(2)連接建立后,用戶在發出列目錄或傳輸文件的命令后,會要求建立數據連接;

(3)FTP客戶端在控制連接上發出主動模式指令,告知服務器客戶端的數據連接端口號;

(4)服務端收到指令后,會使用20號端口連接客戶端指定的數據連接端口號,從而建立數據連接。

被動模式:

被動模式的連接過程與主動模式類似,區別點在於客戶端發出列目錄或傳輸文件的命令后,客戶端會發送PASV指令至服務端;

服務端收到PASV指令后,告知客戶端服務端的數據連接IP地址和端口號;

客戶端根據返回的服務端數據連接IP和端口號,發起數據連接。

3 問題 & 解決思路

當前,客戶端需要通過Nginx代理方能訪問FTP服務端。通過Nginx stream可以實現控制命令的轉發,但是對於客戶端和服務端協商的數據連接,較難實現代理。

不過查閱相關文檔,vsftpd支持設置數據連接的端口范圍,亦支持設置數據連接的IP。

因此,我們可以指定vsftpd模式為被動模式(默認即為被動模式),設置數據連接IP地址為Nginx代理地址,合理設置數據連接端口范圍(Nginx監聽本地此端口范圍內數據)。當ftp客戶端與vsftpd服務端協商數據連接后,ftp客戶端根據數據連接IP(已設置為Nginx代理地址)以及端口號發起連接(實際連接至Nginx服務器),Nginx將此端口上監聽的數據轉發至vsftpd對應的數據端口。

4 方案示例

機器信息:

  • Nginx代理機: 192.168.56.101;
  • vsftpd服務端: 192.168.56.102;
  • 測試機: 192.168.56.106。

此處,利用開發機上安裝的虛擬機完成驗證,未具體限制網段。

vsftpd服務端配置:

# cat /etc/vsftpd/vsftpd.conf

listen=YES
listen_ipv6=NO                  # 修改listen配置,只允許監聽在IPv4地址,這是因為在被動模式下,設置pasv_address存在bug(具體可搜索stackoverflow)

pasv_enable=YES                 # 開啟pasv模式
pasv_min_port=50000             # pasv模式下,數據連接最小端口號
pasv_max_port=50002             # pasv模式下,數據連接最大端口號
pasv_address=192.168.56.101     # pasv模式下,告知客戶端的數據連接IP
pasv_promiscuous=YES            # 關閉pasv模式下,關閉對IP地址的檢查,此檢查確保控制連接和數據連接來自同一IP

pasv_promiscuous關閉存在安全隱患;
在實際組網情況下,Nginx轉發時可設置保留源IP信息,但是客戶端與服務端無法直接訪問,因此只能放棄保留源IP信息。

Nginx配置:

stream {
        upstream ftp {  # FTP控制面轉發
                server 192.168.56.102:21 max_fails=2 fail_timeout=3s weight=1;
        }

        server {    # 轉發FTP控制面請求
                listen 11000;   #監聽端口
                #失敗重試
                proxy_next_upstream on;
                proxy_next_upstream_timeout 0;
                proxy_next_upstream_tries 0;
                #超時配置
                proxy_connect_timeout 1s;
                proxy_timeout 10m;
                #限速配置
                proxy_upload_rate 1024k;
                proxy_download_rate 2048k;
                #上游服務器
                proxy_pass ftp;
       }

        upstream ftp_pasv1 {    
                server 192.168.56.102:50000 max_fails=2 fail_timeout=3s weight=1;
        }

        upstream ftp_pasv2 {    
                server 192.168.56.102:50001 max_fails=2 fail_timeout=3s weight=1;
        }

        upstream ftp_pasv3 {    
                server 192.168.56.102:50002 max_fails=2 fail_timeout=3s weight=1;
        }

        server {                # 轉發客戶端發送到Nginx代理機的數據連接
                listen 50000;
                proxy_pass ftp_pasv1;
        }

        server {                # 轉發客戶端發送到Nginx代理機的數據連接
                listen 50001;
                proxy_pass ftp_pasv2;
        }

        server {                # 轉發客戶端發送到Nginx代理機的數據連接
                listen 50002;
                proxy_pass ftp_pasv3;
        }
}

此處省略對FTP數據連接的具體控制(諸如限速)。

5 驗證

重啟vsftpd以及Nginx,從測試機:192.168.56.103發起連接,具體如下所示:

tcpdump抓包分析:

6 弊端

使用Nginx代理FTP服務,存在以下缺點:

  • 控制連接和數據連接是否來自同一連接無法驗證,存在安全隱患;
  • FTP被動模式下,數據端口范圍較寬時,Nginx添加配置比較麻煩;
  • Nginx代理機需要開放較多端口,諸如iptables等安全設置復雜。

使用SFTP,簡單又可靠。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM