FTP服务 文件传输协议

发布于:2025-07-06 ⋅ 阅读:(17) ⋅ 点赞:(0)

FTP(File Transfer Protocol,文件传输协议)是一种用于在计算机网络上进行文件传输的标准协议。通过FTP服务,用户可以上传、下载、删除和重命名文件,以及创建和删除目录等操作。

注意:一般 FTP 是“客户端-上传到服务端”模式,内网做服务端,外部主动连接,总之是内网服务器做服务端

所以需要保证客户端能访问到服务端,服务端需要有公网 或者 需要在路由器上做端口映射

目标:

● 掌握:FTP的工作原理

● 掌握:FTP安装部署

● 掌握:FTP访问控制

5.1 VSFTP 概述 (安全的FTP)

Vsftpd(Very Secure FTP Daemon)是linux类操作系统上运行的ftp服务器软件,FTP(文件传输协议)全称是:Very Secure FTP Server

ftp客户端软件:

linux:ftp lftp

windows:FileZilla 快速搭建FTP服务器(局域网内文件共享) 【Windows系统 IIS】_哔哩哔哩_bilibili 几分钟学会

功能: 提供主机间的文件共享

服务端口:

21		## 端口用于连接 
20		## 端口用于传输数据

工作模式 (VSFTP的通讯原理)

注意:无论是主动还是被动模式,都是对于 服务端 来说

1 主动模式(PORT):

阶段1:
FTP控制连接   客户端(源端口 :随机) -- 主动叩开 --> 服务端(目标端口:21)

阶段2:
FTP数据传输   客户端(目标端口:随机) <-- 主动叩开 -- 服务端(源端口 :20)

从防火墙的角度来看:
   在数据传输阶段,是:FTP服务器 --> 主动叩开 --> FTP客户端的防火墙

原理图如下

在这里插入图片描述

2 被动模式 (PASV) 并未使用20端口

在被动模式下,服务器动态分配一个大于1024的端口号作为数据连接端口,以避免防火墙或路由器的限制。

阶段1:
FTP建立连接  客户端(源端口:随机) -- 主动叩开 --> 服务端(目标端口:21)

阶段2:
FTP数据传输  客户端(源端口:随机) -- 主动叩开 --> 服务端(目标端口:1024~65535)

从防火墙的角度来看:
   在<数据传输阶段>是:FTP客户端 --> 主动叩开 --> FTP服务器的防火墙
   
## 注意:一般情况下,默认的是被动模式

原理图如下

在这里插入图片描述

步骤:

  1. 主动模式(PORT)

    所谓主动模式,指的是FTP服务器主动去连接客户端的数据端口来传输数据(不是服务端主动连接客户端,是客户端请求了,服务端才主动连接)

    其过程具体来说就是:客户端从一个任意的非特权端口N(N>1024)连接到FTP服务器的命令端口(即tcp 21端口),紧接着客户端开始监听端口N+1,并发送FTP命令“port N+1”到FTP服务器。然后服务器会从它自己的数据端口(20)“主动”连接到客户端指定的数据端口(N+1),这样客户端就可以和ftp服务器建立数据传输通道了。

  2. 被动模式(PASV)

    所谓被动模式,指的是FTP服务器被动等待客户端来连接自己的数据端口

    其过程具体是:当开启一个FTP连接时,客户端打开两个任意的非特权本地端口N(N >1024)和N+1。第一个端口连接服务器的21端口,但与主动方式的FTP不同,客户端不会提交PORT命令并允许服务器来回连它的数据端口,而是提交PASV命令。这样做的结果是服务器会开启一个任意的非特权端口P(P > 1024),并发送PORT P命令给客户端。然后客户端发起从本地端口N+1到服务器的端口P的连接用来传送数据。

    注意:此模式下的FTP服务器不需要开启tcp 20端口

主动模式在防火墙后面可能会遇到问题,因为客户端需要接受来自服务器的数据连接。在现代网络环境中,被动模式更为普遍使用。更安全

5.2 安装 FTP 组件

安装 和 启动 VSFTP

yum install -y vsftpd xferstats
systemctl enable vsftpd && systemctl start vsftpd	 
netstat -tunlp |grep vsftpd		

## vsftpd:   FTP主程序
## xferstats:log组件 										

客户端下载

yum install -y lftp       				 		## 然后就可以使用 ftp 去连接查看
systemctl enable lftp && systemctl start lftp

配好主配置文件之后,如果给了上传和下载的权限,可以进行如下操作

比如服务端ip是 192.168.58.100
客户端匿名用户连接 lftp 192.168.58.100 进去后 cd pub ,进去才算成功
进去的是 服务端的 ftp 家目录 即 /var/ftp /var/ftp/pub

上传1.txt到上面   put 1.txt
下载1.txt下来用   get 1.txt -o /tmp/	

## -o 指定下载到哪
## 该目录相当于是中转站,共享目录,可从服务端上传和下载内容到客户

如果是用户连接,比如dj用户

注意 dj 用户服务端创建的用户而不是客户端的用户,虽然在客户端指定用户登录

lftp -u dj 192.168.58.100 
或者 
lftp dj@192.168.58.100  
不能 
lftp -u dj@192.168.58.100

注意:/var/ftp/pub 目录是下载 vsftpd 就存在,lftp 服务只是用来建立连接

配置防火墙

针对<FTP连接控制阶段>:开放<21/tcp>端口,加载<ftp连接状态跟踪模块>,允许客户端<被动模式>下的<数据传输连接> 使用服务的方式无需理会端口的改变

firewall-cmd --permanent --zone=public --add-service=ftp
firewall-cmd --reload

配置:SElinux针对FTP的安全策略

setsebool -P ftpd_full_access on
setsebool -P ftpd_use_passive_mode on
setsebool -P ftpd_connect_all_unreserved on
getsebool -a | grep ftpd

