
Linux网络服务之FTP
Linux网络服务之FTP
一、存储类型
分为三种:
直连式存储:Direct-Attached Storage,简称DAS
存储区域网络:Storage Area Network,简称SAN
网络附加存储:Network-Attached Storage,简称NAS
1.1 DAS 存储
DAS存储是最常见的一种存储方式,尤其是在中小企业应用中。PC中的硬盘或只有一个外部SCSI接口的JBOD都属于DAS架构。DAS是指存储设备直接连接到服务器总线上,存储设备只与一台独立的主机连接,其他主机不能使用这个存储设备。DAS存储设备与服务器主机之间的连接通道通常采用SCSI连接,DAS存储设备主要是磁盘阵列(RAID: Redundant Arrays of Independent Disks)、磁盘簇(JBOD:Just a Bunch Of Disks)等。
1.2 NAS 存储
NAS存储就是存储设备通过标准的网络拓扑结构(比如以太网)添加到一群计算机上。与DAS以及SAN不同,NAS是文件级的存储方法。采用NAS较多的功能是用来进行文件共享。
NAS存储也通常被称为附加存储,顾名思义,就是存储设备通过标准的网络拓扑结构(例如以太网)添加到一群计算机上。NAS是文件级的存储方法,它的重点在于帮助工作组和部门级机构解决迅速增加存储容量的需求。如今更多的亲们采用NAS较多的功能是用来文档共享、图片共享、电影共享等等,而且随着云计算的发展,一些NAS厂商也推出了云存储功能,大大方便了企业和亲们等个人用户的使用。NAS产品是真正即插即用的产品。NAS设备一般支持多计算机平台,用户通过网络支持协议可进入相同的文档,因而NAS设备无需改造即可用于混合Unix/Windows NT局域网内,同时NAS的应用非常灵活。
但NAS有一个关键性问题,即备份过程中的带宽消耗。与将备份数据流从LAN中转移出去的存储区域网(SAN)不同,NAS仍使用网络进行备份和恢复。NAS 的一个缺点是它将存储事务由并行SCSI连接转移到了网络上。这就是说LAN除了必须处理正常的最终用户传输流外,还必须处理包括备份操作的存储磁盘请求。
1.3 SAN 存储
存储区域网络,这个是通过光纤通道或以太网交换机连接存储阵列和服务器主机,最后成为一个专用的存储网络。SAN经过十多年历史的发展,已经相当成熟,成为业界的事实标准(但各个厂商的光纤交换技术不完全相同,其服务器和SAN存储有兼容性的要求)。
SAN提供了一种与现有LAN连接的简易方法,并且通过同一物理通道支持广泛使用的SCSI和IP协议。SAN不受现今主流的、基于SCSI存储结构的布局限制。特别重要的是,随着存储容量的爆炸性增长,SAN允许企业独立地增加它们的存储容量。SAN的结构允许任何服务器连接到任何存储阵列,这样不管数据置放在那里,服务器都可直接存取所需的数据。因为采用了光纤接口,SAN还具有更高的带宽。
如今的SAN解决方案通常会采取以下两种形式:光纤信道以及iSCSI或者基于IP的SAN,也就是FC SAN和IP SAN。光纤信道是SAN解决方案中大家最熟悉的类型,但是,最近一段时间以来,基于iSCSI的SAN解决方案开始大量出现在市场上,与光纤通道技术相比较而言,这种技术具有良好的性能,而且价格低廉。
SAN的优势:
1)随着存储容量的增长,SAN允许企业独立地增加他们的存储容量。
2)SAN允许任何服务器连接到任何存储阵列(好处是:不管数据放在哪里,服务器都可以直接存取所需的数据)
3)由于使用光纤接口,SAN具有更高的带宽。除了FC连接,SAN连接还有ISCSI(SCSI over IP)以及SAS(Serial Attached SCSI)接口。
4)光纤接口可以提供10公里那么长那么远的连接长度,非常容易实现物理分离的存储
1.4 三种存储比较
SAN 与 NAS的主要区别体现在文件系统所在的位置
1.5 三种存储架构的应用场景
DAS虽然比较古老了,但是还是很适用于那些数据量不大,对磁盘访问速度要求较高的中小企业
NAS多适用于文件服务器,用来存储非结构化数据,虽然受限于以太网的速度,但是部署灵活,成 本低
SAN则适用于大型应用或数据库系统,缺点是成本高、较为复杂

