如何在Ubuntu20.04上为用户目录设置vsftpd

来自菜鸟教程
跳转至:导航、​搜索

介绍

FTP是File Transfer Protocol的缩写,是一种网络协议,曾经被广泛用于在客户端和服务器之间移动文件。 FTP 仍用于支持具有非常特殊需求的遗留应用程序和工作流。 如果您可以选择协议,请考虑更高效、更安全且更方便地传递文件的现代选项。 例如,使用 https 直接从 Web 浏览器下载的 Internet 用户,以及使用 scpSFTP 等安全协议的命令行用户。

vsftpd, 非常安全的 FTP 守护程序 ,是许多类 Unix 系统(包括 Linux)的 FTP 服务器,并且通常也是许多 Linux 发行版的默认 FTP 服务器。 vsftpd 有利于优化安全性、性能和稳定性。 它还针对其他 FTP 服务器中发现的安全问题提供了强大的保护。 vsftpd 可以处理虚拟 IPD 配置、与 SSL 集成的加密支持等等。

在本教程中,您将配置 vsftpd 以允许用户使用由 SSL/TLS 保护的登录凭据使用 FTP 将文件上传到他们的主目录。 您还将使用开源 FTP 客户端 FileZilla 连接您的服务器,以测试 TLS 加密。

先决条件

要学习本教程,您需要:

  • 您需要的第一件事是 Ubuntu 20.04 服务器、具有 sudo 权限的非 root 用户和启用的防火墙。 您可以在我们的 Initial Server Setup with Ubuntu 20.04 指南中了解有关如何执行此操作的更多信息。
  • 您需要的第二件事是 FileZilla,这是一个开源 FTP 客户端,已在您的本地计算机上安装和配置。 这将允许您测试客户端是否可以通过 TLS 连接到您的服务器。 您可以从此 tutorial 中找到在 Debian 和 Ubuntu 系统上安装 FileZilla 的说明,以及在其他系统上安装它的说明的链接。

第 1 步 — 安装 vsftpd

首先更新您的软件包列表:

sudo apt update

接下来,安装 vsftpd 守护进程:

sudo apt install vsftpd

安装完成后,复制配置文件,这样您就可以从空白配置开始,同时将原始配置保存为备份:

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.orig

备份配置后,您就可以配置防火墙了。

第 2 步 — 打开防火墙

首先,检查防火墙状态以查看它是否已启用。 如果是,那么您将进行调整以确保允许 FTP 流量,以便防火墙规则不会阻止测试。

检查防火墙状态:

sudo ufw status

此输出显示防火墙处于活动状态,仅允许 SSH 通过:

OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

您可能有其他规则或根本没有防火墙规则。 由于只允许 SSH 流量,因此您需要为 FTP 流量添加规则。

首先打开端口 2021990,以便在启用 TLS 时它们准备就绪:

sudo ufw allow 20,21,990/tcp

接下来,为您将在配置文件中设置的被动端口范围打开端口 40000-50000

sudo ufw allow 40000:50000/tcp

检查防火墙的状态:

sudo ufw status

您的防火墙规则的输出现在应该如下所示:

OutputStatus: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
20,21,990/tcp              ALLOW       Anywhere
40000:50000/tcp            ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
20,21,990/tcp (v6)         ALLOW       Anywhere (v6)
40000:50000/tcp (v6)       ALLOW       Anywhere (v6)

安装了 vsftpd 并打开了必要的端口,现在是时候创建一个专用的 FTP 用户了。

第 3 步 — 准备用户目录

在此步骤中,您将创建一个专用的 FTP 用户。 但是,您可能已经有一个用户需要 FTP 访问。 本指南概述了如何保留现有用户对其数据的访问权限,但即便如此,我们还是建议您从新的专用 FTP 用户开始,直到您配置并测试了您的设置,然后再重新配置任何现有用户。

首先添加一个测试用户:

sudo adduser sammy

出现提示时分配密码。 随意按 ENTER 跳过以下提示,因为这些细节对于此步骤的目的并不重要。

当用户被限制在特定目录时,FTP 通常更安全。 vsftpd 使用 chroot 监狱来实现这一点。 当为本地用户启用 chroot 时,默认情况下他们被限制在他们的主目录中。 由于 vsftpd 以特定方式保护目录,因此它不能被用户写入。 这对于应该只通过 FTP 连接的新用户来说很好,但如果现有用户也有 shell 访问权限,他们可能需要写入他们的主文件夹。