备注:
ftpd_use_nfs                 	## 允许ftpd使用<NFS共享文件系统>
ftpd_use_cifs               	## 允许ftpd使用<cifs共享文件系统>
ftpd_use_fusefs             	## 允许ftpd使用<fusefs文件系统>
ftpd_connect_db            	 	## 允许ftpd连接<数据库>
ftpd_full_access                ## 允许ftpd的<所有的访问>
ftpd_use_passive_mode      	 	## 允许ftpd的<passive被动模式>
ftpd_connect_all_unreserved 	## 允许ftpd连接<所有的非保留端口>
ftpd_anon_write             	## 允许ftpd的<匿名读写> ,anon 表示匿名

推荐直接关闭selinux

sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
reboot  # 重启生效

如果没法重启
setenforce 0  # 切换为 Permissive 模式(仅记录不拦截)

5.3 FTP 的配置文件解析

1 FTP 的配置文件如下

[root@sun pub]# cd /etc/vsftpd/
[root@sun vsftpd]# ll
总用量 20
-rw-------. 1 root root  125 610 2021 ftpusers
-rw-------. 1 root root  361 610 2021 user_list
-rw-------. 1 root root 5116 610 2021 vsftpd.conf
-rwxr--r--. 1 root root  338 610 2021 vsftpd_conf_migrate.sh

注意:加粗为重要

常用的配置文件 功能作用 与之关联的<主配置文件>参数
/etc/vsftpd/vsftpd.conf FTP主配置文件 所有功能均由此文件定义
/etc/vsftpd/ftpusers FTP用户黑名单 无独立参数,强制生效
/etc/vsftpd/user_list FTP用户控制列表 需要使用:userlist_enable=YES 启用
/var/ftp 匿名用户的家目录 anon_root=/var/ftp(可自定义路径)
/var/ftp/pub 默认上传下载的目录 需要使用:anon_upload_enable=YES和 anon_mkdir_write_enable=YES
允许匿名用户上传和创建目录

2 /etc/vsftpd/vsftpd.conf (FTP主配置文件)

一般情况下配置这个文件和创建ftp用户即可

[root@dj exports.d]# cat /etc/vsftpd/vsftpd.conf | egrep -v "^[ \s]*(#|$)"
anonymous_enable=YES		
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES

下面是解析

[root@dj exports.d]# cat /etc/vsftpd/vsftpd.conf | egrep -v "^[ \s]*(#|$)"
anonymous_enable=YES		允许匿名用户登录
local_enable=YES			允许本地用户登录
write_enable=YES			允许用户进行写操作 上传和删除文件
local_umask=022				设置本地用户创建文件的默认权限掩码为 022
dirmessage_enable=YES		启用目录列表中的消息显示功能  当<FTP用户>第一次进入<一个目录>时,显示<欢迎词>的功能
xferlog_enable=YES			启用传输日志记录功能
connect_from_port_20=YES	使用数据连接的端口 20
xferlog_std_format=YES		将传输日志记录为标准格式
listen=NO					禁用独立模式,通过 inetd 或 systemd 来管理 VSFTPD 服务
listen_ipv6=YES				启用 IPv6 监听
pam_service_name=vsftpd		使用 VSFTPD 作为 PAM 服务名称  重要  验证使用
userlist_enable=YES			启用用户列表功能	
tcp_wrappers=YES			启用 TCP 包装器,用于基于主机的访问控制  # 共13行 定义了本地 和 匿名用可以登录

下边也是解析

通过man vsftpd.conf命令,可以查看vsftpd.conf配置文件的中各种参数含义及默认值
通过/usr/share/doc/vsftpd-3.0.2/EXAMPLE目录,可以学习查看<各种FTP主配置文件>的<帮助模板文件>

cat /etc/vsftpd/vsftpd.conf | grep -vP "^[ \t]*(#|$)"    去掉空行和注释

进程管理、工作模式、端口、日志、消息、安全、时限 ... 等等

listen=NO                   ## 不开启:<基于IPv4的独立进程模式>,意味着 隶属<xinetd超级进程>,不由FTP自身来处>理传入的连接
listen_ipv6=YES             ## 开启:<基于IPv6的独立进程模式>,意味着不隶属<xinetd超级进程>, 由FTP自身来处>理传入的连接。
connect_from_port_20=YES  	## 设置:<主动模式>的<20/tcp源端口>
xferlog_enable=YES          ## 启用:日志功能,默认的日志文件为:/var/log/vsftpd.log
xferlog_std_format=YES      ## 定义:<日志消息>采用<标准的xferlog格式>,将生成:/var/log/xferlog日志文件                           							    ## 默认未启用</var/log/xferlog日志文件的写入功能>,需要使用 dual_log_enable=YES                         
							## 我们可以注释掉xferlog_std_format=YES选项,从而只使用/var/log/vsftpd.log
tcp_wrappers=YES         	## 启用:<TCP Wrappers访问控制>功能,实现<基于主机IP和主机名>的访问控制 
							## <TCP Wrappers访问控制>涉及</etc/hosts.allow文件>和</etc/hosts.deny文件>
dirmessage_enable=YES     	## 启用:当<FTP用户>第一次进入<一个目录>时,显示<欢迎词>的功能
                            ## <欢迎词>默认来自于<目录>中的<.message隐藏文件>,我们可以手动创建<.message隐藏文件>                                           								## 例如:echo "欢迎光临" > /var/ftp/.message
## 例如:echo "欢迎光临" > /var/ftp/pub/.message## 用户控制 ... 等等
       
pam_service_name=vsftpd     ## 指定:vsftpd所使用的<pam本地用户验证模块>,这个参数很重要,否则<本地用户>无法>通过验证,必有
local_enable=YES            ## 允许:<本地用户>访问,<本地用户>指<非匿名账户>,<虚拟用户>也属于<本地用户>
userlist_enable=YES         ## 启用:</etc/vsftpd/user_list配置文件>的<FTP用户控制列表>功能
anonymous_enable=YES        ## 允许:匿名访问,匿名账户为:anonymous 或 ftp
write_enable=YES            ## 允许:全局性<写入权限> 如果局部另外定义则听局部的,没有就听全局的
local_umask=022             ## 设置:<本地用户>创建<文件或目录>时的<umask权限掩码> 权限目录 755 文件 644 可不设置

配置例子

