部署自己的FTP服务

橘子 发布于 2025-08-08 137 次阅读


想在自己的服务器上部署FTP服务吗?搜了一下,很多文章推荐vsftpd,理由是容易配置……

扯淡!非常难配置!需要注意的地方非常多,会踩很多坑!

这篇文章记录一下详细教程……

目的

这个FTP服务器主要预期效果如下:

  1. 开放一个FTP服务。
  2. 必须有权限认证,也就是禁用匿名登录,需要使用用户名和密码登录。但是,不希望该用户同时拥有SSH等其他权限,这样不安全。
  3. 必须使用SSL加密内容。

参考文档

安装与配置

安装

sudo apt-get update
sudo apt-get install vsftpd

接着检查用户。应该可以发现一个以及创建的名为“ftp”的用户。使用如下命令可以查看该用户的情况:

getent passwd ftp

得到的输出如下:

ftp:x:112:114:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin

这就说明默认根目录是 /srv/ftp。 有的教程会让你自己新建一个用户,或者使用ftp用户但是目录却是/var/ftp。这里我们还是使用默认目录/srv/ftp,但是稍后会创建一个新的名为ftpuser的用户。

配置

在开始编辑前,强调一下,禁止行尾注释!!!否则会出错!!!我就是被千问输出的配置给误导了,百炼的千问还是太笨了。一旦有行尾注释,这个配置项就不能正确解析……

备份原始文件并且使用vim修改:

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak
sudo vim /etc/vsftpd.conf

但是这个过程会很麻烦,因为这里注释很多很长,推荐使用vscode编辑会好很多:

ls /etc/vsftpd.conf -lah
sudo chmod 666 /etc/vsftpd.conf
code /etc/vsftpd.conf
# 修改完了之后
sudo chmod 644 /etc/vsftpd.conf

我修改的配置如下,注意有一些其他默认选项没放在这里,维持原样即可:

# 禁用匿名登录
anonymous_enable=NO
# 允许本地用户登录
local_enable=YES
# 允许所有写操作(全局开关)
write_enable=YES
# 设置文件权限mask。022表示文件权限为 644,目录为 755。
local_umask=022
# 鉴权使用的 PAM service名称
pam_service_name=vsftpd
# SSL设置,禁止SSL数据连接都需要表现出SSL会话重用
rsa_cert_file=/path/to/your/file.pem
rsa_private_key_file=/path/to/your/file.key
ssl_enable=YES
require_ssl_reuse=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
# 使用UTF8
utf8_filesystem=YES

# 指定用户的根目录(所有用户将被限制在此目录)
local_root=/srv/ftp
# 禁止用户跳出根目录
chroot_local_user=YES
# 允许chroot的写权限
allow_writeable_chroot=YES
# 鉴权设定,使用用户名单
userlist_enable=YES
# 鉴权设定,用户名单为白名单(默认deny=YES就是黑名单)
userlist_deny=NO
# 默认的用户列表为 /etc/vsftpd.user_list
userlist_file=/etc/vsftpd.user_list
# 是否检查登录用户有shell权限,NO为不检查
check_shell=NO
# 设置被动模式端口范围
pasv_min_port=21000
pasv_max_port=21100

设置登录用户

不能使用“ftp”这个用户!这是因为协议规定,这个用户名和anonymous均视为匿名用户。

创建一个新的名为ftpuser的用户,并且设置密码:

sudo useradd ftpuser -d /srv/ftp -s /sbin/nologin
sudo passwd ftpuser

检查一下目录权限。如果该目录的所有者是ftp就一切正常,就不需要后续修改所有者的操作。这里默认的权限应该是 drwxr-xr-x,也就是755,表示只有自己可读可写,其他都是只读。此外目录必须给可执行权限才能用cd。

ls /srv/ftp -lah
sudo chown -R ftpuser:ftpuser /srv/ftp
sudo chmod 755 /srv/ftp

然后,需要检查ftp服务的权限认证逻辑。回顾一下先前配置的/etc/vsftpd.conf,里面有一个没提到的配置,如下:pam_service_name=vsftpd ,这行配置的意思是说,权限认证的服务会使用配置文件。

