前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >如何在Ubuntu 16.04上为用户目录设置vsftpd

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

原创
作者头像
GeekZ
修改2018-10-29 18:28:23
修改2018-10-29 18:28:23
2.3K00
代码可运行
举报
运行总次数:0
代码可运行

介绍

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

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

在本教程中,我们将向您展示如何配置vsftpd以允许用户使用具有SSL / TLS保护的登录凭据的FTP将文件上载到他或她的主目录。

先决条件

要学习本教程,您需要:

  • 具有sudo权限的非root用户的Ubuntu 16.04服务器 ,没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器

一旦你有一台Ubuntu服务器,你就可以开始了。

第1步 - 安装vsftpd

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo apt-get update
sudo apt-get install vsftpd

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.orig

通过备份配置,我们已准备好配置防火墙。如果您使用的是腾讯云的CVM服务器,您可以直接在腾讯云控制台中的安全组进行设置。

第2步 - 打开防火墙

我们将检查防火墙状态以查看它是否已启用。如果是这样,我们将确保允许FTP流量,这样您就不会遇到阻止您进行测试的防火墙规则。

代码语言:javascript
代码运行次数:0
运行
复制
sudo ufw status

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

代码语言:javascript
代码运行次数:0
运行
复制
Status: active
​
To Action  From
-- ------  ----
OpenSSH ALLOW   Anywhere
OpenSSH (v6)   ALLOW   Anywhere (v6)

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

我们需要打开端口20和21用于FTP,端口990用于以后我们启用TLS,端口40000-50000用于我们计划在配置文件中设置的被动端口范围:

代码语言:javascript
代码运行次数:0
运行
复制
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 990/tcp
sudo ufw allow 40000:50000/tcp
sudo ufw status

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

代码语言:javascript
代码运行次数:0
运行
复制
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安装和必要的端口打开,我们已经准备好进行下一个步骤。

第3步 - 准备用户目录

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

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo adduser sammy

在提示时分配密码,可以通过其他提示按“ENTER”。

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

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

创建ftp文件夹,设置其所有权,并确保使用以下命令删除写入权限:

代码语言:javascript
代码运行次数:0
运行
复制
sudo mkdir /home/sammy/ftp
sudo chown nobody:nogroup /home/sammy/ftp
sudo chmod a-w /home/sammy/ftp

让我们验证权限:

代码语言:javascript
代码运行次数:0
运行
复制
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 ..

接下来,我们将创建可以上载文件的目录,并为用户分配所有权:

代码语言:javascript
代码运行次数:0
运行
复制
sudo mkdir /home/sammy/ftp/files
sudo chown sammy:sammy /home/sammy/ftp/files

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo ls -la /home/sammy/ftp
Outputtotal 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

代码语言:javascript
代码运行次数:0
运行
复制
echo "vsftpd test file" | sudo tee /home/sammy/ftp/files/test.txt

现在我们已经保护了ftp目录并允许用户访问files目录,我们将注意力转向配置。

第4步 - 配置FTP访问

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo nano /etc/vsftpd.conf
代码语言:javascript
代码运行次数:0
运行
复制
. . .
# Allow anonymous FTP? (Disabled by default).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
. . .

接下来,我们需要更改文件中的一些值。为了允许用户上传文件,我们将取消注释write_enable设置,以便我们拥有:

代码语言:javascript
代码运行次数:0
运行
复制
. . .
write_enable=YES
. . .

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

代码语言:javascript
代码运行次数:0
运行
复制
. . .
chroot_local_user=YES
. . .

我们将添加一个user_sub_token以便在我们的local_root directory路径中插入用户名,以便我们的配置适用于此用户以及可能添加的任何未来用户。

代码语言:javascript
代码运行次数:0
运行
复制
user_sub_token=$USER
local_root=/home/$USER/ftp

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

代码语言:javascript
代码运行次数:0
运行
复制
pasv_min_port=40000
pasv_max_port=50000

注意:我们预先打开了我们在这里为被动端口范围设置的端口。如果更改值,请务必更新防火墙设置。

由于我们只打算根据具体情况允许FTP访问,因此我们将设置配置,以便只有当用户明确添加到列表而不是默认情况下才能访问用户:

代码语言:javascript
代码运行次数:0
运行
复制
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

userlist_deny可以切换逻辑。当它设置为“YES”时,列表中的用户被拒绝FTP访问。当它设置为“NO”时,只允许列表中的用户访问。完成更改后,保存并退出文件。

最后,我们将创建用户并将其添加到文件中。我们将使用该-a标志追加到文件:

代码语言:javascript
代码运行次数:0
运行
复制
echo "sammy" | sudo tee -a /etc/vsftpd.userlist

仔细检查它是否按预期添加:

代码语言:javascript
代码运行次数:0
运行
复制
cat /etc/vsftpd.userlist
sammy

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo systemctl restart vsftpd

现在我们准备好进行测试了。

第5步 - 测试FTP访问