##网络及服务设置
listen=NO					(不监听):表示不监听任何网络接口。
listen_ipv6=YES				(监听IPv6):表示监听IPv6网络接口。
pam_service_name=vsftpd		(PAM服务名称):指定用于身份验证的PAM服务名称。
connect_from_port_20=YES	(通过端口20连接):表示启用通过端口20建立数据连接。

##本地用户设置
local_enable=YES			(启用本地用户):表示允许本地用户登录。
write_enable=YES			(启用写权限):表示允许本地用户上传、删除和重命名文件。 全局启用

##匿名用户设置
anonymous_enable=YES			(启用匿名用户):表示允许匿名用户登录。
anon_world_readable_only=NO		(非只读):表示匿名用户可以下载和读取文件。
anon_other_write_enable=YES		(启用其他用户写权限):表示允许匿名用户上传、删除和重命名文件。
anon_upload_enable=YES			(启用上传权限):表示允许匿名用户上传文件。
anon_mkdir_write_enable=YES		(启用创建目录写权限):表示允许匿名用户创建目录。
anon_max_rate=50000				(匿名用户最大传输速率):表示限制匿名用户的最大传输速率为50,000字节/秒。
								 注意:不包含<目录中的文件>
---------------------------------------------------
##进程、网络、日志
listen=NO						(不监听):表示不监听任何网络接口。
listen_ipv6=YES					(监听IPv6):表示监听IPv6网络接口。
pam_service_name=vsftpd			(PAM服务名称):指定用于身份验证的PAM服务名称。
connect_from_port_20=YES		(通过端口20连接):表示启用通过端口20建立数据连接。
xferlog_enable=YES				(启用传输日志):表示启用传输日志记录。

##本地用户验证、权限
local_enable=YES				(启用本地用户):表示允许本地用户登录。
userlist_enable=YES				(启用用户列表):表示使用用户列表文件进行用户验证。
userlist_deny=YES				(用户列表拒绝模式):表示默认拒绝名单中的用户登录。黑名单。写no就是白名单,删除即不受影响
chroot_local_user=YES			(本地用户限制在主目录):表示将本地用户限制在其主目录下。
allow_writeable_chroot=YES		(允许可写的chroot):表示在chroot环境下允许用户具有写权限。
write_enable=YES				(启用写权限):表示允许本地用户上传、删除和重命名文件。
local_umask=022					(本地用户掩码):表示本地用户创建文件和目录时的默认掩码。 默认 077 ,权限很少

##匿名用户验证、权限
anonymous_enable=NO				(禁用匿名用户):表示禁止匿名用户登录。

示例 anonymous 表示匿名用户 和 local 表示本地用户

anonymous_enable=YES			 ## 指定是否允许匿名用户访问FTP服务器。
local_enable=YES				 ## 指定是否允许本地用户登录FTP服务器。
write_enable=YES				 ##  指定是否允许用户上传文件。  全局选项
local_umask=022					 ## 指定上传文件的权限掩码。
chroot_local_user=YES			 ## 指定是否限制本地用户在自己的主目录中。
pasv_enable=YES					 ## pasv_enable:指定是否启用被动模式。
pasv_min_port 和 pasv_max_port	## 指定被动模式使用的端口范围。

## 示例:pasv_min_port=30000和pasv_max_port=31000

3 了解 /etc/vsftpd/ftpusers(FTP用户黑名单)

一般没必要配置

注意:该<黑名单>永久生效

cat /etc/pam.d/vsftpd  ## vsftpd所使用的<pam本地用户验证模块>中引用了/etc/vsftpd/ftpusers>文件

cat /etc/vsftpd/ftpusers | grep -vPe "(^[ \t]*#|^[ \t]$)"  ## 查看:默认拒绝的<用户名单>

4 了解 /etc/vsftpd/user_list(FTP用户控制列表)

注意1:</etc/vsftpd/user_list文件功能>是否生效,将取决于userlist_enable=YES|NO

userlist_enable=YES  ## 启用</etc/vsftpd/user_list文件功能> 
userlist_enable=NO   ## 禁用</etc/vsftpd/user_list文件功能>

注意2:</etc/vsftpd/user_list文件功能>不能简单的理解为<允许>或<拒绝>,它将随着<userlist_deny=选项值>的不同>而不同

userlist_deny=NO    ## 允许<文件中列出的用户>登录FTP,允许少数,拒绝多数,变成白名单
userlist_deny=YES   ## 拒绝<文件中列出的用户>登录FTP,拒绝少数,允许多数(这是:默认状态)黑名单
         
vim  /etc/vsftpd/user_lis   ## 翻译后解析

#vsftpd用户列表
#如果userlist_deny=NO,则只允许用户在此文件中
#如果userlist_deny=YES(默认值),则从不允许用户在此文件中,并且
#甚至不要提示输入密码。
#请注意,默认的vsftpd-pam配置还检查/etc/vsftpd/ftpusers
#对于被拒绝的用户。

5 了解 /etc/shells(shell 控制列表)

vsftp会根据</etc/shells配置文件>来判断:<登录用户>是否是<有效用户>?
vsftp会阻止:<登录shell>不在</etc/shells配置文件>中的<ftp用户登陆>
如果<ftp用户登陆>的<登录shell>为</sbin/nologin>,则需要将</sbin/nologin>添加到</etc/shells配置文件>

cat > /etc/shells <<EOF
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/sbin/nologin
/usr/sbin/nologin
EOF

## 这里最后两个要设置,不然设置用户的时候登录不进去
## 添加之前先查看有什么内容,是追加最好 cat /etc/shells 

echo "/sbin/nologin" >> /etc/shells 
echo "/usr/sbin/nologin" >> /etc/shells 

5.4 配置 主配置文件 例子

1 配置主动模式和被动模式

  1. 了解:<被动模式>的<主要选项>
listen_port=21              	## 设置:<FTP控制连接>的<TCP侦听端口>,默认为:21
pasv_enable=YES           		## 启用:<FTP被动模式>,默认为:YES

# 以下是:<NAT网关>不支持<ip_nat_ftp状态跟踪模块>的场景中,需要使用的<选项>
pasv_min_port=50000     		## 设置:<FTP被动模式>中的<数据传输端口最小为50000>
默认为:0(表示:任意端口)

