1. FTP介绍

1.1 FTP介绍

FTPFile TransferProtocol)文件传输协议,是一个用于在客户端和服务器之间进行文件传输的协议,采用的是明文的方式进行数据的传输。FTPHTTP协议都是文件传输协议,都运行在TCP层之上的应用层协议,而FTP采用的是两个并行的TCP连接,一个是控制连接,一个是数据连接。控制连接用于在客户端和服务器之间发送控制信息,如用户名和密码以及一些控制指令的传输。数据连接用于数据的传输。由于FTP采用的是TCP作为其传输层协议,因此在发送数据之前需要完成TCP的三次握手。FTP有两种工作模式,一个是主动模式(Active),一个是被动模式(Passive)。

1.2 主动模式Active

FTP的主动模式下,先建立控制连接,然后在建立数据连接。具体过程如下:

1. 首先客户端使用一个大于1024的随机端口(如portAA)连接到服务器的21端口,需要完成TCP的三次握手。

2. FTP服务器的21端口主要在控制连接用于命令的下达,如果有数据进行传输时,就不使用这个端口了。当客户端有数据传输需求时,客户端会通过控制连接使用port command告诉服务器端要采用Active方式进行数据传输,以及自己用于数据传输时所使用的端口(如port BB),并等待服务器的连接。

3. FTP服务器主动的使用20号端口连接至客户端通告的端口(port BB),这时就建立了两条连接,一个是用于命令发送的控制连接,一个是用于数据发送的数据连接。

具体过程如下图所示:

wKioL1MEVvPwminZAADc0qgdEAo033.jpg

所谓的主动模式,就是在数据连接时,由FTP服务器主动的连接到FTP客户端。

在主动模式下,服务器和客户端所使用的端口号如下:

服务器端:

控制连接:使用的端口号是21

数据连接:使用的端口号是20

客户端:

控制连接:使用的端口是随机端口

数据连接:使用的端口是随机端口


当客户端和服务器端采用的是NAT方式,并且经过防火墙时,在主动模式下会发生如下情况,如下图所示:

wKioL1MEVwmA0RfcAAEa0Wjwz3Q179.jpg

1. 当客户端使用一个随机端口(PortAA)连接至FTP服务器的21号端口建立控制连接时,由于防火墙端的NAT会主动的记录由内部送往外部的信息,因此命令连接可以正常的建立。

2. 当客户端使用portcommand通过控制连接告诉服务器采用主动模式进行数据连接的建立以及客户端用于数据连接的端口号(Port BB)。

3. 服务器端主动的使用20号端口连接至客户端的PortBB,当到达防火墙时,由于Port BB在防火墙上并没有相应的信息记录,因此防火墙会阻止此连接的建立。该连接失败。


解决方法:

方法1:使用FTP的被动模式。

在主动模式下,数据连接的建立是FTP服务器主动的连接FTP客户端,因此在被动模式下,就是FTP客户端主动的连接FTP服务器了。

方法2:使用iptables所提供的FTP侦测模块。

使用modprobe加载ip_conntrack_ftpip_nat_ftp等模块,这几个模块会主动的分析目标端口是21的连接,所以可以得到port BB的端口信息,如果是FTP服务器的主动连接,则可以将数据包发送到正确的客户端。

[root@server1 ~]# modprobe  ip_nat_ftp

[root@server1 ~]# modprobe  ip_conntrack_ftp

[root@server1 ~]# lsmod | grep ftp

nf_nat_ftp             3507  0

nf_conntrack_ftp      12913  1 nf_nat_ftp

nf_nat                 22759  2 nf_nat_ftp,iptable_nat

nf_conntrack          79453  7nf_nat_ftp,nf_conntrack_ftp,iptable_nat,nf_nat,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state

[root@server1 ~]#

1.3 被动模式Passive

同样的,在被动模式下,也是先建立控制连接,然后在建立数据连接。具体过程如下图所示:

wKiom1MEV0WzQefyAADvu9P07WU773.jpg

1. 客户端使用一个随机端口(PortAA)连接到FTP服务器的21号端口,完成TCP的三次握手,建立控制连接。

2. 当两端需要数据发送时,客户端通过控制连接发送一个PASV command命令给服务器,要求采用被动模式进行数据传输。

3. 服务器端随机选择一个端口告诉客户端,自己进行数据连接时所使用的端口号,等待客户端的连接

4. 客户端随机选择一个大于1024的端口(Port BB)连接到FTP服务器的随机端口,用于数据传输。

因此,在被动模式下,在数据传输阶段,是客户端主动的连接服务器。

在被动模式下,服务器和客户端所使用的端口号如下:

服务器端:

控制连接:使用的端口号是21

数据连接:使用的端口是随机端口

客户端:

控制连接:使用的端口是随机端口

数据连接:使用的端口是随机端口


目前实现FTP的软件有很多,在Windows平台下有IISServ-U等,Linux平台下有PorFTPd以及vsftpd等,在这里介绍的是VSFTPD

2. vsftpd安装

VSFTPDVery Secure FTP)非常安全的FTP,是一个基于GPL发布的在类UNIX操作系统上使用的FTP服务器端软件。

安装vsftpd

指令:yum install -y vsftpd

查看是否正确安装:

[root@server1 ~]# rpm -qa | grep vsftpd

vsftpd-2.2.2-11.el6.x86_64

[root@server1 ~]#

查看该软件的配置文件的位置和名称:

[root@server1 ~]# rpm -qc vsftpd

/etc/logrotate.d/vsftpd

/etc/pam.d/vsftpd

/etc/vsftpd/ftpusers

/etc/vsftpd/user_list

/etc/vsftpd/vsftpd.conf

[root@server1 ~]#

3. vsftpd的配置

3.1 服务的启动

vsftpd服务的用法:

[root@server1 ~]# /etc/init.d/vsftpd

Usage: /etc/init.d/vsftpd{start|stop|restart|try-restart|force-reload|status}

[root@server1 ~]#

开机自动启动:

[root@server1 ~]# chkconfig vsftpd --level 35 on