二、 FTP 文件传输协议
2.1 FTP工作原理介绍
文件传输协议:File Transfer Protocol 早期的三个应用级协议之一,基于C/S结构
数据传输格式:二进制(默认)和文本
双通道协议:命令和数据连接
两种模式:从服务器角度
主动(PORT style):服务器主动连接 命令(控制):客户端:随机port ---> 服务器:21/tcp 数据:客户端:随机port <---服务器:20/tcp
主动模式的FTP是指服务器主动连接客户端的数据端口
在主动模式下,FTP客户端随机开启一个大于1024的端口N向服务器的21号端口发起连接,然后开放N+1号端口进行监听,并向服务器发出PORT N+1命令。服务器接收到命令后,会用其本地的FTP数据端口(通常是20)来连接客户端指定的端口N+1,进行数据传输。
主动模式的工作模型工作过程描述:
1)客户端以随机非特权端口N,就是大于1024的端口,对server端21端口发起连接
2)客户端开始监听 N+1端口;
3)服务端会主动以20端口连接到客户端的N+1端口。
优点:
服务端配置简单,利于服务器安全管理,服务器只需要开放21端口
缺点:
如果客户端开启了防火墙,或客户端处于内网(NAT网关之后), 那么服务器对客户端端口发起的连接可能会失败
被动(PASV style):客户端主动连接 命令(控制):客户端:随机port ---> 服务器:21/tcp 数据:客户端:随机port ---> 服务器:随机port /tcp
在被动模式下,FTP客户端随机开启一个大于1024的端口(N)向服务器的21号端口发起连接,同时会开启N+1号端口。然后向服务器发送PASV命令,通知服务器自己处于被动模式。服务器收到命令后,会开放一个大于1024的端口(P)进行监听,然后用PORTP命令通知客户端,自己的数据端口是P。客户端收到命令后,会通过N+1号端口连接服务器的端口P,然后在两个端口之间进行数据传输
被动模式的工作模型工作过程描述:
1)客户端以随机非特权端口连接服务端的21端口
2)服务端开启一个非特权端口为被动端口,并返回给客户端
3)客户端以非特权端口+1的端口主动连接服务端的被动端口
缺点:
服务器配置管理稍显复杂,不利于安全,服务器需要开放随机高位端口以便客户端可以连接,因此大多数FTP服务软件都可以手动配置被动端口的范围
优点:
对客户端网络环境没有要求
注意:
这里的主动和被动,是相对于的FTP server 端来判断的
如果server 去连接client 开放的端口,说明是主动的,相反,如果client去连接server开放的端口,则是被动的。
范例:服务器被动模式数据端口
227 Entering Passive Mode (172,16,0,1,224,59)
服务器数据端口计算公式:224*256+59
FTP 服务状态码
1XX:信息 125:数据连接打开
2XX:成功类状态 200:命令OK 230:登录成功
3XX:补充类 331:用户名OK
4XX:客户端错误 425:不能打开数据连接
5XX:服务器错误 530:不能登录
用户认证
匿名用户:ftp,anonymous,对应Linux用户ftp
系统用户:Linux用户,用户/etc/passwd,密码/etc/shadow
虚拟用户:特定服务的专用用户,独立的用户/密码文件
2.2 常见 FTP 相关软件
FTP 服务器端软件
Wu-ftpd,Proftpd,Pureftpd,Filezilla Server,Serv-U,Wing FTP Server,IIS
vsftpd:Very Secure FTP Daemon,CentOS 默认FTP服务器 高速,稳定,下载速度是WU-FTP的两倍 ftp.redhat.com数据:单机最多可支持15000个并发
vsftpd 官网: https://security.appspot.com/vsftpd.html
Filezilla官网: https://filezilla-project.org/index.php
客户端软件
ftp,lftp,lftpget,wget,curl
ftp -A ftpserver port -A 主动模式 -p 被动模式
lftp -u username ftpserver
lftp username@ftpserver
lftpget ftp://ftpserver/pub/file
gftp:GUI centos5 最新版2.0.19 (11/30/2008),官网:https://www.gftp.org/
filezilla,FTP Rush,CuteFtp,FlashFXP,LeapFtp
IE ftp://username:password@ftpserver
注:从RHEL6开始,系统镜像中默认没有ftp客户端命令。取而代之的是lftp命令
2.3 vsftpd 介绍安装
由 vsftpd 包提供,不再由xinetd管理
用户认证配置文件:/etc/pam.d/vsftpd
启动服务相关文件
/usr/lib/systemd/system/vsftpd.service
/etc/rc.d/init.d/vsftpd
配置文件
/etc/vsftpd/vsftpd.conf
帮助:man 5 vsftpd.conf
配置文件格式
option=value 注意:= 前后不要有空格
选项=赋值
用户和其共享目录
匿名用户(映射为系统用户ftp )共享文件位置:/var/ftp
系统用户共享文件位置:用户家目录
虚拟用户共享文件位置:专用于FTP服务的用户帐号, 为其映射的系统用户的家目录
2.4 vsftpd 服务常见配置
2.4.1 更改命令端口
[root@vsftpd ~]$ vim /etc/vsftpd/vsftpd.conf
listen_port=2021 # 添加一行,更换默认端口,默认端口 21
<h1 id="指定端口登录">指定端口登录</h1>
<p>[root@client~]$ ftp 10.0.0.8 2021
2.4.2 主动模式端口
connect_from_port_20=YES # 主动模式端口为20
ftp_data_port=20 (默认) # 指定主动模式的端口</p>
<p>linux ftp # Linux 客户端默认使用被动模式
windows ftp # Windows 客户端默认使用主动模式
2.4.3 被动模式端口范围
linux ftp # 客户端默认使用被动模式
windows ftp # 客户端默认使用主动模式
pasv_min_port=6000 # 0 为随机分配,端口范围会影响客户端的并发数
pasv_max_port=6010 # 可用 6000-6010 端口,也就是最多只支持11个并发
2.4.4 使用当地时间
use_localtime=YES # 使用当地时间(默认为NO,使用GMT)
2.4.5 匿名用户登录
anonymous_enable=YES # 支持匿名用户,CentOS8 默认不允许匿名
no_anon_password=YES # 匿名用户略过口令检查 , 默认NO</p>
<h1 id="指定 ftp 家目录为 /data/ftproot/ ,默认在 /var/ftp">指定 ftp 家目录为 /data/ftproot/ ,默认在 /var/ftp</h1>
<p>[root@vsftpd ~]# usermod -d /data/ftproot/ ftp
[root@vsftpd ~]# getent passwd ftp
2.4.6 匿名用户上传,下载
anon_mkdir_write_enable=YES # 匿名建目录
anon_upload_enable=YES # 匿名上传</p>
<h1 id="注意:文件系统权限">注意:文件系统权限</h1>
<p>[root@vsftpd ~]# setfacl -m u:ftp:rwx /var/ftp/pub # 给ACL权限
[root@vsftpd ~]# setfacl -b /var/ftp/ # 取消ACL权限</p>
<h1 id="注意:配置好 ftp 文件权限后,还需要开启文件系统访问的权限,不能给FTP根目录写权限,只能给子目录写权限。</code></pre><pre><code># 可在配置文件中配置这三项,所有人都可以下载,如果不能下载请检查权限是否为所有人可读">注意:配置好 ftp 文件权限后,还需要开启文件系统访问的权限,不能给FTP根目录写权限,只能给子目录写权限。
# 可在配置文件中配置这三项,所有人都可以下载,如果不能下载请检查权限是否为所有人可读</h1>
<p>anon_world_readable_only=NO # 只能下载全部读的文件, 默认YES
anon_umask=0333 # 指定匿名上传文件的umask,默认077,注意:0333中的0不能省略
anon_other_write_enable=YES # 配置上传的文件可删除和修改,默认是NO
2.4.7 指定匿名用户的上传文件的默认的所有者和权限
# 指定匿名用户的 上传文件的 默认的所有者和权限</p>
<h1 id="修改文件上传的所有者">修改文件上传的所有者</h1>
<p>chown_uploads=YES
chown_username=test
chown_upload_mode=0644
2.4.8 Linux系统用户
local_enable=YES # 是否允许linux用户登录,建议关闭
write_enable=YES # 允许linux用户上传文件
local_umask=022 # 指定系统用户上传文件的默认权限对应umask
2.4.9 将所有系统用户映射为指定的guest用户
guest_enable=YES # 所有系统用户都映射成guest用户
guest_username=ftp # 配合上面选项才生效,指定guest用户名(默认启用)
local_root=/ftproot # 指定guest用户登录所在目录,但不影响匿名用户的登录目录,不指定默认是 ftp 默认的 /var/ftp 目录
user_config_dir=/etc/vsftpd/conf.d/ # 每个用户独立的配置文件目录,需要手动创建</p>
<p>guest_username=haha # 指定进程账号
2.4.10 禁锢系统用户
chroot_local_user=YES #禁锢系统用户,默认NO,即不禁锢</p>
<h1 id="使用客户端登陆测试 (发现登陆失败,原因是 把 /home/test 当成了 ftp 的根目录了,但是作为 ftp 的根站点是不允许有写权限的)">使用客户端登陆测试 (发现登陆失败,原因是 把 /home/test 当成了 ftp 的根目录了,但是作为 ftp 的根站点是不允许有写权限的)</h1><h1 id="解决办法:将写权限去掉">解决办法:将写权限去掉</h1>
<p>[root@vsftpd ~]# chmod 555 /home/test/</p>
<hr />
<hr />
<p>禁锢或不禁锢特定的系统用户在家目录中,与上面设置功能相反</p>
<p>chroot_list_enable=YES # 实现白名单, (默认是NO,黑名单)
chroot_list_file=/etc/vsftpd/chroot_list # 默认值</p>
<p>当chroot_local_user=YES和chroot_list_enable=YES时,则chroot_list中用户不禁锢,即白名单
当chroot_local_user=NO和chroot_list_enable=YES时,则chroot_list中用户禁锢,即黑名单
2.4.11 日志
# wu-ftp 日志:默认启用 --> <strong>老牌的FTP软件</strong>
xferlog_enable=YES # 启用记录上传下载日志,此为默认值
xferlog_std_format=YES # 使用wu-ftp日志格式,此为默认值
xferlog_file=/var/log/xferlog # 可自动生成, 此为默认值</p>
<p>#v sftpd日志:默认不启用
dual_log_enable=YES # 使用vsftpd日志格式,默认不启用
vsftpd_log_file=/var/log/vsftpd.log # 可自动生成, 此为默认值</p>
<p>注意:两份日志开启一个就好!看自己习惯
2.4.12 提示信息
ftpd_banner="welcome to linux ftp server"
或
banner_file=/etc/vsftpd/ftpbanner.txt
[root@vsftpd ~]# vim /etc/vsftpd/ftpbanner.txt
Welcome come to 2023 ftp !!</p>
<h1 id="注意这两个配置同时使用,banner_file的优先级更高!">注意这两个配置同时使用,banner_file的优先级更高!</h1><h1 id="显示更为丰富 vim 的插入模式下 ^[ 需要快捷键按出来: ctrl+v+[">显示更为丰富 vim 的插入模式下 ^[ 需要快捷键按出来: ctrl+v+[</h1>
<p>[root@vsftpd ~]# vim /etc/vsftpd/ftpbanner.txt
^[[1;31mWelcome come to 2023 ftp^[[0m</p>
<p>********* 目录访问提示信息 *********
dirmessage_enable=YES # 此为默认值
message_file=.message # 信息存放在指定目录下.message ,此为默认值,只支持单行说明
2.4.13 PAM模块实现用户访问控制
/etc/vsftpd/vsftpd.conf
/etc/vsftpd/ftpusers
/etc/pam.d/vsftpd</p>
<h1 id="将 test 账号 加入到 /etc/vsftpd/ftpusers 中">将 test 账号 加入到 /etc/vsftpd/ftpusers 中</h1>
<p>[root@vsftpd ~]# echo test >> /etc/vsftpd/ftpusers
[root@client~]$ ftp 10.0.0.8
Connected to 10.0.0.8 (10.0.0.8).
220-Welcome come to 2023 ftp
220
Name (10.0.0.8:root): test
331 Please specify the password.
Password:
530 Login incorrect.
Login failed.</p>
<h1 id="登录失败">登录失败</h1><h1 id="修改 /etc/pam.d/vsftpd 将其变成白名单,默认是黑名单">修改 /etc/pam.d/vsftpd 将其变成白名单,默认是黑名单</h1>
<p>[root@vsftpd ~]# vim /etc/pam.d/vsftpd</p>
<h1 id="将 sense=deny 改成 sense=allow</code></pre><h5 style="text-align: start; " id="heading-27"><strong><span fontsize="" color="">2.4.14 是否启用控制用户登录的列表文件</span></strong></h5><pre><code>userlist_enable=YES # 此为默认值">将 sense=deny 改成 sense=allow
2.4.14 是否启用控制用户登录的列表文件
userlist_enable=YES # 此为默认值</h1>
<p>userlist_deny=YES(默认值) # 黑名单,不提示口令,NO为白名单
userlist_file=/etc/vsftpd/user_list # 此为默认值</p>
<h1 id="使 /etc/vsftpd/user_list 文件变成白名单">使 /etc/vsftpd/user_list 文件变成白名单</h1>
<p>userlist_deny=NO</p>
<h1 id="客户端登录测试 (发现普通账号都不可以登录)">客户端登录测试 (发现普通账号都不可以登录)</h1><h1 id="将 demo 账号加入到 /etc/vsftpd/user_list 文件中">将 demo 账号加入到 /etc/vsftpd/user_list 文件中</h1>
<p>[root@vsftpd ~]$ cat /etc/vsftpd/user_list | grep demo
2.4.15 vsftpd 服务指定用户身份运行
nopriv_user=nobody # 此为默认值</p>
<p>[root@vsftpd ~]# id nobody
uid=99(nobody) gid=99(nobody) 组=99(nobody)</p>
<p>#nobody用户 在 centos8 上是 65534 ,在 centos7 上是 99
[root@vsftpd ~]# yum install -y nfs-utils
[root@vsftpd ~]# cat /etc/passwd | grep 65534
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
2.4.16 连接数限制
max_clients=2 # 最大并发连接数</p>
<p>max_per_ip=0 # 每个IP同时发起的最大连接数
2.4.17 传输速率,单位:字节/秒
anon_max_rate=0 # 匿名用户的最大传输速率,以字节为单位,比如:1024000表示1MB/s</p>
<p>local_max_rate=0 # 本地用户的最大传输速率</p>
<h1 id="客户端下载测试速度">客户端下载测试速度</h1>
<p>[root@client ~]# yum install wget -y
[root@client ~]# wget ftp://10.0.0.8/pub/bigfile</p>
<h1 id="针对操作系统账号限速">针对操作系统账号限速</h1>
<p>[root@vsftpd ~]# vim /etc/vsftpd/vsftpd.conf
local_max_rate=10240000</p>
<h1 id="在客户端使用 test 账号下载">在客户端使用 test 账号下载</h1>
<p>[root@client ~]# wget ftp://test:1@192.168.2.11/bigfile
2.4.18 连接时间:秒为单位
connect_timeout=60 # 主动模式数据连接超时时长
accept_timeout=60 # 被动模式数据连接超时时长
data_connection_timeout=300 # 数据连接无数据输超时时长
idle_session_timeout=60 # 无命令操作超时时长
2.4.19 以文本方式传输
以文本方式传输文件时,会自动对文件进行格式转换,比如转换成windows的文本格式</p>
<h1 id="启用此选项可使服务器在ASCII模式下实际对文件进行ASCII处理。">启用此选项可使服务器在ASCII模式下实际对文件进行ASCII处理。</h1><h1 id="默认是禁用,禁用后,服务器将假装允许ASCII模式,但实际上会忽略激活它的请求">默认是禁用,禁用后,服务器将假装允许ASCII模式,但实际上会忽略激活它的请求</h1>
<p>ascii_upload_enable=YES
ascii_download_enable=YES</p>
<h1 id="所以尽量不要用文本格式传文件,尽量使用二进制格式,不然会导致文件损坏</code></pre><h4 style="text-align: start; " id="heading-33"><strong><span fontsize="" color="">2.5 vsftpd 虚拟用户</span></strong><br></h4><p style=""><strong><span fontsize="" color="">虚拟用户:给特定服务使用的用户帐号</span></strong></p><ul><li><p style=""><span fontsize="" color="">所有虚拟用户会统一映射为一个指定的系统帐号:访问共享位置,即为此系统帐号的家目录</span></p></li><li><p style=""><span fontsize="" color="">各虚拟用户可被赋予不同的访问权限,通过匿名用户的权限控制参数进行指定</span></p></li></ul><p style="text-align: start; "><strong><span fontsize="" color="">虚拟用户帐号的存储方式:</span></strong></p><ul><li><p style=""><strong><span fontsize="" color="">文件</span></strong><span fontsize="" color="">:创建文本文件,奇数行为用户名,偶数行为密码,再被编码为hash 格式Berkeley DB database文件</span></p></li></ul><pre><code>db_load -T -t hash -f vusers.txt vusers.db</code></pre><ul><li><p style=""><strong><span fontsize="" color="">关系型数据库中的表中</span></strong><span fontsize="" color="">:实时查询数据库完成用户认证</span></p><p style=""><span fontsize="" color="">vsftpd 支持mysql库:pam要依赖于pam-mysql</span></p></li></ul><pre><code>/lib64/security/pam_mysql.so">所以尽量不要用文本格式传文件,尽量使用二进制格式,不然会导致文件损坏
2.5 vsftpd 虚拟用户
虚拟用户:给特定服务使用的用户帐号
所有虚拟用户会统一映射为一个指定的系统帐号:访问共享位置,即为此系统帐号的家目录
各虚拟用户可被赋予不同的访问权限,通过匿名用户的权限控制参数进行指定
虚拟用户帐号的存储方式:
文件:创建文本文件,奇数行为用户名,偶数行为密码,再被编码为hash 格式Berkeley DB database文件
db_load -T -t hash -f vusers.txt vusers.db
关系型数据库中的表中:实时查询数据库完成用户认证
vsftpd 支持mysql库:pam要依赖于pam-mysql
/lib64/security/pam_mysql.so</h1>
<p>/usr/share/doc/pam_mysql-0.7/README
2.5.1 实现基于文件验证的vsftpd虚拟用户
2.5.1.1 创建用户数据库文件
[root@vsftpd ~]# rpm -qf <code>which db_load
libdb-utils-5.3.21-20.el7.x86_64
[root@vsftpd ~]# vim /etc/vsftpd/vusers.txt
xiaom
123
xiaoh
123
[root@vsftpd ~]# chmod 600 /etc/vsftpd/vusers.txt
[root@vsftpd ~]# db_load -T -t hash -f /etc/vsftpd/vusers.txt /etc/vsftpd/vusers.db
[root@vsftpd ~]# chmod 600 /etc/vsftpd/vusers.*
2.5.1.2 创建用户和访问FTP目录
[root@vsftpd ~]# useradd -d /data/ftproot -s /sbin/nologin -r vuser
[root@vsftpd ~]# mkdir -pv /data/ftproot/upload
[root@vsftpd ~]# setfacl -m u:vuser:rwx /data/ftproot/upload #家目录默认不能有写的权限,因此需要在家目录下创建子目录,并赋予权限
2.5.1.3 创建pam配置文件
[root@vsftpd ~]# vim /etc/pam.d/vsftpd.db
auth required pam_userdb.so db=/etc/vsftpd/vusers
account required pam_userdb.so db=/etc/vsftpd/vusers
2.5.1.4 指定pam配置文件
[root@vsftpd ~]# vim /etc/vsftpd/vsftpd.conf
将 pam_service_name=vsftpd 改为 pam_service_name=vsftpd.db</p>
<h1 id="并且加以下两行">并且加以下两行</h1>
<p>guest_enable=YES
guest_username=vuser</p>
<p>[root@vsftpd ~]# ls /data/ftproot/
ftp.txt upload</p>
<p>[root@vsftpd ~]# touch /data/ftproot/a.txt</p>
<h1 id="当前用户只可以下载不能上传 (网络服务共享涉及到系统权限和服务自身权限,刚才已通过ACL打开系统权限,服务自身权限未打开)">当前用户只可以下载不能上传 (网络服务共享涉及到系统权限和服务自身权限,刚才已通过ACL打开系统权限,服务自身权限未打开)</h1><h1 id="打开服务自身匿名写权限">打开服务自身匿名写权限</h1>
<p>[root@vsftpd ~]# vim /etc/vsftpd/vsftpd.conf # 添加下面三行
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
2.5.1.5 虚拟用户建立独立的配置文件
# 指定各个用户配置文件存放的路径
[root@vsftpd ~]# vim /etc/vsftpd/vsftpd.conf # 添加下面一行,删除匿名写权限配置,如果开启也请注释掉删除匿名写权限配置
user_config_dir=/etc/vsftpd/conf.d/
# 创建各个用户配置文件存放的路径
[root@vsftpd ~]# mkdir /etc/vsftpd/conf.d/</p>
<p>[root@vsftpd ~]# vim /etc/vsftpd/conf.d/xiaom
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES</p>
<h1 id="创建各个用户配置文件存放的路径">创建各个用户配置文件存放的路径</h1>
<p>[root@vsftpd ~]# mkdir /etc/vsftpd/conf.d/</p>
<p>[root@vsftpd ~]# vim /etc/vsftpd/conf.d/xiaom
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES</p>
<p>[root@vsftpd ~]# vim /etc/vsftpd/conf.d/xiaom
local_root=/data/ftproot1
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES</p>
<p>[root@vsftpd ~]# vim /etc/vsftpd/conf.d/xiaoh
local_root=/data/ftproot2
# 新增一个虚拟用户 xiaoq
[root@vsftpd ~]# vim /etc/vsftpd/vusers.txt # 添加两行
xiaoq
123</p>
<p>[root@vsftpd ~]# db_load -T -t hash -f /etc/vsftpd/vusers.txt /etc/vsftpd/vusers.db</p>
<h1 id="客户端登陆测试</code></pre><h5 style="text-align: start; " id="heading-40"><strong><span fontsize="" color="">2.5.2 实现基于MYSQL验证的vsftpd虚拟用户</span></strong></h5><p style="text-align: start; "><span fontsize="" color="">利用 pam_mysql 模块可以实现基于MySQL的FTP虚拟用户功能</span></p><p style="text-align: start; "><strong><span fontsize="" color="">项目网站:</span></strong></p><pre><code>http://pam-mysql.sourceforge.net/">客户端登陆测试
2.5.2 实现基于MYSQL验证的vsftpd虚拟用户
利用 pam_mysql 模块可以实现基于MySQL的FTP虚拟用户功能
项目网站:
http://pam-mysql.sourceforge.net/</h1>
<p>https://sourceforge.net/projects/pam-mysql/
http://sf.net/projects/pam-mysql
注意:因为此项目年代久远不再更新,当前只支持CentOS 6,7,不支持CentOS 8
环境准备
本实验在两台主机上实现
一台做为FTP服务器 CentOS 7
一台做 MySQL(不要使用 8.0)或者 Mariadb 数据库服务器
2.5.2.1 在数据库服务器上安装mysql数据库
# 注意:MySQL8.0由于取消了PASSWORD()函数不支持,因此选择Mariadb
[root@mysql ~]# yum -y install mariadb-server # centos7
[root@mysql ~]# yum -y install mysql-server # centos8
[root@mysql ~]# systemctl enable --now mariadb
[root@mysql ~]# mysqladmin -u root password 1
[root@mysql ~]# mysql -uroot -p1
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 5.5.68-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> select password("123")
-> ;
+-------------------------------------------+
| password("123") |
+-------------------------------------------+
| *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
+-------------------------------------------+
1 row in set (0.00 sec)
2.5.2.2 在数据库服务上配置数据库支持vsftpd服务
# MySQL 服务器 IP:192.168.2.7</p>
<h1 id="建立存储虚拟用户数据库和表">建立存储虚拟用户数据库和表</h1>
<p>MariaDB [(none)]> CREATE DATABASE vsftpd;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> USE vsftpd;
Database changed
MariaDB [vsftpd]> CREATE TABLE users (
-> id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> name CHAR(50) BINARY NOT NULL,
-> password CHAR(48) BINARY NOT NULL
-> );
Query OK, 0 rows affected (0.00 sec)
</p>
<h1 id="添加虚拟用户,为了安全应该使用PASSWORD函数加密其密码后存储">添加虚拟用户,为了安全应该使用PASSWORD函数加密其密码后存储</h1>
<p>MariaDB [vsftpd]> insert users (name,password) values('tony',password('123'));
Query OK, 1 row affected (0.00 sec)
MariaDB [vsftpd]> insert users (name,password) values('cool',password('321'));
Query OK, 1 row affected (0.00 sec)
MariaDB [vsftpd]> select * from users;
+----+------+-------------------------------------------+
| id | name | password |
+----+------+-------------------------------------------+
| 1 | tony | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
| 2 | cool | *7297C3E22DEB91303FC493303A8158AD4231F486 |
+----+------+-------------------------------------------+
2 rows in set (0.01 sec)
</p>
<h1 id="创建连接的数据库用户">创建连接的数据库用户</h1>
<p>MariaDB [vsftpd]> GRANT SELECT ON vsftpd.* TO vsftpd@'192.168.2.%' IDENTIFIED BY '1';
Query OK, 0 rows affected (0.00 sec)
MariaDB [vsftpd]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
2.5.2.3 在FTP服务器上安装vsftpd 和 pam_mysql包
[root@vsftpd ~]# yum install -y vsftpd
2.5.2.4 在FTP服务器上安装 pam_mysql
对于 centos 6:pam_mysql 由EPEL的源中提供
[root@centos6 ~]# yum install pam_mysql -y
对于 centos7 和 8:无对应rpm包,需手动编译安装 注意: 当前版本的源码不支持 CentOS 8,使用中会提示下面错误
[root@centos8 ~]# tail -f /var/log/secure
centos8 vsftpd[15519]: PAM unable to dlopen(/usr/lib64/security/pam_mysql.so):/usr/lib64/security/pam_mysql.so: undefined symbol: make_scrambled_password
# 安装相关包
[root@vsftpd ~]# yum -y install vsftpd gcc gcc-c++ make mariadb-devel pam-devel
</p>
<h1 id="pam-mysql 源码进行编译">pam-mysql 源码进行编译</h1><h1 id="在线下载">在线下载</h1>
<p>[root@vsftpd ~]# wget http://prdownloads.sourceforge.net/pam-mysql/pam_mysql0.7RC1.tar.gz</p>
<h1 id="或者">或者</h1>
<p>[root@vsftpd ~]# https://github.com/NigelCunningham/pam-MySQL/archive/v0.8.1.tar.gz
</p>
<h1 id="将 pam_mysql-0.7RC1.tar.gz 上传到 linux 服务器上">将 pam_mysql-0.7RC1.tar.gz 上传到 linux 服务器上</h1>
<p>[root@vsftpd ~]# rz -E
rz waiting to receive.
[root@vsftpd ~]# ls
pam_mysql-0.7RC1.tar.gz
</p>
<h1 id="解压">解压</h1>
<p>[root@vsftpd ~]# tar xf pam_mysql-0.7RC1.tar.gz -C /usr/local/src/
[root@vsftpd ~]# cd /usr/local/src/pam_mysql-0.7RC1/
[root@vsftpd pam_mysql-0.7RC1]#./configure --with-pam-mods-dir=/lib64/security
#如果上面命令不指定 --with-pam-mods-dir=/lib64/security 会报以下错误
#checking if the second argument of pam_conv.conv() takes const pointer... no
configure: error: Your system doesn't appear to be configured to use PAM.
Perhaps you need to specify the correct location where the PAM modules reside.
[root@vsftpd pam_mysql-0.7RC1]# make install
[root@vsftpd pam_mysql-0.7RC1]# ll /lib64/security/pam_mysql*
-rwxr-xr-x 1 root root 882 11月 5 23:22 /lib64/security/pam_mysql.la
-rwxr-xr-x 1 root root 141704 11月 5 23:22 /lib64/security/pam_mysql.so
2.5.2.5 在FTP服务器上建立pam认证所需文件
[root@vsftpd ~]# vim /etc/pam.d/vsftpd.mysql # 添加如下两行
auth required pam_mysql.so user=vsftpd passwd=1 host=192.168.2.7 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
account required pam_mysql.so user=vsftpd passwd=1 host=192.168.2.7 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
</p>
<h1 id="注意:以上参考 README文档</code></pre><p style="text-align: start; "><strong><span fontsize="" color="">crypt 加密方式:</span></strong></p><ul><li><p style=""><span fontsize="" color="">0表示不加密</span></p></li><li><p style=""><span fontsize="" color="">1表示crypt(3)加密</span></p></li><li><p style=""><span fontsize="" color="">2表示使用mysql password()函数加密</span></p></li><li><p style=""><span fontsize="" color="">3表示md5加密</span></p></li><li><p style=""><span fontsize="" color="">4表示sha1加密</span></p></li></ul><p style="text-align: start; "><strong><span fontsize="" color="">配置字段说明:</span></strong></p><ul><li><p style=""><span fontsize="" color="">auth 表示认证</span></p></li><li><p style=""><span fontsize="" color="">account 验证账号密码正常使用</span></p></li><li><p style=""><span fontsize="" color="">required 表示认证要通过</span></p></li><li><p style=""><span fontsize="" color="">pam_</span><a target="_blank" rel="noopener noreferrer nofollow" href="http://mysql.so"><span fontsize="" color="">mysql.so</span></a><span fontsize="" color="">模块是默认的相对路径,是相对/lib64/security/路径而言,也可以写绝对路径;后面为给此模块传递的参数</span></p></li><li><p style=""><span fontsize="" color="">user=vsftpd为登录mysql的用户</span></p></li><li><p style=""><span fontsize="" color="">passwd=magedu 登录mysql的的密码</span></p></li><li><p style=""><span fontsize="" color="">host=mysqlserver mysql服务器的主机名或ip地址</span></p></li><li><p style=""><span fontsize="" color="">db=vsftpd 指定连接msyql的数据库名称</span></p></li><li><p style=""><span fontsize="" color="">table=users 指定连接数据库中的表名</span></p></li><li><p style=""><span fontsize="" color="">usercolumn=name 当做用户名的字段</span></p></li><li><p style=""><span fontsize="" color="">passwdcolumn=password 当做用户名字段的密码</span></p></li><li><p style=""><span fontsize="" color="">crypt=2 密码的加密方式为mysql password()函数加密</span></p></li></ul><h6 style="text-align: start; " id="heading-46"><strong><span fontsize="" color="">2.5.2.6 建立相应用户和修改vsftpd配置文件</span></strong></h6><pre><code># 建立虚拟用户映射的系统用户及对应的目录">注意:以上参考 README文档
crypt 加密方式:
0表示不加密
1表示crypt(3)加密
2表示使用mysql password()函数加密
3表示md5加密
4表示sha1加密
配置字段说明:
auth 表示认证
account 验证账号密码正常使用
required 表示认证要通过
pam_mysql.so模块是默认的相对路径,是相对/lib64/security/路径而言,也可以写绝对路径;后面为给此模块传递的参数
user=vsftpd为登录mysql的用户
passwd=magedu 登录mysql的的密码
host=mysqlserver mysql服务器的主机名或ip地址
db=vsftpd 指定连接msyql的数据库名称
table=users 指定连接数据库中的表名
usercolumn=name 当做用户名的字段
passwdcolumn=password 当做用户名字段的密码
crypt=2 密码的加密方式为mysql password()函数加密
2.5.2.6 建立相应用户和修改vsftpd配置文件
# 建立虚拟用户映射的系统用户及对应的目录</h1>
<p>[root@vsftpd ~]# useradd -s /sbin/nologin -d /data/ftproot -r vuser</p>
<h1 id="centos7 需除去 ftp 根目录的写权限">centos7 需除去 ftp 根目录的写权限</h1>
<p>
[root@vsftpd ~]# mkdir -pv /data/ftproot/upload
[root@vsftpd ~]# setfacl -m u:vuser:rwx /data/ftproot/upload
</p>
<h1 id="确保/etc/vsftpd/vsftpd.conf中已经启用了以下选项">确保/etc/vsftpd/vsftpd.conf中已经启用了以下选项</h1>
<p>[root@vsftpd ~]# vim /etc/vsftpd/vsftpd.conf
guest_enable=YES
guest_username=vuser</p>
<h1 id="修改下面一项,原系统用户无法登录">修改下面一项,原系统用户无法登录</h1>
<p>pam_service_name=vsftpd.mysql
[root@vsftpd ~]# systemctl restart vsftpd
</p>
<h1 id="客户端登陆测试">客户端登陆测试</h1><h1 id="默认不能上传文件</code></pre><h6 style="text-align: start; " id="heading-47"><strong><span fontsize="" color="">2.5.2.7 在FTP服务器上配置虚拟用户具有不同的访问权限</span></strong></h6><p style="text-align: start; "><span fontsize="" color="">vsftpd 可以在配置文件目录中为每个用户提供单独的配置文件以定义其ftp服务访问权限,每个虚拟用户 的配置文件名同虚拟用户的用户名。配置文件目录可以是任意未使用目录,只需要在vsftpd.conf指定其 路径及名称即可!</span></p><pre><code># 配置vsftpd为虚拟用户使用配置文件目录">默认不能上传文件
2.5.2.7 在FTP服务器上配置虚拟用户具有不同的访问权限
vsftpd 可以在配置文件目录中为每个用户提供单独的配置文件以定义其ftp服务访问权限,每个虚拟用户 的配置文件名同虚拟用户的用户名。配置文件目录可以是任意未使用目录,只需要在vsftpd.conf指定其 路径及名称即可!
# 配置vsftpd为虚拟用户使用配置文件目录</h1>
<p>[root@vsftpd ~]# vim /etc/vsftpd/vsftpd.conf
#添加如下选项
user_config_dir=/etc/vsftpd/conf.d/
</p>
<h1 id="创建所需要目录,并为虚拟用户提供配置文件">创建所需要目录,并为虚拟用户提供配置文件</h1>
<p>[root@vsftpd ~]# mkdir /etc/vsftpd/conf.d/
[root@vsftpd ~]# vim /etc/vsftpd/conf.d/tony
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES</p>
<h1 id="登录目录改变至指定的目录">登录目录改变至指定的目录</h1>
<p>local_root=/data/ftproot1
[root@vsftpd ~]# vim /etc/vsftpd/conf.d/cool
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES</p>
<h1 id="登录目录改变至指定的目录">登录目录改变至指定的目录</h1>
<p>local_root=/data/ftproot2
[root@vsftpd ~]# mkdir /data/ftproot1
[root@vsftpd ~]# mkdir /data/ftproot2
[root@vsftpd ~]# touch /data/ftproot2/cool.txt
[root@vsftpd ~]# touch /data/ftproot1/tony.txt
[root@vsftpd ~]# mkdir /data/ftproot1/upload
[root@vsftpd ~]# mkdir /data/ftproot2/upload
[root@vsftpd ~]# chown vuser.vuser /data/ftproot1/upload/
[root@vsftpd ~]# chown vuser.vuser /data/ftproot2/upload/
[root@vsftpd ~]# systemctl restart vsftpd
</p>
<h1 id="客户端登陆测试</code></pre><pre><code># 新增一个虚拟用户 jack">客户端登陆测试
# 新增一个虚拟用户 jack</h1>
<p>MariaDB [vsftpd]> insert users (name,password) values('jack',password('666'));
Query OK, 1 row affected (0.00 sec)</p>
<h1 id="客户端登陆测试</code></pre><h2 style="" id="heading-48"><br><span fontsize="" color="">三、FTP加密</span><br></h2><pre><code>tcpdump -i ens33 -nn -X tcp port 21">客户端登陆测试
三、FTP加密
tcpdump -i ens33 -nn -X tcp port 21</h1>
<p>-i interface:指定tcpdump需要监听的接口</p>
<p>-n #对地址以数字方式显式,否则显式为主机名</p>
<p>-nn #除了-n的作用外,还把端口显示为数值,否则显示端口服务名</p>
<h2 id="-X #输出包的头部数据,会以16进制和ASCII两种方式同时输出</code></pre><p style=""></p><h4 style="text-align: start; " id="heading-49"><strong><span fontsize="" color="">3.1 查看 vsftpd 是否支持 openssl</span></strong></h4><pre><code>[root@localhost vip]# ldd /usr/sbin/vsftpd | grep libssl
libssl.so.10 => /lib64/libssl.so.10 (0x00007fcbe6111000)</code></pre><h4 style="text-align: start; " id="heading-50"><strong><span fontsize="" color="">3.2 生成加密信息的秘钥和证书文件</span></strong></h4><h5 style="text-align: start; " id="heading-51"><strong><span fontsize="" color="">3.2.1 生成私钥</span></strong></h5><pre><code>[root@localhost vip]# openssl genrsa -out vsftpd.key 1024
Generating RSA private key, 1024 bit long modulus
..........++++++
............++++++
e is 65537 (0x10001)</code></pre><h5 style="text-align: start; " id="heading-52"><strong><span fontsize="" color="">3.2.2 生成csr信息</span></strong></h5><pre><code>[root@localhost vip]# 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.">-X #输出包的头部数据,会以16进制和ASCII两种方式同时输出
3.1 查看 vsftpd 是否支持 openssl
[root@localhost vip]# ldd /usr/sbin/vsftpd | grep libssl
libssl.so.10 => /lib64/libssl.so.10 (0x00007fcbe6111000)
3.2 生成加密信息的秘钥和证书文件
3.2.1 生成私钥
[root@localhost vip]# openssl genrsa -out vsftpd.key 1024
Generating RSA private key, 1024 bit long modulus
..........++++++
............++++++
e is 65537 (0x10001)
3.2.2 生成csr信息
[root@localhost vip]# 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.</h2>
<p>Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:WH
Organization Name (eg, company) [Default Company Ltd]:IT
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:vsftptest.com
Email Address []:wuchaofeng@qq.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:cn
[root@localhost vip]#
3.2.3 使用ca签发证书
[root@localhost vip]# openssl x509 -req -days 365 -sha256 -in vsftpd.csr -signkey vsftpd.key -out vsftpd.crt
Signature ok
subject=/C=CN/ST=HB/L=WH/O=IT/OU=IT/CN=vsftptest.com/emailAddress=wuchaofeng@qq.com
Getting Private key
[root@localhost vip]#
注意 1:生成完秘钥和证书文件后,将本目录{/etc/ssl/certs/}的权限修改为 500.如果生成的证书文件不在这,请移动到/etc/ssl/certs目录下。
注意 2:在实验环境中可以用命令生成测试,在生产环境中必须要在 https 证书厂商注册(否则浏览器不识别)
3.2.4 修改权限
[root@localhost ~]# chmod 500 /etc/ssl/certs
[root@localhost ~]# ll -d /etc/ssl/certs/
dr-x------. 2 root root 117 Oct 7 20:19 /etc/ssl/certs/
3.3 修改vsftpd配置文件,加入如下的行(匿名访问)
anonymous_enable=YES
ssl_enable=YES
ssl_tlsv1=YES
ssl_sslv2=YES
ssl_sslv3=YES
allow_anon_ssl=YES
force_anon_logins_ssl=YES
force_anon_data_ssl=YES
rsa_cert_file=/etc/ssl/certs/vsftpd.crt
rsa_private_key_file=/etc/ssl/certs/vsftpd.key
allow_writeable_chroot=YES
本地用户加密
ssl_enable=YES
allow_anon_ssl=NO
force_local_logins_ssl=YES
force_local_data_ssl=YES
rsa_cert_file=/etc/ssl/certs/vsftpd.crt
rsa_private_key_file=/etc/ssl/certs/vsftpd.key
3.4 重启服务
[root@localhost vsftpd]# systemctl restart vsftpd
3.5 测试,这里我们使用winscp客户端来测试
查看抓包信息,发现都是被加密的信息了,无法在查看到明文信息
四、总结
FTP(File Transfer Protocol)是一种常用的网络协议,它可以帮助用户在不同计算机之间传输文件。FTP协议已经被广泛应用于文件共享、网站管理、软件发布和数据备份等方面。
使用FTP协议,用户可以通过FTP客户端软件连接到FTP服务器,浏览、上传和下载文件,或者创建、删除和重命名文件和文件夹。FTP提供了很多安全措施,例如用户名和密码验证、SSL/TLS加密传输等,以确保文件传输的安全性。
虽然FTP协议已经存在了很长一段时间,但是随着云计算、对象存储等技术的兴起,越来越多的用户正在转向更现代化的解决方案。然而,FTP仍然是一个非常重要的网络协议,尤其是在需要高效地传输大量文件的情况下。因此,了解和掌握FTP协议对于网络技术人员来说仍然是很重要的一项技能。
- 感谢你赐予我前进的力量