pasv_max_port=60000      		## 设置:<FTP被动模式>中的<数据传输端口最大为60000>
								## 默认为:0(表示:任意端口)

pasv_address=IP 或 HOSTNAME	   ## 设置:<FTP被动模式>中<回复数据包>的<源IP地址 或源主机名>
								## 专用于:<NAT网关>不支持<ip_nat_ftp状态跟踪模块>的场景
								##  <源IP地址>应该是:<NAT网关>的<外网接口IP地址>

pasv_addr_resolve=IP      		## 设置:<pasv_address=HOSTNAME>中的<HOSTNAME主机IP地址>

2. 了解:<主动模式><主要选项>
listen_port=21            		## 设置:<FTP控制连接>的<TCP侦听端口>,默认为:21
port_enable=YES           		## 启用:<FTP主动模式>,默认为:YES
connect_from_port_20=YES  		## 设置:<FTP主动模式>的<20/tcp源端口>,默认为:YES
ftp_data_port=20          		## 设置:<FTP主动模式>的<20/tcp源端口>,默认为:20
                          		## 主要用于 connect_from_port_20=NO 的情况
                          		
---------------------------------------------------
我们配置文件都可以使用主动模式,如下所示

进程、网络和日志设置  (可固定这样写)
listen=NO					## (不监听):表示不监听任何网络接口。
listen_ipv6=YES				## (监听IPv6):表示监听IPv6网络接口。
pam_service_name=vsftpd		## (PAM服务名称):指定用于身份验证的PAM服务名称。 本地用户必写,密码验证机制
connect_from_port_20=YES	## (通过端口20连接):表示启用通过端口20建立数据连接。
xferlog_enable=YES			## (启用传输日志):表示启用传输日志记录。

本地用户配置  如果只做匿名登录内容,这里可不写  配置按照格式来,下面有例子
...

匿名用户配置 如果只做本地用户登录,可以直接设置匿名用户不能登录 比如 anonymous_enable=NO
...

2 了解配置FTP 进程选项、连接选项、传输选项

listen=NO                    		## 禁止:采用<独立工作模式>,不侦听<IPv4套接字>
									## 而是通过<xinetd守护进程>来运行维护,默认为:NO
                             		## 需要另行配置<xinetd守护进程>
## 注意:listen=YES 和 listen_ipv6=YES 互斥不可同时为"YES"

listen_address=              		## 设置:<FTP服务>绑定的<IPv4地址>
									## 默认为:未设置(表示:所有IPv4地址)

listen_ipv6=YES              		## 启用:<独立工作模式>,并侦听<IPv6套接字>
									## 默认为:YES
                             		## 当侦听<所有IPv6地址>时,则既可以接受<IPv4客户端>也可以接受<IPv6客户端>
## 注意:listen=YES 和 listen_ipv6=YES 互斥不可同时为"YES"

listen_address6=             		## 设置:<FTP服务>绑定的<IPv4地址>
									## 默认为:未设置(表示:所有IPv6地址)
accept_timeout=60            		## 设置:<FTP被动模式>中,与<远程客户端>建立<数据传输连接>的<连接超时>,默认为:60(秒)
connect_timeout=60           		## 设置:<FTP主动模式>中,与<远程客户端>建立<数据传输连接>的<连接超时>,默认为:60(秒)
data_connection_timeout=300  		## 设置:在<数据传输阶段>中,允许<停顿时限>超时之后,继续传输,默认为:300(秒)
idle_session_timeout=300     		## 设置:<远程客户端>执行<FTP命令>时的<耗费时限>超时之后,继续执行,默认为:300(秒)
ascii_download_enable=NO     		## 允许:基于<ASCII模式>的<下载>,默认为:NO
									## 如果为YES,FTP会执行<ASCII修改>,建议:保持NO(禁用)
ascii_upload_enable=NO       		## 允许:基于<ASCII模式>的<上传>,默认为:NO
									## 如果为YES,FTP会执行<ASCII修改>,建议:保持NO(禁用)
async_abor_enable=NO         		## 禁用:执行<异步ABOR紧急模式>的<特殊FTP命令>默认为:NO
									## 建议:保持NO(禁用)
anon_max_rate=50000          		## 设置:<匿名用户>进行<数据传输>的<最大速率(B/s)>
									## 默认为:0(无限制)
local_max_rate=50000         		## 设置:<本地用户>进行<数据传输>的<最大速率(B/s)>
									## 默认为:0(无限制)
max_clients=300              		## 设置:<客户端连接>的<最大并发连接数>
max_per_ip=10                		## 设置:<每个IP>的<最大并发连接数>
ls_recurse_enable=NO         		## 禁止:使用<ls -R 命令>,来递归显示目录
hide_ids=YES                 		## 启用:隐藏用户ID,将<所有者>和<所属组>均显示为<ftp名称>

3 配置 FTP 的匿名用户访问

一般情况下只不会允许匿名用户访问,只允许本地用户访问,如下是测试使用

权限要求:既可匿名FTP下载,也可匿名FTP上传

3.1.1 配置:<UNIX本地权限>和<SELinux策略>

注意:如果想实现<匿名上传>,请注意<UNIX本地权限>和<SELinux策略>

chmod o=rwx /var/ftp/pub/         ## 设置:UNIX本地权限  给匿名用户(客户端任意用户)权限
setsebool -P ftpd_anon_write on   ## 设置:SELinux允许<匿名写入> 或者把 SELlinux设置为禁用模式

3.1.2 了解要写入配置的主要选项

## 辅助性选项
write_enable=YES             		## YES允许:写入权限,这是一个:全局性的<写入开关>,既针对<匿名访问>,也针对<本地验证访问>

## 匿名用户选项
one_process_model=YES       		## 启用:单进程模式(即:每个连接仅使用一个进程),以支持大量同时连接的用户,默认为:NO
                             		## 仅用于:anonymous_enable=YES
                             		## 不可用于:local_enable=YES
                             		## 当<本地用户验证>和<匿名>同时使用时,请不要使用 one_process_model=YES 选项
