runsisi's

technical notes

ftp Active mode vs Passive mode

2019-02-11 runsisi#linux

ftp 真的是一个很老很老的协议。

怀念在学校用 ftp 下载电影的日子[1]。。。

问题描述

在测试某个 ftp 服务端实现时发现 ftp 客户端在设置 Active 数据传输模式时,即使服务端防火墙阻止 20 端口的流量,数据传输仍然能够正常完成,而这与我所了解的 ftp 的行为并不一致。

测试代码如下:

#! /usr/bin/env python

from ftplib import FTP

ftp = FTP()

ftp.connect('host-or-ip', 21, 15)
ftp.login('user', 'password')

print(ftp.getwelcome())
print(ftp.pwd())

# ftp.retrlines('LIST')

def stor(fp):
    def _stor(data):
        fp.write(data)
    return _stor

# Active mode
ftp.set_pasv(False)

# Passive mode
# ftp.set_pasv(True)

fn = 'test.zip'
with open(fn, 'wb') as fp:
    ftp.retrbinary('RETR ' + fn, stor(fp))

print('retr \'{}\' ok, quit'.format(fn))
ftp.quit()

问题分析

报文交互截图如下,其中 192.168.5.4 是 ftp 客户端,192.168.9.131 是 ftp 服务端:

ftp active
Active 模式

ftp passive
Passive 模式

显然,从 Active 模式的截图可以看到,服务端在主动连接客户端建立数据传输通道时,服务端并没有 bind 到 20 端口,从而防火墙就无法阻止 20 端口的流量了。

而根据 RFC[5] 的描述:

3.2.  ESTABLISHING DATA CONNECTIONS

      The mechanics of transferring data consists of setting up the data
      connection to the appropriate ports and choosing the parameters
      for transfer.  Both the user and the server-DTPs have a default
      data port.  The user-process default data port is the same as the
      control connection port (i.e., U).  The server-process default
      data port is the port adjacent to the control connection port
      (i.e., L-1).

3.3.  DATA CONNECTION MANAGEMENT

      Default Data Connection Ports:  All FTP implementations must
      support use of the default data connection ports, and only the
      User-PI may initiate the use of non-default ports.

在 Active 模式下,服务端应该是需要 bind 到 20 (L - 1 = 21 - 1 = 20) 端口的。

参考资料

[1] lftp使用

http://www.cppblog.com/runsisi/articles/77572.html

[2] Active FTP vs. Passive FTP, a Definitive Explanation

http://slacksite.com/other/ftp.html

[3] What is the difference between active and passive FTP?

https://stackoverflow.com/a/27820711

[4] Why does FTP passive mode use a range of ephemeral ports as opposed to a single well known port?

https://networkengineering.stackexchange.com/questions/43680/why-does-ftp-passive-mode-use-a-range-of-ephemeral-ports-as-opposed-to-a-single

[5] FILE TRANSFER PROTOCOL (FTP)

https://tools.ietf.org/html/rfc959