一、FTP协议、服务器
FTP:文件传输协议(用于网络文件双向传输的应用层协议)
特点:最广泛、最底层、较简单,但是明文传输;适用于较大文件的传输
1.常见客户端、服务器
- 客户端:WINSCP or filezilla(windows),ftp(linux)
- 服务器:IIS(windows)、vsftpd(linux)
- VSFTPD:very secure FTP daemon
2.FTP服务参数
服务端
- 软件名:vsftpd
- 服务名:vsftpd
- 端口号:20、21、指定范围的随机端口
- 配置文件:/etc/vsftpd/vsftpd.conf
- 日志文件:/var/log/messages
客户端
- 软件名:ftp
- 格式:ftp 服务器ip
- 命令:连上ftp后,用help或?命令查看,!命令------可以执行客户端命令
注:ftp连接需要将客户端用户禁锢在家目录,防止权限过大
二、FTP用户模式
- 匿名用户模式:测试用户,用户名为ftp或anonymous,密码随意
- 本地用户模式:服务器上的/etc/passwd的用户(默认禁止/etc/vsftpd/user_list中用户连接)
- 虚拟用户模式(不做重点)
用户属性:账号、共享位置、访问权限、设置指定的访问权限、下载(上传)的文件的位置
访问权限
- FTP服务的访问权限:下载、上传、创建文件夹、其他写入权限等
- Linux系统的访问权限:r、w、x
1.匿名用户
服务端共享目录:/var/ftp
默认权限:可下载、不能上传(设置权限由两部分控制:主配置文件和文件系统权限)
客户端下载目录:下载在连接ftp时所在目录位置
匿名用户参数:
- anontmous_enable=YES 启用匿名访问
- anon_umask=022 匿名用户所上传文件的权限掩码
- anon_root=/var/ftp 匿名用户FTP的根目录
- anon_upload_enable=YES 允许上传文件
- anon_mkdir_write_enable=YES 允许创建目录
- anon_other_write_enable=YES 允许其他写权限
- anon_max_rate=2 限制最大传输速率(字节/秒)
参数设置注意事项:
- 想要使用,除配置文件允许外,还需要设置独立的文件系统权限(建议用acl)
- 即便可以上传文件,上传文件的权限也仅有600,其他人(包括上传者)无法下载使用
- 想要让其他人也能正常下载,需要修改匿名用户上传文件掩码值为022
2.本地用户
用户名、密码:服务器端设置的系统用户名和密码
服务端共享目录:系统用户家目录
默认权限(FTP的所有权限):可上传、下载、创建目录、删除、重命名等其他写入权限
客户端下载目录:下载在连接ftp时所在的目录位置
本地用户参数
- local_enable=YES 启用本地用户访问
- local_umask=022 本地用户所上传文件的权限掩码
- local_root=/home/用户名 设置本地用户的FTP根目录
- chroot_local_user=YES 是否将用户禁锢在主目录
- allow_writeable_chroot=YES 禁锢后允许写入
- local_max_rate=2 限制最大传输速率(字节/秒)
补充:useradd -s /sbin/nologin -d /data/ftp wangwu------设置不能登录系统;仅禁锢用户在主目录依旧不够安全,也要同时拒绝ssh连接的通道
设置了/sbin/nologin后,客户端用ftp有可能无法连接,因为服务端/etc/shells下没有/sbin/nologin,需要手动添加才可以连接
3.VSFTPD全局参数
- write_enable=YES 是否启用写入权限
- download_enable=YES 是否允许下载文件
- connect_timeout=60 主动模式下的连续超时时间
- accept_timeout=60 被动模式下的连续超时时间
- data_connection_timeout=300 进行完整数据传输后的再操作连接时间
- idle_session_timeout=300 验证完用户名和密码后等待传输数据的超时时间
注:其中有一个配置:pam_service_name=vsftpd,其中vsftpd指的是/etc/pam.d/vsftpd文件,该文件可验证/etc/vsftpd/ftpuser文件下用户登录;如果修改,则客户端连接会因为无法验证而失败
例:vim /etc/pam.d/vsftpd