anonymous_enable=YES        		## YES允许:匿名访问

anon_world_readable_only=NO  		## NO 允许:<浏览器>既可显示列表,也可下载
									## 注意:这不意味着<允许其他FTP匿名权限>
                             		## YES允许:<浏览器>仅可显示列表,不可下载
									## 注意:这不意味着<拒绝其他FTP匿名权限>
                             		## 默认为:YES
                             		## 其他FTP工具,无论是YES还是NO,均可下载

anon_other_write_enable=NO   		## NO 禁止:重命名、删除<文件和目录>
anon_upload_enable=NO        		## NO 禁止:上传、创建<文件>
anon_mkdir_write_enable=NO   		## NO 禁止:上传、创建<目录>
									## 注意:不包含<目录中的文件>
anon_umask=077               		## 设置:<匿名用户>创建<文件或目录>时的<umask权限掩码>,默认为:077
anon_max_rate=50000          		## 设置:<匿名用户>进行<数据传输>的<最大速率(B/s)>,默认为:0(无限制)

3.1.3 要求匿名用户 即可下载 也可以上传 这里使用

cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak ## 先做备份
cat > /etc/vsftpd/vsftpd.conf <<EOF

## 网络及服务设置
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
connect_from_port_20=YES
xferlog_enable=YES

## 本地用户设置
local_enable=YES
write_enable=YES

## 匿名用户设置
anonymous_enable=YES
anon_world_readable_only=NO
anon_other_write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_max_rate=50000
EOF


## 重启vsftpd服务
systemctl restart vsftpd

## 开启防火墙 如果关闭防火墙,不需要进行如下操作
## 针对<FTP连接控制阶段>:开放<21/tcp>端口,加载<ftp连接状态跟踪模块>
firewall-cmd --permanent --zone=public --add-service=ftp
firewall-cmd --reload

3.1.4 测试

已经配置成功,可以使用win10的此电脑那里 或者浏览器 看能不能连接,浏览器可能会出错

注意:客户端机器访问要下载 lftp 并启动 ,win11 不用(自带)

如下所示,则连接成功,然后看能不能上传或者下载文件,可以则成功,也可以到客户机去测试

1 在此电脑资源管理器测试,如下所示

在这里插入图片描述

可上传 可下载

在这里插入图片描述

2 在客户端进行操作测试 客户端ip是 130,服务端 ip是 100

[root@dj ~]# lftp 192.168.58.100
lftp 192.168.58.100:~> cd pub
cd 成功, 当前目录=/pub
lftp 192.168.58.100:/pub> pwd
ftp://192.168.58.100/pub

## 登录成功 此目录是服务端的 /var/ftp/pub  ,可上传文件到此,也可下载该目录下的文件
## 一般是服务端上传内容到上面,要几百台客户端到上面下载下来
## 注意:这里要有权限才行,而且表示完整的shell环境,比如没有touch命令
cd /tmp/  
## 测试发现可以到别人家里

上传测试:put /tmp/1.txt
ls 查看验证

下载测试:get 1.txt -o ~/				将 1.txt 下载到家目录下
exit 退出,ls ~   查看是否成功
##测试完璧,一般上传下载如果成功的话,在进行操作的时候会有字节传输显示,比如 已传输2408字节 如下所示
2408 bytes transferred			

在浏览器也可以测试,不过有可能会出现问题,可以换浏览器测试

4 配置 FTP 本地用户验证

要求:各个<FTP本地用户>只能进入各自的<FTP主目录>,允许FTP下载/上传

4.1 创建 FTP 本地用户

创建 user01 和 user02 ,都不能登录,且 user02 搬家,方便一会测试 FTP本地用户 是不是 只能进去自己家操作,能不能进别人家操作

<FTP本地用户>:就是一个<nologin的OS用户>
<FTP本地用户>:必须拥有<用户home家目录>,并且,作为<FTP本地用户>的<FTP主目录>

## 创建<nologin不能交互式登录>的<本地用户>  user01用户 修改密码为1
useradd -s /sbin/nologin user01 && echo 'user01:1' | chpasswd

## 基于应用需要可以创建<自定义home主目录:/var/www/html>的<nologin本地用户> 这里使用到 apache
mkdir -p /var/www/html
chmod 775 /var/www/html

## 设置密码和权限  ACL权限感觉没必要设置也行
useradd -m -d /var/www/html -s /sbin/nologin user02 && echo '1' | passwd user2 --stdin
setfacl -m u:user02:rwx /var/www/html

4.2 了解要写入配置的主要选项

pam_service_name=vsftpd		## 指定:vsftpd所使用的<pam本地用户验证模块>这个参数很重要,否则<本地用户>无法通过验证!!!
local_enable=YES           	## YES允许:本地用户验证
userlist_enable=YES        	## YES启用:/etc/vsftpd/user_list(用户控制列表)
userlist_deny=YES          	## YES设置:通过/etc/vsftpd/user_list,来拒绝少数,允许多数
chroot_local_user=YES		## YES禁止:<本地用户>离开<FTP主目录>即:将<本地用户>chroot圈禁在<主目录>中
allow_writeable_chroot=YES 	## YES设置:将<本地用户>的<写操作>限制在<chroot圈禁的目录>中
                           	## 在2.3.5版本之后,chroot_local_user和allow_writeable_chroot必须一起使用,否则拒绝连接
write_enable=YES           	## YES允许:写入权限,这是一个:全局性的<写入开关>既针对<匿名访问>,也针对<本地验证访问>
local_umask=022				## 设置:<本地用户>创建<文件或目录>时的<umask权限掩码>
local_max_rate=50000      	## 设置:<本地用户>进行<数据传输>的<最大速率(B/s)>默认为:0(无限制)
anonymous_enable=NO			## 不允于匿名用户登录

4.3 要求:各个<FTP本地用户>只能进入各自的<FTP主目录>,允许FTP下载/上传

#注意:建议备份,防止出错可以恢复,还有原文件一定要备份,因为里面有很多注释的格式

## 创建FTP配置文件
cat > /etc/vsftpd/vsftpd.conf <<EOF

## 涉及:进程、网络、日志
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
connect_from_port_20=YES
xferlog_enable=YES