如果现在你去尝试登录ftp,会发现用户ftpuser无法登录。还记得先前创建ftpuser的命令吗?注意看shell设置。/sbin/nologin,这表示ftpuser用户的根目录是/srv/ftp,而登录使用的shell是/usr/sbin/nologin,也就是不允许shell登录。这就是问题所在。查看配置 /etc/pam.d/vsftpd,会发现内容如下:

# Standard behaviour for ftpd(8).
auth    required        pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed

# Note: vsftpd handles anonymous logins on its own. Do not enable pam_ftp.so.

# Standard pam includes
@include common-account
@include common-session
@include common-auth
auth    required        pam_shells.so

这里的最后一行,就约定了登录的用户必须要有shell权限。而用户ftpuser没有shell权限!所以无法使用它登陆。而我们希望的是,当你给别人授权一个ftp用户时,他不能使用ssh登录,也无法使用shell。而把ftpuser使用的shell设置为/usr/sbin/nologin之后,你就会发现虽然可以在ssh时指定用户为ftpuser,并且输入密码会有成功连接的界面,但是连接建立后会显示:

This account is currently not available.
Connection to xxxx closed.

这就是正确的安全配置,让ftpuser用户不能登录shell。所以这就是矛盾所在:

  1. 我们的需求是,只给ftpuser用户有限的权限,不让他们使用shell。
  2. vsftpd的鉴权逻辑是,只给拥有shell权限的用户放行。

所以这里解决冲突就有两个方向:

  1. 给用户shell权限,风险就是该用户会得到SSH权限。这是很危险的。
  2. 不给ftpuser用户开放shell。修改vsftpd的鉴权逻辑,不检查SHELL。但同时,一旦不检查shell,其他没有配置shell的用户(比如sys、www之类的你平时都不知道他们存在的用户)就可以连接上ftp服务了,这也很危险。所以最好配置ftp用户的白名单,只放行白名单内的用户。

这里采用的是方法2. 换句话说,我们不给ftpuser用户开放shell权限,通过设置白名单的方法约定哪些用户可以使用FTP服务。主要分为以下几个步骤:

修改/etc/pam.d/vsftpd,使用#号注释掉shell鉴权这一行:

# auth    required        pam_shells.so

确保/etc/vsftpd.conf中有如下设定:

# 鉴权设定,使用用户名单
userlist_enable=YES
# 鉴权设定,用户名单为白名单(默认deny=YES就是黑名单)
userlist_deny=NO
# 默认的用户列表为 /etc/vsftpd.user_list
userlist_file=/etc/vsftpd.user_list
# 是否检查登录用户有shell权限,NO为不检查
check_shell=NO

添加用户ftp到白名单,这里也可以用vim或者其他编辑方式:

echo "ftpuser" | sudo tee -a /etc/vsftpd.user_list

到此配置完毕。重启服务,就可以使用ftpuser用户登录了。

这里说一个题外话,/etc/pam.d/vsftpd第一行约定了使用/etc/ftpusers文件作为黑名单,不过这个文件似乎默认情况下不会创建。此外,默认的设定下/etc/vsftpd.user_list是黑名单,一定要设置 userlist_deny=NO 转变为白名单。

重启FTP

重启指令:

sudo service vsftpd restart

测试连接

首先在本地测试能否连接到ftp,最好测试一下能否连接、能否上传下载、能否跳出目录(测试权限配置是否正确)、测试是否启用了ssl。

ftp localhost
# 输入用户名和密码
530 Non-anonymous sessions must use encryption.
ftp: Login failed

这就说明强制启用了SSL。可以使用FileZilla等客户端,更方便的测试。

远端视频流

使用ftp服务的一个诱因其实是希望远端提供视频流服务。简单来说,使用ftp上传视频到服务器,再使用SMB共享文件,手机只要通过SMB连接到服务器就可以不用下载视频直接播放视频流了。

这里有几个技术要素: