vsftpd配置实践,构建安全高效的文件传输解决方案

FTP 简介

在日常工作中,我们经常需要在客户端(或服务器)与服务器之间传输文件,尤其是大文件的传输。使用 FTP 来传输时,其实是具有一定程度的安全风险的,因为数据在网络上面是明文传输的,但是,构建一个相对安全的 FTP 服务还是有其必要性的。

FTP(文件传输协议),是在客户端与服务器之间传输文件的应用层协议,通过 FTP 传输的流量不加密,所有传输通过明文进行。

FTP 服务使用两个通道进行通信:命令通道和数据通道,两个通道都通过 TCP 建立连接,需要经过三层握手。命令通道通常在 21 端口运行,用于传输 FTP 命令和响应,数据通道,端口号动态指定,不固定。在主动模式下,由客户端指定并告知服务器。在被动模式下,由服务器提供一个随机端口给客户端。数据通道用于实际的数据传输,如文件上传和下载。数据通道不是持久的,它只在需要传输数据时才打开,并在传输完成后关闭。

主动模式与被动模式

在主动模式中,客户端打开两个端口:一个用于命令传输(控制连接),另一个用于数据传输(数据连接)。以下是具体步骤的图解:

    主动模式的FTP连接过程:

    [客户端]                          [服务器]
       |                                 |
Port AA|---(1)连接命令端口(21)---------->|Port 21
       |                                 |
Port AA|<--(2)命令响应(200 OK)-----------|Port 21
       |                                 |
Port AA|---(3)PORT命令,告知客户端数据端口Port BB--->|Port 21
       |                                 |
Port AA|<--(4)确认使用PORT命令(200 OK)----|Port 21
       |                                 |
Port BB|<--(5)服务器从端口20向客户端数据端口发起连接---|Port 20
       |                                 |
Port BB|---(6)数据传输开始---------------|Port 20
       |                                 |

在这个过程中:

  1. 客户端随机取一个大于 1024 以上的端口 (Port AA) 连接服务器的 FTP 端口(通常是 21 端口)。
  2. 服务器响应客户端请求,允许命令传输。
  3. 客户端在需要数据的情况下,会告知服务器用什么方式来连接,如果是主动模式 (active) 时,客户端会先随机启用一个端口 (Port BB) ,且通过命令通道告知 FTP 服务器这两个信息,并等待 FTP 服务器的连接。客户端发送 PORT 命令及其数据端口号给服务器。命令格式: PORT 命令的格式通常包括客户端的 IP 地址和数据端口号。格式大致为 PORT h1,h2,h3,h4,p1,p2 ,其中 h1 到 h4 是客户端 IP 地址的四个部分, p1 和 p2 是端口号的两个字节。实际上,端口号由 p1*256 + p2 计算得出。命令发送:客户端通过命令通道发送这个命令给服务器。该命令告诉服务器,客户端已经准备好在指定的端口上接收数据连接。
  4. 服务器确认收到 PORT 命令,并准备连接到客户端指定的数据端口。客户端发送了 PORT 命令之后,在指定的端口上监听来自服务器的连接请求。这意味着客户端必须确保其防火墙和安全设置允许从服务器(特定的 IP 和端口)到该端口的入站连接。
  5. 服务器从其数据端口(通常是 20 端口)连接到客户端的数据端口。
  6. 数据传输开始。

