Nginx proxy FTP


1 demand

Recently, it is necessary to use nginx to proxy the intranet FTP service for external users to access. Therefore, technical research is carried out on this.
Software version:

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

2 FTP mode

FTP has two ports: control port (to complete commands such as login and directory query / switching) and data port (to be responsible for specific data transmission)

After installing vsftpd on CentOS, start the service and find that vsftpd listens for commands on port 21 (there is no client access at this time), as shown in the following figure:

There are two FTP connection modes: active mode (port) and passive mode (PASV).

Active mode:

(1) When the FTP client connects to the server in the active mode, the client initiates the connection to the command port of the server with the dynamically selected port number;

(2) After the connection is established, the user will ask to establish a data connection after issuing the command of column directory or transfer file;

(3) The FTP client sends an active mode command on the control connection to inform the server client of the data connection port number;

(4) After receiving the instruction, the server will use port 20 to connect to the data connection port number specified by the client, so as to establish a data connection.

Passive mode:

The connection process of passive mode is similar to that of active mode. The difference is that after the client sends the command of column directory or transfer file, the client will send PASV command to the server;

After receiving the PASV instruction, the server informs the client of the data connection IP address and port number of the server;

The client initiates the data connection according to the returned server data connection IP and port number.

3. Problems & Solutions

Currently, the client needs to access the FTP server through the nginx agent. The forwarding of control commands can be realized through nginx stream, but it is difficult to realize the proxy for the data connection negotiated between the client and the server.

However, referring to relevant documents, vsftpd supports setting the port range of data connection and the IP of data connection.

Therefore, we can specify the vsftpd mode as the passive mode (the default is the passive mode), set the data connection IP address as the nginx proxy address, and reasonably set the data connection port range (nginx listens to the local data within this port range). After the FTP client negotiates the data connection with the vsftpd server, the FTP client initiates the connection according to the data connection IP (set as the nginx proxy address) and port number (actually connected to the nginx server), and nginx forwards the data monitored on this port to the data port corresponding to vsftpd.

4 scheme example

Machine information:

  • Nginx agent:;
  • Vsftpd server:;
  • Testing machine:

Here, the virtual machine installed on the development machine is used to complete the verification, and the network segment is not specifically limited.

Vsftpd server configuration:

# cat /etc/vsftpd/vsftpd.conf

listen_ IPv6 = no # modify the listen configuration to allow listening only on IPv4 addresses. This is because PASV is set in passive mode_ There is a bug in address (specifically, you can search stackoverflow)

pasv_ Enable = yes # enable PASV mode
pasv_ min_ Minimum port number of data connection in port = 50000 # PASV mode
pasv_ max_ Maximum port number of data connection in port = 50002 # PASV mode
pasv_ Address = # PASV mode, inform the client of the data connection IP
pasv_ Promiscuous = yes # turn off the check of IP address in PASV mode. This check ensures that the control connection and data connection come from the same IP

pasv_ There are potential safety hazards when promiscuous is closed;
In the actual networking situation, the source IP information can be reserved during nginx forwarding, but the client and server cannot access it directly, so they can only give up the reservation of the source IP information.

Nginx configuration:

stream {
        Upstream FTP {# FTP control plane forwarding
                server max_fails=2 fail_timeout=3s weight=1;

        Server {# forwards FTP control plane request
                listen 11000;   # Listening port
                #Failed to retry
                proxy_next_upstream on;
                proxy_next_upstream_timeout 0;
                proxy_next_upstream_tries 0;
                #Timeout configuration
                proxy_connect_timeout 1s;
                proxy_timeout 10m;
                #Speed limit configuration
                proxy_upload_rate 1024k;
                proxy_download_rate 2048k;
                #Upstream server
                proxy_pass ftp;

        upstream ftp_pasv1 {    
                server max_fails=2 fail_timeout=3s weight=1;

        upstream ftp_pasv2 {    
                server max_fails=2 fail_timeout=3s weight=1;

        upstream ftp_pasv3 {    
                server max_fails=2 fail_timeout=3s weight=1;

        The server {# forwards the data connection sent by the client to the nginx agent
                listen 50000;
                proxy_pass ftp_pasv1;

        The server {# forwards the data connection sent by the client to the nginx agent
                listen 50001;
                proxy_pass ftp_pasv2;

        The server {# forwards the data connection sent by the client to the nginx agent
                listen 50002;
                proxy_pass ftp_pasv3;

The specific control of FTP data connection (such as speed limit) is omitted here.

5 verification

Restart vsftpd and nginx and initiate a connection from the tester:, as shown below:

Tcpdump packet capture analysis:

6 disadvantages

Using nginx proxy FTP service has the following disadvantages:

  • Whether the control connection and data connection come from the same connection cannot be verified, and there are potential safety hazards;
  • In FTP passive mode, when the range of data ports is wide, it is troublesome to add configuration to nginx;
  • The nginx agent needs to open more ports, and the security settings such as iptables are complex.

Using SFTP is simple and reliable.