文件传输协议(FTP)是一种基于TCP协议在客C/S架构的协议,占用20和21端口
简单文件传输协议(TFTP)是一种基于UDP协议在客C/S架构的协议,占用69端口 TFTP的命令功能不如FTP服务强大,甚至不能遍历目录,在安全性方面也弱于FTP服务 因为TFTP不需要客户端的权限认证,也就减少了无谓的系统和网络带宽消耗,效率更高。
一般来讲,人们将计算机联网的首要目的就是获取资料,而文件传输是一种非常重要的获取资料的方式。今天的互联网是由几千万台个人计算机、工作站、服务器、小型机、大型机、巨型机等具有不同型号、不同架构的物理设备共同组成的,而且即便是个人计算机,也可能会装有Windows、Linux、UNIX、Mac等不同的操作系统。为了能够在如此复杂多样的设备之间解决问题解决文件传输问题,文件传输协议(FTP)应运而生。
FTP是一种在互联网中进行文件传输的协议,基于客户端/服务器(C/S)模式,默认使用20、21号端口,其中端口20(数据端口)用于进行数据传输,端口21(命令端口)用于接受客户端发出的相关FTP命令与参数。FTP服务器普遍部署于内网中,具有容易搭建、方便管理的特点。而且有些FTP客户端工具还可以支持文件的多点下载以及断点续传技术,因此FTP服务得到了广大用户的青睐。
FTP服务器是按照FTP协议在互联网上提供文件存储和访问服务的主机,FTP客户端则是向服务器发送连接请求,以建立数据传输链路的主机。FTP协议有下面两种工作模式。
防火墙一般是用于过滤从外网进入内网的流量,因此有些时候需要将FTP的工作模式设置为主动模式,才可以传输数据。但是因为客户端主机一般都设有防火墙,会禁止服务器的连接请求,所有适当的iptables规则变得越来越重要了。
由于FTP是一种基于(C/S)客户端/服务器模式的协议,所有有很多的程序能够提供FTP服务的功能。
FTP服务的响应码
1xx: 信息 2xx: 成功类的状态码 3xx: 提示需进一步提供补充类信息的状态码 4xx: 客户端错误 5xx: 服务端错误
vsftpd(非常安全的FTP守护进程)是一款运行在Linux操作系统上的 FTP 服务程序,不仅完全开源而且免费,此外,还具有很高的安全性、传输速度,以及支持虚拟用户验证等其他FTP服务程序具备的特点。
[root@localhost ~]# yum install vsftpd Loaded plugins: langpacks, product-id, subscription-manager ………………省略部分输出信息……………… ================================================================================ Installing: vsftpd x86_64 3.0.2-9.el7 rhel 166 k Transaction Summary ================================================================================ Install 1 Package vsftpd.x86_64 0:3.0.2-9.el7 Complete! [root@linuxprobe ~]# yum install ftp Loaded plugins: langpacks, product-id, subscription-manager ………………省略部分输出信息……………… Install 1 Package ftp.x86_64 0:0.17-66.el7 Complete!
关闭本机防火墙
# iptables防火墙管理工具默认禁止了FTP传输协议的端口号 [root@localhost ~]# iptables -F
配置 FTP 服务
# 程序的主配置文件为/etc/vsftpd/vsftpd.conf [root@localhost ~]# cat /etc/vsftpd/vsftpd.conf 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
CentOS6 中的配置文件位置,在 CentOS7 中有可能不同。
主配置文件:/etc/vsftpd/vsftpd.conf 配置文件目录:/etc/vsftpd/*.conf 服务启动脚本:/etc/rc.d/init.d/vsftpd 用户认证配置文件:/etc/pam.d/vsftpd
匿名用户(映射为ftp用户)共享资源位置:/var/ftp 系统用户通过ftp访问的资源的位置:用户自己的家目录 虚拟用户通过ftp访问的资源的位置:给虚拟用户指定的映射成为的系统用户的家目录
常用配置参数都为主配置文件,/etc/vsftpd/vsftpd.conf 的常用配置。
listen=[YES|NO] #是否以独立运行的方式监听服务 listen_address=IP地址 #设置要监听的 IP 地址 listen_port=21 #设置 FTP 服务的监听端口 download_enable=[YES|NO] #是否允许下载文件 max_clients=0 #最大客户端连接数,0 为不限制 max_per_ip=0 #同一 IP 地址的最大连接数,0 为不限制 chown_uploads=[YES|NO] #是否允许改变上传文件的属主 chown_username=whoever #改变上传文件的属主为 whoever pam_service_name=vsftpd #让 vsftpd 使用 pam 完成用户认证,使用的文件为/etc/pam.d/vsftpd
匿名用户的配置
anonymous_enable=[YES|NO] #是否允许匿名用户访问 anon_upload_enable=[YES|NO] #是否允许匿名用户上传文件 anon_mkdir_write_enable=[YES|NO] #是否允许匿名用户创建目录 anon_other_write_enable=[YES|NO] #是否开放匿名用户的其他写入权限(包括重命名、删除等操作权限) anon_umask=022 #匿名用户上传文件的 umask 值 anon_root=/var/ftp #匿名用户的 FTP 根目录 anon_max_rate=0 #匿名用户的最大传输速率(字节/秒),0 为不限制
系统用户的配置
anonymous_enable=NO #禁止匿名访问模式 local_enable=[YES|NO] #是否允许本地用户登录 FTP write_enable=[YES|NO] #是否开放本地用户的其他写入权限 local_umask=022 #本地用户上传文件的 umask 值 local_root=/var/ftp #本地用户的 FTP 根目录 local_max_rate=0 #本地用户最大传输速率(字节/秒),0 为不限制 userlist_enable=[YES|NO] #开启用户作用名单文件功能 userlist_deny=[YES|NO] #启用禁止用户名单,名单文件为 ftpusers 和/etc/vsftpd/user_list chroot_local_user=[YES|NO] #是否将用户权限禁锢在 FTP 家目录中,以确保安全 chroot_list_enable=[YES|NO] #禁锢文件中指定的 FTP 本地用户于其家目录中 chroot_list_file=/etc/vsftpd/chroot_list #指定禁锢文件位置,需要和 chroot_list_enable 一同开启
日志功能
xferlog_enable=[YES|NO] #是否开启 FTP 日志功能 xferlog_std_format=[YES|NO] #是否以标准格式保持日志 xferlog_file=/var/log/xferlog #指定保存日志的文件名称,需要一同开启
vsftpd 作为更加安全的文件传输的服务程序,允许用户以三种认证模式登录到 FTP 服务器上。
vsftpd 服务程序默认开启了匿名开放模式,我们需要做的就是开放匿名用户的上传、下载文件的权限,以及让匿名用户创建、删除、更名文件的权限。
# 匿名访问模式主配置文件 [root@localhost ~]# 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 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@localhost ~]# systemctl restart vsftpd # 服务程序加入到开机启动项中,以保证服务器在重启后依然能够正常提供传输服务 [root@localhost ~]# systemctl enable vsftpd ln -s '/usr/lib/systemd/system/vsftpd.service' '/etc/systemd/system/multi-user.target.wants/vsftpd.service
# 在vsftpd服务程序的匿名开放认证模式下,其账户统一为anonymous,密码为空 # 连接到FTP服务器后,默认访问的是/var/ftp目录,我们可以在其中进行创建、删除等操作 [root@localhost ~]# ftp 192.168.10.10 Connected to 192.168.10.10 (192.168.10.10). 220 (vsFTPd 3.0.2) Name (192.168.10.10:root): anonymous 331 Please specify the password. Password:此处敲击回车即可 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> cd pub 250 Directory successfully changed. ftp> mkdir files 550 Permission denied.
# 系统显示拒绝创建目录,这是为什么呢? # 查看该目录的权限得知,只有root管理员才有写入权限,开放ftp用户权限(该账户在系统中已经存在) [root@localhost ~]# ls -ld /var/ftp/pub drwxr-xr-x. 3 root root 16 Jul 13 14:38 /var/ftp/pub [root@localhost ~]# chown -Rf ftp /var/ftp/pub [root@localhost ~]# ls -ld /var/ftp/pub drwxr-xr-x. 3 ftp root 16 Jul 13 14:38 /var/ftp/pub [root@localhost ~]# ftp 192.168.10.10 ………………省略部分输出信息……………… ftp> mkdir files 550 Create directory operation failed.
# 我们发现还是无法创建目录,发现是SELinux服务在捣乱了 # 使用getsebool命令查看与FTP相关的SELinux域策略都有哪些 [root@localhost ~]# getsebool -a | grep ftp ftp_home_dir --> off ftpd_anon_write --> off ftpd_connect_all_unreserved --> off ftpd_connect_db --> off ftpd_full_access --> off ftpd_use_cifs --> off ftpd_use_fusefs --> off ftpd_use_nfs --> off ftpd_use_passive_mode --> off httpd_can_connect_ftp --> off httpd_enable_ftp_server --> off sftpd_anon_write --> off sftpd_enable_homedirs --> off sftpd_full_access --> off sftpd_write_ssh_home --> off tftp_anon_write --> off tftp_home_dir --> off # 根据经验和策略的名称判断出是ftpd_full_access--> off策略规则导致了操作失败 [root@localhost ~]# setsebool -P ftpd_full_access=on # 此时,匿名用户就可以正常使用FTP服务了 [root@linuxprobe ~]# ftp 192.168.10.10 ………………省略部分输出信息……………… ftp> mkdir files 257 "/pub/files" created ftp> rename files database 350 Ready for RNTO. 250 Rename successful. ftp> exit 221 Goodbye.
如果大家之前用的是匿名开放模式,现在就可以将它关了,然后开启本地用户模式。
# 本地用户模式主配置文件 [root@localhost ~]# vim /etc/vsftpd/vsftpd.conf anonymous_enable=NO local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES connect_from_port_20=YES listen=NO listen_ipv6=YES pam_service_name=vsftpd userlist_enable=YES tcp_wrappers=YES xferlog_enable=YES xferlog_std_format=YES
# 同样需要重启服务和开机自启动 [root@localhost ~]# systemctl restart vsftpd # 服务程序加入到开机启动项中,以保证服务器在重启后依然能够正常提供传输服务 [root@localhost ~]# systemctl enable vsftpd ln -s '/usr/lib/systemd/system/vsftpd.service' '/etc/systemd/system/multi-user.target.wants/vsftpd.service
# 现在已经完全可以本地用户的身份登录FTP服务器了,但是使用root无法登陆 [root@localhost ~]# ftp 192.168.10.10 Connected to 192.168.10.10 (192.168.10.10). 220 (vsFTPd 3.0.2) Name (192.168.10.10:root): root 530 Permission denied. Login failed. ftp> # 这是因为,为了系统的安全,默认禁止root等用户登录FTP服务被系统拒绝访问 # 因为vsftpd服务程序所在的目录中,默认存放着两个名为用户名单的文件,ftpusers和user_list # 在ftpusers和user_list两个用户文件中将root用户删除就可以登录了 [root@localhost ~]# cat /etc/vsftpd/user_list root bin daemon [root@localhost ~]# cat /etc/vsftpd/ftpusers root bin daemon
# 在采用本地用户模式登录FTP服务器后,默认访问的是该用户的家目录,因此不存在写入权限不足的情况 # 如果不关闭SELinux,则需要再次开启SELinux域中对FTP服务的允许策略 [root@localhost ~]# setsebool -P ftpd_full_access=on # 即可以使用系统用户进行FTP服务的登录了 [root@localhost ~]# ftp 192.168.10.10 Connected to 192.168.10.10 (192.168.10.10). 220 (vsFTPd 3.0.2) Name (192.168.10.10:root): escape 331 Please specify the password. Password:此处输入该用户的密码 230 Login successful. Remote system type is UNIX.
认证模式:vsftpd + pam + file
# 编辑虚拟用户文件 [root@localhost ~]# cd /etc/vsftpd/ [root@localhost vsftpd]# vim vuser.list zhangsan redhat lisi redhat
# 明文信息既不安全,也不符合让vsftpd服务程序直接加载的格式 # 因此需要使用db_load命令用哈希算法将原始的明文信息文件转换成数据库文件 # 降低数据库文件的权限,然后再把原始的明文信息文件删除 [root@localhost vsftpd]# db_load -T -t hash -f vuser.list vuser.db [root@localhost vsftpd]# file vuser.db vuser.db: Berkeley DB (Hash, version 9, native byte-order) [root@localhost vsftpd]# chmod 600 vuser.db [root@localhost vsftpd]# rm -f vuser.list
[root@localhost ~]# useradd -d /var/ftproot -s /sbin/nologin virtual [root@localhost ~]# ls -ld /var/ftproot/ drwx------. 3 virtual virtual 74 Jul 14 17:50 /var/ftproot/ [root@localhost ~]# chmod -Rf 755 /var/ftproot/
# 新建一个用于虚拟用户认证的PAM文件vsftpd.vu # PAM文件内的db=参数为使用db_load命令生成的账户密码数据库文件的路径,但不用写数据库文件的后缀 [root@localhost ~]# vim /etc/pam.d/vsftpd.vu auth required pam_userdb.so db=/etc/vsftpd/vuser account required pam_userdb.so db=/etc/vsftpd/vuser
# 我们要做的就是把vsftpd主配置文件中原有的PAM认证文件vsftpd修改为新建的vsftpd.vu文件即可 [root@localhost ~]# vim /etc/vsftpd/vsftpd.conf anonymous_enable=NO pam_service_name=vsftpd.vu user_config_dir=/etc/vsftpd/vusers_dir local_enable=YES guest_enable=YES guest_username=virtual allow_writeable_chroot=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 userlist_enable=YES tcp_wrappers=YES
[root@localhost ~]# mkdir /etc/vsftpd/vusers_dir/ [root@localhost ~]# cd /etc/vsftpd/vusers_dir/ [root@localhost vusers_dir]# touch lisi [root@localhost vusers_dir]# vim zhangsan anon_upload_enable=YES anon_mkdir_write_enable=YES anon_other_write_enable=YES
# 先按照前面实验中的步骤开启SELinux域的允许策略,以免再次出现操作失败的情况 [root@localhost ~]# setsebool -P ftpd_full_access=on [root@localhost ~]# getsebool -a | grep ftp ftp_home_dir –> off ftpd_anon_write –> off ftpd_connect_all_unreserved –> off ftpd_connect_db –> off ftpd_full_access –> off ftpd_use_cifs –> off ftpd_use_fusefs –> off ftpd_use_nfs –> off ftpd_use_passive_mode –> off httpd_can_connect_ftp –> off httpd_enable_ftp_server –> off sftpd_anon_write –> off sftpd_enable_homedirs –> off sftpd_full_access –> on sftpd_write_ssh_home –> off tftp_anon_write –> off tftp_home_dir –> off
[root@localhost ~]# ftp 192.168.10.10 Connected to 192.168.10.10 (192.168.10.10). 220 (vsFTPd 3.0.2) Name (192.168.10.10:root): lisi 331 Please specify the password. Password:此处输入虚拟用户的密码 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> mkdir files 550 Permission denied. ftp> exit 221 Goodbye.
[root@localhost ~]# ftp 192.168.10.10 Connected to 192.168.10.10 (192.168.10.10). 220 (vsFTPd 3.0.2) Name (192.168.10.10:root): zhangsan 331 Please specify the password. Password:此处输入虚拟用户的密码 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> mkdir files 257 "/files" created ftp> rename files database 350 Ready for RNTO. 250 Rename successful. ftp> rmdir database 250 Remove directory operation successful. ftp> exit 221 Goodbye.
认证模式:vsftpd + pam + mysql
# 安装mysql和pam_mysql,pam_mysql由epel源提供 $ yum -y install vsftpd mysql-server mysql-devel pam_mysql
# 1、准备数据库及相关表 首先请确保mysql服务已经正常启动。而后,按需要建立存储虚拟用户的数据库即可,这里将其创建为vsftpd数据库 mysql> create database vsftpd; 授权vsftpd用户可以通过localhost主机操作select权限vsftpd库的所有表,密码为www.escapelife.com mysql> grant select on vsftpd.* to vsftpd@localhost identified by 'www.escapelife.com'; mysql> grant select on vsftpd.* to vsftpd@127.0.0.1 identified by 'www.escapelife.com'; mysql> flush privileges; (这里是本机安装所有授权localhost主机,如果不同需要使用不同的主机地址) (mysql> grant select on vsftpd.* to vsftpd@'192.168.31.%' identified by 'www.escapelife.com';) (mysql> flush privileges;) 创建相关表 mysql> use vsftpd; mysql> create table users ( -> id INT UNSIGNED AUTO_INCREMENT NOT NULL, -> name VARCHAR(50) BINARY NOT NULL, -> password char(48) BINARY NOT NULL, -> PRIMARY KEY(id) -> );
# 2、添加测试的虚拟用户 根据需要添加所需要的用户,需要说明的是,这里将其密码为了安全起见应该使用PASSWORD函数加密后存储 mysql> INSERT INTO users(name, password) VALUES('tom', password('escapelife')); mysql> INSERT INTO users(name, password) VALUES('bob', password('escapelife')); SELETC * FROM user;
# 1.建立pam认证所需文件 $ vi /etc/pam.d/vsftpd.mysql #添加如下两行,主要32位和64位库文件的不同位置,模块路径可不写表示pam模块路径 指定用户、密码、主机、数据库、表、用户名字段、密码字段、密码的加密方式 密码的加密方式可以通过安装的pam_mysql的文档查看,/usr/share/doc/pam_mysql-0.7/README rpm -ql pam_mysql auth required /lib64/security/pam_mysql.so user=vsftpd passwd=www.escapelife.com host=localhost db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2 account required /lib64/security/pam_mysql.so user=vsftpd passwd=www.escapelife.com host=localhost db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2 (auth required /lib64/security/pam_mysql.so user=vsftp passwd=www.escapelife.com host=192.168.31.71 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2) (account required /lib64/security/pam_mysql.so user=vsftp passwd=www.escapelife.com host=192.168.31.71 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2)
注意:由于mysql的安装方式不同,pam_mysql.so基于unix sock连接mysql服务器时可能会出问题,此时,建议授权一个可远程连接的mysql并访问vsftpd数据库的用户。
# 2.修改vsftpd的配置文件,使其适应mysql认证 建立虚拟用户映射的系统用户及对应的目录 $ useradd -s /sbin/nologin -d /var/ftproot vuser $ chmod go+rx /var/ftproot 请确保/etc/vsftpd.conf中已经启用了以下选项 anonymous_enable=YES local_enable=YES write_enable=YES anon_upload_enable=NO anon_mkdir_write_enable=NO chroot_local_user=YES 而后添加以下选项 guest_enable=YES guest_username=vuser 并确保pam_service_name选项的值如下所示 pam_service_name=vsftpd.mysql
# 启动vsftpd服务 $ service vsftpd start $ chkconfig vsftpd on # 查看端口开启情况 $ netstat -tnlp | grep :21 tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN 23286/vsftpd # 使用虚拟用户登录,验正配置结果 $ ftp localhost
# vsftpd可以在配置文件目录中为每个用户提供单独的配置文件以定义其ftp服务访问权限,每个虚拟用户的配置文件名同虚拟用户的用户名。配置文件目录可以是任意未使用目录,只需要在vsftpd.conf指定其路径及名称即可。 # 1、配置vsftpd为虚拟用户使用配置文件目录 $ vim vsftpd.conf user_config_dir=/etc/vsftpd/vusers_config # 2、创建所需要目录,并为虚拟用户提供配置文件 $ mkdir /etc/vsftpd/vusers_config/ $ cd /etc/vsftpd/vusers_config/ $ touch tom bob # 3、配置虚拟用户的访问权限 # 虚拟用户对vsftpd服务的访问权限是通过匿名用户的相关指令进行的 # 如果需要让tom用户具有上传文件的权限,可以修改/etc/vsftpd/vusers_config/tom文件 anon_upload_enable={YES|NO} anon_mkdir_write_enable={YES|NO} anon_other_write_enable={YES|NO}
作者: Escape 链接:https://www.escapelife.site/p...