主动模式中, FTP 服务器端使用到的端口主要有:命令通道的 ftp (默认为 Port 21) 与
数据通道的 ftp-data (默认为 Port 20)。这两个端口连接发起端是不一样的,首先 Port 21 主要接受来自客户端的主动连接,而 Port 20 则为 FTP 服务器主动连接至客户端。这样的情况在服务器与客户端两者同时为公共 IP 的互联网上面通常没有太大的问题,不过,如果客户端是在防火墙后端或 NAT 服务器后端,会有什么问题吗?我们回顾一下整个流程,

  1. 客户端与服务器间命令通道的建立:因为 NAT 会主动的记录由内部送往外部的连接信息,而由于命令通道的建立是由客户端向服务器端连接的,因此这一条连接可以顺利建立起来。
  2. 客户端与服务器间数据通道建立时的通知:同样的,客户端主机会先启用 Port BB ,并透过命令通道告知 FTP 服务器,且等待服务器端的主动连接。
  3. 服务器主动连到 NAT 等待转发至客户端的连接问题:由于透过 NAT 的转换后,FTP 服务器只能得知 NAT 的 IP 而不是客户端的 IP ,因此 FTP 服务器会以 Port 20 主动的向 NAT 的 Port BB 发送主动连接的要求。但 NAT 并没有启动 Port BB 来监听 FTP 服务器的连接。

被动模式可以解决这个问题。

在被动模式中,服务器打开两个端口:命令端口和数据端口。服务器会告知客户端数据端口号,客户端将主动连接到这个端口。以下是具体步骤的图解:

    被动模式的FTP连接过程:

    [客户端]                          [服务器]
       |                                 |
Port AA|---(1)连接命令端口(21)---------->|Port 21
       |                                 |
Port AA|<--(2)命令响应(200 OK)-----------|Port 21
       |                                 |
Port AA|---(3)PASV命令请求服务器数据端口--->|Port 21
       |                                 |
Port AA|<--(4)响应PASV命令,提供数据端口号Port PASV---|Port 21
       |                                 |
Port BB|---(5)客户端连接到服务器提供的数据端口--->|Port PASV
       |                                 |
       |---(6)数据传输开始---------------|
       |                                 |

在这个过程中:

  1. 客户端随机取一个大于 1024 以上的端口 (Port AA) 连接服务器的 FTP 端口(通常是21端口)。
  2. 服务器响应客户端请求,允许命令传输。
  3. 当有使用数据通道的指令时,客户端可透过命令通道发出 PASV 的被动式连接要求 (Passive 的缩写),并等待服务器的回应。客户端发送 PASV 命令,请求服务器进入被动模式。
  4. 服务器回应 PASV 命令,并提供一个随机的高端口用于数据传输。如果 FTP 服务器是能够处理被动式连接的,此时 FTP 服务器会先启动一个端口监听。这个端口号可能是随机的,也可以自定义某一范围的端口,看 FTP 服务器软件而定。 然后 FTP 服务器会透过命令通道告知客户端该已经启动的端口 (图中的 Port PASV), 并等待客户端的连接。
  5. 客户端连接到服务器提供的数据端口。
  6. 数据传输开始。

所以,主动模式和被动模式有不同的适用场景,

  • 主动模式:服务器主动连接到客户端提供的数据端口,适合服务器网络环境开放,客户端网络环境受限的场景。
  • 被动模式:客户端主动连接到服务器的数据端口,适合服务器网络环境受限,客户端网络环境开放的场景。

vsftpd 配置实践

vsftpd 是用于类 Unix 系统(包括 Linux)的 FTP 服务器,它最初发展的理念就是建构一个以安全为重的 FTP 服务器。在 Linux 服务器上,可以通过包管理器安装 vsftpd ,如在 CentOS 上使用命令 yum install vsftpd 安装,vsftpd 的主要配置文件是 /etc/vsftpd/vsftpd.conf ,我们来看看它的默认配置,

sudo grep -v '^#' /etc/vsftpd/vsftpd.conf | grep -v '^$'
# 1. 与匿名用户有关的信息
# 支持匿名用户登入使用 FTP 功能
anonymous_enable=YES

# 2. 与实体用户有关的设定
# 支持本地端的实体用户登入
local_enable=YES
# 允许用户上传数据 (包括档案与目录)
write_enable=YES
# 建立新目录 (755) 与档案 (644) 的权限
local_umask=022
# 3. 与服务器环境有关的设定
# 若目录下有 .message 则会显示该档案的内容
dirmessage_enable=YES
# 启动登录文件记录,记录于 /var/log/xferlog
xferlog_enable=YES
# 支持主动式连接功能
connect_from_port_20=YES
# 支持 WuFTP 的登录档格式
xferlog_std_format=YES
# vsftpd 不是以 standalone 的方式来启动
listen=NO
# 如果启用了IPv6支持(通过listen_ipv6=YES),listen=YES应被设置为NO,因为listen_ipv6选项会覆盖listen选项。
listen_ipv6=YES
# 支持 PAM 模块的管理
pam_service_name=vsftpd
# 支持 /etc/vsftpd/user_list 档案内的账号登入管控
userlist_enable=YES
# 支持 TCP Wrappers 的防火墙机制
tcp_wrappers=YES

针对 vsftpd 的一些默认设置选项,我根据自己的需求,修改了以下内容:

  1. 禁止匿名账号 anonymous 登录,默认设置下,匿名账号可以登录,家目录在 /var/ftp ,可以下载 /var/ftp 的数据,无上传权限,已经被 chroot 。虽然可以同时开启实体用户与匿名用户,不过建议服务器还是依据需求,针对单一种身份设定,故设置 anonymous_enable=NO ,只开放实体用户。

  2. 限制登入 FTP 的账号,可以在两个配置文件中设置, /etc/vsftpd/ftpusers 是 PAM 模块的抵挡设定项目,将限制登入 FTP 的账号写入这个文件即可,一行一个账号。 而 /etc/vsftpd/user_list 是 vsftpd 自定义的抵挡项目,它的功能根据 vsftpd.conf 配置文件内的 userlist_deny={YES/NO} 而不同。

我们来对比一下两种设置方法的区别。在默认情况下 userlist_deny=YES ,我们将禁止使用 FTP 的账号写入 /etc/vsftpd/user_list 文件,没有写入 /etc/vsftpd/user_list 的使用者就可以使用 FTP 了,且未来新增的使用者默认都能够使用 FTP 的服务。

# 支持 /etc/vsftpd/user_list 档案内的账号登入管控
userlist_enable=YES
userlist_deny=YES
# 禁止使用 FTP 的账号
userlist_file=/etc/vsftpd/user_list

如果我想只让某些账号可以使用 FTP ,即新增的账号默认不可以使用 FTP 这个服务。那么修改配置文件成为这样:

# 支持 /etc/vsftpd/user_list 档案内的账号登入管控
userlist_enable=YES
userlist_deny=NO
# 可以使用 FTP 的账号
userlist_file=/etc/vsftpd/user_list
  1. 使用本地时间 use_localtime=YES ,vsftpd 默认使用 GMT 时间(格林威治),所以默认的 FTP 内的文件日期会比北京时间晚 8 小时,建议修改为 YES 。

  2. 使用 stand alone 方式启动 vsftpd ,修改命令通道的默认端口。

# 使用 stand alone 方式启动 vsftpd
listen=YES
listen_port=3021
  1. 支持数据流的被动连接模式,指定几个固定范围内的端口来作为 FTP 的被动式数据连接之用,这样我们能够预先知道 FTP 数据连接的端口,用于 FTP 服务的防火墙设置,假设被动连接的端口为 65400 到 65410 这几个端口,可以这样设置:
# 支持数据流的被动连接模式
pasv_enable=YES
pasv_min_port=65400
pasv_max_port=65410
  1. 对使用者 (包括未来新增用户) 进行 chroot ,建议默认让实体用户被 chroot , 而允许不必 chroot 的账号额外设置。