## 涉及:本地用户验证、权限
local_enable=YES
userlist_enable=YES
userlist_deny=YES
chroot_local_user=YES
allow_writeable_chroot=YES
write_enable=YES
local_umask=022

## 涉及:匿名用户验证、权限
anonymous_enable=NO
EOF
## 重启vsftpd服务
systemctl restart vsftpd
## 开启防火墙  测试的话关闭防火墙也可以
## 针对<FTP连接控制阶段>:开放<21/tcp>端口,加载<ftp连接状态跟踪模块>
firewall-cmd --permanent --zone=public --add-service=ftp
firewall-cmd --reload

4.4 测试 安装并启动 lftp 服务,不然无法建立连接

注意:一定要把 登录shell 增加

/sbin/nologin
/usr/sbin/nologin

这两个,因为 user01 和 user02 创建的时候都是设置了不可登录的权限,因为这样好管理,降低出错,增加可如下写,覆盖或者添加写入

vsftp会根据</etc/shells配置文件>来判断:<登录用户>是否是<有效用户>
vsftp会阻止:<登录shell>不在</etc/shells配置文件>中的<ftp用户登陆>
如果<ftp用户登陆><登录shell></sbin/nologin>,则需要将</sbin/nologin>添加到</etc/shells配置文件>
cat > /etc/shells <<EOF
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/sbin/nologin
/usr/sbin/nologin
EOF
## 主要是添加这里最后两个shell,不然设置用户的时候登录不进去,建议使用追加方式

1 使用win11 进行测试 (在资源管理器测试)

注意:user01 和 user02 密码是1 ,且是服务端创建的不是客户端创建的用户

输入 ftp://192.168.58.100/ 或者 ftp://user@192.168.58.100/

在这里插入图片描述

在这里插入图片描述

测试可知 user01 登录进去是空的,因为其家目录是 /home/user01,没有在里面创建内容

可以进行 下载上传操作,都是成功的

接下来登录 user02,先在服务端 user02 的家目录 /var/www/html/ 创建 aa bb 两个目录 ,登录后如下所示,

在这里插入图片描述

在这里插入图片描述

测试发现可下载可上传,但是不能在里面删除

2 使用 客户机 user01 用户 进行测试

[root@192 mnt]# lftp 192.168.58.100
lftp 192.168.58.100:~> cd pub
Interrupt    
##如上所示测试可知 匿名用户无法登录

##下面使用 user01 进行登录 ,注意 user01 是在服务端创建的 ,家目录是 /home/user01
提前在服务端的/home/user01 创建 1.txt和2.txt
[root@192 mnt]# lftp -u user01 192.168.58.100
Password: 
lftp user01@192.168.58.100:~> cd pub   
cd: Access failed: 550 Failed to change directory. (/pub)
lftp user01@192.168.58.100:/> cd ~
cd ok, cwd=/
lftp user01@192.168.58.100:/> pwd
ftp://user01@192.168.58.100/
lftp user01@192.168.58.100:/> ls
-rw-r--r--    1 0        0               0 Aug 09 12:02 1.txt
-rw-r--r--    1 0        0               0 Aug 09 12:02 2.txt

get 1.txt -o /tmp/
##如上所示测试发现客户端确实有1.txt,说明下载成功   -o指定下载到的目录

lftp user01@192.168.58.100:/> put ~/1.sh 
2409 bytes transferred
lftp user01@192.168.58.100:/> ls
-rw-r--r--    1 1003     1003         2409 Aug 09 12:12 1.sh
-rw-r--r--    1 0        0               0 Aug 09 12:02 1.txt
-rw-r--r--    1 0        0               0 Aug 09 12:02 2.txt
##如上所示测试上传成功

lftp user01@192.168.58.100:/> touch 3.txt
Unknown command `touch'.
lftp user01@192.168.58.100:/> mkdir aa
mkdir ok, `aa' created
lftp user01@192.168.58.100:/> ls
-rw-r--r--    1 1003     1003         2409 Aug 09 12:12 1.sh
-rw-r--r--    1 0        0               0 Aug 09 12:02 1.txt
-rw-r--r--    1 0        0               0 Aug 09 12:02 2.txt
drwxr-xr-x    2 1003     1003            6 Aug 09 12:13 aa
##如上所示测试创建目录成功,文件不能创建,因为没有 touch 命令  如上所示

lftp user01@192.168.58.100:/> cd /tmp
cd: Access failed: 550 Failed to change directory. (/tmp)
##如上所示测试发现不能cd,说明只能在自己家里操作  

3 使用 客户机 user02 用户 进行测试

其家目录是 /var/www/html 可以先在客户端创建 aa bb 目录

[root@192 mnt]# lftp user02@192.168.58.100
Password: 
lftp user02@192.168.58.100:~> cd ~     
cd ok, cwd=/                  
lftp user02@192.168.58.100:/> ls
drwxr-xr-x    2 0        0               6 Aug 09 12:20 aa
drwxr-xr-x    2 0        0               6 Aug 09 12:20 bb

lftp user02@192.168.58.100:/> ls
drwxr-xr-x    2 0        0               6 Aug 09 12:20 aa
drwxr-xr-x    2 0        0               6 Aug 09 12:20 bb
lftp user02@192.168.58.100:/> put /tmp/1.txt 
lftp user02@192.168.58.100:/> ls                  
-rw-r--r--    1 1004     1004            0 Aug 09 12:32 1.txt
drwxr-xr-x    2 0        0               6 Aug 09 12:20 aa
drwxr-xr-x    2 0        0               6 Aug 09 12:20 bb

lftp user02@192.168.58.100:/> get aa -o /tmp/
get: Access failed: 550 Failed to open file. (aa)
lftp user02@192.168.58.100:/> get 3.txt -o /tmp/
lftp user02@192.168.58.100:/> exit
[root@192 mnt]# ls /tmp
3.txt 

## 可知登录成功
## 操作和 user01 一样,都可以上传创建目录,但是不能下载目录,但可以下载文件,但是不能跑到别人家里面,满足主配置文件设置的权限

5 配置自定义 FTP 主目录

