FTP服务器
简介
FTP(File Transfer Protocol,文件传输协议),属于网络传输协议的应用层,这个协议使用的是明文传输。为了更安全的使用FTP协议,只介绍较为安全但功能较少的vsftpd这个软件。
它提供以下几个主要功能:
1、不同的用户:
FTP服务器在默认的情况下,依据用户登录的情况而分为三种不同的身份,分别是:实体用户,real user;访客,guest;匿名用户,anonymous。
2、命令记录与日志文件记录
FTP可以利用系统的syslogd来进行数据的记录,而记录的数据包括了用户曾经使用过的命令与用户传输数据(传输时间、文件大小等)的记录,所以你可以在/var/log/里面找到各项日志信息。
3、限制用户活动的目录(change root,简称chroot)
为了避免用户在你的linux系统中随意切换目录,所以将用户的工作范围局限在用户主目录下面。FTP可以限制用户仅能在自己的用户主目录当中活动。当用户登录FTP后,由于用户无法离开自己的用户主目录,显示的根目录就是自己用户主目录的内容。这种环境称为change root,即chroot,即改变根目录的意思。
工作流程
使用TCP数据包协议。FTP服务器使用了两个连接,分别是命令通道与数据流通道。由于是TCP数据包,这两个连接都需要经过三次握手。
建立命令通道的过程
客户端会随机获取一个大于1024以上的端口来与FTP服务器端的port 21来实现连接,这个过程需要三次握手。实现连接后客户端便可以通过这个连接来对FTP服务器执行命令,查询文件名、下载、上传等命令都是利用这个通道来执行的。
建立数据通道的过程
(1)通知FTP服务器端使用主动连接且告知连接的端口号
FTP服务器的端口21号主要用在命令的执行,但是牵涉到数据流时,就不是使用这个连接了。客户端在需要数据的情况下,会告知服务器端要用什么方式来连接,如果是主动连接,客户端会先随机启用一个端口,且通过命令通道告知FTP服务器这两个信息,并等待FTP服务器的连接。
FTP服务器主动向客户端连接
FTP服务器由命令通道了解客户端的需求后,会主动地由port 20向客户端的数据端口连接,这个连接也会经过三次握手。此时FTP的客户端与服务器端会建立两条连接,分别用在命令的执行与数据的传递。而默认FTP服务器端使用的主动连接端口就是port 20。
数据传输通道是在有数据传输的行为时才会建立的通道,并不是一开始连接到FTP服务器就立刻建立的通道。
注意:port 21主要接收来自客户端的主动连接,port 20则为FTP服务器主动连接至客户端。
(2)客户端选择被动式连接模式
客户端通过命令通道发出被动式连接要求,并等待服务器的回应。
FTP服务器启动数据端口,并通知客户端连接
如果你所使用的FTP服务器是能够处理被动式连接的,此时FTP服务器会先启动一个监听端口。这个端口号码可以是随机的,也可以自定义某一范围的端口,这要看FTP服务器软件而定。然后FTP服务器会通过命令通道告知客户端这个已经启动的端口port pasv,并等待客户端的连接。
然后客户端会随机取用一个大于1024的端口号来进行对主机的port pasv连接。如果一切都没有问题的话,那么FTP数据就可以通过客户端的随机端口和服务端的port pasv来传送了。
主配置文件常用的字段
12 anonymous_enable=YES //YES表示允许匿名用户登录
16 local_enable=YES //YES表示允许系统用户登录
19 write_enable=YES //YES表示允许系统用户上传数据
23 local_umask=022 //系统用户上传普通文件权限掩码
29 #anon_upload_enable=YES //YES表示允许匿名用户上传文件
33 #anon_mkdir_write_enable=YES //YES表示允许匿名用户具有建立目录的权限。
37 dirmessage_enable=YES //当用户进入某个目录时,会显示该目录需要注意的内容
40 xferlog_enable=YES //设置为YES时,用户上传与下载文件都会被记录下来
43 connect_from_port_20=YES //主动模式时服务端使用20号端口作为数据端口请求客户端随机端口 53
49 #chown_username=whoever //匿名用户上传的文件或文件夹的所属者和所属组
53 #xferlog_file=/var/log/xferlog //如果xferlog_enable=YES,这里就可以设置日志文件的文件名
57 xferlog_std_format=YES //是否采用标准格式
60 #idle_session_timeout=600 //如果用户在600秒内都没有命令操作,强制脱机。
63 #data_connection_timeout=120 //如果服务器与客户端的数据连接已经成功建立,但是由于线路问题导致120秒内还是无法顺利的完成数据的传送,那客户端的连接就会被强制断开
67 #nopriv_user=ftpsecure //设置一个执行vsftpd服务的用户
82 #ascii_upload_enable=YES //YES表示客户端默认使用ascii格式上传文件
83 #ascii_download_enable=YES //YES表示client默认使用ASCII格式下载文件
90 #deny_email_enable=YES //YES表示将某些特殊的email address阻挡住
92 #banned_email_file=/etc/vsftpd/banned_emails //如果deny_email_enable=YES,可以利用这个设置项目来规定哪个email address不可登录我们的vsftpd。在上面设置的文件内,一行输入一个email address即可
100 #chroot_local_user=YES //YES表示用户会被限制在自己的主目录之内
101 #chroot_list_enable=YES //YES表示启用chroot写入列表的功能
103 #chroot_list_file=/etc/vsftpd/chroot_list //如果chroot_list_enable=YES就可以设置这个项目,这个项目与chroot_local_user有关
114 listen=NO
123 listen_ipv6=YES
125 pam_service_name=vsftpd //设置PAM认证模块名称为vsftpd
126 userlist_enable=YES //YES表示借助vsftpd的阻挡机制来处理某些不受欢迎的账号
127 tcp_wrappers=YES //服务端和客户端访问控制策略
匿名用户访问
装包
[root@server ~]# yum install vsftpd\* -y
关闭selinux
[root@server ~]# setenforce 0
防火墙放行ftp服务
[root@server ~]# firewall-cmd --add-service=ftp --per
success
[root@server ~]# firewall-cmd --reload
success
新建测试文件
[root@server ~]# echo this is ftp test! > /var/ftp/pub/test.txt
编辑配置文件
[root@server ~]# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=YES //允许匿名用户访问
anon_upload_enable=YES //允许匿名用户上传文件
anon_mkdir_write_enable=YES //允许匿名用户新建目录
anon_umask=055 //匿名用户umask
anon_other_write_enable=yes //允许匿名用户删除文件
匿名用户默认访问的文件夹是/var/ftp,要使匿名用户可以上传文件到/var/ftp/pub,则需给pub文件夹其他用户加上w权限
[root@server ~]# chmod o+w /var/ftp/pub/
重启服务
[root@server ~]# systemctl restart vsftpd
测试,客户端使用用户名ftp,空密码登陆
[root@client ~]# ftp 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): ftp
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
测试下载
ftp> ls
227 Entering Passive Mode (192,168,19,101,70,86).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 14:57 test
226 Directory send OK.
ftp> get test
local: test remote: test
227 Entering Passive Mode (192,168,19,101,177,223).
150 Opening BINARY mode data connection for test (0 bytes).
226 Transfer complete.
测试上传文件
ftp> put ftptest
local: ftptest remote: ftptest
227 Entering Passive Mode (192,168,19,101,78,139).
150 Ok to send data.
226 Transfer complete.
测试新建目录
ftp> mkdir tests
257 "/pub/tests" created
测试删除文件
ftp> delete test
250 Delete operation successful.
测试上传的文件夹和文件的权限,在服务端查看
匿名用户默认上传文件夹权限为700,文件为600,这里设置umask为055,即上传的文件夹权限为722,上传的文件权限为622。
[root@server pub]# ll
total 0
-rw--w--w-. 1 ftp ftp 0 Nov 14 22:58 ftptest
drwx-w--w-. 2 ftp ftp 6 Nov 14 22:58 tests
也可在Windows环境下进行测试
系统用户访问
关闭匿名访问
[root@server ~]# vim /etc/vsftpd/vsftpd.conf
anonymous_enable=NO
默认已经允许系统用户上传和下载,删除文件或目录
write_enable=YES
默认登录后显示的信息是该用户的家目录的信息,但是该用户可以查看到根目录,因此这里有一个很重要的概念chroot
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
chroot_list_enable用于控制chroot_list文件是否生效,yes生效,no不生效
1.若chroot_local_user=YES,表示所有用户都不可以切换到上一级目录,即只能在自己的家目录切换,此时chroot_list相当于白名单,位于此名单内的用户不受影响依然可以自由切换目录。
2.若chroot_local_user=NO,表示所有用户都可以自由切换目录,此时chroot_list相当于黑名单,位于此名单内的用户则被限制在自己的家目录内。
注:请添加如下字段,否则未写在chroot_list文件的用户无法登录
allow_writeable_chroot=YES
以下将验证上述两种情况
首先配置字段如下,
allow_writeable_chroot=YES
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
系统中有两个普通用户redhat和xiaohei,且redhat在chroot_list文件中,测试结果应该为redhat可以自由切换目录,xiaohei不行
[root@server pub]# cat /etc/vsftpd/chroot_list
redhat
使用redhat测试
ftp> open 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): redhat
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,19,101,64,117).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 15:36 redhat
226 Directory send OK.
ftp> cd ..
250 Directory successfully changed.
ftp> ls
227 Entering Passive Mode (192,168,19,101,86,189).
150 Here comes the directory listing.
drwx------ 6 1000 1000 4096 Nov 14 15:36 redhat
drwx------ 3 1001 1001 87 Nov 14 12:30 vhaha
drwx------ 3 1002 1002 88 Nov 14 15:36 xiaohei
226 Directory send OK.
使用xiaohei测试
ftp> open 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): xiaohei
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,19,101,46,165).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 15:36 xiaohei
226 Directory send OK.
ftp> cd ..
250 Directory successfully changed.
ftp> ls
227 Entering Passive Mode (192,168,19,101,251,48).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 15:36 xiaohei
226 Directory send OK.
结果正确,使用redhat切换目录,已经切换到上一级目录,使用xiaohei切换目录,显示切换成功,实际上还是在自己的家目录下
接下来修改配置字段为
allow_writeable_chroot=YES
chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
测试结果应该为redhat不能切换目录,xiaohei可以
使用redhat测试
ftp> open 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): redhat
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,19,101,149,234).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 15:36 redhat
226 Directory send OK.
ftp> cd ..
250 Directory successfully changed.
ftp> ls
227 Entering Passive Mode (192,168,19,101,120,62).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 15:36 redhat
226 Directory send OK.
使用xiaohei测试
ftp> open 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): xiaohei
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,19,101,220,15).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 15:36 xiaohei
226 Directory send OK.
ftp> cd ..
250 Directory successfully changed.
ftp> ls
227 Entering Passive Mode (192,168,19,101,145,171).
150 Here comes the directory listing.
drwx------ 6 1000 1000 4096 Nov 14 15:36 redhat
drwx------ 3 1001 1001 87 Nov 14 12:30 vhaha
drwx------ 3 1002 1002 88 Nov 14 15:36 xiaohei
226 Directory send OK.
结果正确,使用redhat切换目录显示成功,实际上ls时还是在自己的家目录,使用xiaohei切换目录时,已经切换到上一级目录。
虚拟用户访问
创建一个用于虚拟用户访问的用户,且不允许登陆
[root@server ~]# useradd -s /sbin/nologin vhaha
编辑配置文件,增加以下字段
guest_enable=YES
guest_username=vhaha
virtual_use_local_privs=YES
//本地虚拟用户特权为YES表示和本地用户访问时的权限一样,如果为NO表示虚拟用户和匿名用户是相同的权限
指定两个虚拟用户
[root@server ~]# vim /etc/vsftpd/vhaha
xixi
redhat
haha
redhat
将虚拟用户文件转换成数据库文件
[root@server ~]# db_load -T -t hash -f /etc/vsftpd/vhaha /etc/vsftpd/vhaha.db
注:
-T表示允许应用程序能够将文本文件转译载入进数据库
-t hash表示使用hash码加密
-f指定包含用户名和密码文本文件。此文件格式为:奇数行为用户名、偶数行为密码
设置数据库访问权限
[root@server ~]# chmod 600 /etc/vsftpd/vhaha.db
修改PAM认证方式,注释掉所有内容并添加如下字段,注释掉的内容为对系统用户的验证,注释之后系统用户将不能登录,也是为了安全
[root@server ~]# vim /etc/pam.d/vsftpd
auth required pam_userdb.so db=/etc/vsftpd/vhaha
account required pam_userdb.so db=/etc/vsftpd/vhaha
重启服务
[root@server ~]# systemctl restart vsftpd
测试
ftp> open 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): xixi
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,19,101,62,28).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 12:30 xxxxxx
226 Directory send OK.
ftp> close
221 Goodbye.
ftp> open 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): haha
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,19,101,169,158).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 12:30 xxxxxx
226 Directory send OK.
但此时两个虚拟用户访问的目录都是vhaha的家目录,这样创建多个虚拟用户显得无意义
因此,我们为每个虚拟用户创建自己的家目录
[root@server ~]# mkdir -p /home/vhaha/xixi /home/vhaha/haha
更改权限
[root@server ~]# chown -R vhaha:vhaha /home/vhaha/
创建用户配置文件夹user_conf
[root@server ~]# mkdir /etc/vsftpd/user_conf
为每个用户创建配置文件
[root@server ~]# touch /etc/vsftpd/user_conf/xixi /etc/vsftpd/user_conf/haha
编辑主配置文件,添加如下字段
[root@server ~]# vim /etc/vsftpd/vsftpd.conf
user_config_dir=/etc/vsftpd/user_conf
编辑xixi的配置文件
[root@server ~]# vim /etc/vsftpd/user_conf/xixi
local_root=/home/vhaha/xixi
由于主配置文件中
virtual_use_local_privs=YES
故虚拟用户和系统用户有相同的权限,因此xixi和系统用户权限相同
编辑haha的配置文件
[root@server ~]# vim /etc/vsftpd/user_conf/haha
local_root=/home/vhaha/haha
virtual_use_local_privs=NO //虚拟用户和匿名用户权限相同,故设置以下匿名用户权限
anon_umask=077 //umask
anon_upload_enable=YES //允许上传
anon_mkdir_write_enable=NO //不允许创建文件夹
anon_other_write_enable=NO //不允许删除
anon_world_readable_only=NO //允许列出文件和目录
测试结果应为 xixi和系统用户权限相同,haha只能上传和下载
使用xixi测试
ftp> open 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): xixi
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,19,101,94,191).
150 Here comes the directory listing.
-rw-r--r-- 1 1001 1001 0 Nov 14 16:28 v-xixi
226 Directory send OK.
ftp> mkdir xixi
257 "/xixi" created
ftp> put ftptest
local: ftptest remote: ftptest
227 Entering Passive Mode (192,168,19,101,155,143).
150 Ok to send data.
226 Transfer complete.
ftp> get v-xixi
local: v-xixi remote: v-xixi
227 Entering Passive Mode (192,168,19,101,68,5).
150 Opening BINARY mode data connection for v-xixi (0 bytes).
226 Transfer complete.
ftp> delete v-xixi
250 Delete operation successful.
使用haha测试
ftp> open 192.168.19.101
Connected to 192.168.19.101 (192.168.19.101).
220 (vsFTPd 3.0.2)
Name (192.168.19.101:root): haha
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,19,101,143,108).
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 0 Nov 14 17:25 v-haha
226 Directory send OK.
ftp> delete v-haha
550 Permission denied.
ftp> put ftptest
local: ftptest remote: ftptest
227 Entering Passive Mode (192,168,19,101,105,180).
150 Ok to send data.
226 Transfer complete.
ftp> mkdir ddd
550 Permission denied.
ftp> get v-haha
local: v-haha remote: v-haha
227 Entering Passive Mode (192,168,19,101,147,54).
150 Opening BINARY mode data connection for v-haha (0 bytes).
226 Transfer complete.