[root@server1 ~]# chkconfig --list | grep vsftpd

vsftpd         0:off   1:off   2:off  3:on    4:off   5:on   6:off

[root@server1 ~]#

注意:如果您不知道该如何配置SElinuxiptables的话,请关闭它们。

关闭SELinux

vim /etc/sysconfig/selinux

SELINUX设置为disabled,保存退出,并重启系统。

关闭iptables

临时关闭:

iptables -F

永久关闭:

/etc/init.d/iptables stop

chkconfig iptables off

重启系统。


配置文件的语法结构:

#开头的表示注释;对大小写敏感;语法格式是“参数 = value

3.2 配置参数

vsftpd允许多种用户登录,如果是系统用户,则被引导到用户的家目录,如果是匿名用户,则被引导到/var/ftp目录,如果是虚拟用户,则被引导到所映射的系统用户的家目录。这些用户的登录方式在3.3节中介绍。

常用的配置参数如下:(可以用man vsftpd.conf查看帮助)

anonymous_enable=YES|NO:是否允许匿名用户登录。

allow_anon_ssl=YES|NO:是否允许匿名用户使用SSL连接。需要ssl_enable设置为YES

local_enable=YES|NO:是否允许本地用户登录。

write_enable=YES|NO:是否允许非匿名用户上传文件。

anon_upload_enable=YES|NO:是否允许匿名用户上传文件。

anon_mkdir_write_enable=YES|NO:是否允许匿名用户在FTP服务器上创建目录。

anon_other_write_enable=YES|NO是否允许匿名用户执行创建目录之外的写操作,如删除、重命名。

download_enable=YES|NO:是否允许用户下载文件。

local_umask本地用户上传文件的umask值,如local_umask=022,则到服务器上查看该文件的权限为777-022或者是666-022

anon_umask:匿名用户上传文件的umask值。

chown_uploads=YES|NO:是否改变匿名用户上传文件的拥有者。

