FTP基本概念
连接方式
FTP使用两个TCP连接,一个用于控制连接,用于传输命令和响应;另一个是数据连接,用于实际的文件上传下载的数据传输。在传输过程中,控制连接始终保持连接,而数据连接在文件传输过程中打开,传输完毕后关闭。
数据连接分为以下两种模式:
主动模式
主动模式下,客户端从任意空高位端口发起控制连接到服务器(默认21端口)请求数据传输;然后服务器从自己端口(默认20)主动建立数据连接到客户端指定的数据端口。
特点:
- 客户端使用任意空闲的高位端口(>1024)作为数据传输端口。
- 数据连接由服务器发起,因此,客户端防火墙需要允许服务器访问对应端口。
被动模式
被动模式下,服务器监听一个端口,当客户端通过控制连接与服务器建立连接后,服务器为数据连接分配一个数据端口(配置的端口范围内),客户端通过数据端口进行数据传输。
特点:
- 服务器除了控制连接的端口还需要开放用于数据连接的端口。
- 客户端主动连接到服务器提供的数据连接的端口进行数据上传。
- 不需要服务器主动建立连接,对于防火墙和NAT环境更加友好。
加密方式
Implicit TLS/SSL
Implicit TLS/SSL模式下客户端和服务器在建立连接时立即进行TLS/SSL握手,从一开始就进行加密,没有明文通信,整个会话从一开始就进行加密保护(默认的连接端口990)。
Explicit TLS/SSL
Explicit TLS/SSL模式下, 客户端和服务器首先先建立一个普通未加密的FTP连接(默认21端口),然后由客户端通过发送Auto TLS命令请求加密,然后服务器与客户端进行TLS握手,后续的会话通过加密通道进行。
安装配置vsftpd(被动模式)
1. 安装vsftpd
sudo apt update
sudo apt install vsftpd
备份配置文件
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.backup
2.创建ftp用户
chroot 配置是vsftpd用来限制ftp连接只能访问特定目录的,开启chroot时,ftpuser默认被限制只能访问自己的家目录,但需要去掉用户的写权限。如果这个用户只用于FTP上传,可以这样弄;但如果用户还需要在自己的家目录做其他写操作的话,可以在家目录中重新建一个FTP用的目录,然后调整这个目录的权限作为chroot限制目录。
- 创建用户
sudo adduser ftpuser
- 创建ftp目录
sudo mkdir /home/ftpuser/ftp
- 更改文件归属和权限
sudo chown nobody:nogroup /home/ftpuser/ftp
--删除写权限
sudo chmod a-w /home/ftpuser/ftp
- 创建上传文件目录
sudo mkdir /home/ftpuser/ftp/files
sudo chown ftpuser:ftpuser /home/ftpuser/ftp/files
3.修改配置文件
配置文件位于/etc/vsftpd.conf,需要修改对应项为如下配置(默认配置文件有的需要解除注释,没有的,需要添加到文件中)
- 禁止匿名登录
anonymous_enable=NO
- 允许本地用户登录
local_enable=YES
- 允许上传文件
write_enable=YES
- 阻止访问ftp上传以外的目录
chroot_local_user=YES
- 添加user_sub_token,以插入用户名到ftp的访问目录local_root中,后续添加其他ftp用户时只需要创建对应目录即可
user_sub_token=$USER
local_root=/home/$USER/ftp
- 被动模式下,添加数据端口范围,需要保证足够的可用连接
pasv_min_port=40000
pasv_max_port=50000
- 为了便于管理,设置用户只有被添加到vsftpd.userlist中才能进行访问
userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO
然后保存配置文件。
- 添加vsftpd.userlist文件,并添加ftpuser
echo "ftpuser" | sudo tee -a /etc/vsftpd.userlist
- 重启vsftpd服务
sudo systemctl restart vsftpd
4.放行ftp端口
最后需要在防火墙中放行ftp的连接端口和数据端口;如果使用的是UFW工具,执行以下命令开启端口:
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 40000:50000/tcp
如果开启TLS,也需要放行对应的端口;最后,可通过sudo ufw status
命令检查防火墙状态。
5.测试ftp
- 登录ftp
ftp -p ip
--output
Connected to ip
220 (vsFTPd 3.0.3)
Name (ip:default): ftpuser
331 Please specify the password.
Password: password
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>
- 测试下载权限
-- 创建测试文件
echo "vsftpd test file" | sudo tee /home/ftpuser/ftp/files/test.txt
cd files
get test.txt
- 测试写权限
put test.txt upload.txt
配置SSL安全传输
- 创建ssl 证书
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem
/etc/vsftpd.conf 配置文件中添加如下配置:
- 开启ssl,并配置证书
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
ssl_enable=YES
- 设置使用TLS
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
- 关闭连接重用(可选,开启这个部分客户端无法正常连接),并设置使用高级加密套件(key长度大于等于128bit)
require_ssl_reuse=NO
ssl_ciphers=HIGH
- 最终ssl部分配置为以下内容
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
require_ssl_reuse=NO
ssl_ciphers=HIGH
- 重启vsftp服务
sudo systemctl restart vsftpd
参考内容
How To Set Up vsftpd for a User’s Directory on Debian 10
Configuring a Secure FTP Server with VSFTPD on Debian 12
How to Configure a VSFTP Server to Run in Passive Mode on Ubuntu 20.04 and Debian 11
看懂FTP的主动和被动模式