我们已将服务器配置为仅允许用户sammy通过FTP连接。让我们确保是这样的。

匿名用户应该无法连接:我们禁用了匿名访问。在这里,我们将通过尝试匿名连接来测试。如果我们已正确完成,则应拒绝匿名用户的权限:

代码语言:javascript
代码运行次数:0
运行
复制
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>

关闭连接:

代码语言:javascript
代码运行次数:0
运行
复制
bye

其他用户sammy应该无法连接:接下来,我们将尝试以sudo用户身份进行连接。他们也应该被拒绝访问,并且应该在他们被允许输入密码之前发生。

代码语言:javascript
代码运行次数:0
运行
复制
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>

关闭连接:

代码语言:javascript
代码运行次数:0
运行
复制
bye

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

代码语言:javascript
代码运行次数:0
运行
复制
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命令将我们之前创建的测试文件传输到本地计算机:

代码语言:javascript
代码运行次数:0
运行
复制
cd files
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>

我们将向右转,尝试使用新名称上传文件以测试写入权限:

代码语言:javascript
代码运行次数:0
运行
复制
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)

关闭连接:

代码语言:javascript
代码运行次数:0
运行
复制
bye

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

第6步 - 保护交易

因为FTP并没有加密在传输过程中的任何数据,包括用户的凭据,我们将启用TTL / SSL来提供加密。第一步是创建用于vsftpd的SSL证书。

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

我们将使用以下命令执行此操作:

代码语言:javascript
代码运行次数:0
运行
复制
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem

系统将提示您提供证书的地址信息。用以下问题替换您自己的信息:

代码语言:javascript
代码运行次数:0
运行
复制
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_IP_address
Email Address []:

有关证书标志的更多详细信息,请参阅腾讯云SSL证书服务

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo nano /etc/vsftpd.conf

在文件的底部,你应该有两行以rsa_开头。评论他们使看起来像:

代码语言:javascript
代码运行次数:0
运行
复制
# rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
# rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

在它们下面,添加以下行,这些行指向我们刚刚创建的证书和私钥:

代码语言:javascript
代码运行次数:0
运行
复制
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem

之后,我们将强制使用SSL,这将阻止无法处理TLS的客户端连接。这是必要的,以确保所有流量都已加密,但可能会强制您的FTP用户更改客户端。更改ssl_enableYES

代码语言:javascript
代码运行次数:0
运行
复制
ssl_enable=YES

之后,添加以下行以显式拒绝SSL上的匿名连接,并要求SSL进行数据传输和登录:

代码语言:javascript
代码运行次数:0
运行
复制
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES

在此之后,我们将服务器配置为使用TLS,它是SSL的首选后继者,添加以下行:

代码语言:javascript
代码运行次数:0
运行
复制
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO

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

代码语言:javascript
代码运行次数:0
运行
复制
require_ssl_reuse=NO
ssl_ciphers=HIGH

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

现在,我们需要重新启动服务器才能使更改生效:

代码语言:javascript
代码运行次数:0
运行
复制
sudo systemctl restart vsftpd

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

代码语言:javascript
代码运行次数:0
运行
复制
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的客户端进行连接。

第7步 - 使用FileZilla测试TLS

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

首次打开FileZilla时,找到文字下方的“站点管理器”图标,这是最上一行最左侧的图标。点击它:

将打开一个新窗口。点击右下角的“新网站”按钮:

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

您必须使用名称或IP地址填写“主机”字段。在“加密”下拉菜单下,选择“要求显式FTP over TLS”。

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

单击界面底部的“连接”。系统将要求您输入用户密码:

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

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

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

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo nano /bin/ftponly

我们将添加一条消息,告诉用户他们无法登录的原因。粘贴如下:

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/sh
echo "This account is limited to FTP access only."

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo chmod a+x /bin/ftponly

打开有效shell列表:

代码语言:javascript
代码运行次数:0
运行
复制
sudo nano /etc/shells

在底部,添加:

代码语言:javascript
代码运行次数:0
运行
复制
. . .
/bin/ftponly

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

代码语言:javascript
代码运行次数:0
运行
复制
sudo usermod sammy -s /bin/ftponly

现在尝试以sammy身份登录:

代码语言:javascript
代码运行次数:0
运行
复制
ssh sammy@203.0.113.0

你应该看到类似的东西:

代码语言:javascript
代码运行次数:0
运行
复制
This account is limited to FTP access only.
Connection to 203.0.113.0 closed.

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

结论

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

更多Ubuntu教程请前往腾讯云+社区学习更多知识。


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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 先决条件
  • 第1步 - 安装vsftpd
  • 第2步 - 打开防火墙
  • 第3步 - 准备用户目录
  • 第4步 - 配置FTP访问
  • 第5步 - 测试FTP访问
  • 第6步 - 保护交易
  • 第7步 - 使用FileZilla测试TLS
  • 第8步 - 禁用Shell访问(可选)
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档