FTP 是一种在互联网中进行文件传输的协议,基于客户端/服务器模式,默认使用 20、21 号端口,其中端口20 用于进行数据传输,端口21 用于接受客户端发出的相关FTP 命令与参数。FTP 服务器普遍部署于内网中,具有容易搭建、方便管理的特点。而且有些 FTP 客户端工具还可以支持文件的多点下载以及断点续传技术,因此得到了广大用户的青睐。
FTP 服务器是按照 FTP 协议在互联网上提供文件存储和访问服务的主机,FTP 客户端则是向服务器发送连接请求,以建立数据传输链路的主机。FTP 协议有下面两种工作模式。
- 主动模式:FTP 服务器主动向客户端发起连接请求。
- 被动模式:FTP 服务器等待客户端发起连接请求(默认工作模式)。
由于 FTP、HTTP、Telnet 等协议的数据都是使用明文进行传输的,因此从设计上就是不可靠的。为满足以密文方式传输文件的需求,发明了 vsftpd 服务程序。
vsftpd(very secure ftp daemon,非常安全的 FTP 守护进程)是一款运行在 Linux 操作系统上的 FTP 服务程序,不仅完全开源而且免费。此外,它还具有很高的安全性、传输速度,以及支持虚拟用户验证等其他 FTP 服务程序不具备的特点。在不影响使用的前提下,管理者可以自行决定客户端是采用匿名开放、本地用户还是虚拟用户的验证方式来登录 vsftpd 服务器。这样即便拿到了虚拟用户的账号密码,也不见得能成功登录 vsftpd 服务器。
安装vsftpd程序
第一步:配置妥当软件仓库之后,安装 vsftpd 服务程序。
[root@RS ~]# dnf install vsftpd //安装 vsftpd 服务程序
第二步:iptables 防火墙管理工具默认禁止了 FTP 协议的端口号,因此在正式配置 vsftpd 服务程序之前,为了避免这些默认的防火墙策略“捣乱”,还需要清空 iptables 防火墙的默认策略,并把当前已经被清理的防火墙策略状态保存下来:
[root@RS ~]# iptables -F //清空防火墙策略
[root@RS ~]# iptables-save //保存
第三步:再把 FTP 协议添加到 firewalld 服务的允许列表中:
[root@RS ~]# firewall-cmd --permanent --zone=public --add-service=ftp //防火墙放行ftp服务
[root@RS ~]# firewall-cmd --reload //重新加载防火墙
第四步:vsftpd 服务程序的主配置文件(/etc/vsftpd/vsftpd.conf)内容总长度有 127 行之多,但其中大多数参数在开头都添加了井号(#),从而成为注释信息,不必在注释信息上花费太多的时间。
可以在 grep 命令后面添加 -v 参数,过滤并反选出没有包含井号(#)的参数行(即过滤掉所有的注释信息),然后将过滤后的参数行通过输出重定向符写回原始的主配置文件中。操作后就只剩下 12 行有效参数了:
[root@RS ~]# mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak
[root@RS ~]# grep -v "#" /etc/vsftpd/vsftpd.conf.bak > /etc/vsftpd/vsftpd.conf
vsftpd 服务程序主配置文件中常用的参数以及作用如下表所示
vsftpd认证模式
vsftpd作为更加安全的文件传输的服务程序,允许用户以三种认证模式登录到FTP服务器上。
- 匿名开放模式:是一种最不安全的认证模式,任何人都可以无需密码验证而直接登录到FTP服务器。
- 本地用户模式:是通过Linux系统本地的账户密码信息进行认证的模式,相较于匿名开放模式更安全,而且配置起来也很简单。但是如果被黑客破解了账户的信息,就可以畅通无阻地登录FTP服务器,从而完全控制整台服务器。
- 虚拟用户模式:是这三种模式中最安全的一种认证模式,它需要为FTP服务单独建立用户数据库文件,虚拟出用来进行口令验证的账户信息,而这些账户信息在服务器系统中实际上是不存在的,仅供FTP服务程序进行认证使用。这样,即使黑客破解了账户信息也无法登录服务器,从而有效降低了破坏范围和影响。
ftp 是 Linux 系统中以命令行界面的方式来管理 FTP 传输服务的客户端工具。首先手动安装这个 ftp 客户端工具,以便在后续实验中查看结果。
dnf install ftp
使用不同方式登录后的所在的位置
登录方式 | 默认目录 |
---|---|
匿名公开 | /var/ftp |
本地用户 | 该用户的家目录 |
虚拟用户 | 对应映射用户的家目录 |
匿名访问模式
匿名开放模式是最不安全的一种认证模式。任何人都可以无须密码验证而直接登录 FTP 服务器。这种模式一般用来访问不重要的公开文件(在生产环境中尽量不要存放重要文件)。当然,如果采用防火墙管理工具(如 TCP Wrapper 服务程序)将 vsftpd 服务程序允许访问的主机范围设置为企业内网,也可以提供基本的安全性。
可以向匿名用户开放的权限参数以及作用如下表所示
参数 | 作用 |
---|---|
anonymous_enable=YES | 允许匿名访问模式 |
anon_umask=022 | 匿名用户上传文件的umask值 |
anon_upload_enable=YES | 允许匿名用户上传文件 |
anon_mkdir_write_enable=YES | 允许匿名用户创建目录 |
anon_other_write_enable=YES | 允许匿名用户修改目录名称或删除目录 |
1、 在 vsftpd 服务程序的主配置文件中正确填写参数,然后保存并退出。
[root@RS ~]# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=yes
anon_umask=022
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
2、 重启 vsftpd服务程序,让新的配置参数生效。
[root@RS ~]# systemctl restart vsftpd //重启vsftpd服务
[root@RS ~]# systemctl enable vsftpd //加入开机启动项
3、 在客户端执行 ftp 命令连接到远程的 FTP 服务器了。在 vsftpd 服务程序的匿名开放认证模式下,其账户统一为 anonymous,密码为空。在连接 FTP 服务器后,默认访问的是/var/ftp 目录。
[root@client ~]# ftp 192.168.8.10 //连接ftp
Connected to 192.168.8.10 (192.168.8.10).
220 (vsFTPd 3.0.3)
Name (192.168.8.10:root): anonymous //【填写固定用户名anonymous】
331 Please specify the password.
Password: //【密码直接回车即可】
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub
4、 系统显示拒绝创建目录!明明在前面清空了 iptables 防火墙策略,而且也在 vsftpd服务程序的主配置文件中添加了允许匿名用户创建目录和写入文件的权限。
在 vsftpd 服务程序的匿名开放认证模式下,默认访问的是/var/ftp 目录。查看该目录的权限得知,只有 root 管理员才有写入权限。所以系统会拒绝操作呢!下面将目录的所有者身份改成系统账户 ftp 即可:
[root@RS ~]# ls -ld /var/ftp/pub //查看文件属主,以下属于 root
drwxr-xr-x. 2 root root 6 Aug 12 2018 /var/ftp/pub
[root@RS ~]# chown -R ftp /var/ftp/pub //更改文件属主为 ftp 用户
[root@RS ~]# ls -ld /var/ftp/pub //在查看,属主已为 ftp 用户
drwxr-xr-x. 2 ftp root 6 Aug 12 2018 /var/ftp/pub
系统再次报错!尽管在使用 ftp 命令登入 FTP 服务器后,在创建目录时系统依然提示操作失败,但是报错信息却发生了变化。在没有写入权限时,系统提示“权限拒绝”(Permission denied),所以是权限的问题。但现在系统提示“创建目录的操作失败”(Create directory operation failed),应该意识到是 SELinux 服务在“捣乱”了吧。下面使用 getsebool 命令查看与 FTP 相关的 SELinux 域策略都有哪些:
[root@RS ~]# getsebool -a | grep ftp //查看与 FTP 相关的 SELinux 域策略
......
ftpd_full_access --> off
......
[root@RS ~]# setsebool -P ftpd_full_access=on //开启策略
这就可以正常创建目录了。
由于权限不足,所以我们将/var/ftp/pub 目录的所有者设置成 ftp 用户本身。除了这种方法,也可以通过设置权限的方法让其他用户获取到写入权限(例如 777 这样的权限)。
但是,由于 vsftpd 服务自身带有安全保护机制,因此不要直接修改/var/ftp 的权限,这有可能导致服务被“安全锁定”而不能登录。一定要记得是对里面的 pub 目录修改权限。
本地用户模式
相较于匿名开放模式,本地用户模式要更安全,而且配置起来也很简单。如果之前用的是匿名开放模式,现在就可以将它关了,然后开启本地用户模式。针对本地用户模式的权限参数以及作用如表所示。
本地用户模式使用的权限参数以及作用
参数 | 作用 |
---|---|
anonymous_enable=NO | 禁止匿名访问模式 |
local_enable=YES | 允许本地用户模式 |
write_enable=YES | 设置可写权限 |
local_umask=022 | 本地用户模式创建文件的umask值 |
userlist_deny=YES | 启用“禁止用户名单”,名单文件为ftpusers和user_list |
userlist_enable=YES | 开启用户作用名单文件功能 |
unmask 一般被称为“权限掩码”或“权限补码”,能够直接影响到新建文件的权限值。普通文件的默认权限是 666,目录的默认权限是 777,这都是写在系统配置文件中的。但默认值不等于最终权限值。umask 参数的默认值是 022,根据公式“默认权限−umask=实际权限”,所以普通文件的默认权限到手后就剩下 644,而目录文件就剩下 755 了。umask 实际是权限的反掩码,通过它可以调整文件最终的权限大小。
1、配置本地用户的参数
[root@RS ~]# vim /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_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
2、重启 vsftpd服务程序,让新的配置参数生效。将配置好的服务添加到开机启动项中。
[root@RS ~]# systemctl restart vsftpd //重启服务
[root@RS ~]# systemctl enable vsftpd //加入启动项
3、按理来讲,现在已经完全可以用本地用户的身份登录 FTP 服务器了。但是在使用 root 管理员的身份登录后,系统提示如下的错误信息:
[root@Client ~]# ftp 192.168.8.10
Connected to 192.168.8.10 (192.168.8.10).
220 (vsFTPd 3.0.3)
Name (192.168.8.10:root): root //尝试root用户登录
530 Permission denied.
Login failed.
在输入 root 管理员的密码之前,就已经被系统拒绝访问了。这是因为 vsftpd服务程序所在的目录中默认存放着两个名为“用户名单”的文件(ftpusers 和 user_list)。vsftpd 服务程序目录中的这两个文件的功能:只要里面写有某位用户的名字,就不再允许这位用户登录到 FTP 服务器上。
[root@RS ~]# cat /etc/vsftpd/user_list
[root@RS ~]# cat /etc/vsftpd/ftpusers
vsftpd 服务程序为了保证服务器的安全性而默认禁止了 root 管理员和大多数系统用户的登录行为,这样可以有效地避免黑客通过 FTP 服务对root 管理员密码进行暴力破解。如果确认在生产环境中使用root 管理员不会对系统安全产生影响,只需按照上面的提示删除掉 root 用户名即可。也可以选择ftpusers 和user_list 文件中不存在的一个普通用户尝试登录FTP 服务器!
为什么同样是禁止用户登录的功能,却要制作两个一模一样的文件呢?
如果把上面主配置文件中 userlist_deny 的参数值改成 NO,那么 user_list 列表就变成了强制白名单。它的功能与之前完全相反,只允许列表内的用户访问,拒绝其他人的访问。
另外,在采用本地用户模式登录 FTP 服务器后,默认访问的是该用户的家目录,而且该目录的默认所有者、所属组都是该用户自己,因此不存在写入权限不足的情况。但是当前的操作仍然被拒绝,这是因为我们刚才将虚拟机系统还原到最初的状态了。为此,需要再次开启 SELinux 域中对 FTP 服务的允许策略
[root@RS ~]# getsebool -a | grep ftp //查看与 FTP 相关的 SELinux 域策略
......
ftpd_full_access --> off
......
[root@RS ~]# setsebool -P ftpd_full_access=on //开启策略
虚拟用户模式
虚拟用户模式是这 3 种模式中最安全的一种认证模式,是专门创建出一个账号来登录 FTP 传输服务的,而且这个账号不能用于以 SSH 方式登录服务器。因为安全性较之于前面两种模式有了提升,所以配置流程也会稍微复杂一些。
1、安装 vsftpd 服务。
创建用于进行 FTP 认证的用户数据库文件,其中奇数行为账户名,偶数行为密码。例如,分别创建 ftp0 和 ftp1 两个用户,密码均为 123456 :
[root@RS ~]# cd /etc/vsftpd/
[root@RS vsftpd]# vim vuser.list
ftp0 //账户
123456 //密码
ftp1 //账户
123456 //密码
要使用db_load 命令用哈希(hash)算法将原始的明文信息文件转换成数据库文件,并且降低数据库文件的权限(避免其他人看到数据库文件的内容),然后再把原始的明文信息文件删除。
[root@RS vsftpd]# db_load -T -t hash -f vuser.list vuser.db
[root@RS vsftpd]# chmod 600 vuser.db
[root@RS vsftpd]# rm -rf vuser.list
2、创建 vsftpd 服务程序用于存储文件的根目录以及用于虚拟用户映射的系统本地用户。vsftpd 服务用于存储文件的根目录指的是 当虚拟用户登录后所访问的默认位置。
为了方便管理 FTP 服务器上的数据,可以把这个系统本地用户的家目录设置为/var 目录(该目录用来存放经常发生改变的数据)。并且为了安全起见,将这个系统本地用户设置为不允许登录 FTP 服务器,这不会影响虚拟用户登录,而且还能够避免黑客通过这个系统本地用户进行登录。/var/ftproot/
[root@RS ~]# useradd -d /var/ftproot -s /sbin/nologin virtual
[root@RS ~]# ls -ld /var/ftproot/
drwx------. 3 virtual virtual 78 Dec 23 01:15 /var/ftproot/
[root@RS ~]# chmod -Rf 755 /var/ftproot/
3、建立用于支持虚拟用户的 PAM 文件。
PAM(可插拔认证模块)是一种认证机制,通过一些动态链接库和统一的 API 把系统提供的服务与认证方式分开,使得系统管理员可以根据需求灵活调整服务程序的不同认证方式。
通俗来讲,PAM 是一组安全机制的模块,系统管理员可以用来轻易地调整服务程序的认证方式,而不必对应用程序进行任何修改。
新建一个用于虚拟用户认证的 PAM 文件 vsftpd.vu,其中 PAM 文件内的“db=”参数为使用 db_load 命令生成的账户密码数据库文件的路径,但不用写数据库文件的后缀:
[root@RS ~]# vim /etc/pam.d/vsftpd.vu
auth required pam_userdb.so db=/etc/vsftpd/vuser
account required pam_userdb.so db=/etc/vsftpd/vuser
4、修改配置文件,利用PAM文件进行认证时使用的参数以及作用
参数 | 作用 |
---|---|
anonymous_enable=NO | 禁止匿名开放模式 |
local_enable=YES | 允许本地用户模式 |
guest_enable=YES | 开启虚拟用户模式 |
guest_username=virtual | 指定虚拟用户账户 |
pam_service_name=vsftpd.vu | 指定PAM文件 |
allow_writeable_chroot=YES | 允许对禁锢的FTP根目录执行写入操作,而且不拒绝用户的登录请求 |
[root@RSA ~]# vim /etc/vsftpd/vsftpd.conf
1 anonymous_enable=NO
2 local_enable=YES
3 write_enable=YES
4 guest_enable=YES
5 guest_username=virtual
6 allow_writeable_chroot=YES
7 local_umask=022
8 dirmessage_enable=YES
9 xferlog_enable=YES
10 connect_from_port_20=YES
11 xferlog_std_format=YES
12 listen=NO
13 listen_ipv6=YES
14 pam_service_name=vsftpd.vu
15 userlist_enable=YES
/*参数pam_service_name=vsftpd,表示登录FTP服务器时是根据/etc/pam.d/vsftpd文件进行安全认证的。
现在要做的就是把vsftpd主配置文件中原有的PAM认证文件vsftpd修改为新建的vsftpd.vu文件即可。*/
5、为虚拟用户设置不同的权限。虽然账户 ftp0 和 ftp1 都是用于 vsftpd 服务程序认证的虚拟账户,但是我们依然想对这两人进行区别对待。比如,允许 ftp0 上传、创建、修改、查看、删除文件,只允许 ftp1 查看文件。这可以通过vsftpd服务程序来实现。只需新建一个目录,在里面分别创建两个以 ftp0 和 ftp1 命名的文件,其中在名为 ftp1 的文件中写入允许的相关权限(使用匿名用户的参数):
[root@RS ~]# mkdir /etc/vsftpd/vusers_dir
[root@RS ~]# cd /etc/vsftpd/vusers_dir/
[root@RS vusers_dir]# touch ftp1
[root@RS vusers_dir]# vim ftp0
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
再次修改 vsftpd 主配置文件,通过添加 user_config_dir 参数来定义这两个虚拟用户不同权限的配置文件所存放的路径。为了让修改后的参数立即生效,需要重启 vsftpd 服务程序并将该服务添加到开机启动项中:
[root@RS ~]# vim /etc/vsftpd/vsftpd.conf
#最后一行追加以下内容
user_config_dir=/etc/vsftpd/vusers_dir
[root@RS vusers_dir]# systemctl restart vsftpd //重启服务
[root@RS vusers_dir]# systemctl enable vsftpd //加入开机启动项
6、设置 SELinux 域允许策略,然后使用虚拟用户模式登录 FTP 服务器。
[root@RS ~]# getsebool -a | grep ftp //查询策略
......
ftpd_full_access --> off
......
[root@RS ~]# setsebool -P ftpd_full_access=on //开启策略
[root@RS ~]# firewall-cmd --permanent --zone=public --add-service=ftp //防火墙放行
[root@RS ~]# firewall-cmd --reload //重新加载防火墙
[root@Client01 ~]# ftp 192.168.8.10 //连接ftp
Connected to 192.168.8.10 (192.168.8.10).
220 (vsFTPd 3.0.3)
Name (192.168.8.10:root): ftp0 //输入账户
331 Please specify the password.
Password: //输入密码
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> mkdir files //创建名为 files 的目录
257 "/files" created
ftp> rename files databases //重命名为 databases
350 Ready for RNTO.
250 Rename successful.
ftp0只能登录,没有其他权限; ftp1不仅可以登录,还可以创建、改名和删除文件,因此ftp1的权限是满的。
TFTP(简单文件传输协议)
简单文件传输协议(Trivial File Transfer Protocol,TFTP)是一种基于 UDP 协议在客户端和服务器之间进行简单文件传输的协议。它提供不复杂、开销不大的文件传输服务,可将其当作 FTP 协议的简化版本。
TFTP 的命令功能不如 FTP 服务强大,甚至不能遍历目录,在安全性方面也弱于 FTP 服务。而且,由于 TFTP 在传输文件时采用的是 UDP 协议,占用的端口号为 69,因此文件的传输过程也不像 FTP 协议那样可靠。但是,因为 TFTP 不需要客户端的权限认证,也就减少了无谓的系统和网络带宽消耗,因此在传输琐碎(trivial)不大的文件时,效率更高。
1、在系统上安装相关的软件包,其中,tftp-server 是服务程序,tftp 是用于连接测试的客户端工具,xinetd 是管理服务:
[root@serverA ~]# dnf install tftp-server tftp xinetd //安装服务程序
2、TFTP服务是使用xinetd服务程序来管理的。xinetd服务可以用来管理多种轻量级的网络服务,而且具有强大的日志功能。简单来说,在安装TFTP软件包后,还需要在xinetd服务程序中将其开启,把默认的禁用(disable)参数修改为no ,RHEL 8系统中tftp所对应的配置文件默认不存在,需要根据示例文件(/usr/share/doc/xinetd/sample.conf)自行创建,直接将下面的内容复制到文件中,就可以使用了::
[root@serverA ~]# vim /etc/xinetd.d/tftp
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /var/lib/tftpboot
disable = no
per_source = 11
cps = 100 2
flags = IPv4
}
3、重启 xinetd 服务并将它添加到系统的开机启动项中,以确保 TFTP 服务在系统重启后依然处于运行状态。
系统的防火墙默认没有允许 UDP 协议的 69 端口,因此需要手动将该端口号加入到防火墙的允许策略中:
[root@serverA ~]# systemctl restart tftp //重启 tftp 服务
[root@serverA ~]# systemctl enable tftp //加入开机启动项
[root@serverA ~]# systemctl restart xinetd //重启 xinetd
[root@serverA ~]# systemctl enable xinetd //加入开机启动项
[root@serverA ~]# firewall-cmd --permanent --zone=public --add-port=69/udp //防火墙放行udp 69端口
[root@serverA ~]# firewall-cmd --reload //重新加载防火墙
4、TFTP 的根目录为/var/lib/tftpboot。可以使用刚才安装好的 tftp 命令尝试访问其中的文件,体验 TFTP 服务的文件传输过程。在使用 tftp 命令访问文件时,可能会用到下表中的参数。
参数 | 作用 |
---|---|
? | 帮助信息 |
put | 上传文件 |
get | 下载文件 |
verbose | 显示详细的处理信息 |
status | 显示当前的状态信息 |
binary | 使用二进制进行传输 |
ascii | 使用ASCII码进行传输 |
timeout | 设置重传的超时时间 |
quit | 退出 |