在此示例中,不是从主目录中删除写权限,而是创建一个 ftp 目录作为 chroot 和一个可写的 files 目录来保存实际文件。

创建 ftp 文件夹:

sudo mkdir /home/sammy/ftp

设置其所有权:

sudo chown nobody:nogroup /home/sammy/ftp

删除写权限:

sudo chmod a-w /home/sammy/ftp

验证权限:

sudo ls -la /home/sammy/ftp
Outputtotal 8
dr-xr-xr-x 2 nobody nogroup 4096 Sep 14 20:28 .
drwxr-xr-x 3 sammy sammy  4096 Sep 14 20:28 ..

接下来,创建文件上传目录:

sudo mkdir /home/sammy/ftp/files

然后将所有权分配给用户:

sudo chown sammy:sammy /home/sammy/ftp/files

ftp 目录的权限检查应返回以下输出:

sudo ls -la /home/sammy/ftp
Outputtotal 12
dr-xr-xr-x 3 nobody nogroup 4096 Sep 14 20:30 .
drwxr-xr-x 3 sammy sammy  4096 Sep 14 20:28 ..
drwxr-xr-x 2 sammy sammy  4096 Sep 14 20:30 files

最后,添加一个 test.txt 文件用于测试:

echo "vsftpd test file" | sudo tee /home/sammy/ftp/files/test.txt
Outputvsftpd test file

现在您已经保护了 ftp 目录并允许用户访问 files 目录,接下来您将修改我们的配置。

第 4 步 — 配置 FTP 访问

在此步骤中,您将允许具有本地 shell 帐户的单个用户连接 FTP。 在 vsftpd.conf 中已经设置了这两个键的设置。 使用您喜欢的文本编辑器打开此文件。 在这里,我们将使用 nano

sudo nano /etc/vsftpd.conf

打开文件后,确认 anonymous_enable 指令设置为 NO 并且 local_enable 指令设置为 YES

/etc/vsftpd.conf

. . .
# Allow anonymous FTP? (Disabled by default).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
. . .

这些设置分别阻止匿名登录和允许本地登录。 请记住,启用本地登录意味着 /etc/passwd 文件中列出的任何普通用户都可以用于登录。