<FTP匿名主目录>默认是:/var/ftp/

自定义<匿名主目录>

(1) 创建:<匿名主目录>
mkdir -p /ftppublic

(2) 配置:<匿名主目录><权限root:root:other=755>
chown -R root:root /ftppublic && chmod 755 /ftppublic
注意:
针对:自定义<匿名主目录>,不可以设置<other其他人>拥有<w写入权限>

(3) 配置:<vsftpd.conf配置文件>
vi /etc/vsftpd/vsftpd.conf
## 涉及:匿名用户验证、权限
anonymous_enable=YES
anon_world_readable_only=NO
anon_other_write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_max_rate=50000
## 添加参数:anon_root=/ftppublic,设置:自定义的<匿名FTP主目录>
anon_root=/ftppublic

(4) 重启:vsftpd服务进程
systemctl restart vsftpd

(5) 创建:一个FTP管理者
## 创建:user01用户
useradd -m -d /ftppublic -s /sbin/nologin ftpadmin && echo 'ftpadmin:a123456!' | chpasswd
setfacl -m u:ftpadmin:rwx /ftppublic

## 配置:<vsftpd.conf配置文件>
vi /etc/vsftpd/vsftpd.conf
## 涉及:本地用户验证、权限
## 修改或添加如下
local_enable=YES
userlist_enable=YES
userlist_deny=YES
chroot_local_user=YES
allow_writeable_chroot=YES
write_enable=YES
local_umask=022

## 重启:vsftpd服务
systemctl restart vsftpd

6 设置统一FTP主目录

<FTP本地用户>的<FTP主目录>默认是:<OS用户home家目录>

让<所有的FTP本地用户>采用<统一FTP主目录>

(1) 创建:<统一FTP主目录> mkdir -p /ftprootdir
(2) 配置:<统一FTP主目录>的<权限root:root:other=757>
chown -R root:root /ftprootdir && chmod 757 /ftprootdir
(3) 配置:<vsftpd.conf配置文件>添加参数:local_root=/ftprootdir
设置:当<FTP用户>连接之后,尝试将其从<用户home家目录>改变到<统一FTP主目录>
(4) 重启:vsftpd服务进程systemctl restart vsftpd
(5) 创建<nologin的OS用户>(注意:不能禁止创建<用户home家目录>) userdel -r user01useradd -s /sbin/nologin user01echo ‘a123456!’ | passwd user01 --stdin

5.5 FTP虚拟用户

意义

FTP(文件传输协议)虚拟用户是一种在FTP服务器上创建的用户账号,这些用户并不存在于操作系统的用户列表中,而是由FTP服务器自身进行管理。虚拟用户的优势在于更灵活地管理FTP访问权限和目录结构。

## 由于<匿名FTP>不限制<任何人>的访问,因此,我们觉得:管理太松了,过于宽泛
## 由于本地验证FTP需要为每一个<访问者>创建一个OS 本地用户,因此,我们觉得:OS 本地用户管理量又太大了
## 实际问题:
##    有没有一种类似<匿名FTP访问>,又可以通过<用户验证>来加以限制,同时也无需创建太多的<OS 本地用户>?
## 解决办法:
## 采用<FTP虚拟用户>
## 特点:
##      <FTP虚拟用户>不是<OS 本地用户>,因此,比较安全
##      <FTP虚拟用户>是通过映射的<指定的OS本地用户>,来访问<FTP 资源>
##      <FTP虚拟用户>的<FTP登录验证>是执行<OS 本地用户验证>,而不是执行<匿名用户验证>
## 我们可以通过<anon_world_readable_only 控制参数>,来控制<所有FTP虚拟用户>的<上传/下载 FTP权限>
## 我们可以通过<所有FTP虚拟用户>映射的<OS 本地用户>,来控制<所有FTP虚拟用户>的<OS 本地权限>

要配置FTP虚拟用户,通常需要进行以下步骤:

1 安装和配置FTP服务器:首先,你需要选择并安装适合你需求的FTP服务器软件,例如vsftpd、ProFTPD、Pure-FTPd等。按照软件提供的文档进行基本的配置,包括监听端口、网络设置等。

2 创建虚拟用户数据库:接下来,你需要创建一个虚拟用户数据库,用于存储虚拟用户账号信息。这个数据库可以是纯文本文件、数据库文件或其他形式的存储。每个虚拟用户记录包含用户名、密码、目录等信息。

3 配置FTP服务器与虚拟用户数据库的集成:在FTP服务器的配置文件中,你需要指定使用虚拟用户数据库来验证用户登录和管理权限。具体的配置方式因FTP服务器软件而异,请参考对应软件的文档进行配置。

4 设置虚拟用户的目录访问权限:你可以为每个虚拟用户设置其可以访问的目录范围。这可以通过FTP服务器的配置文件或虚拟用户数据库进行配置。确保虚拟用户只能访问其所属的目录,并限制对其他目录的访问权限。

1 建立<FTP虚拟用户>的<数据库文件>

(1) 创建:<FTP虚拟用户><用户列表>文件
##  注意:一行<FTP虚拟用户名>,一行<FTP虚拟用户密码>,以此类推
cat > /etc/vsftpd/vuser.list <<EOF
vuser01
123456
vuser02
123456
vuser03
123456
EOF
chmod 600 /etc/vsftpd/vuser.list

(2) 使用db_load命令,用HASH算法,生成<FTP虚拟用户><数据库文件:vuser.db>
db_load -T -t hash -f /etc/vsftpd/vuser.list /etc/vsftpd/vuser.db
     ## 备注:
     ##    -T                         表示:将<文本文件>加载到<数据库文件>中
     ##    -f /etc/vsftpd/vuser.list  指定:<文本文件>
     ##    /etc/vsftpd/vuser.db       指定:<数据库文件>
     
(3)<数据库文件>设置<尽量小的权限>
chmod 600 /etc/vsftpd/vuser.db
  1. 创建用于映射<FTP虚拟用户>的<OS普通用户>
(1) 创建:<统一家目录>
mkdir /ftproot