其中,*.so文件是该服务的依赖,依赖分为动态依赖和静态依赖
- 静态依赖:static,随着服务启动而存在
- 动态依赖:如so,服务启动时没有,需要使用的时候加载
三、VSFTPD原理
工作模式:主动模式、被动模式
传输模式:ASCII模式、Binary模式
- ASCII模式:将文件内容转换成存储文本文件的格式;多用于传输文本文件
- BINARY(二进制)模式:不对数据进行任何处理,逐位复制;多用于传输非文本文件,如程序、数据库、压缩文件
1.FTP被动模式

被动模式原理
- 客户端连接服务器的21端口、验证用户名和密码,建立控制连接
- 客户端想传输数据时,在控制连接中发送PASV命令
- 服务器收到该命令后,生成随机端口返回给客户端、等待客户端的请求
- 传输数据时,客户端的随机端口连接服务器的指定端口,建立数据连接
- 客户端和服务器进行数据传输
注:20端口不在被动模式里
控制连接
客户端(随机端口)------服务端(21端口)
数据连接
客户端(随机端口)------服务端(指定端口)
被动切主动
- 客户端传输数据时,FTP服务默认采用被动模式
- 被动和主动是由客户端决定的
- 被动和主动作用的是服务器的动作,是主动连接还是被动的等待连接
- 使用主动模式:ftp>passive off
2.FTP主动模式