# 针对某些使用者 chroot 的相关设置
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
# 建立不被 chroot 的使用者账号列表,即使没有任何账号,此文件也要存在
[root@host ~]# vim /etc/vsftpd/chroot_list
user01
  1. 增加 /var/log/vsftpd.log 的支持,默认配置下, /var/log/vsftpd.log 不会出现,只有 /var/log/xferlog 。如果你想要加入 /var/log/vsftpd.log 的支持,可以这样设置,
# 增加 /var/log/vsftpd.log 的支持
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log
  1. 给不同的用户设置指定的 FTP 目录,

(1)配置主 vsftpd.conf 文件,在 vsftpd.conf 配置文件中,添加以下设置:

user_sub_token=$USER
# 启用用户配置文件
user_config_dir=/etc/vsftpd/user_conf
# 允许在 chroot 环境中进行写操作
allow_writeable_chroot=YES

(2)创建用户配置文件目录,根据 user_config_dir=/etc/vsftpd/user_conf ,创建目录, sudo mkdir -p /etc/vsftpd/user_conf ,这个目录来存放每个用户的配置文件,这些配置文件允许你为每个用户单独设置 FTP 目录和其他参数。

(3)为每个用户设置 FTP 根目录,你可以为每个用户创建一个配置文件,在其中指定用户的 FTP 根目录。例如,如果你想为用户名为 user01 的用户设置专用的 FTP 目录,可以按以下步骤操作:

首先,创建一个配置文件名与用户名相同,

sudo nano /etc/vsftpd/user_conf/user01

在这个文件中,设置用户的FTP根目录,

# 设置用户的根目录
local_root=/home/user01/ftp

确保指定的目录存在,并设置适当的权限,

sudo mkdir -p /home/user01/ftp
sudo chown user01:user01 /home/user01/ftp
sudo chmod 755 /home/user01/ftp

最后,汇总一下修改后的 vsftpd.conf 配置内容,

# 1. 禁止匿名账号 anonymous 登录使用 FTP 功能
anonymous_enable=NO

# 2. 与实体用户有关的设定
# 支持本地端的实体用户登入
local_enable=YES
# 允许用户上传数据 (包括档案与目录)
write_enable=YES
# 建立新目录 (755) 与档案 (644) 的权限, umask 值定义了文件和目录创建时要被“屏蔽”掉的权限位。它与操作系统中的默认权限(通常为文件是666,目录是777)结合使用来计算新文件和目录的实际权限。默认权限减去 umask 值等于新创建文件或目录的权限。
local_umask=022

# 支持 /etc/vsftpd/user_list 档案内的账号登入管控
userlist_enable=YES
userlist_deny=YES
# 禁止使用 FTP 的账号
userlist_file=/etc/vsftpd/user_list

# 3. 与服务器环境有关的设定
use_localtime=YES
# 若目录下有 .message 则会显示该档案的内容
dirmessage_enable=YES
# 启动登录文件记录,记录于 /var/log/xferlog
xferlog_enable=YES
# 支持主动式连接功能
connect_from_port_20=YES
# 支持 WuFTP 的登录档格式
xferlog_std_format=YES
# 使用 stand alone 方式启动 vsftpd
listen=YES
listen_port=3021
# 支持数据流的被动连接模式
pasv_enable=YES
pasv_min_port=65400
pasv_max_port=65410
# 支持 PAM 模块的管理
pam_service_name=vsftpd
# 支持 TCP Wrappers 的防火墙机制
tcp_wrappers=YES

# 针对某些使用者 chroot 的相关设置
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list

# 增加 /var/log/vsftpd.log 的支持
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log

# 给不同的用户设置指定的 FTP 目录
user_sub_token=$USER
user_config_dir=/etc/vsftpd/user_conf
allow_writeable_chroot=YES

修改配置后,需要重启 vsftpd 服务,以确保所有的更改都已生效。


微信公众号「padluo」,分享数据科学家的自我修养,既然遇见,不如一起成长。关注【老罗说AI】公众号,后台回复【文章】,获得整理好的【老罗说AI】文章全集。

数据分析二维码.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值