(2) 创建:用于映射<FTP虚拟用户><OS普通用户>,并设置<自定义家目录></ftproot>
useradd -d /ftproot -s /sbin/nologin ftpvuser

(3) 设置:<ftpvuser普通用户><家目录UNIX本地权限>
chmod -Rf 750 /ftproot
setfacl -m u:ftpvuser:rwx /ftproot
  1. 创建支持<FTP虚拟用户>的<PAM认证文件>

配置:<FTP虚拟用户>的<PAM认证文件>

cat > /etc/pam.d/vsftpd.vuser <<EOF
auth      required   pam_userdb.so   db=/etc/vsftpd/vuser
account   required   pam_userdb.so   db=/etc/vsftpd/vuser
EOF

## 参数db:用于指向刚刚生成的</etc/vsftpd/vuser.db文件>,但不要写<.db后缀名>
  1. 配置<vsftpd.conf配置文件>使用<新建的PAM认证文件:vsftpd.vuser>
cat > /etc/vsftpd/vsftpd.conf <<EOF
listen=NO
listen_ipv6=YES
connect_from_port_20=YES
xferlog_enable=YES
tcp_wrappers=YES
dirmessage_enable=YES
#################################
## 配置:<FTP虚拟用户>
#################################
## 我们既可启用<匿名访问>,也可禁用<匿名访问>
anonymous_enable=NO
## 启用:来宾账户,即:将所有的<非匿名用户>均归类为<来宾用户>,<来宾用户>的<用户账户>为<guest_username=选项值>
guest_enable=YES
## 将<来宾账户>指定为:<FTP虚拟用户>映射的<OS普通用户:ftpvuser>
guest_username=ftpvuser
## 授予:<来宾用户>的<anon匿名浏览和下载>权限
anon_world_readable_only=NO
## 将 pam_service_name=vsftpd 改为 vsftpd.vuser
pam_service_name=vsftpd.vuser
## 指定:单个<FTP虚拟用户>的<权限配置文件目录>
user_config_dir=/etc/vsftpd/vusers_dir
#################################
## 以下是<本地用户验证>的<默认设置>
#################################
local_enable=YES
userlist_enable=YES
userlist_deny=YES
chroot_local_user=YES
allow_writeable_chroot=YES
write_enable=YES
local_umask=022
EOF
  1. 在</etc/vsftpd/vusers_dir目录>中,创建单个<FTP虚拟用户>的<权限配置文件>
## 在</etc/vsftpd/vusers_dir目录>中,创建单个<FTP虚拟用户>的<权限配置文件>,从而可以区别配置<FTP虚拟用户>的权限
## 注意:须以<FTP虚拟用户名>来创建<权限配置文件>
mkdir -p /etc/vsftpd/vusers_dir
## 配置:vuser01具备:anon所有权限
cat > /etc/vsftpd/vusers_dir/vuser01 <<EOF
anon_other_write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
EOF
## 配置vuser02仅仅具备:anon上传/创建<文件>的权限
cat > /etc/vsftpd/vusers_dir/vuser02 <<EOF
anon_other_write_enable=NO
anon_upload_enable=YES
anon_mkdir_write_enable=NO
EOF
## 配置vuser03仅仅具备:anon上传/创建<文件和目录>的权限
cat > /etc/vsftpd/vusers_dir/vuser03 <<EOF
anon_other_write_enable=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
EOF

5.6 生产环境

一般是内网服务器做服务端,不同网段内网可以有很多服务端,通过一个客户端进行传输数据

客户端 上传和下载数据 到服务端

一般因为安全原因内网服务器无法插入u盘,我们可以插入u盘到专门的ftp客户端上传或下载数据

注意:我们的业务服务器充当服务端比较安全,这样直接通过客户端去单向连接服务端比较安全,数据存在服务端

FTP 是一种双向通信协议,允许客户端和服务器端在文件传输过程中互相发送和接收数据

如下是服务端的配置 主动模式

[root@app ~]# egrep -v'^\s*(#|$)' /etc/vsftpd/vsftpd.conf
anonymous enable=NO
local enable=YES
write enable=YES
local umask=022
dirmessage_enable=YES
xferlog enable=YES
connect from port 20=YES
xferlog file=/amberdata/logs/ftp/xferlog
xferlog std format=YES
listen=NO
listen ipv6=YES
pam service name=vsftpd
userlist enable=YES
local root=/amberdata/rpa/data

配置解析

anonymous_enable=NO           # 禁止匿名登录(安全 ✅)
local_enable=YES              # 允许本地用户登录 ✅
write_enable=YES              # 允许上传、删除、重命名文件 ✅
local_umask=022               # 本地用户创建文件的默认权限掩码,022 = 755 ✅
dirmessage_enable=YES         # 进入目录时显示 .message 文件内容(可选)
xferlog_enable=YES            # 启用传输日志 ✅
connect_from_port_20=YES      # 使用端口20进行主动连接(可选)
xferlog_file=/amberdata/logs/ftp/xferlog   # 日志文件路径 ✅
xferlog_std_format=YES        # 使用标准格式日志 ✅
listen=NO                     # 禁用 IPv4 监听 ❗
listen_ipv6=YES               # 启用 IPv6 监听 ❗(需系统支持 IPv6)
pam_service_name=vsftpd       # 使用 PAM 认证配置,通常默认 ✅
userlist_enable=YES           # 启用用户黑名单(vsftpd.user_list) ✅
local_root=/amberdata/rpa/data   # 设置用户登录后的根目录 ✅

## 根据情况进行修改,比如打开ipv4,大多数客户端(特别是 Windows 工具)默认用 IPv4

然后创建本地用户并设置其目录权限,就可以开始使用 FTP 上传下载了

useradd -d /amberdata/rpa/data -s /sbin/nologin ftpuser
passwd ftpuser

chown -R ftpuser:ftpuser /amberdata/rpa/data
chmod 755 /amberdata/rpa/data

客户端连接进行上传或下载数据的时候,最好使用同一个用户,这样每次直连即可

注意:/etc/shells 文件追加 /sbin/nologin 和 /usr/sbin/nologin

或者服务器系统任意用户也可以,只要不是匿名用户,有文件访问权限即可