介绍
FTP,简称文件传输协议,是一个网络协议,曾经被广泛用于在客户端和服务器之间移动文件. 它已被更快,更安全,更方便的方式交付文件取代. 许多随机的互联网用户期望直接从他们的Web浏览器下载https
,命令行用户更有可能使用安全的协议,如scp
或sFTP
(https://andsky.com/tech/tutorials/how-to-use-sftp-to-securely-transfer-files-with-a-remote-server)。
FTP 仍然用于支持具有非常具体需求的旧应用程序和工作流程. 如果您有选择使用哪个协议,请考虑探索更现代的选项. 然而,当您需要 FTP 时,vsftpd 是一个很好的选择. 优化了安全性,性能和稳定性,vsftpd 提供了强大的保护,防止其他 FTP 服务器中发现的许多安全问题,并且是许多 Linux 发行版的默认。
在本教程中,我们将向您展示如何配置 vsftpd 以允许用户使用 FTP 将文件上传到其主目录,并使用 SSL/TLS 保护的登录凭证。
前提条件
要跟随这个教程,你需要:
- ** 具有
sudo
特权的非根用户的 Ubuntu 16.04 服务器:您可以在我们的 Ubuntu 16.04 初始服务器设置 指南中了解有关如何设置具有这些特权的用户的更多信息。
一旦你有一个Ubuntu服务器,你已经准备好开始。
步骤 1 – 安装 vsftpd
我们将通过更新我们的包列表和安装vsftpd daemon开始:
1sudo apt-get update
2sudo apt-get 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流量添加规则。
我们需要为 FTP 打开端口 20 和 21,在我们启用 TLS 后打开端口 990,并为我们计划在配置文件中设置的被动端口范围打开端口 40000-50000 :
1sudo ufw allow 20/tcp
2sudo ufw allow 21/tcp
3sudo ufw allow 990/tcp
4sudo ufw allow 40000:50000/tcp
5sudo ufw status
现在我们的防火墙规则看起来像:
1[secondary_label Output]
2Status: active
3
4To Action From
5-- ------ ----
6OpenSSH ALLOW Anywhere
7990/tcp ALLOW Anywhere
820/tcp ALLOW Anywhere
921/tcp ALLOW Anywhere
1040000:50000/tcp ALLOW Anywhere
11OpenSSH (v6) ALLOW Anywhere (v6)
1220/tcp (v6) ALLOW Anywhere (v6)
1321/tcp (v6) ALLOW Anywhere (v6)
14990/tcp (v6) ALLOW Anywhere (v6)
1540000:50000/tcp (v6) ALLOW Anywhere (v6)
安装了vsftpd
并打开了必要的端口,我们已经准备好进入下一步。
步骤三:准备用户目录
对于本教程,我们将创建一个用户,但您可能已经有一个需要FTP访问的用户。我们将注意在以下指示中保留现有用户对其数据的访问。
首先,我们将添加一个测试用户:
1sudo adduser sammy
当被提示时分配密码,并可以通过其他提示按ENTER
。
当用户被限制在特定目录时,FTP通常更安全。‘vsftpd’通过‘chroot’监狱实现了这一点.当‘chroot’为本地用户启用时,他们默认情况下被限制在其主目录中。然而,由于‘vsftpd’保护目录的方式,它不能被用户编写。这对新用户来说是很好的,他们只需通过FTP进行连接,但如果他们还没有访问,现有用户可能需要写到他们的主目录。
在本示例中,而不是从主目录中删除写权限,我们将创建一个ftp
目录作为chroot
目录和一个可写的文件
目录来保留实际文件。
创建ftp
文件夹,设置其所有权,并确保使用以下命令删除写权限:
1sudo mkdir /home/sammy/ftp
2sudo chown nobody:nogroup /home/sammy/ftp
3sudo chmod a-w /home/sammy/ftp
让我们来检查许可证:
1sudo ls -la /home/sammy/ftp
1[secondary_label Output]
2total 8
34 dr-xr-xr-x 2 nobody nogroup 4096 Aug 24 21:29 .
44 drwxr-xr-x 3 sammy sammy 4096 Aug 24 21:29 ..
接下来,我们将创建文件可上传的目录,并将所有权分配给用户:
1sudo mkdir /home/sammy/ftp/files
2sudo chown sammy:sammy /home/sammy/ftp/files
在文件
目录上的权限检查应返回以下内容:
1sudo ls -la /home/sammy/ftp
1[secondary_label Output]
2total 12
3dr-xr-xr-x 3 nobody nogroup 4096 Aug 26 14:01 .
4drwxr-xr-x 3 sammy sammy 4096 Aug 26 13:59 ..
5drwxr-xr-x 2 sammy sammy 4096 Aug 26 14:01 files
最后,我们将添加一个test.txt
文件,在我们稍后测试时使用:
1echo "vsftpd test file" | sudo tee /home/sammy/ftp/files/test.txt
现在我们已经保护了ftp
目录,并允许用户访问文件
目录,我们将关注配置。
步骤 4 – 配置 FTP 访问
我们计划允许一个具有本地壳帐户的单个用户使用 FTP 连接,这两个关键设置已经设置在 vsftpd.conf
中。
1sudo nano /etc/vsftpd.conf
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. . .
接下来,我们需要更改文件中的某些值,为了允许用户上传文件,我们将删除写_允许
设置,以便我们有:
1[label /etc/vsftpd.conf]
2. . .
3write_enable=YES
4. . .
此外,我们还会删除 root,以防止 FTP 连接的用户访问目录树以外的任何文件或命令。
1[label /etc/vsftpd.conf]
2. . .
3chroot_local_user=YES
4. . .
我们将添加一个user_sub_token
,以便将用户名插入到我们的local_root 目录
路径中,以便我们的配置为此用户和可能添加的任何未来用户工作。
1[label /etc/vsftpd.conf]
2user_sub_token=$USER
3local_root=/home/$USER/ftp
我们将限制可用于被动FTP的端口范围,以确保有足够的连接:
1[label /etc/vsftpd.conf]
2pasv_min_port=40000
3pasv_max_port=50000
<$>[注] **注:**我们预先打开了我们在这里设置的被动端口范围的端口。
由于我们只计划以个案为基础允许 FTP 访问,我们将设置配置,以便只有当用户被明确添加到列表时,而不是默认时,才能获得访问:
1[label /etc/vsftpd.conf]
2userlist_enable=YES
3userlist_file=/etc/vsftpd.userlist
4userlist_deny=NO
「userlist_deny」會轉換邏輯。當設定為「YES」時,列表中的用戶會被拒絕FTP存取。當設定為「NO」時,只有列表中的用戶才能存取。
最后,我们将创建并将我们的用户添加到文件中. 我们将使用-a
旗帜添加到文件中:
1echo "sammy" | sudo tee -a /etc/vsftpd.userlist
重复检查它是否按预期添加了:
1cat /etc/vsftpd.userlist
1[secondary_label Output]
2sammy
重新启动 DAEMON 以加载配置更改:
1sudo systemctl restart vsftpd
现在我们已经准备好进行测试了。
步骤5:测试 FTP 访问
我们已经配置了服务器,以允许只有用户sammy
通过FTP连接。
匿名用户不应该连接:我们禁用了匿名访问. 在这里,我们将通过尝试匿名连接来测试。
1ftp -p 203.0.113.0
1[secondary_label Output]
2Connected to 203.0.113.0.
3220 (vsFTPd 3.0.3)
4Name (203.0.113.0:default): anonymous
5530 Permission denied.
6ftp: Login failed.
7ftp>
关闭连接:
1bye
sammy
以外的用户不应该连接:接下来,我们将尝试作为我们的sudo
用户连接他们也应该被拒绝访问,并且应该发生在他们被允许输入密码之前。
1ftp -p 203.0.113.0
1[secondary_label Output]
2Connected to 203.0.113.0.
3220 (vsFTPd 3.0.3)
4Name (203.0.113.0:default): sudo_user
5530 Permission denied.
6ftp: Login failed.
7ftp>
关闭连接:
1bye
sammy
应该能够连接,以及阅读和写入文件:在这里,我们将确保我们的指定用户 _can_connect:
1ftp -p 203.0.113.0
1[secondary_label Output]
2Connected to 203.0.113.0.
3220 (vsFTPd 3.0.3)
4Name (203.0.113.0:default): sammy
5331 Please specify the password.
6Password: your_user's_password
7230 Login successful.
8Remote system type is UNIX.
9Using binary mode to transfer files.
10ftp>
我们将更改到文件
目录,然后使用获取
命令将我们之前创建的测试文件传输到我们的本地机器:
1cd files
2get test.txt
1[secondary_label Output]
2227 Entering Passive Mode (203,0,113,0,169,12).
3150 Opening BINARY mode data connection for test.txt (16 bytes).
4226 Transfer complete.
516 bytes received in 0.0101 seconds (1588 bytes/s)
6ftp>
我们将向右转,并尝试将文件上传以新的名称来测试写权限:
1put test.txt upload.txt
1[secondary_label Output]
2227 Entering Passive Mode (203,0,113,0,164,71).
3150 Ok to send data.
4226 Transfer complete.
516 bytes sent in 0.000894 seconds (17897 bytes/s)
关闭连接:
1bye
现在我们已经测试了我们的配置,我们将采取措施进一步保护我们的服务器。
步骤6:确保交易
由于 FTP 不加密过境中的任何数据,包括用户身份证件,我们将允许TTL/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_IP_address
20Email Address []:
有关证书旗帜的详细信息,请参阅 OpenSSL Essentials: 使用 SSL 证书、私钥和 CSR
创建证书后,重新打开vsftpd
配置文件:
1sudo nano /etc/vsftpd.conf
向檔案的底部,你應該兩行,以「rsa_」開始。
1[label /etc/vsftpd.conf]
2# rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
3# rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
下面,添加以下行,指向我们刚刚创建的证书和私钥:
1[label /etc/vsftpd.conf]
2rsa_cert_file=/etc/ssl/private/vsftpd.pem
3rsa_private_key_file=/etc/ssl/private/vsftpd.pem
之后,我们将强制使用SSL,这将防止无法处理TLS的客户端连接,这是为了确保所有流量都加密,但可能会迫使您的FTP用户更改客户端。
1[label /etc/vsftpd.conf]
2ssl_enable=YES
然后,添加以下行,明确拒绝通过SSL进行匿名连接,并要求SSL用于数据传输和登录:
1[label /etc/vsftpd.conf]
2allow_anon_ssl=NO
3force_local_data_ssl=YES
4force_local_logins_ssl=YES
在此之后,我们将配置服务器以使用TLS,即SSL的首选继任者,通过添加以下行:
1[label /etc/vsftpd.conf]
2ssl_tlsv1=YES
3ssl_sslv2=NO
4ssl_sslv3=NO
最后,我们将添加两种选项,首先,我们将不需要重复使用SSL,因为它可以打破许多FTP客户端,我们将需要高
加密加密套件,这意味着当前的密钥长度等于或大于128位:
1[label /etc/vsftpd.conf]
2require_ssl_reuse=NO
3ssl_ciphers=HIGH
完成后,保存并关闭文件。
现在,我们需要重新启动服务器,以便更改生效:
1sudo systemctl restart vsftpd
此时,我们将无法再连接到一个不安全的命令行客户端. 如果我们尝试,我们会看到这样的东西:
1ftp -p 203.0.113.0
2Connected to 203.0.113.0.
3220 (vsFTPd 3.0.3)
4Name (203.0.113.0:default): sammy
5530 Non-anonymous sessions must use encryption.
6ftp: Login failed.
7421 Service not available, remote server has closed connection
8ftp>
接下来,我们将验证我们可以使用支持 TLS 的客户端连接。
步骤 7 – 使用 FileZilla 测试 TLS
大多数现代 FTP 客户端可以配置使用 TLS 加密,我们将展示如何使用 FileZilla 进行连接,因为其跨平台支持。
当您第一次打开FileZilla时,请在单词文件
下面找到网站管理器图标,这是上行最左边的图标。
新窗口将打开,点击右下角的新网站
按钮:
Under "My Sites" a new icon with the words "New site" will appear. You can name it now or return later and use the Rename button.
您必须用名称或 IP 地址填写主机
字段,在加密
下载菜单中选择要求明确的 FTP over TLS
。
对于登录类型
,选择请求密码
。在用户
字段中填写您创建的 FTP 用户:
Click "Connect" at the bottom of the interface. You will be asked for the user's password:
Click "OK" to connect. You should now be connected with your server with TLS/SSL encryption.
When you’ve accepted the certificate, double-click the
files
folder and drag upload.txt to the left to confirm that you’re able to download files.
When you’ve done that, right-click on the local copy, rename it to upload-tls.txt` and drag it back to the server to confirm that you can upload files.
You’ve now confirmed that you can securely and successfully transfer files with SSL/TLS enabled.
步骤 8 – 禁用 Shell 访问(可选)
如果您由于客户端要求无法使用 TLS,您可以通过禁用 FTP 用户以任何其他方式登录的能力来获得一些安全性。 一个相对简单的方法来防止它是通过创建自定义壳。
首先,在 Bin 目录中打开名为ftponly
的文件:
1sudo nano /bin/ftponly
我们会添加一个消息,告诉用户为什么他们无法登录。
1#!/bin/sh
2echo "This account is limited to FTP access only."
更改权限以使文件可执行:
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:
1ssh [email protected]
你应该看到这样的东西:
1[secondary_label Output]
2This account is limited to FTP access only.
3Connection to 203.0.113.0 closed.
这确认了用户不再可以ssh
到服务器,并且仅限于FTP访问。
结论
在本教程中,我们涵盖了使用本地帐户的用户的FTP设置。如果您需要使用外部身份验证源,您可能会想看看vsftpd对虚拟用户的支持。