如何在 Ubuntu 18.04 上为用户目录设置 vsftpd

介绍

FTP,简称文件传输协议,是一个网络协议,曾经被广泛用于在客户端和服务器之间移动文件. 它已被更快,更安全,更方便的方式交付文件取代. 许多随机的互联网用户期望直接从他们的Web浏览器下载https,命令行用户更有可能使用安全的协议,如scpSFTP(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 保护的登录凭证。

前提条件

要跟随这个教程,你需要:

  • Ubuntu 18.04 服务器和具有 sudo 特权的非根用户:您可以在我们的 Ubuntu 18.04 初始服务器设置指南中了解有关如何设置具有这些特权的用户的更多信息。

步骤 1 – 安装 vsftpd

让我们开始更新我们的包列表并安装vsftpd大门:

1sudo apt update
2sudo 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流量添加规则。

让我们为 FTP 打开 2021 端口,为我们启用 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用户。

步骤三:准备用户目录

我们将创建一个专用 FTP 用户,但您可能已经有一个需要 FTP 访问的用户。我们将在以下指示中保留现有用户对其数据的访问权限。

首先,添加一个测试用户:

1sudo adduser sammy

请在提示时分配密码. 请通过其他提示按ENTER

当用户被限制在特定目录时,FTP通常更安全。 vsftpd 通过 chroot 监狱实现了这一点. 当为本地用户启用 chroot 时,他们默认情况下被限制在其主目录中。然而,由于 `vsftpd' 保护目录的方式,它不应该被用户编写。 这对新用户来说是很好的,他们应该只通过 FTP 连接,但如果他们也有壳访问,现有用户可能需要写到他们的主目录。

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

创建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
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

ftp目录上的权限检查应返回以下内容:

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. . .

接下来,让我们允许用户通过不评论 Write_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,将用户名插入到我们的local_root 目录路径中,以便我们的配置为此用户和任何其他未来的用户工作。

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」時,只有列表中的用戶才能存取。

完成更改后,保存文件并退出编辑器。

最后,让我们将我们的用户添加到 /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应该能够连接、阅读和写文件:让我们确保我们的指定用户可以连接:

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
3get 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 (16 bytes).
5226 Transfer complete.
616 bytes received in 0.0101 seconds (1588 bytes/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.
616 bytes sent in 0.000894 seconds (17897 bytes/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

完成后,保存并关闭文件。

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

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的客户端连接。

步骤 7 – 使用 FileZilla 测试 TLS

大多数现代的 FTP 客户端可以配置为使用 TLS 加密,我们将展示如何通过 FileZilla进行连接,因为其跨平台支持。

当您第一次打开 FileZilla 时,请在单词 Host上方找到网站管理器图标,这是上行最左边的图标。

Site Manager Screent Shot

打开一个新窗口,点击右下角的新网站按钮:

New Site Button 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.

在 ** 加密 ** 下载菜单中,选择 ** 需要明确的 FTP over TLS**。

对于 ** 登录类型**,请选择 ** 请求密码**. 在 ** 用户** 字段中填写您的 FTP 用户:

General Settings Tab

点击连接在接口的底部,您将被要求提供用户密码:

Password Dialogue

点击 OK 连接. 您现在应该通过 TLS/SSL 加密连接到您的服务器。

成功后,您将收到一个看起来像这样的服务器证书:

Site Certificate Dialogue

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

Download test.txt

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

Rename and Upload

您现在已经确认,您可以安全且成功地将 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."

保存文件并离开编辑器。

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

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等其他系统中管理用户,这是一个很好的选择。

Published At
Categories with 技术
comments powered by Disqus