介绍
FTP 简称为 File Transfer Protocol,是一种网络协议,曾经被广泛用于在客户端和服务器之间移动文件。 FTP 仍然用于支持具有非常具体需求的旧应用程序和工作流程. 如果您有协议的选择,请考虑现代选项,这些选项更高效,更安全,更方便地交付文件。例如,互联网用户直接从他们的 Web 浏览器下载到 https,以及使用安全协议的命令行用户如 scp 或 SFTP(https://andsky.com/tech/tutorials/how-to-use-sftp-to-securely-transfer-files-with-a-remote-server)。
vsftpd 是许多 Unix 类型系统的 FTP 服务器,包括 Linux,并且常常是许多 Linux 发行版的默认 FTP 服务器。 vsftpd 对优化安全性、性能和稳定性有益。
在本教程中,您将配置 vsftpd 以允许用户将文件上传到其主目录使用 FTP 与 SSL/TLS 安全登录凭证. 您还将使用 FileZilla 连接您的服务器,一个开源 FTP 客户端,以测试 TLS 加密。
前提条件
要跟随这个教程,你需要:
- 您需要的第一件事是Ubuntu 20.04服务器,具有 sudo 特权的非根用户,并启用了防火墙。您可以在我们的 初始服务器设置与Ubuntu 20.04]指南中了解更多有关如何做到这一点. *您需要的第二件事是FileZilla,一个开源的FTP客户端,安装和配置在您的本地机器上。这将允许您测试客户端是否可以通过TLS连接到您的服务器。您可以从本教程(https://docs.digitalocean.com/products/droplets/how-to/transfer-files/#install-filezilla)找到在Debian和Ubuntu系统上安装FileZilla的说明,以及安装在其他系统上的说明
步骤 1 – 安装 vsftpd
开始更新您的包列表:
1sudo apt update
接下来,安装vsftpd
DAEMON:
1sudo apt install vsftpd
安装完成后,复制配置文件,以便您可以从空格配置开始,同时将原始文件保存为备份:
1sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.orig
有了配置的备份,您已经准备好配置防火墙。
第2步:打开防火墙
首先,检查防火墙的状态,看看是否已启用,如果是,则将进行调整,以确保FTP流量被允许,以便防火墙规则不会阻止测试。
检查防火墙状态:
1sudo ufw status
此输出显示,防火墙是活跃的,只有通过SSH才允许:
1[secondary_label Output]
2Status: active
3
4To Action From
5-- ------ ----
6OpenSSH ALLOW Anywhere
7OpenSSH (v6) ALLOW Anywhere (v6)
您可能有其他规则或根本没有防火墙规则,因为只允许SSH流量,您需要为FTP流量添加规则。
首先,打开20
、21
和990
端口,以便在启用 TLS 后完成操作:
1sudo ufw allow 20,21,990/tcp
接下来,为您在配置文件中设置的被动端口范围打开40000-50000
端口:
1sudo ufw allow 40000:50000/tcp
检查你的防火墙的状态:
1sudo ufw status
您的防火墙规则的输出现在应该如下:
1[secondary_label Output]
2Status: active
3
4To Action From
5-- ------ ----
6OpenSSH ALLOW Anywhere
720,21,990/tcp ALLOW Anywhere
840000:50000/tcp ALLOW Anywhere
9OpenSSH (v6) ALLOW Anywhere (v6)
1020,21,990/tcp (v6) ALLOW Anywhere (v6)
1140000:50000/tcp (v6) ALLOW Anywhere (v6)
有了安装的vsftpd
和打开所需的端口,现在是时候创建一个专用的FTP用户了。
步骤三:准备用户目录
在此步骤中,您将创建一个专用 FTP 用户. 然而,您可能已经有一个需要 FTP 访问的用户. 本指南概述了如何保护现有用户对其数据的访问权限,但即使如此,我们建议您从一个新的专用 FTP 用户开始,直到您在重新配置任何现有用户之前配置并测试您的设置。
首先,添加一个测试用户:
1sudo adduser sammy
当被提示时分配密码. 请轻松按ENTER
,跳过以下提示,因为这些细节对于本步骤的目的并不重要。
当用户被限制在特定目录时,FTP通常更安全。 vsftpd
通过 chroot
监狱实现了这一点. 当为本地用户启用 chroot
时,用户默认情况下被限制在其主目录中。由于 vsftpd
以特定方式保护目录,用户不应该能够写它。 这对新用户来说是很好的,他们只需通过 FTP 连接,但如果他们也有壳访问,现有用户可能需要写到他们的主目录。
在本示例中,而不是从主目录中删除写权限,请创建一个ftp
目录作为chroot
目录和一个可写的files
目录来存储实际文件。
创建FTP
文件夹:
1sudo mkdir /home/sammy/ftp
设定其所有权:
1sudo chown nobody:nogroup /home/sammy/ftp
删除写权限:
1sudo chmod a-w /home/sammy/ftp
查看许可证:
1sudo ls -la /home/sammy/ftp
1[secondary_label Output]
2total 8
3dr-xr-xr-x 2 nobody nogroup 4096 Sep 14 20:28 .
4drwxr-xr-x 3 sammy sammy 4096 Sep 14 20:28 ..
接下来,创建文件上传的目录:
1sudo mkdir /home/sammy/ftp/files
然后将所有权分配给用户:
1sudo chown sammy:sammy /home/sammy/ftp/files
在ftp
目录上的权限检查应返回以下输出:
1sudo ls -la /home/sammy/ftp
1[secondary_label Output]
2total 12
3dr-xr-xr-x 3 nobody nogroup 4096 Sep 14 20:30 .
4drwxr-xr-x 3 sammy sammy 4096 Sep 14 20:28 ..
5drwxr-xr-x 2 sammy sammy 4096 Sep 14 20:30 files
最后,添加一个test.txt
文件用于测试:
1echo "vsftpd test file" | sudo tee /home/sammy/ftp/files/test.txt
1[secondary_label Output]
2vsftpd test file
现在你已经保护了ftp
目录并允许用户访问文件
目录,接下来你将更改我们的配置。
步骤 4 – 配置 FTP 访问
在此步骤中,您将允许一个具有本地壳帐户的单个用户连接到 FTP. 这两个关键设置已经设置在 vsftpd.conf
. 使用您偏好的文本编辑器打开此文件. 在这里,我们将使用 nano
:
1sudo nano /etc/vsftpd.conf
打开文件后,请确认匿名_允许
指令设置为NO
,本地_允许
指令设置为YES
:
1[label /etc/vsftpd.conf]
2. . .
3# Allow anonymous FTP? (Disabled by default).
4anonymous_enable=NO
5#
6# Uncomment this to allow local users to log in.
7local_enable=YES
8. . .
这些设置防止匿名登录,并允许本地登录,分别. 请记住,启用本地登录意味着在 `/etc/passwd 文件中列出的任何正常用户都可以使用登录。
一些 FTP 命令允许用户在文件系统中添加、更改或删除文件和目录. 通过不评论writ_enable
设置,启用这些命令。
1[label /etc/vsftpd.conf]
2. . .
3write_enable=YES
4. . .
删除chroot
,以防止 FTP 连接的用户访问目录树以外的任何文件或命令:
1[label /etc/vsftpd.conf]
2. . .
3chroot_local_user=YES
4. . .
接下来,添加一个user_sub_token
指令,其值是$USER
环境变量,然后添加一个local_root
指令,并将其设置为显示的路径,其中还包括$USER
环境变量。
1[label /etc/vsftpd.conf]
2. . .
3user_sub_token=$USER
4local_root=/home/$USER/ftp
限制可以用于被动FTP的端口范围,以确保足够的连接可用:
1[label /etc/vsftpd.conf]
2. . .
3pasv_min_port=40000
4pasv_max_port=50000
<$>[注] **注:**在步骤2中,您打开了这里为被动端口范围设置的端口。
若要根据具体情况允许 FTP 访问,请设置配置以便用户仅在明确添加到列表时才能访问,而不是默认情况下:
1[label /etc/vsftpd.conf]
2. . .
3userlist_enable=YES
4userlist_file=/etc/vsftpd.userlist
5userlist_deny=NO
userlist_deny
会改变逻辑:当设置为YES
时,列表中的用户将被拒绝FTP访问;当设置为NO
时,只有列表中的用户才允许访问。
完成更改后,保存文件并退出编辑器. 如果您使用nano
来编辑文件,则可以按CTRL + X
,Y
,然后按ENTER
。
最后,添加您的用户到 /etc/vsftpd.userlist
. 使用 -a
旗帜添加到文件:
1echo "sammy" | sudo tee -a /etc/vsftpd.userlist
检查它是否如你所期望的那样被添加:
1cat /etc/vsftpd.userlist
1[secondary_label Output]
2sammy
重新启动 DAEMON 以加载配置更改:
1sudo systemctl restart vsftpd
有了配置,您现在可以测试 FTP 访问。
步骤5:测试 FTP 访问
我们已经配置了服务器,以允许只有用户 sammy通过FTP连接,现在我们将确保这按预期工作。
由于您已禁用了匿名访问,您可以通过尝试匿名连接来测试它。如果配置设置正确,匿名用户应该被拒绝许可。 打开另一个终端窗口并运行以下命令。
1[environment local]
2ftp -p 203.0.113.0
当被提示使用者名称时,尝试登录作为一个不存在的用户,如 匿名,你将收到以下输出:
1[secondary_label Output]
2[environment local]
3Connected to 203.0.113.0.
4220 (vsFTPd 3.0.3)
5Name (203.0.113.0:default): anonymous
6530 Permission denied.
7ftp: Login failed.
8ftp>
关闭连接:
1[environment local]
2bye
除 sammy 以外的用户也应该无法连接。 尝试作为 sudo 用户连接. 他们也应该被拒绝访问,并且应该在允许他们输入密码之前发生:
1[environment local]
2ftp -p 203.0.113.0
1[secondary_label Output]
2[environment local]
3Connected to 203.0.113.0.
4220 (vsFTPd 3.0.3)
5Name (203.0.113.0:default): sudo_user
6530 Permission denied.
7ftp: Login failed.
8ftp>
关闭连接:
1[environment local]
2bye
另一方面,用户 sammy 应该能够连接、阅读和写文件. 确保指定的 FTP 用户可以连接:
1[environment local]
2ftp -p 203.0.113.0
1[secondary_label Output]
2[environment local]
3Connected to 203.0.113.0.
4220 (vsFTPd 3.0.3)
5Name (203.0.113.0:default): sammy
6331 Please specify the password.
7Password: your_user's_password
8230 Login successful.
9Remote system type is UNIX.
10Using binary mode to transfer files.
11ftp>
现在转到文件
目录:
1[environment local]
2cd files
1[secondary_label Output]
2[environment local]
3250 Directory successfully changed.
接下来,运行get
,将您之前创建的测试文件传输到本地机器:
1[environment local]
2get test.txt
1[secondary_label Output]
2[environment local]
3227 Entering Passive Mode (203,0,113,0,169,12).
4150 Opening BINARY mode data connection for test.txt (17 bytes).
5226 Transfer complete.
617 bytes received in 0.00 secs (4.5496 kB/s)
7ftp>
接下来,上传新名称的文件来测试写权限:
1[environment local]
2put test.txt upload.txt
1[secondary_label Output]
2[environment local]
3227 Entering Passive Mode (203,0,113,0,164,71).
4150 Ok to send data.
5226 Transfer complete.
617 bytes sent in 0.00 secs (5.3227 kB/s)
关闭连接:
1[environment local]
2bye
现在你已经测试了配置,接下来你将采取措施进一步保护你的服务器。
步骤6:确保交易
由于 FTP 不加密过境中的任何数据,包括用户身份证件,您可以启用TLS/SSL来提供加密,第一步是创建SSL证书以使用vsftpd。
使用openssl
创建新证书,并使用-days
旗帜使其有效一年。在同一命令中,添加一个私有 2048 位 RSA 密钥。
1sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem
您将被要求为您的证书提供地址信息. 将自己的信息替换为所突出的值:
1[secondary_label Output]
2Generating a 2048 bit RSA private key
3............................................................................+++
4...........+++
5writing new private key to '/etc/ssl/private/vsftpd.pem'
6-----
7You are about to be asked to enter information that will be incorporated
8into your certificate request.
9What you are about to enter is what is called a Distinguished Name or a DN.
10There are quite a few fields but you can leave some blank
11For some fields there will be a default value,
12If you enter '.', the field will be left blank.
13-----
14Country Name (2 letter code) [AU]:US
15State or Province Name (full name) [Some-State]:NY
16Locality Name (eg, city) []:New York City
17Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
18Organizational Unit Name (eg, section) []:
19Common Name (e.g. server FQDN or YOUR name) []: your_server_ip
20Email Address []:
有关证书旗帜的详细信息,请参阅 OpenSSL Essentials: 使用 SSL 证书、私钥和 CSR。
创建证书后,重新打开vsftpd
配置文件:
1sudo nano /etc/vsftpd.conf
到文件的底部,将有两行,以rsa_
开始. 评论他们通过以磅符号(#
)前面每个行:
1[label /etc/vsftpd.conf]
2. . .
3# rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
4# rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
5. . .
在这些行之后,添加以下行,指向您创建的证书和私钥:
1[label /etc/vsftpd.conf]
2. . .
3rsa_cert_file=/etc/ssl/private/vsftpd.pem
4rsa_private_key_file=/etc/ssl/private/vsftpd.pem
5. . .
现在你将强制使用SSL,这将防止无法处理TLS的客户端连接,这是必要的,以确保所有流量都加密,但它可能会迫使你的FTP用户更改客户端。
1[label /etc/vsftpd.conf]
2. . .
3ssl_enable=YES
4. . .
接下来,添加以下行,明确拒绝通过SSL进行匿名连接,并要求SSL用于数据传输和登录:
1[label /etc/vsftpd.conf]
2. . .
3allow_anon_ssl=NO
4force_local_data_ssl=YES
5force_local_logins_ssl=YES
6. . .
然后,通过添加以下行来配置服务器以使用 TLS,即 SSL 的首选继任者:
1[label /etc/vsftpd.conf]
2. . .
3ssl_tlsv1=YES
4ssl_sslv2=NO
5ssl_sslv3=NO
6. . .
最后,添加两种最终选项:第一个将不需要SSL的重复使用,因为它可以打破许多FTP客户端;第二个将需要高
加密加密套件,这意味着当前的密钥长度等于或大于128位:
1[label /etc/vsftpd.conf]
2. . .
3require_ssl_reuse=NO
4ssl_ciphers=HIGH
5. . .
以下是所有这些更改完成后该文件的此部分应该如何显示:
1[label /etc/vsftpd.conf]
2# This option specifies the location of the RSA certificate to use for SSL
3# encrypted connections.
4#rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
5#rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
6rsa_cert_file=/etc/ssl/private/vsftpd.pem
7rsa_private_key_file=/etc/ssl/private/vsftpd.pem
8ssl_enable=YES
9allow_anon_ssl=NO
10force_local_data_ssl=YES
11force_local_logins_ssl=YES
12ssl_tlsv1=YES
13ssl_sslv2=NO
14ssl_sslv3=NO
15require_ssl_reuse=NO
16ssl_ciphers=HIGH
完成后,保存并关闭文件. 如果您使用了nano
,您可以通过按CTRL + X
,Y
,然后ENTER
来退。
重新启动服务器,以便更改生效:
1sudo systemctl restart vsftpd
在此时,您将无法连接到不安全的命令行客户端. 如果您尝试,您将收到以下消息:
1[secondary_label Output]
2[environment local]
3ftp -p 203.0.113.0
4Connected to 203.0.113.0.
5220 (vsFTPd 3.0.3)
6Name (203.0.113.0:default): sammy
7530 Non-anonymous sessions must use encryption.
8ftp: Login failed.
9421 Service not available, remote server has closed connection
10ftp>
接下来,请验证您可以使用支持 TLS 的客户端连接,例如 FileZilla。
步骤 7 – 使用 FileZilla 测试 TLS
大多数现代的 FTP 客户端可以配置为使用 TLS 加密。 为我们的目的,我们将展示如何通过跨平台的支持与 FileZilla连接。
当您第一次打开 FileZilla 时,请找到位于单词 ** Host** 上方的 ** 网站管理器 ** 图标,这是上行左边的图标。
打开一个新窗口,点击右下角的新网站
按钮:
在我的网站
下,会出现一个新的图标,上面写着新网站
,您可以现在命名它,或者稍后返回,然后使用重命名
按钮。
在加密
下,选择要求明确的 FTP over TLS
。
对于 ** 登录类型**,请选择 ** 请求密码**. 在 ** 用户** 字段中填写您的 FTP 用户:
在接口的底部点击连接
按钮,您将被要求提供用户的密码:
选择 OK 连接. 您现在应该通过 TLS/SSL 加密连接到您的服务器。
接下来,您将收到一个看起来如下的服务器证书:
当您接受证书后,双击文件
文件夹并将upload.txt
拖到左侧以确认您可以下载文件:
完成此操作后,右键单击本地副本,重命名为upload-tls.txt
,然后将其拖回服务器,以确认您可以上传文件:
您现在已经确认,您可以安全且成功地将 SSL/TLS 激活的文件传输。
步骤 8 – 禁用 Shell 访问(可选)
如果您由于客户端要求无法使用 TLS,您可以通过禁用 FTP 用户以任何其他方式登录的能力来获得一些安全性。防止这种情况的一种方法是通过创建自定义壳。
首先,在bin
目录中打开名为ftponly
的文件:
1sudo nano /bin/ftponly
添加一个信息,告诉用户为什么他们无法登录:
1[label /bin/ftponly]
2#!/bin/sh
3echo "This account is limited to FTP access only."
如果你使用了nano
,你可以通过按CTRL + X
,Y
,然后ENTER
来退出。
然后,更改权限以使文件可执行:
1sudo chmod a+x /bin/ftponly
打开有效壳的列表:
1sudo nano /etc/shells
在底部添加:
1[label /etc/shells]
2. . .
3/bin/ftponly
用以下命令更新用户的壳:
1sudo usermod sammy -s /bin/ftponly
现在,尝试登录您的服务器作为 sammy:
1[environment local]
2ssh sammy@your_server_ip
您将收到以下消息:
1[secondary_label Output]
2[environment local]
3This account is limited to FTP access only.
4Connection to 203.0.113.0 closed.
这确认了用户不再可以ssh
到服务器,并且仅限于FTP访问。请注意,如果您在登录服务器时收到错误消息,这可能意味着您的服务器不接受密码验证。使用基于密码的身份验证可以使您的服务器容易受到攻击,这就是为什么您可能想考虑禁用密码验证。
结论
在本教程中,我们解释了如何为本地帐户的用户设置FTP。如果您需要使用外部身份验证源,您可能想探索vsftpd
对虚拟用户的支持。通过使用 _PAM,插入式身份验证模块,这提供了丰富的选项,如果您在LDAP或Kerberos等其他系统中管理用户,则是一个很好的选择。您也可以阅读有关 vsftpd功能,最新版本和更新以了解更多信息。