chown_username=who:将匿名用户上传文件的拥有者改为who。当然需要允许匿名用户(anonymous_enable=YES)以及允许匿名用户上传(anon_upload_enable=YES.

userlist_file:指定存放被允许或禁止登录的用户列表文件,默认为/etc/vsftpd/user_list

userlist_enable=YES|NO:是否启用userlist_file的功能。当为YES时,在userlist_file文件中指定的用户尝试登录系统时,在输入密码之前就被拒绝登录了。

userlist_deny=YES|NO:当为yes时,表示拒绝userlist_file文件中的用户登录,当为no时则表示允许该文件中的用户登录。默认值为YES

注意:ftpusers文件和user_list文件都可以用来限制不能登录ftp服务器的用户,ftpusers这个文件中的用户是不允许登录的,没有开关可以控制,而user_list中文件默认也是不允许登录的,可以控制能否登录。如果在ftpusersuser_List中都存在用户,一个不允许,一个允许,以ftpusers文件优先。

chroot_local_user=YES|NO:本地用户是否被chroot,限制在自己的家目录里面。yes表示本地用户会被chroot到自己的家目录里面,no表示本地用户不会被chroot到自己的家目录里面。默认为NO

chroot_list_file:指定chrootfile的文件名。

chroot_list_enable=YES|NO:是否启用chroot_list_file的功能。当chroot_local_user=YES时,且chroot_list_enable也为yes时,表示chroot_list_file里面所指定的用户不会被chroot。当该选项为no时,则会被chroot到自己的家目录。默认为NO

local_root:指定非匿名用户登录时会引导到的目录。匿名用户的家目录为/var/ftp

anon_max_rate匿名用户的最大传输速率。单位是bytes/s

local_max_rate:本地用户的最大传输速率。单位是bytes/s

ascii_upload_enable=YES|NO:上传文件时是否允许使用ascii传输模式

ascii_download_enable=YES|NO:下载文件时是否允许使用ascii传输模式。

idle_session_timeout:指定会话超时时间。客户端连接到了FTP服务器,但是未操作。单位为秒。

data_connection_timeout:指定数据传输超时时间,单位为秒。

deny_file:不允许上传的文件类型。如deny_file={*.exe,*.dll}

pam_service_name=vsftpd:指定vsftpd使用的pam模块的配置文件名称。该配置文件默认在/etc/pam.d目录下。默认的vsftpd的内容如下:

[root@server1 vsftpd]# more /etc/pam.d/vsftpd

#%PAM-1.0

session   optional     pam_keyinit.so    force revoke

auth      required     pam_listfile.so item=user  sense=deny  file=/etc/vsftpd/ftpusers onerr=succeed

auth      required     pam_shells.so

auth      include      password-auth

account   include      password-auth

session   required     pam_loginuid.so

session   include      password-auth

[root@server1 vsftpd]#

注释:item指定允许或拒绝的对象类型,可以是usergroup

sense:指定是允许allow或拒绝deny

file:指定文件名

其他的配置:

listen_address:指定vsftpd服务器监听的地址

listen_port:指定vsftpd服务器的监听端口。默认为21端口

max_clientsvsftpd允许的最大连接数。

max_per_ipvsftpd允许同一个ip的最大连接数。

use_localtime=YES|NO:是否在显示目录列表时使用本地时间。

ftp_banner:登录到FTP服务器时的欢迎信息。

banner_filebanner信息存放的位置。

dirmessage_enable=YES|NO:当用户首次切换到某一个目录时,会显示该目录下的.message里面的内容。

banner_fail:当用户连接失败时,显示该文件里面的内容。如banner_fail=/etc/vsftpd/errorinfo。该参数可以用在vsftpdxinetd管理的时候,可用。

xferlog_enable=YES|NO:是否允许用户上传或下载文件时记录日志。

xferlog_file:指定存放上传或下载信息的日志文件名。

xferlog_std_format=YES|NO:是否使用标准格式记录日志。

nopriv_user:指定vsftpd服务的运行账户,默认为ftp

connect_from_port_20=YES|NO:是否使用20端口传输数据。

pasv_min_portpasv_max_port:设置用于被动模式下,服务器所启用的用于数据传输的端口范围。

pasv_enable:是否允许pasv模式。默认为yes

port_enable:是否允许主动模式,默认为yes

listen=YES开启ipv4的支持

tcp_wrappers=YES|NO:是否允许tcp_wrappers管理。

connect_timeout:在主动模式下,客户端连接服务器的端口时的最大超时时间。默认为60s

virtual_use_local_privs=YES虚拟用户使用本地用户权限。设置为YES时,虚拟用户使用与本地用户相同权限,设置为NO时,虚拟用户使用与匿名用户相同权限(必须开启),如果为YES,则创建文件时的权限依赖于local_umask,如果为NO,则依赖于anon_umask,该值默认为077.


3.3 多用户登录方式

vsftpd中可以访问的用户有如下几种:

1. 匿名用户:默认情况下vsftpd的匿名用户可以下载,不能上传。默认的匿名用户为ftp

2. 授权用户:当授权用户访问VSFTPD服务器时,必须输入用户名和密码。有如下两种:

本地用户:是默认配置,以/etc/passwd里面的用户和密码作为认证来源。

虚拟用户:虚拟用户不FTP服务器的专用用户,可以将用户名和密码保存在本地数据文件、MySQL数据库以及LDAP中。

授权用户的访问介绍如下3种方法:

1. 通过系统用户访问:

只要存在于/etc/passwd中的用户就可以访问VSFTPD服务器。

如:useradd <username> -s  /sbin/nologin

通过-s指定用户的shell/sbin/nologin,不允许其登录系统。

2. 通过本地数据文件实现虚拟用户访问

使用本地数据文件实现虚拟用户访问时,需要先建立一个文件,将用户名和密码保存在该文件中,这种方法主要适用于用户比较少且变动不频繁的情况下。步骤如下:

1安装db4-utils软件,该软件是将一个文件转换成数据库文件。

yum install -y db4-utils

2创建本地映射用户,并修改其家目录。如:

useradd  -d  /var/ftp/vuserdir  -s /sbin/nolog  vuser

chmod o=rwx /var/ftp/vuserdir

3修改/etc/vsftpd/vsftpd.conf文件,增加如下内容:

guest_enable=YES:允许虚拟用户登录

guest_username=vuser:指定虚拟用户映射的本地用户,这里为vuser用户。

4创建一个文件,用于保存用户名和密码,该文件中的用户为虚拟用户,格式为:

username1

username1’s password

username2

username’s password

……

5将该文件转为数据库文件。

db_load -T -t hash -f  <虚拟用户文件的位置>  <虚拟数据库文件的位置>

6修改PAM认证文件/etc/pam.d/vsftpd,将原有内容注释,并增加如下内容:

32位系统:

auth required /lib/security/pam_userdb.so  db=/etc/vsftpd/vsftpd_login

account required /lib/security/pam_userdb.so  db=/etc/vsftpd/vsftpd_login

64位系统:

auth required /lib64/security/pam_userdb.so  db=/etc/vsftpd/vsftpd_login

account required /lib64/security/pam_userdb.so  db=/etc/vsftpd/vsftpd_login

注释:db后面的文件为虚拟用户的数据库文件所在的路径。不需要加扩展名哦,否则会报错。

7修改pam服务名。

pam_service_name=vsftpd

如果是直接在原有的PAM模块vsftpd的基础上修改的话,则这一步可以省略,如果不是,则这一步要进行修改,并将原来的pam_service_name=vsftpd注释掉。

8重启服务。

/etc/init.d/vsftpd restart

3. 通过MySQL实现虚拟用户的访问

FTP的用户非常多,且变化比较频繁时,使用这种方法。

步骤如下:

1安装Mysql数据库。

yum install -y mysql-*

2启动mysql服务

/etc/init.d/mysqld restart

chkconfig mysqld --level 35 on

3使用mysqladmin修改管理员密码

mysqladmin -u root password ‘passwd’

4使用root用户登录到mysql数据库,并创建用于虚拟用户的数据库、表、以及虚拟用户和虚拟用户的密码。

创建数据库:create database forftp;

进入到刚创建的数据库:use forftp

创建表:create table virusers(name varchar(20),password  varchar(20));

创建虚拟用户:insert into virusers(name,password) values (‘ftp1’,’ftp1’);

查看表里面的数据内容:select * from virusers

5出于安全考虑,创建一个用于读取用于FTP虚拟用户的数据库里面的表的用户并为其授权。

grant select on<database-name>.<table-name> to <username>@<host> identified by ‘password’;

flush privileges;

如:

grant select on  forftp.virusers  to viruser@localhost  identified by ‘viruser’;

flush privileges;

6测试该用户是否可以访问

mysql -h localhost -u viruser -p

如果可以正常登录和查看该数据库和表则正常。

7创建本地映射用户并修改权限

useradd  -d  /var/ftp/vuserdir  -s /sbin/nolog  vuser

chmod o=rwx /var/ftp/vuserdir

8修改/etc/vsftpd/vsftpd.conf文件,增加如下内容:

guest_enable=YES:允许虚拟用户登录

guest_username=vuser:指定虚拟用户映射的本地用户,这里为vuser用户。

9下载基于mysqlpam认证模块(pam_mysql-0.7RC1.tar.gz

解压:tar -zxvf pam_mysql-0.7RC1.tar.gz

编译和安装:

cd pam_mysql-0.7RC1

./configure

make

make install

10修改pam的认证模块/etc/pam.d/vsftpd,将原有的内容注释,并加入如下内容

wKiom1MEV6GwbDU9AAF579H4w6I610.jpg

注释:

/lib/security/pam_mysql.so为安装的pam_mysql库文件的位置,这里要确认是在lib下,还是在lib64下。

user:指定登录数据库的用户。

passwd:指定用户所对应的密码

host:指定mysql服务器的地址。如果是本地,则为localhost

db:存放虚拟用户的数据库名称

table:存放虚拟用户的表名称

usercolumn:指定存放用户名的字段。

passwdcolumn:指定存放密码的字段。

crypt:指定密码字段是以什么方式存储在数据库中的。crypt=0,则表示以明文的方式保存的,crypt=1则表示crypt()函数加密保存密码,crypt=2则表示以password()函数加密保存密码,crypt=3则表示以md5的方式保存密码的。

11重启vsftpd服务

/etc/init.d/vsftpd restart


配置完虚拟用户以后,所有的虚拟用户访问FTP服务器的权限都是以guest_username所指定的用户为准,如果需要对不同的虚拟用户指定不同的权限,则需要使用如下配置:

1. /etc/vsftpd/vsftpd.conf配置文件里面,使用user_config_dir参数指定一个存放虚拟用户配置文件的目录:

user_config_dir=/etc/vsftpd/vuserconf

2. 在该目录下以每一个虚拟用户的用户名为名称建立配置文件即可。

如存在一个ftp1的虚拟用户,则其配置文件名为ftp1,里面的参数就可以用3.2节所指定的那些参数。

3.4 FTPS配置

FTPHTTP一样,则默认情况下都是采用明文进行数据传输的,如果希望保证FTP服务器与客户端传输数据的安装,可以使用SSL对其进行加密。具体步骤如下:

1. 建议一个用于存放证书的目录

mkdir /etc/vsftpd/.sslkey

2. 创建证书。在建立证书时需要输入相关信息,可以根据提示输入,但是common name必须是客户端访问服务器时的FQDN,也就是服务器端的FQDNIP地址。

指令:

cd /etc/vsftpd/.sslkey

openssl  req  -new -x509 -nodes -out vsftpd.pem -keyout vsftpd.pem

生成的vsftpd.pem就包含证书也包含私钥。

3. 修改存放证书的目录权限

chmod 400 /etc/vsftpd/.sslkey

4. 修改/etc/vsftpd/vsftpd.conf配置文件的内容,增加如下信息:

ssl_enable=YES   //启用SSL的支持

ssl_sslv2=YES    //vsftpd支持SSLv2

ssl_sslv3=YES    //vsftpd支持SSLv3

ssl_tlsv1=YES    //vsftpd支持tls加密方式v1

force_local_logins_ssl=YES

force_local_data_ssl=YES  //强制本地用户在进行数据传输时使用ssl加密。NO表示可以选择加密,也可以选择不加密

rsa_cert_file=/etc/vsftpd/vsftpd.pem   //指定证书存放路径

4. 客户端访问

客户端访问方式:

1. 通过浏览器访问:

ftp://ftp-serverIP地址或FQDN

ftp://user:password@f tp-serverIP地址或FQDN

2. 通过客户端软件

FileZilla

5. 示例

前提:由于在我的测试环境中启用了iptables,因此先配置一下防火墙规则。

1. 修改/etc/vsftpd/vsftpd.conf配置文件,增加如下信息:

pasv_min_port=5000

pasv_max_port=6000

指定被动模式下,FTP服务器用于数据传输的最小端口和最大端口范围。

iptables -A INPUT -i eth0 -p tcp -s 172.17.100.0/24 -d172.17.100.254 --dport 21 -j ACCEPT

iptables -A INPUT -i eth0 -p tcp -s 172.17.100.0/24 -d172.17.100.254 -m multiport --dport 5000:6000 -j ACCEPT

2. vsftpd.conf所做的任何修改都要重启vsftpd服务:/etc/init.d/vsftpdrestart

5.1 匿名用户相关设置

5.1.1 允许匿名用户上传和创建目录

配置参数如下:

anonymous_enable=YES

anon_upload_enable=YES

anon_mkdir_write_enable=YES

客户端测试:

wKioL1MEV5rwE9UMAAG2UKdAxLM062.jpg

连接到FTP服务器,并上传文件到pub目录下:

wKiom1MEV9bgLp_SAAMm61TBCTI671.jpg

上传文件的时候,提示“严重文件传输错误”。

查看pub目录的权限:

[root@server1 ftp]#ll

total 4

drwxr-xr-x 2 rootroot 4096 Feb 19 09:32 pub

[root@server1 ftp]#

原因:pub目录的权限是755,对于others用户来说,没有w权限,因此就无法上传。

修改pub目录的权限,将其权限改为757.

[root@server1 ftp]#chmod o=rwx pub

[root@server1 ftp]#ll

total 4

drwxr-xrwx 2 rootroot 4096 Feb 19 09:32 pub

[root@server1 ftp]#

重启vsftpd服务,并重新测试:

wKiom1MEV-2QczMRAAKBtU_eaDE655.jpg

文件传输成功……

结论:对于一个目录,如果允许用户上传的话,则相应的目录要具有w权限。

5.1.2 匿名用户修改自己上传文件的名称

在原有参数的基础上,增加如下内容:

anon_other_write_enable=YES

该参数的意思是:允许匿名用户删除、重命名文件。

重启服务器,客户端测试:

wKioL1MEV9zRNXeGAANLNj_hY3Q217.jpg

重命名成功……。

删除该文件,客户端测试:

wKiom1MEWBfRBFbPAAOCSgHogGo630.jpg

直接右键,删除

wKioL1MEWAiwSEHUAANDtiWWT_0302.jpg

提示,删除操作成功。

5.1.3 改变匿名用户上传文件的权限和拥有者

改变匿名用户上传文件的权限:

默认情况下,匿名用户的umask值为077,因此上传一个目录的话,则权限为777-077,结果为700,如果上传的是一个文件的话,则权限为666-077,结果为600,且文件的拥有者和所属组都是ftp

wKiom1MEWEvzaLy1AAN6DeQ2lJ8348.jpg

使用匿名用户上传了两个档案,一个是目录,一个是文件,到VSFTPD服务器上的/var/ftp/pub目录下查看该文件的权限。

[root@server1 pub]#ll

total 4

-rw------- 1 ftpftp    0 Feb 19 10:04 lmsZ46PR62.txt

drwx------ 2 ftpftp 4096 Feb 19 10:04 X-Shell4

[root@server1 pub]#

可以看到,文件的权限为600,目录的权限为700,与我们分析的结果一致。如何改变匿名用户的上传档案的权限呢?需要使用下面的参数:

anon_umask

这个参数用于控制匿名用户上传档案的umask值,默认为077,还有一个和该参数意思一样的是local_umask,这个参数的umask值是022,用于控制本地用户上传档案的权限。

修改anon_umask值为022,并观察上传档案的权限,并将刚才上传的文件删除。

anon_umask=022

wKioL1MEWD_hS3I-AANX-Rt9o08182.jpg

服务器端查看上传文件的权限:

[root@server1 pub]#ll

total 4

-rw-r--r-- 1 ftpftp    0 Feb 19 10:23 lmsZ46PR62.txt

drwxr-xr-x 2 ftpftp 4096 Feb 19 10:23 X-Shell4

[root@server1 pub]#

符合自己的要求。

删除文件:

wKioL1MEWFewe1xWAAMfBCvob08404.jpg

删除成功。如果不修改anon_umask值而使用默认的umask的话,则匿名用户无法删除目录的哦。

改变匿名用户上传文件的拥有者:

配置参数:

chown_uploads=YES

chown_username=who

参数解释:

chown_uploads:是否改变匿名用户上传文件的拥有者

chown_username:改变匿名用户上传文件的拥有者为who

测试,将匿名用户上传文件的拥有者改为frame

chown_uploads=YES

chown_username=frame

上传文件:

wKiom1MEWJWTbRR7AAMwco5U8p8887.jpg

服务器端查看上传文件的拥有者是否改变:

wKioL1MEWIaxtvjLAAHqLavuA-o666.jpg

可以看到只有文件的拥有者有改变,但是目录的拥有者并没有改变。

5.1.4 改变匿名用户的默认的家目录

匿名用户默认的家目录为/var/ftp,可以通过如下参数改变匿名用户的家目录:

anon_root=/directory

这个参数和local_root的功能是一样的。

测试,将匿名用户的家目录改为/ftp-directory

anon_root=/ftp-directory

wKiom1MEWL_z-CQyAAMxs3nrHm8816.jpg

当上传文件时,上传失败,且显示的根目录中也没有pub,那么这个目录是不是就是我们所制定的ftp-directory目录呢?测试:

ftp-directory目录的权限真多others增加rwx的权限,并上传文件测试,然后到服务器端查看:

[root@server1 /]#chmod o=rwx ftp-directory/

[root@server1 /]#ll -d ftp-directory/

drwxr-xrwx 4ftpuser ftpuser 4096 Feb 19 09:24 ftp-directory/

[root@server1 /]#

当对该目录针对others用户增加w权限时,并启动服务,发现客户端连接不上了,并报如下错误:

wKioL1MEWLCz_PZaAAM5v444r8s297.jpg

原因:是由于对匿名用户的家目录针对others用户增加了w权限。

解决方法:在该目录下创建一个新的目录,并对others用户设置rwx权限,将匿名用户的家目录取消w权限。

[root@server1 /]#chmod o=rx ftp-directory/

[root@server1 /]#cd ftp-directory/

[root@server1ftp-directory]# mkdir test

[root@server1ftp-directory]# chmod o=rwx test/

[root@server1ftp-directory]# ll

total 4

drwxr-xrwx 2 rootroot 4096 Feb 19 10:45 test

[root@server1ftp-directory]# ll -d ../ftp-directory/

drwxr-xr-x 5ftpuser ftpuser 4096 Feb 19 10:45 ../ftp-directory/

[root@server1ftp-directory]#

客户端连接测试:

wKiom1MEWOjixd4uAAMfFJ1aCCo821.jpg

测试成功,anon_root所指定的目录就是匿名用户的家目录。

5.2 杂项设置

5.2.1 配置监听地址和端口

listen_address:指定监听地址

listen_port:指定用于控制连接时的监听端口,默认为21端口。

修改如下:

listen_address=172.17.100.254

listen_port=100

使用netstat 查看监听的地址和端口:

[root@server1vsftpd]# netstat -tnlp | grep vsftp

tcp        0     0 172.17.100.254:100         0.0.0.0:*                   LISTEN      10135/vsftpd        

[root@server1vsftpd]#

当客户端连接的时候,就要修改默认的端口为指定的端口了。

5.2.2 最大连接数和单个ip的最大连接数

最大连接数:max_clients

单个IP的最大连接数:max_per_ip

参数设置:

max_clients=2

max_per_ip=1

客户端测试:

wKioL1MEWNzRn8FHAAOpCmGTuEw002.jpg

由于我们设置的一个ip只允许一个连接,因此第一个连接可以正常建立,第二个连接失败。

如果直接使用命令的方式连接到FTP服务器,看到的结果会更明显的哦!

wKioL1MEWPDxKfYqAANzkXYUyN0093.jpg

5.2.3 banner

针对FTPbanner信息有如下几种:

1. banner_file:指定存放banner信息的文件名,则登录时会显示里面的信息。

2. ftpd_banner:直接指定banner信息。如果同时指定了banner_fileftpd_banner的话,则优先显示banner_file里面的信息。

测试:

1先指定ftpd_banner

ftpd_banner=Welcometo Frame's FTP service.

客户端测试:

wKiom1MEWSjjEizLAACFL3_uaNs977.jpg

2)不指定ftpd_banner,指定banner_file

banner_file=/etc/vsftpd/banner

[root@server1vsftpd]# cat banner

##############################

Welcom to Frame's FTP Server

##############################

[root@server1vsftpd]#

客户端测试:

wKioL1MEWR7T-jkXAADH7PT-xEc609.jpg

3 ftpd_bannerbanner_file同时指定

ftpd_banner=Welcometo Frame's FTP service.

banner_file=/etc/vsftpd/banner

客户端测试:

wKiom1MEWVXhllb7AADHtWMPY1U858.jpg

显示的依然是banner_file所指定的文件里面的内容。

5.2.4 dirmessage

dirmessage_enable=YES:当用户第一次进入到一个目录的时候,显示该目录下的.message里面的内容。

客户端测试:

ftp-directory目录下的test目录下,创建一个.message,里面的内容如下:

[root@server1test]# echo 'Hello,Welcome to into this directory!' > .message

[root@server1test]# cat .message

Hello,Welcome tointo this directory!

[root@server1test]#

启用该功能:

dirmessage_enable=YES

wKiom1MEWWrxPYd6AAHf4rQId0o097.jpg

5.3 本地用户相关设置

与本地用户相关的参数如下:

local_umask:指定本地用户上传文件的umask

local_enable:是否允许本地用户登录

write_enable:是否允许本地用户上传

local_root:本地用户的根目录。

5.3.1 拒绝本地用户登录

参数设置:

local_enable=NO

客户端以frame用户测试:

wKioL1MEWVnzuCncAAEakbub-dg781.jpg

登录失败……,提示只允许匿名用户登录。

5.3.2 允许本地用户登录,拒绝上传

参数配置:

local_enable=YES

write_enable=NO

客户端上传测试:

wKiom1MEWZPzVHerAANJZtfEIpE777.jpg

5.3.3 指定本地用户的根目录

参数配置:

local_root=/ftp-directory

write_enable=YES

客户端测试:

wKioL1MEWYXRQDe_AAMyqtSEveY050.jpg

服务器端查看:

[root@server1test]# pwd

/ftp-directory/test

[root@server1test]# ll

total 0

-rw-r--rw- 1 frameframe 0 Feb 19 12:54 lmsZ46PR62.txt

[root@server1test]#

测试成功。

5.3.4 拒绝指定的用户登录

参数配置:

userlist_file:指定存放拒绝或允许登录的用户的文件名。默认为/etc/vsftpd/user_list

userlist_enable=YES:是否启用userlist_file的功能。

userlist_denyYES表示拒绝userlist_file文件中用户登录,NO表示允许里面的用户登录,不再里面的用户则不允许登录。

如果该文件和ftpusers里面的用户冲突的话,则以ftpusers优先。

测试1

测试环境参数配置如下:

userlist_enable=YES

userlist_file=/etc/vsftpd/user_list

userlist_deny=YES

userlist_deny设置为YES,表示拒绝里面的用户登录。

user_list文件的内容如下:

[root@server1vsftpd]# grep frame user_list

frame

[root@server1vsftpd]#

可以看到frame用户在该文件中,理论上来说frame用户则无法登录。另外还有一个测试用户为ftpuser,该用户不再user_list文件中,则该用户可以登录。

测试:

wKiom1MEWcaQ4hlXAAHxem9GiN0191.jpg

frame用户在没有出现要求输入密码前就提示登录失败,而ftpuser用于由于不再user_list文件中,因此可以正常登录。

测试2

user_deny设置为NO,则表示允许里面的用户登录,其他不再该文件中的用户将不能登录。并且user_list文件中的用户和ftpusers文件中的用户有重叠的部分,如root用户。

相关文件的内容如下:

[root@server1vsftpd]# grep root ftpusers

root

[root@server1vsftpd]# grep root user_list

root

[root@server1vsftpd]# grep frame user_list

frame

[root@server1vsftpd]# grep ftpuser user_list

# Note that thedefault vsftpd pam config also checks /etc/vsftpd/ftpusers

[root@server1vsftpd]#

从上述文件可以看出,ftpusersuser_list文件中均有root用户,frame用户在user_list文件中,ftpuser不再user_list文件中。

ftpusersuser_list中的用户存在冲突时,以ftpusers文件中内容优先,因此root用户不能够登录。

userlist_deny设置为NO,因此允许在user_list文件中的用户登录,因此允许frame用户登录,而ftpuser不再user_list文件中,因此ftpuser不能够登录。

下面来验证:

wKiom1MEWdyAC9TNAAEwigKNlvE009.jpg

使用root用户测试时,会提示输入密码,当我输入正确的密码时,也无法登录,不是密码输错了哦。

wKioL1MEWc7TSNC6AAJEEHfi6mA677.jpg

frame用户可以正常登录,而ftpuser不能登录

5.3.5 chroot功能

chroot就是将用户限制在自己的家目录中,可以防止一些错误的权限设置,对系统造成影响。

常用的参数配置:

chroot_local_user=YES:对本地用户进行chrootyes表示本地用户会被chroot到自己的家目录下,no表示本地用户不会被chroot到自己的家目录下。默认为NO

chroot_list_file:指定要被chroot或者是不被chroot的用户列表文件。

chroot_list_enable=YES:是否启用chroot_list_file的功能。当chroot_local_user=YES时,且chroot_list_enable也为yes时,表示chroot_list_file里面所指定的用户不会被chroot。当该选项为no时,则会被chroot到自己的家目录。默认为NO

测试环境配置:

测试1chroot_local_user=NO,本地用户不会被chroot到自己的家目录下。

wKioL1MEWeSSaidVAANMDMsX4sY791.jpg

可以看到frame用户没有被chroot

测试2chroot_local_user=YES,将本地用户chroot到自己的家目录

wKiom1MEWhzzfbebAANG5u0_sc8341.jpg

无法进行切换了,已经是最顶层目录了。

测试3:设置不会被chroot的用户。

参数配置:

chroot_local_user=YES

chroot_list_file=/etc/vsftpd/chroot_list

chroot_list_enable=YES

chroot_list_enable=YESchroot_local_user=YES时,表示chroot_list_file所指定的文件中的用户是不会被chroot的,没有在里面的用户则会被chroot

chroot_list文件中的内容如下:

[root@server1vsftpd]# cat chroot_list

frame

[root@server1vsftpd]#

理论上,frame用户不会被chroot,而另一个测试用户ftpuser由于不再该文件中,因此会被chroot

验证:

wKioL1MEWgrxYpYYAANlVfGYZgc469.jpg

frame用户没有被chroot

wKiom1MEWkHTQqsfAANMPXQAiNE037.jpg

ftpuserchroot了。

注意:如果在测试的时候,用户无法登录的话,有可能就是你的user_list的设置问题了。

5.4 虚拟用户

vsftpd允许多种用户登录的,一个是匿名用户,一个是授权用户,其中授权用户又分为本地用户(存在/etc/passwd里面的用户)和虚拟用户。

5.4.1通过本地数据文件实现虚拟用户访问

配置步骤如下:

1. 安装db4-utils软件,该软件是将一个文件转换成数据库文件。

yum install -y db4-utils

查看是否正确安装:

[root@server1vsftpd]# rpm -qa | grep db4

db4-4.7.25-17.el6.x86_64

db4-utils-4.7.25-17.el6.x86_64

gpg-pubkey-db42a60e-37ea5438

[root@server1vsftpd]#

2. 创建虚拟用户要映射的本地用户

[root@server1vsftpd]# useradd-d /ftp-directory -s /sbin/nologin ftpuser

[root@server1vsftpd]# ll -d /ftp-directory/

drwx------ 4ftpuser ftpuser 4096 Feb 19 13:36 /ftp-directory/

[root@server1vsftpd]# chmodo=rwx /ftp-directory

[root@server1vsftpd]# ll -d /ftp-directory

drwx---rwx 4ftpuser ftpuser 4096 Feb 19 13:36 /ftp-directory

[root@server1vsftpd]# passwdftpuser

Changing passwordfor user ftpuser.

New password:

BAD PASSWORD: it isbased on a dictionary word

Retype newpassword:

passwd: allauthentication tokens updated successfully.

[root@server1vsftpd]#

3. 修改配置文件,允许虚拟用户访问

增加如下参数:

guest_enable=YES

guest_username=ftpuser

guest_enable=YES表示允许虚拟用户访问

guest_username:指定虚拟用户要映射的本地用户。

4. 创建一个存放虚拟用户的文件,文件格式为奇数行为用户,其对应的偶数行为用户的密码。

[root@server1vsftpd]# cat viruser

ftp1

111111

ftp2

222222

[root@server1vsftpd]#

这里ftp1ftp2就是虚拟用户,其中ftp1的密码为111111ftp2的密码为222222.

5. 使用db_load将保存虚拟用户的文件转换成数据库文件。

db_load -T -t hash  -f  <虚拟用户文件的位置>  <虚拟数据库文件的位置>

[root@server1vsftpd]# db_load -T -t hash -f viruser viruser.db

[root@server1vsftpd]#

6. 修改pam认证文件的内容

32位系统:

auth required /lib/security/pam_userdb.sodb=/etc/vsftpd/vsftpd_login

account required /lib/security/pam_userdb.sodb=/etc/vsftpd/vsftpd_login

64位系统:

auth required /lib64/security/pam_userdb.sodb=/etc/vsftpd/vsftpd_login

account required /lib64/security/pam_userdb.sodb=/etc/vsftpd/vsftpd_login

注释:db后面的文件为虚拟用户的数据库文件所在的路径,不需要加扩展名,否则报错。

由于我测试的系统为64位系统,因此配置如下:

[root@server1vsftpd]# cat /etc/pam.d/vsftpd.localdb

auth required/lib64/security/pam_userdb.so db=/etc/vsftpd/viruser

account required /lib64/security/pam_userdb.sodb=/etc/vsftpd/viruser

[root@server1vsftpd]#

7. 修改pam模块服务名。

pam_service_name=vsftpd.localdb

8. 重启服务

/etc/init.d/vsftpd restart

客户端测试:

注意:如果配置了虚拟用户的话,则只允许虚拟用户登录,本地用户和匿名用户则不允许登录。

如果启用了userlist的话,则要按照要求将虚拟用户加入到user_list文件中。

wKiom1MEWl7h4YJYAANCUuiugWQ707.jpg

ftp1ftp2两个虚拟用户均可以正常登录。

测试文件的上传和下载:

下载:

wKioL1MEWlDSHyGlAANqutANkzY247.jpg

下载成功,下载文件没有问题。

测试上传:

wKiom1MEWovh843hAANyQ6-BNCE064.jpg

文件上传成功。

到服务器端查看上传文件的权限:

[root@server1test]# ll

total 628

-rw-r--r--1 ftpuser ftpuser      0 Feb 19 14:01lmsZ46PR62.txt

-rw-r--r-- 1root    root    641020 Feb 19 13:57 services

[root@server1test]#

查看下vsftpd.conf里面所配置的umask的情况:

[root@server1vsftpd]# grep umask vsftpd.conf

# Default umask forlocal users is 077. You may wish to change this to 022,

local_umask=020

anon_umask=022

[root@server1vsftpd]#

本地用户的umask020,而匿名用户的umask022,而上传文件的权限为644,正好是666-022=644,因此这里面就是虚拟用户使用的是匿名用户的权限,而控制虚拟用户使用的是本地用户还是匿名用户的权限的参数是:virtual_use_local_privs

这个参数默认值为NONO表示的就是虚拟用户使用的是匿名用户的权限,如果是YES,则表示的是虚拟用户使用的是本地用户的权限。

5.4.2 使用mysql数据库实现虚拟用户访问

具体步骤如下:

1. 安装mysql数据库

yum install -ymysql-*

2. 启动mysql服务

/etc/init.d/mysqld restart

chkconfig mysqld --level 35 on

3. 使用mysqladmin修改管理员密码

mysqladmin -u root password passwd

4. 使用root用户登录到mysql数据库,并创建用于虚拟用户的数据库、表、以及虚拟用户和虚拟用户的密码。

创建数据库:createdatabase forftp;

进入到刚创建的数据库:useforftp

创建表:createtable virusers(name varchar(20),password  varchar(20));

创建虚拟用户:insertinto virusers(name,password) values (ftp1,ftp1);

查看表里面的数据内容:select* from virusers


mysql> select *from virusers;

+------+----------+

| name | password |

+------+----------+

| ftp1 | ftp1     |

+------+----------+

1 row in set (0.03sec)


mysql>

5. 出于安全考虑,创建一个用于读取用于FTP虚拟用户的数据库里面的表的用户并为其授权。

grant select on <database-name>.<table-name>  to<username>@<host>  identified by password;

flush privileges;

如:

mysql> grant select on forftp.virusers  to  viruser@localhost  identified by 'viruser';

Query OK, 0 rowsaffected (0.17 sec)


mysql> flushprivileges;

Query OK, 0 rowsaffected (0.06 sec)

mysql>

6. 测试该用户是否可以访问

mysql -h localhost  -u viruser -p

如果可以正常登录和查看该数据库和表则正常。

7. 创建虚拟用户要映射的本地用户

[root@server1vsftpd]# useradd-d /ftp-directory -s /sbin/nologin ftpuser

[root@server1vsftpd]# ll -d /ftp-directory/

drwx------ 4ftpuser ftpuser 4096 Feb 19 13:36 /ftp-directory/

[root@server1vsftpd]# chmodo=rwx /ftp-directory

[root@server1vsftpd]# ll -d /ftp-directory

drwx---rwx 4ftpuser ftpuser 4096 Feb 19 13:36 /ftp-directory

[root@server1vsftpd]# passwdftpuser

Changing passwordfor user ftpuser.

New password:

BAD PASSWORD: it isbased on a dictionary word

Retype newpassword:

passwd: allauthentication tokens updated successfully.

[root@server1vsftpd]#

8. 修改配置文件,允许虚拟用户访问

增加如下参数:

guest_enable=YES

guest_username=ftpuser

guest_enable=YES表示允许虚拟用户访问

guest_username:指定虚拟用户要映射的本地用户。

9.下载基于mysqlpam认证模块(pam_mysql-0.7RC1.tar.gz

解压:tar -zxvfpam_mysql-0.7RC1.tar.gz

编译和安装:

cd pam_mysql-0.7RC1

./configure

make

make install


[root@server1software]# ll pam_mysql-0.7RC1.tar.gz

-rw-r--r-- 1 rootroot 335240 Nov 14 14:44 pam_mysql-0.7RC1.tar.gz

[root@server1software]#

在编译的时候如果出现如下错误:configure: error: Cannot find pam headers. Please check if yoursystem is ready for pam module development,则需要使用yum 安装pam-devel包。

10. 修改pam的认证模块/etc/pam.d/vsftpd或者是新创建一个模块,并加入如下内容:

[root@server1 ~]#cat /etc/pam.d/vsftpd.mysql

auth    required        /lib/security/pam_mysql.so      user=viruser    passwd=viruser  host=localhost \

                       db=forftp       table=virusers  usercolumn=name passwdcolumn=password   crypt=0


accountrequired       /lib/security/pam_mysql.so     user=viruser   passwd=viruser  host=localhost \

                       db=forftp       table=virusers  usercolumn=name passwdcolumn=password   crypt=0

[root@server1 ~]#

11. 修改pam服务名

pam_service_name=vsftpd.mysql

12. 重启服务

/etc/init.d/vsftpd restart

客户端测试:

wKioL1MEWoShrQCuAAMzeay3s4I244.jpg

成功登录……

5.5 FTPS

FTPHTTP一样,则默认情况下都是采用明文进行数据传输的,如果希望保证FTP服务器与客户端传输数据的安装,可以使用SSL对其进行加密。具体步骤如下:

1. 建议一个用于存放证书的目录

mkdir  /etc/vsftpd/.sslkey

2. 创建证书。在建立证书时需要输入相关信息,可以根据提示输入,但是common name必须是客户端访问服务器时的FQDN,也就是服务器端的FQDNIP地址。

指令:

cd /etc/vsftpd/.sslkey

openssl  req  -new  -x509 -nodes -out vsftpd.pem -keyout vsftpd.pem

生成的vsftpd.pem就包含证书也包含私钥。


[root@server1vsftpd]# pwd

/etc/vsftpd

[root@server1vsftpd]# mkdir .sslkey

[root@server1vsftpd]# cd .sslkey/

[root@server1.sslkey]# openssl  req  -new -x509 -nodes -out vsftpd.pem -keyout vsftpd.pem

Generating a 2048bit RSA private key

..................................+++

...+++

writing new privatekey to 'vsftpd.pem'

-----

You are about to beasked to enter information that will be incorporated

into yourcertificate request.

What you are aboutto enter is what is called a Distinguished Name or a DN.

There are quite afew fields but you can leave some blank

For some fieldsthere will be a default value,

If you enter '.',the field will be left blank.

-----

Country Name (2letter code) [XX]:CN

State or ProvinceName (full name) []:AnHui

Locality Name (eg,city) [Default City]:HeFei

Organization Name(eg, company) [Default Company Ltd]:Frame  

Organizational UnitName (eg, section) []:

Common Name (eg, your name or your server'shostname) []:ftp.frame.com

Email Address []:

[root@server1.sslkey]# ll vsftpd.pem

-rw-r--r-- 1 rootroot 2977 Feb 19 14:51 vsftpd.pem

[root@server1.sslkey]#

3. 修改存放证书的目录权限

chmod 400 /etc/vsftpd/.sslkey

[root@server1.sslkey]#  chmod 400 vsftpd.pem

[root@server1.sslkey]# ll vsftpd.pem

-r-------- 1 rootroot 2977 Feb 19 14:51 vsftpd.pem

[root@server1.sslkey]#

4. 修改/etc/vsftpd/vsftpd.conf配置文件的内容,增加如下信息:

ssl_enable=YES   //启用SSL的支持

ssl_sslv2=YES    //vsftpd支持SSLv2

ssl_sslv3=YES    //vsftpd支持SSLv3

ssl_tlsv1=YES     //vsftpd支持tls加密方式v1

force_local_logins_ssl=YES

force_local_data_ssl=YES  //强制本地用户在进行数据传输时使用ssl加密。NO表示可以选择加密,也可以选择不加密

rsa_cert_file=/etc/vsftpd/vsftpd.pem  //指定证书存放路径

客户端测试:

wKiom1MEWsLx-fNEAAHZDryUl_E853.jpg

wKioL1MEWraBRNBrAAM4M-4x8vQ855.jpg

wKiom1MEWvCQn56rAAN1-gq_Rbs062.jpg

上传文件成功……