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

介绍

FTP是文件传输协议的缩写,是一种曾经广泛用于在客户端和服务器之间移动文件的网络协议。它已被更快,更安全,更方便的文件传输方式所取代。许多普通网民希望通过https直接从他们的网络浏览器下载,命令行用户更有可能使用安全协议,如scp或SFTP

FTP仍然用于支持具有特定需求的遗留应用程序和工作流。但是,当您确实需要FTP时,vsftpd是一个很好的选择。vsftpd针对安全性,性能和稳定性进行了优化,可以很好地防范其他FTP服务器中存在的许多安全问题,并且是许多Linux发行版的默认设置。

在本教程中,您将配置vsftpd以允许用户使用具有SSL/TLS保护的登录凭据的FTP将文件上载到其主目录。

准备

要学习本教程,您需要:

  • Ubuntu 18.04服务器和具有可以使用sudo权限命令的非root用户

第一步 - 安装vsftpd

让我们首先更新软件包列表并安装vsftpd守护进程:

$ sudo apt update
$ sudo apt install vsftpd

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

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

通过备份配置,我们已准备好配置防火墙。

第二步 - 打开防火墙

让我们检查防火墙状态以查看它是否已启用。如果是,我们将确保允许FTP流量,因此防火墙带有的规则并不会阻止我们的测试。

检查防火墙状态:

$ sudo ufw status

在这种情况下,只允许SSH通过:

Status: active

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

您可能会有其他规则或根本没有防火墙规则。由于在这种情况下只允许SSH流量,因此我们需要为FTP流量添加规则。

让我们打开端口2021用于FTP,端口990用于启用TLS,端口40000-50000用于我们计划在配置文件中设置的passive模式端口范围:

$ sudo ufw allow 20/tcp
$ sudo ufw allow 21/tcp
$ sudo ufw allow 990/tcp
$ sudo ufw allow 40000:50000/tcp
$ sudo ufw status

我们的防火墙规则现在应如下所示:

Status: active

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

随着vsftpd安装和打开必要的端口,让我们继续创建一个专用的FTP用户。

第三步 - 准备用户目录

我们将创建一个专用的FTP用户,但您可能已经有一个需要FTP访问的用户。我们将注意保留现有用户对以下说明中的数据的访问权限。即便如此,我们建议您在配置和测试安装之前先使用新用户。

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

$ sudo adduser sammy

出现提示时设置密码。其他提示按下ENTER键。

当用户被限制在特定目录时,FTP通常更安全。vsftpd用chrootjails 完成了这个。当本地用户启动chroot时,默认情况下它们仅限于其主目录。但是,由于vsftpd保护目录的方式,用户不能写入。这对于只应通过FTP连接的新用户来说很好,但如果现有用户也具有shell访问权限,则可能需要写入其主文件夹。

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

创建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
total 8
4 dr-xr-xr-x  2 nobody nogroup 4096 Aug 24 21:29 .
4 drwxr-xr-x  3 sammy  sammy   4096 Aug 24 21:29 ..

接下来,让我们创建文件上传目录并为用户分配所有权:

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

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

$ sudo ls -la /home/sammy/ftp
total 12
dr-xr-xr-x 3 nobody nogroup 4096 Aug 26 14:01 .
drwxr-xr-x 3 sammy  sammy   4096 Aug 26 13:59 ..
drwxr-xr-x 2 sammy  sammy   4096 Aug 26 14:01 files

最后,在我们在测试时添加一个test.txt文件:

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

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

第四步 - 配置FTP访问

我们计划允许具有本地shell帐户的单个用户与FTP连接。两个关键设置已在vsftpd.conf中设置。首先打开配置文件,验证配置中的设置是否与以下设置相匹配:

$ sudo nano /etc/vsftpd.conf

/etc/vsftpd.conf

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

接下来,让我们通过取消注释write_enable设置让用户上传文件:

/etc/vsftpd.conf

. . .
write_enable=YES
. . .

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

/etc/vsftpd.conf

. . .
chroot_local_user=YES
. . .

我们还添加一个user_sub_token以在local_root directory路径中插入用户名,这样我们的配置将适用于此用户和任何其他未来用户。在文件中的任何位置添加这些设置:

/etc/vsftpd.conf

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

我们还限制了可用于 FTP Passive模式的端口范围,以确保有足够的连接可用:

/etc/vsftpd.conf

. . .
pasv_min_port=40000
pasv_max_port=50000

注意:在第二步中,我们打开了我们在此处为Passive模式端口范围设置的端口。如果您需要更改其值,请务必更新防火墙设置。

要根据具体情况允许FTP访问,让我们设置配置,以便用户只有在明确添加到列表时才能访问,而不是在默认情况下:

/etc/vsftpd.conf

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

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

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

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

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

检查它是否按您的预期来添加:

$ cat /etc/vsftpd.userlist
sammy

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

$ sudo systemctl restart vsftpd

配置到位后,我们继续测试FTP访问。

第五步 - 测试FTP访问

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

匿名用户应该无法连接:我们已禁用匿名访问。让我们通过尝试匿名连接来测试它。如果我们的配置设置正确,则应拒绝匿名用户的权限。请务必将203.0.113.0替换为服务器的公共IP地址:

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

关闭连接:

ftp> bye

除了sammy以外的用户应无法连接:接下来,让我们尝试连接我们使用sudo命令的用户。他们也应该被拒绝访问,并且应该在他们被允许输入密码之前发生:

$ ftp -p 203.0.113.0
Connected 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>

关闭连接:

ftp> bye

用户sammy应该能够连接,读取和写入文件:让我们确保我们的指定用户可以连接:

$ ftp -p 203.0.113.0
Connected 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目录并使用get命令将我们之前创建的测试文件传输到本地机器中:

ftp> cd files
ftp> get test.txt
227 Entering Passive Mode (203,0,113,0,169,12).
150 Opening BINARY mode data connection for test.txt (16 bytes).
226 Transfer complete.
16 bytes received in 0.0101 seconds (1588 bytes/s)
ftp>

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

ftp> put test.txt upload.txt
227 Entering Passive Mode (203,0,113,0,164,71).
150 Ok to send data.
226 Transfer complete.
16 bytes sent in 0.000894 seconds (17897 bytes/s)

关闭连接:

ftp> bye

现在我们已经测试了我们的配置,让我们采取措施进一步保护我们的服务器。

第六步 - 保护传输数据

因为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

系统将提示您提供证书的地址信息。将您自己的信息替换为以下高亮显示的值:

Generating 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 []:

创建证书后,再次打开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

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

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

$ sudo systemctl restart vsftpd

此时,我们将无法再使用不安全的命令行客户端进行连接。如果去尝试,我们会看到类似以下的结果:

$ ftp -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测试TLS

大多数现代FTP客户端都可以配置为使用TLS加密。我们将演示如何与FileZilla连接,因为它支持跨平台。

当你第一次打开FileZilla中,找到刚才上面管理图标Host(在顶行最左侧的图标)。点击它:

管理图标

这将打开一个新窗口。单击右下角的“ New Site”按钮:

New Site

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

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

对于Logon Type,选择Ask for password。在“User”字段中填写您的FTP用户:

点击Connect在界面的底部。系统将要求您输入用户密码:

单击OK以进行连接。您现在应该使用TLS / SSL加密与您的服务器连接。

成功后,您将看到一个如下所示的服务器证书:

当您接受证书后,双击该files文件夹并upload.txt向左拖动以确认您能够下载文件:

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

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

第八步 - 禁用Shell访问(可选)

如果由于客户端要求而无法使用TLS,则可以通过禁用FTP用户以任何其他方式登录的方式来获得一些安全性。一种相对简单的方法是通过创建自定义shell来防止它。这不会提供任何加密,但会限制被盗用帐户对FTP可访问的文件的访问。

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

$ sudo nano /bin/ftponly

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

/bin/ftponly

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

保存文件并退出编辑器。

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

$ 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

您会看到类似以下输出结果:

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

这确认用户不能再使用ssh访问服务器,其仅限于FTP访问。

结论

在本教程中,我们介绍了为具有本地帐户的用户设置FTP。如果您需要使用外部身份验证源,您可能需要了解vsftpd对虚拟用户的支持。这通过使用PAM(可插入身份验证模块)提供了丰富的选择,如果您管理其他系统(如LDAP或Kerberos)中的用户,这也是一个不错的选择。


参考文献:《How To Set Up vsftpd for a User's Directory on Ubuntu 18.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏令仔很忙

新手学Linux(六)----安装Nginx

nginx是C语言开发,建议在linux上运行,本教程使用Centos7.0作为安装环境。

2132
来自专栏北京马哥教育

批量管理自动化运维100台小规模服务器

---- 目录 1.脚本背景介绍 2.脚本技术需求分析 2.1 SSH免登陆认证 2.2 Expect实现key分发 2.2 PSSH家族命...

1.9K15
来自专栏IT可乐

邮件实现详解(二)------手工体验smtp和pop3协议

  上篇博客我们简单介绍了电子邮件的发送和接收过程,对参与其中的邮件服务器,邮件客户端软件,邮件传输协议也有简单的介绍。我们知道电子邮件需要在邮件客户端和邮件服...

37810
来自专栏云计算教程系列

如何使用Python-GnuPG和Python 3验证代码和加密数据

GnuPG包提供用于生成和存储加密密钥的完整解决方案。它还允许您加密和签名数据和通信。

5908
来自专栏惨绿少年

SSH服务详解

第1章 SSH服务 1.1 SSH服务协议说明 SSH 是 Secure Shell Protocol 的简写,由 IETF 网络工作小组(Network Wo...

3400
来自专栏原创

个推推送iOS版 常见问题详解

1、提交了.p12文件后多久可以测试? 提交后10分钟左右才可以测试,并不是立即生效的。 2、应用在后台时接收不到消息,即APNS消息接收不到? 1.    先...

37811
来自专栏云计算教程系列

如何在Ubuntu 14.04上保护Nginx

即使使用默认设置,Nginx也是一个非常安全可靠的Web服务器。但是,有很多方法可以进一步保护Nginx。

1562
来自专栏谈补锅

ASP和ASP.NET发送邮件笔记

    这两天因公司网站邮件发不出去,然后研究了在asp网站发送邮件和在asp.net网站发送邮件的代码,把碰到的问题这里记录一下。

1753
来自专栏网络

一步步带你了解前后端分离利器之JWT

一、HTTP的无状态性 HTTP 是无状态协议,它不对之前发送过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。假设要求登录认证的 ...

3175
来自专栏Youngxj

emlog后台登录失败邮件通知

1273

扫码关注云+社区

领取腾讯云代金券