主动模式原理
- 客户端连接服务器的21端口、验证用户名和密码,建立控制连接
- 客户端想传输数据时,在控制连接中发送PORT命令【1.该命令中包含了客户端想要进行数据传输的指定端口;2.服务器收到该命令后,会主动连接客户端】
- 要传输数据时,服务器的20端口连接至客户端的指定端口,建立数据连接
- 客户端和服务器进行数据传输
控制连接
客户端(随机端口)------服务器端(21端口)
数据连接
服务端(20端口)------客户端(指定端口)
3.模式对比
(1)控制连接过程不同
(2)数据连接部分不同【FTP的主被动模式是由客户端决定的,针对服务器而言的】
(3)使用场景不同:
- FTP服务器较弱时,可以考虑主动模式;
- 公网无法要求客户端开放防火墙,一般采用被动模式;
- 被动模式下,可以通过pasv_min_port和pasv_max_port控制随机端口范围
4.问题:为什么用被动连接模式?
- 主动模式下数据连接都走20端口,压力大
- 防火墙规则:管进不管出;主动连接在数据传输时需要客户端放行端口、不太可控
四、本地用户登录及设置
1.服务端(77.77)
bash
#安装软件
$ dnf -y install vsftpd
#开启服务
$ systemctl start vsftpd
#通过端口验证开启成功,结果中可以看到用来监听的21端口
$ ss -antp | grep vsftpd
#禁锢本地用户只能在自己的家目录范围
#注意此时应该先把要上传共享目录的文件系统权限设置上
$ vim /etc/vsftpd/vsftpd.conf
#禁锢本地用户在家目录
chroot_local_user=YES
#禁锢本地用户后允许写权限
allow_writeable_chroot=YES
#重启服务
$ systemctl restart vsftpd
实验:
bash
[root@localhost ~]# dnf -y install vsftpd
[root@localhost ~]# systemctl start vsftpd
[root@localhost ~]# ss -anpt | grep vsftpd
LISTEN 0 32 *:21 *:* users:(("vsftpd",pid=991,fd=3))
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
chroot_local_user=YES
allow_writeable_chroot=YES
[root@localhost ~]# systemctl restart vsftpd
2.客户端(77.79)
#安装连接命令
$ dnf -y install ftp
#连接ftp服务器
$ ftp ftp服务器IP
输入用户名:vsftpd服务的用户名
输入密码:vsftpd服务该用户的密码
ftp> pwd #查看当前位置,在本地用户的家目录即/home/用户名
ftp> get 文件名 #从共享目录下载文件到客户端的当前位置
ftp> put 文件名 #向共享目录上传文件、默认有权限
ftp> mkdir 目录名 #在共享目录中创建目录的权限、默认有权限
ftp> rename、delete等 #在共享目录的其他写权限、默认有权限
实验:
bash
[root@localhost ~]# ftp 192.168.77.77
Connected to 192.168.77.77 (192.168.77.77).
220 (vsFTPd 3.0.5)
Name (192.168.77.77:root): zhaoliu
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ?
Commands may be abbreviated. Commands are:
! debug mdir sendport site
$ dir mget put size
account disconnect mkdir pwd status
append exit mls quit struct
ascii form mode quote system
bell get modtime recv sunique
binary glob mput reget tenex
bye hash newer rstatus tick
case help nmap rhelp trace
cd idle nlist rename type
cdup image ntrans reset user
chmod lcd open restart umask
close ls prompt rmdir verbose
cr macdef passive runique ?
delete mdelete proxy send
ftp> ls
227 Entering Passive Mode (192,168,77,77,134,90).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Sep 08 13:49 1.txt
-rw-r--r-- 1 0 0 0 Sep 08 13:49 2.txt
-rw-r--r-- 1 0 0 0 Sep 08 13:49 3.txt
-rw-r--r-- 1 0 0 0 Sep 08 13:49 4.txt
-rw-r--r-- 1 0 0 0 Sep 08 13:49 5.txt
226 Directory send OK.
ftp> pwd
257 "/" is the current directory
ftp> get 1.txt
local: 1.txt remote: 1.txt
227 Entering Passive Mode (192,168,77,77,164,68).
150 Opening BINARY mode data connection for 1.txt (0 bytes).
226 Transfer complete.
ftp> !ls
1.txt anaconda-ks.cfg cat.sh nginx-1.26.3.tar.gz ng.txt
ftp> put cat.sh
local: cat.sh remote: cat.sh
227 Entering Passive Mode (192,168,77,77,211,74).
150 Ok to send data.
226 Transfer complete.
389 bytes sent in 9.6e-05 secs (4052.08 Kbytes/sec)
ftp> mkdir bik.d
257 "/bik.d" created
ftp> delete 3.txt
250 Delete operation successful.
注:在/etc/vsftpd/user_list中定义了被拒绝使用ftp服务的系统用户
补充
windows客户端
1、在文件资源管理器的地址栏中,输入:ftp://vsftpd服务IP/,右键登录
或者:ftp://username:password@vsftpd服务IP
2、filezilla软件
五、匿名用户登录及设置
1.服务端(77.77)
bash
#安装软件
$ dnf -y install vsftpd
#开启服务
$ systemctl start vsftpd
#通过端口验证开启成功,结果中可以看到用来监听的21端口
$ ss -antp | grep vsftpd
#注意此时应该先把要上传共享目录的文件系统权限设置上
$ vim /etc/vsftpd/vsftpd.conf
#开启匿名用户模式
anonymous_enable=YES
#设置上传权限
anon_upload_enable=YES
#设置创建目录权限
anon_mkdir_write_enable=YES
#设置上传后文件或创建目录后的默认权限
anon_umask=022
#设置其他写入权限
anon_other_write_enable=YES
#重启服务
$ systemctl restart vsftpd
注1:权限生效=vsftpd服务开放权限+有文件系统权限(否则会出现550错误状态码)
注2:匿名用户一定不要改/var/ftp这个目录的文件系统权限,否则退出后服务再起不来
注3:配置文件里的布尔类型(YES或NO),结尾不能有空格
2.客户端(77.79)
bash
#安装连接命令
$ dnf -y install ftp
#连接ftp服务器
$ ftp ftp服务器IP
输入用户名:ftp 或 anonymous
输入密码:随便输入、一般输空直接回车
ftp> pwd #查看当前位置,在匿名用户的共享根目录即/var/ftp
ftp> get 文件名 #从共享目录下载文件到客户端的当前位置
ftp> put 文件名 #向共享目录上传文件、默认没有
ftp> mkdir 目录名 #在共享目录中创建目录的权限、默认没有
ftp> rename、delete等 #在共享目录的其他写权限、默认没有
实验:
bash
[root@localhost ~]# ftp 192.168.77.77
Connected to 192.168.77.77 (192.168.77.77).
220 (vsFTPd 3.0.5)
Name (192.168.77.77:root): ftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
257 "/" is the current directory
ftp> ls
227 Entering Passive Mode (192,168,77,77,225,225).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Sep 08 14:02 a.txt
-rw-r--r-- 1 0 0 0 Sep 08 14:02 b.txt
-rw-r--r-- 1 0 0 0 Sep 08 14:02 c.txt
-rw-r--r-- 1 0 0 0 Sep 08 14:02 d.txt
-rw-r--r-- 1 0 0 0 Sep 08 14:02 e.txt
-rw-r--r-- 1 0 0 0 Sep 08 14:02 f.txt
drwxr-xr-x 2 0 0 6 Oct 30 2023 pub
226 Directory send OK.
ftp> !ls
1.txt anaconda-ks.cfg cat.sh nginx-1.26.3.tar.gz ng.txt
#服务器端已配置好vsftpd相关服务,但ftp用户没有文件系统权限
ftp> put cat.sh
local: cat.sh remote: cat.sh
227 Entering Passive Mode (192,168,77,77,81,146).
553 Could not create file.
ftp> mkdir 1.txt
550 Create directory operation failed.
#使用setfacl -m u:ftp:rwx /var/ftp/手动为根目录添加写权限,再试
ftp> mkdir 1.txt
257 "/1.txt" created
ftp> put cat.sh
local: cat.sh remote: cat.sh
227 Entering Passive Mode (192,168,77,77,181,17).
150 Ok to send data.
226 Transfer complete.
389 bytes sent in 3.7e-05 secs (10513.51 Kbytes/sec)
注:默认情况下,只有写权限;不可以用chmod o+w的方式设置文件系统写权限,因为会导致权限泄露;目录只有拥有w权限,才可以创建子文件、子目录、删除文件或改名。
六、VSFTPD加密
1.加密方式(vsftpd+ssl)
- ssl:Secure Socket Layer,安全套接字,安全性协议
- TLS:基于SSL开发,支持更多功能
实验:在服务端使用tcpdump工具抓包,客户端连接

