Very Secure FTP Daemon
vsftpd(Very Secure FTP Daemon)是一个轻量级、稳定且安全的 UNIX-like 系统 FTP 服务器。
安装
安装 vsftpd 并启动/启用 vsftpd.service
守护进程。
要使用 xinetd 监控和控制 vsftpd 连接,请参阅 #使用 xinetd。
配置
vsftpd 的大多数设置都是通过编辑文件 /etc/vsftpd.conf
完成的。该文件本身有很好的文档记录,因此本节仅突出显示您可能想要修改的一些重要更改。 有关所有可用选项和文档,请参阅 vsftpd.conf(5) man 页面。 默认情况下,文件从 /srv/ftp
提供。
启用连接 /etc/hosts.allow
# Allow all connections vsftpd: ALL # IP address range vsftpd: 10.0.0.0/255.255.255.0
启用上传
必须在 /etc/vsftpd.conf
中将 WRITE_ENABLE
标志设置为 YES,才能允许对文件系统进行更改,例如上传
write_enable=YES
本地用户登录
必须将 /etc/vsftpd.conf
中的 local_enable
行设置为 YES
,才能允许 /etc/passwd
中的用户登录
local_enable=YES
匿名登录
这些行控制是否允许匿名用户登录。 默认情况下,匿名登录仅允许从 /srv/ftp
下载
/etc/vsftpd.conf
... # Allow anonymous FTP? (Beware - allowed by default if you comment this out). anonymous_enable=YES ... # Uncomment this to allow the anonymous FTP user to upload files. This only # has an effect if the above global write enable is activated. Also, you will # obviously need to create a directory writable by the FTP user. #anon_upload_enable=YES # # Uncomment this if you want the anonymous FTP user to be able to create # new directories. #anon_mkdir_write_enable=YES ...
您还可以添加例如以下选项(更多选项请参阅 vsftpd.conf(5))
/etc/vsftpd.conf
# No password is required for an anonymous login no_anon_password=YES # Maximum transfer rate for an anonymous client in Bytes/second anon_max_rate=30000 # Directory to be used for an anonymous login anon_root=/example/directory/
Chroot 监狱
可以设置 chroot 环境,以防止用户离开其主目录。 要启用此功能,请将以下行添加到 /etc/vsftpd.conf
chroot_list_enable=YES chroot_list_file=/etc/vsftpd.chroot_list
chroot_list_file
变量指定包含被 jail 用户的文件的路径。
对于更严格的环境,请指定以下行
chroot_local_user=YES
这将使本地用户默认被 jail。 在这种情况下,由 chroot_list_file
指定的文件列出了未被 chroot jail 的用户。
限制用户登录
可以通过在 /etc/vsftpd.conf
中添加两行来阻止用户登录到 FTP 服务器
userlist_enable=YES userlist_file=/etc/vsftpd.user_list
userlist_file
现在指定了列出无法登录的用户的文件的路径。
如果您只想允许某些用户登录,请添加以下行
userlist_deny=NO
由 userlist_file
指定的文件现在将包含能够登录的用户。
限制连接数
可以通过在 /etc/vsftpd.conf
中添加信息来限制本地用户的数据传输速率,即客户端数量和每个 IP 的连接数
local_max_rate=1000000 # Maximum data transfer rate in bytes per second max_clients=50 # Maximum number of clients that may be connected max_per_ip=2 # Maximum connections per IP
使用 xinetd
Xinetd 为监控和控制连接提供了增强的功能。 但对于基本的良好工作的 vsftpd 服务器来说,这不是必需的。
安装 vsftpd 将添加必要的服务文件 /etc/xinetd.d/vsftpd
。 默认情况下,服务处于禁用状态。 启用 ftp 服务
service ftp { socket_type = stream wait = no user = root server = /usr/bin/vsftpd log_on_success += HOST DURATION log_on_failure += HOST disable = no }
如果您已将 vsftpd 守护进程设置为独立模式运行,请在 /etc/vsftpd.conf
中进行以下更改
listen=NO
否则连接将失败
500 OOPS: could not bind listening IPv4 socket
不要启动 vsftpd 守护进程,而是启动并启用 xinetd.service
。
使用 SSL/TLS 加密 FTP
首先,您需要一个 X.509 SSL/TLS 证书才能使用 TLS。 如果您没有,您可以按如下方式轻松生成自签名证书
# cd /etc/ssl/certs # openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout vsftpd.pem -out vsftpd.pem # chmod 600 vsftpd.pem
系统会询问您有关您公司等的问题。 由于您的证书不是受信任的证书,因此填写什么内容并不重要,它仅用于加密。 要使用受信任的证书,您可以从证书颁发机构(例如 Let's Encrypt)获取一个。
然后,编辑配置文件
/etc/vsftpd.conf
ssl_enable=YES # if you accept anonymous connections, you may want to enable this setting #allow_anon_ssl=NO # by default all non anonymous logins and forced to use SSL to send and receive password and data, set to NO to allow non secure connections force_local_logins_ssl=NO force_local_data_ssl=NO # TLS v1 protocol connections are preferred and this mode is enabled by default while SSL v2 and v3 are disabled # the settings below are the default ones and do not need to be changed unless you specifically need SSL #ssl_tlsv1=YES #ssl_sslv2=NO #ssl_sslv3=NO # provide the path of your certificate and of your private key # note that both can be contained in the same file or in different files rsa_cert_file=/etc/ssl/certs/vsftpd.pem rsa_private_key_file=/etc/ssl/certs/vsftpd.pem # this setting is set to YES by default and requires all data connections exhibit session reuse which proves they know the secret of the control channel. # this is more secure but is not supported by many FTP clients, set to NO for better compatibility require_ssl_reuse=NO
在被动模式下解析主机名
要通过服务器的主机名覆盖 vsftpd 在被动模式下通告的 IP 地址,并在启动时对其进行 DNS 解析,请在 /etc/vsftpd.conf
中添加以下两行
pasv_addr_resolve=YES pasv_address=yourdomain.org
- 对于动态 DNS,不需要定期更新 pasv_address 并重启服务器,因为它有时可以被读取。
- 您可能无法再通过 LAN 在被动模式下连接,在这种情况下,请尝试从 LAN 客户端使用主动模式。
端口配置
可能需要调整默认的 FTP 监听端口和被动模式数据端口。 这是一种在服务器位于 NAT 后解决流量问题的方法
- 对于暴露于 Web 的 FTP 服务器,为了降低服务器受到攻击的可能性,可以将监听端口更改为标准端口 21 以外的其他端口。
- 要限制被动模式端口为开放端口,可以提供一个范围。
可以在配置文件中定义端口,如下所示
/etc/vsftpd.conf
listen_port=2211 pasv_min_port=5000 pasv_max_port=5003
配置 iptables
通常,运行 FTP 守护进程的服务器受到 iptables 防火墙的保护。 要允许访问 FTP 服务器,需要使用类似以下命令打开相应的端口
# iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
本文不提供有关如何设置 iptables 的任何说明,但这里有一个示例:简单状态防火墙。
iptables 正确处理 FTP 连接需要一些内核模块,应在此处引用。 其中特别重要的是 nf_conntrack_ftp。 这是必需的,因为 FTP 仅将给定的 listen_port(默认为 21)用于命令;所有数据传输都通过不同的端口完成。 这些端口由 FTP 守护进程随机选择,并且每个会话都不同(也取决于使用主动模式还是被动模式)。 要告诉 iptables 应该接受端口上的数据包,需要 nf_conntrack_ftp。 您可以显式地在启动时加载模块。
如果内核 >= 4.7,您需要通过 sysctl 设置 net.netfilter.nf_conntrack_helper=1,例如
# echo net.netfilter.nf_conntrack_helper=1 > /etc/sysctl.d/70-conntrack.conf
或使用
# iptables -A PREROUTING -t raw -p tcp --dport 21 -j CT --helper ftp
技巧与诀窍
PAM 与虚拟用户
由于 PAM 不再提供 pam_userdb.so
,因此另一种简单的方法是使用 libpam_pwdfileAUR。 本节仅限于解释如何配置 chroot 环境以及通过 pam_pwdfile.so
进行身份验证。
在本示例中,我们创建目录 vsftpd
# mkdir /etc/vsftpd
创建和存储用户名和密码的一种选择是使用 Apache 生成器 htpasswd
# htpasswd -c /etc/vsftpd/.passwd <username>
将 <username>
替换为您要创建的用户名。
上述命令的一个问题是 vsftpd 可能无法读取生成的 MD5 哈希密码。 如果使用 -d 开关运行相同的命令,crypt() 加密,密码将变为 vsftpd 可读,但这方面的缺点是安全性降低,并且密码限制为 8 个字符。 Openssl 可以用于生成带有算法 1 的基于 MD5 的 BSD 密码
# openssl passwd -1
无论哪种解决方案,生成的 /etc/vsftpd/.passwd
都应如下所示
username1:hashed_password1 username2:hashed_password2 ...
接下来,您需要使用 pam_pwdfile.so
和生成的 /etc/vsftpd/.passwd
文件创建 PAM 服务。 在此示例中,我们为 vsftpd 创建了一个 PAM 策略,其内容如下
/etc/pam.d/vsftpd
auth required pam_pwdfile.so pwdfile /etc/vsftpd/.passwd account required pam_permit.so
现在是时候为虚拟用户创建主目录了。 在示例中,决定使用 /srv/ftp
托管虚拟用户的数据,这也反映了 Arch 的默认目录结构。 首先创建通用用户 virtual 并使 /srv/ftp
作为其主目录
# useradd -d /srv/ftp virtual
使 virtual 成为所有者
# chown virtual:virtual /srv/ftp
一个基本的 /etc/vsftpd.conf
,未配置私有文件夹,这将默认为虚拟用户的主文件夹
listen=YES listen 21 connect_from_port_20=YES # sample config file enables it, ftp data dirmessage_enable=YES # sample config data enables it xferlog_enable=YES # sample config data enables it pam_service_name=vsftpd # pointing to the correct PAM service file `/etc/pam.d/vsftpd` rather than `/etc/pam.d/ftp` anonymous_enable=NO # we does not use anonymous mode local_enable=YES # we config virtual user use local privileges, virtual_use_local_privs=YES write_enable=YES # global config, write to filesystem hide_ids=YES # in ftp client interactive console, ls -la: uid=1001 -> ftp chroot_local_user=YES # we do not want user to get the real root(/) directory guest_enable=YES # for virtual user guest_username=virtual # virtual user name: virtual virtual_use_local_privs=YES # permission of virtual user=local user
有关上述选项的更详细含义,请参阅 vsftpd.conf(5) man 页面。
某些参数对于您自己的设置可能不是必需的。 如果您希望 chroot 环境可写,则需要在配置文件中添加以下内容
allow_writeable_chroot=YES
否则,如果 vsftpd 检测到 chroot 是可写的,由于默认安全设置,它会报错。
启动 vsftpd.service
。
现在您应该能够使用 ftp 客户端和存储在 /etc/vsftpd/.passwd
中的任何用户和密码登录。
为虚拟用户添加私有文件夹
首先为用户创建目录
# mkdir /srv/ftp/user1 # mkdir /srv/ftp/user2 # chown virtual:virtual /srv/ftp/user?/
然后,将以下行添加到 /etc/vsftpd.conf
local_root=/srv/ftp/$USER user_sub_token=$USER
故障排除
vsftpd:拒绝在 chroot() 中以可写 root 身份运行
从 vsftpd 2.3.5 开始,用户被锁定到的 chroot 目录必须不可写。 这是为了防止安全漏洞。
启用 chroot 并配置您的 FTP 目录是允许上传的安全方法。
local_root=/srv/ftp/user
# mkdir -p /srv/ftp/user/upload # chmod 550 /srv/ftp/user # chmod 750 /srv/ftp/user/upload
如果您必须
您可以将此添加到您的 /etc/vsftpd.conf
中,以解决此安全增强功能(自 vsftpd 3.0.0 起;来自 Fixing 500 OOPS: vsftpd: refusing to run with writable root inside chroot ())
allow_writeable_chroot=YES
FileZilla 客户端:通过 SSL 连接时出现 GnuTLS 错误 -8 -15 -110
vsftpd 尝试在 SSL 会话中显示纯文本错误消息。为了调试此问题,请暂时禁用加密,您将看到正确的错误消息。[1]
通常,这些错误可以通过添加 [2] 来解决:seccomp_sandbox=NO
vsftpd.service 启动时运行失败
如果您已启用 vsftpd.service
,但它在启动时运行失败,请编辑它,并确保在服务文件中将其设置为在 network.target
之后加载
vsftpd.service
[Unit] Description=vsftpd daemon After=network.target
被动模式回复远程连接本地 IP 地址
如果 vsftpd 向远程连接返回本地地址,例如
227 Entering Passive Mode (192,168,0,19,192,27).
可能是 FTP 服务器位于 NAT 路由器之后,虽然有些设备会监控 FTP 连接并动态地将包含 PASV 响应的数据包的本地 IP 地址规范替换为外部 IP 地址,但有些设备不会。
在 vsftpd 配置中使用以下内容指示外部 IP 地址
pasv_address=externalIPaddress
或者,也可以使用
pasv_addr_resolve=YES pasv_address=my.domain.name
如果在此更改后无法进行内部连接,则可能需要运行 2 个 vsftpd,一个用于内部连接,一个用于外部连接。
ipv6 only 失败,并显示:500 OOPS: run two copies of vsftpd for IPv4 and IPv6
您很可能注释掉了以下行
# When "listen" directive is enabled, vsftpd runs in standalone mode and # listens on IPv4 sockets. This directive cannot be used in conjunction # with the listen_ipv6 directive. #listen=YES # # This directive enables listening on IPv6 sockets. To listen on IPv4 and IPv6 # sockets, you must run two copies of vsftpd with two configuration files. # Make sure, that one of the listen options is commented !! listen_ipv6=YES
而不是设置
# When "listen" directive is enabled, vsftpd runs in standalone mode and # listens on IPv4 sockets. This directive cannot be used in conjunction # with the listen_ipv6 directive. listen=NO
使用 nis 的机器上 vsftpd 连接失败,并显示:yp_bind_client_create_v2: RPC: Unable to send
正如 vsftpd faq 页面上提到的,“...内置沙箱在 Linux 上使用网络隔离。这可能会干扰任何需要使用网络执行操作或查找的模块”
将此未记录的行添加到您的 /etc/vsftpd.conf
isolate_network=NO
LIST 命令重置连接
在 vsftpd.conf
文件中添加
seccomp_sandbox=NO
可以解决此问题。
加固
就像任何其他服务一样,可以通过修改其 systemd 单元来加固 VSFTPD。加固在文献中也称为沙箱化。以下沙箱选项是限制系统暴露于单元进程的有效方法。
以下是加固的 drop-in 文件的示例。根据您的喜好调整以下文件
/etc/systemd/system/vsftpd.service.d/harden.conf
[Service] PrivateTmp = true ProtectSystem = strict ProtectHome = true ProtectKernelTunables = true ReadWritePaths=/srv/ftp /mnt/cctv /var/log/vsftpd.log ReadOnlyPaths = /mnt InaccessiblePaths = /mnt/mybackup
这将允许 VSFTPD 仅写入 /srv/ftp
、/mnt/cctv
和其自己的日志文件,并将限制写入文件系统的其余部分。它还将拒绝访问整个 /home
。这也限制了对 /mnt/mybackup
的任何访问。可以为此选项指定多个路径。
有关 systemd 沙箱选项的更多详细信息,请参见 systemd.exec(5) § SANDBOXING。