Very Secure FTP Daemon

来自 ArchWiki

vsftpdVery Secure FTP Daemon)是一个轻量级、稳定且安全的 UNIX-like 系统 FTP 服务器。

安装

安装 vsftpd启动/启用 vsftpd.service 守护进程。

要使用 xinetd 监控和控制 vsftpd 连接,请参阅 #使用 xinetd

配置

vsftpd 的大多数设置都是通过编辑文件 /etc/vsftpd.conf 完成的。该文件本身有很好的文档记录,因此本节仅突出显示您可能想要修改的一些重要更改。 有关所有可用选项和文档,请参阅 vsftpd.conf(5) man 页面。 默认情况下,文件从 /srv/ftp 提供。

本文或章节已过时。

原因: 我认为此信息已弃用。 libwrap/tcp-wrappers 不是 vsftpd 的依赖项,默认情况下未安装。 最好配置防火墙规则来限制访问。(在 Talk:Very Secure FTP Daemon 中讨论)

启用连接 /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

本文或章节需要语言、wiki 语法或风格改进。 请参阅 Help:Style 以供参考。

原因: 不要重复 OpenSSL#Usage。(在 Talk:Very Secure FTP Daemon 中讨论)

首先,您需要一个 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
提示: 当位于 NAT 后时,请记住修改防火墙以打开这些端口。

配置 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,一个用于内部连接,一个用于外部连接。

提示: 要 выяснить NAT 路由器是否拦截 PASV 响应并将内部 IP 替换为外部 IP,可以检查 TLS 模式下客户端的服务器响应。路由器无法识别加密的数据包,因此不会被修改。

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

另请参阅