某些 FTP 命令允许用户添加、更改或删除文件系统上的文件和目录。 通过取消注释 write_enable 设置来启用这些命令。 您可以通过删除此指令前面的井号 (#) 来做到这一点:

/etc/vsftpd.conf

. . .
write_enable=YES
. . .

取消注释 chroot 以防止 FTP 连接的用户访问目录树之外的任何文件或命令:

/etc/vsftpd.conf

. . .
chroot_local_user=YES
. . .

接下来,添加一个 user_sub_token 指令,其值为 $USER 环境变量。 然后添加一个 local_root 指令并将其设置为显示的路径,其中还包括 $USER 环境变量。 此设置确保配置将允许此用户和未来用户在登录时被路由到相应用户的主目录。 在文件中的任意位置添加这些设置:

/etc/vsftpd.conf

. . .
user_sub_token=$USER
local_root=/home/$USER/ftp

限制可用于被动 FTP 的端口范围,以确保有足够的连接可用:

/etc/vsftpd.conf

. . .
pasv_min_port=40000
pasv_max_port=50000

注意: 在第 2 步中,您打开了在此处为被动端口范围设置的端口。 如果您更改这些值,请务必更新您的防火墙设置。


要根据具体情况允许 FTP 访问,请设置配置,以便用户仅在显式添加到列表时才具有访问权限,而不是默认情况下:

/etc/vsftpd.conf

. . .
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

userlist_deny 切换逻辑:当设置为 YES 时,列表中的用户被拒绝 FTP 访问; 当设置为 NO 时,仅允许列表中的用户访问。

完成更改后,保存文件并退出编辑器。 如果您使用 nano 编辑文件,您可以按 CTRL + XY,然后按 ENTER 进行编辑。

最后,将您的用户添加到 /etc/vsftpd.userlist。 使用 -a 标志附加到文件:

echo "sammy" | sudo tee -a /etc/vsftpd.userlist

检查它是否按预期添加:

cat /etc/vsftpd.userlist
Outputsammy

重新启动守护程序以加载配置更改:

sudo systemctl restart vsftpd

配置到位后,现在您可以测试 FTP 访问。

第 5 步 — 测试 FTP 访问

我们已将服务器配置为仅允许用户 sammy 通过 FTP 连接。 现在我们将确保它按预期工作。

由于您已禁用匿名访问,您可以通过尝试匿名连接来测试它。 如果配置设置正确,则应拒绝匿名用户的权限。 打开另一个终端窗口并运行以下命令。 请务必将 203.0.113.0 替换为您服务器的公共 IP 地址:

ftp -p 203.0.113.0

当提示输入用户名时,尝试以不存在的用户身份登录,例如 anonymous,您将收到以下输出:

OutputConnected to 203.0.113.0.
220 (vsFTPd 3.0.3)
Name (203.0.113.0:default): anonymous
530 Permission denied.
ftp: Login failed.
ftp>

关闭连接:

bye

sammy 以外的用户也应该无法连接。 尝试以您的 sudo 用户身份连接。 他们也应该被拒绝访问,并且应该在他们被允许输入密码之前发生:

ftp -p 203.0.113.0
OutputConnected to 203.0.113.0.
220 (vsFTPd 3.0.3)
Name (203.0.113.0:default): sudo_user
530 Permission denied.
ftp: Login failed.
ftp>

关闭连接:

bye

另一方面,用户 sammy 应该能够连接、读取和写入文件。 确保您指定的 FTP 用户可以连接:

ftp -p 203.0.113.0
OutputConnected to 203.0.113.0.
220 (vsFTPd 3.0.3)
Name (203.0.113.0:default): sammy
331 Please specify the password.
Password: your_user's_password
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

现在切换到 files 目录:

cd files
Output250 Directory successfully changed.

接下来,运行 get 将您之前创建的测试文件传输到本地计算机:

get test.txt
Output227 Entering Passive Mode (203,0,113,0,169,12).
150 Opening BINARY mode data connection for test.txt (17 bytes).
226 Transfer complete.
17 bytes received in 0.00 secs (4.5496 kB/s)
ftp>

接下来,使用新名称上传文件以测试写入权限:

put test.txt upload.txt
Output227 Entering Passive Mode (203,0,113,0,164,71).
150 Ok to send data.
226 Transfer complete.
17 bytes sent in 0.00 secs (5.3227 kB/s)

关闭连接:

bye

现在您已经测试了您的配置,接下来您将采取措施进一步保护您的服务器。

第 6 步 — 保护交易

由于 FTP 对传输中的任何数据(包括用户凭据)进行加密,因此您可以启用 TLS/SSL 来提供该加密。 第一步是创建用于 vsftpd 的 SSL 证书。

使用 openssl 创建新证书并使用 -days 标志使其有效期为一年。 在同一命令中,添加一个私有 2048 位 RSA 密钥。 通过将 -keyout-out 标志设置为相同的值,私钥和证书将位于同一个文件中:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem

系统将提示您提供证书的地址信息。 用您自己的信息替换突出显示的值:

OutputGenerating a 2048 bit RSA private key
............................................................................+++
...........+++
writing new private key to '/etc/ssl/private/vsftpd.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:NY
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []: your_server_ip
Email Address []:

有关证书标志的更多详细信息,请阅读 OpenSSL Essentials:使用 SSL 证书、私钥和 CSR

创建证书后,再次打开 vsftpd 配置文件:

sudo nano /etc/vsftpd.conf

在文件的底部,将有两行以 rsa_ 开头。 通过在每行前面加上井号 (#) 将它们注释掉:

/etc/vsftpd.conf

. . .
# rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
# rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
. . .

在这些行之后,添加指向您创建的证书和私钥的以下行:

/etc/vsftpd.conf

. . .
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
. . .

现在您将强制使用 SSL,这将阻止无法处理 TLS 的客户端进行连接。 这对于确保所有流量都被加密是必要的,但它可能会迫使您的 FTP 用户更改客户端。 将 ssl_enable 更改为 YES

/etc/vsftpd.conf

. . .
ssl_enable=YES
. . .

接下来,添加以下行以明确拒绝通过 SSL 的匿名连接,并要求 SSL 用于数据传输和登录:

/etc/vsftpd.conf

. . .
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
. . .

然后通过添加以下行将服务器配置为使用 TLS(SSL 的首选继任者):

/etc/vsftpd.conf

. . .
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
. . .

最后,添加两个最终选项。 第一个不需要 SSL 重用,因为它可以破坏许多 FTP 客户端。 第二个将需要“高”加密密码套件,这目前意味着密钥长度等于或大于 128 位:

/etc/vsftpd.conf

. . .
require_ssl_reuse=NO
ssl_ciphers=HIGH
. . .

以下是完成所有这些更改后文件的这一部分应如何显示:

/etc/vsftpd.conf

# This option specifies the location of the RSA certificate to use for SSL
# encrypted connections.
#rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH

完成后,保存并关闭文件。 如果您使用 nano,您可以按 CTRL + XY,然后按 ENTER 退出。

重新启动服务器以使更改生效:

sudo systemctl restart vsftpd

此时,您将无法再连接不安全的命令行客户端。 如果您尝试过,您会收到以下消息:

Outputftp -p 203.0.113.0
Connected to 203.0.113.0.
220 (vsFTPd 3.0.3)
Name (203.0.113.0:default): sammy
530 Non-anonymous sessions must use encryption.
ftp: Login failed.
421 Service not available, remote server has closed connection
ftp>

接下来,验证您是否可以使用支持 TLS 的客户端(例如 FileZilla)进行连接。

第 7 步 — 使用 FileZilla 测试 TLS

大多数现代 FTP 客户端都可以配置为使用 TLS 加密。 出于我们的目的,我们将演示如何与 FileZilla 连接,因为它具有跨平台支持。 查阅其他客户端的文档。

当您第一次打开 FileZilla 时,找到位于单词 Host 上方的 Site Manager 图标,即顶行最左侧的图标。 单击此按钮:

将打开一个新窗口。 点击右下角的【X10X】新建站点【X22X】按钮:

My Sites 下将出现一个带有 New Site 字样的新图标。 您可以现在命名或稍后返回并使用 Rename 按钮。

使用名称或 IP 地址填写 Host 字段。 在 Encryption 下拉菜单下,选择 Require explicit FTP over TLS

对于登录类型,选择询问密码。 在 User 字段中填写您的 FTP 用户:

点击界面下方的【X10X】连接【X21X】按钮。 您将被要求输入用户密码:

选择OK进行连接。 您现在应该使用 TLS/SSL 加密连接到您的服务器。

接下来,您将看到如下所示的服务器证书:

当您接受证书后,双击 files 文件夹并将 upload.txt 拖到左侧以确认您可以下载文件:

完成后,右键单击本地副本,将其重命名为 upload-tls.txt 并将其拖回服务器以确认您可以上传文件:

您现在已确认您可以在启用 SSL/TLS 的情况下安全且成功地传输文件。

第 8 步 — 禁用 Shell 访问(可选)

如果由于客户端要求而无法使用 TLS,则可以通过禁用 FTP 用户以任何其他方式登录的能力来获得一些安全性。 防止它的一种方法是创建自定义外壳。 尽管这不会提供任何加密,但可能值得这样做以限制受感染帐户对 FTP 可访问的文件的访问。

首先,在bin目录下打开一个名为ftponly的文件:

sudo nano /bin/ftponly

添加一条消息,告诉用户他们无法登录的原因:

/bin/ftponly

#!/bin/sh
echo "This account is limited to FTP access only."

保存文件并退出编辑器。 如果您使用 nano,您可以按 CTRL + XY,然后按 ENTER 退出。

然后,更改权限以使文件可执行:

sudo chmod a+x /bin/ftponly

打开有效 shell 列表:

sudo nano /etc/shells

在底部添加:

/etc/shells

. . .
/bin/ftponly

使用以下命令更新用户的 shell:

sudo usermod sammy -s /bin/ftponly

现在,尝试以 sammy 身份登录您的服务器:

ssh sammy@your_server_ip

您将收到以下消息:

OutputThis account is limited to FTP access only.
Connection to 203.0.113.0 closed.

这确认用户不能再 ssh 访问服务器,并且仅限于 FTP 访问。 请注意,如果您在登录服务器时收到错误消息,这可能意味着您的服务器不接受密码验证。 使用基于密码的身份验证会使您的服务器容易受到攻击,这就是您可能要考虑禁用密码身份验证的原因。 如果您已经配置了基于 SSH 密钥的身份验证,您可以在 本教程的第 4 步 中了解有关如何在服务器上禁用密码身份验证的更多信息。

结论

在本教程中,我们解释了如何为具有本地帐户的用户设置 FTP。 如果您需要使用外部身份验证源,您可能需要探索 vsftpd 对虚拟用户的支持。 这通过使用 PAM、可插入身份验证模块 提供了一组丰富的选项,如果您在另一个系统(例如 LDAP 或 Kerberos)中管理用户,这是一个不错的选择。 您还可以阅读有关 vsftpd 功能、最新版本和更新 以了解更多信息。