可以看到用户名和密码都是明文传输,并不安全,所以才需要ssl进行加密
2.SSL主要功能
- 认证用户和服务器
- 加密数据
- 维护数据的完整性
3.PKI组成:公钥基础设施(CA,X.509,SSL)
- CA:证书申请------审批------发放------更新------查询、撤销、废止------归档
- 常见的CA机构:Let's Encrypt
- CA申请:公网域名+ip
- 实验:模拟做自签名证书------自己信任
4.加密原理
- 服务端在本地生成一对密钥,携数据、公钥申请CA认证
- CA机构通过单项的哈希算法(如MD5)将申请加密为"信息摘要"
- CA机构对"信息摘要"进行再次加密,变成数字签名
- 数字证书=申请信息+服务器公钥+数字签名
5.加密步骤
(1)安装ssl软件包(openssl和open-devel)
bash
[root@localhost ~]# dnf -y install openssl openssl-devel
(2)基于ssh生成密钥对(对称加密)
bash
#密钥对vsftpd.key
[root@localhost vsftpd]# openssl genrsa -out vsftpd.key 2048
[root@localhost vsftpd]# ls
ftpusers user_list vsftpd.conf vsftpd_conf_migrate.sh vsftpd.key
(3)拿公钥、公司信息做数字证书申请
bash
[root@localhost vsftpd]# openssl genrsa -out vsftpd.key 2048
[root@localhost vsftpd]# ls
ftpusers user_list vsftpd.conf vsftpd_conf_migrate.sh vsftpd.key
[root@localhost vsftpd]# openssl req -new -key vsftpd.key -out vsftpd.csr
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) [XX]:cn
State or Province Name (full name) []:shanxi
Locality Name (eg, city) [Default City]:lvliang
Organization Name (eg, company) [Default Company Ltd]:tuanyuan
Organizational Unit Name (eg, section) []:qingnian
Common Name (eg, your name or your server's hostname) []:qingnian
Email Address []:320966772@qq.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@localhost vsftpd]# ls
ftpusers user_list vsftpd.conf vsftpd_conf_migrate.sh vsftpd.csr vsftpd.key
(4)签发证书
bash
[root@localhost vsftpd]# openssl x509 -req -days 365 -sha256 -in vsftpd.csr -signkey vsftpd.key -out vsftpd.crt
Certificate request self-signature ok
subject=C = cn, ST = shanxi, L = lvliang, O = gongqing, OU = qingnian, CN = xxhf
[root@localhost vsftpd]# ls
ftpusers user_list vsftpd.conf vsftpd_conf_migrate.sh vsftpd.crt vsftpd.csr vsftpd.key
补充:Linux证书扩展名:.crt或.pem(但以pem为扩展名的不一定是证书)
(5)将ssl相关配置写入配置文件(添加加密设置)
vim /etc/vsftpd/vsftpd.conf
bash
#启用ssl认证
ssl_enable=YES
#开启tlsv1、sslv2、sslv3都支持,转换成使用tls1.2
ssl_tlsv1=YES
ssl_sslv2=YES
ssl_sslv3=YES
#允许匿名用户{虚拟用户}
allow_anon_ssl=YES
#匿名登录和传输时强制使用ssl
force_anon_logins_ssl=YES
force_anon_data_ssl=YES
#本地登录和传输时强制使用ssl
force_local_logins_ssl=YES
force_local_data_ssl=YES
#rsa格式的证书
rsa_cert_file=/etc/vsftpd/vsftpd.crt
#rsa格式的公钥
rsa_private_key_file=/etc/vsftpd/vsftpd.key
(6)重启服务
bash
[root@localhost vsftpd]# systemctl start vsftpd
6.客户端验证
注:要找支持ftp、ftps协议的客户端
服务端监听:tcpdump -nA -i ens160 port 21 > ftp2.txt
客户端连接:第三方工具filezilla或lftp服务,均可以看到用户名和密码已经被加密
安装lftp
bash
[root@localhost ~]# dnf -y install lftp
bash
[root@localhost ~]# lftp -u zhaoliu -e "set ssl:verify-certificate no" 192.168.77.77
Password:
lftp zhaoliu@192.168.77.77:~> ls
-rw-r--r-- 1 0 0 0 Sep 08 13:49 1.txt
-rw-r--r-- 1 0 0 0 Sep 08 13:49 2.txt
-rw-r--r-- 1 0 0 0 Sep 08 13:49 4.txt
-rw-r--r-- 1 0 0 0 Sep 08 13:49 5.txt
drwxr-xr-x 2 1004 1004 6 Sep 08 13:50 bik.d
-rw-r--r-- 1 1004 1004 389 Sep 08 13:50 cat.sh
查看服务端文件,可以看到用户名和密码均已被加密

补充说明:
- lftp------命令跟shell都一样;支持fpts协议;vsftpd重启,客户端连接不断
- 虚拟机和真实机时间不同步,可能会导致证书不生效,需要同步时间,可在虚拟机------设置------选项------时间同步,中设置