一、FTP的两种工作模式:
1、主动模式:
客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,服务器从20端口向客户端的空闲端口发送连接请求,建立一条数据链路来传送数据。可以看出,主动模式下FTP服务器使用两个端口,分别是命令端口(也叫控制端口,默认为21)、数据端口(默认为20,如果不使用默认的控制端口,则数据端口号为控制端口号减1)。通常情况下客户端都会设置和开启防火墙,导致主动模式下FTP服务器数据端口向客户端发送连接请求时被客户端过滤掉。另外,如果实际的客户端是通过代理请求的FTP服务器,那么FTP主动模式下,FTP服务器的数据端口会请求代理机上实际客户端告诉服务器的那个端口,显然也会有问题。
2、被动模式:
客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,客户端向服务器的空闲端口发送连接请求,建立一条数据链路来传送数据。可以看出,被动模式下FTP服务器使用两个端口,分别是命令端口(也叫控制端口,默认为21)、数据端口(端口不确定,这是与主动模式最主要的区别)。这样就可以解决在主动模式下FTP服务器请求连接客户端时被客户端防火墙过滤掉的问题。随着浏览器的普及,只需在浏览器地址栏中输入以ftp://为前缀的地址,就会开启FTP被动模式访问。
二、常见的FTP服务器类型:
1、WuFTP:广泛应用在众多的Unix和Linux系统中,是RedHat Linux默认的FTP服务器软件,但是安全漏洞也相当多。主要配置文件是ftpaccess。只能以super daemon的方式启动wuftp服务。登陆者可以分为real , guest , anonmous三种。可以针对不同的目录设置不同的传输速率,控制上传下载比例,针对不同的登陆者设定不同的权限。
2、Proftpd:相比WuFTP更安全,由于Proftpd在自身的原始码中已经包含了所需要的执行指令,不需要Linux系统本机的执行程序的支持,所以在系统安全上更为安全。配置简单且灵活,安装后只需要设置proftpd.conf一个配置文件即可,可配置性更强。可以使用stand-alone或者super daemon方式来启动ftp服务。登录者分为anonymous和real user两种。可以控制上传下载比例,实现流量控制,针对不同的目录设定不同的权限。
- 安装步骤:
可以直接使用yum安装
yum install proftpd
或者按如下步骤安装:
1>安装gcc编译环境,如果已安装,略过。
yum install gcc gcc-c++ autoconf automake
2>下载安装包:
cd /usr/local
wget ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.6.tar.gz
3>解压:
tar -xzvf proftpd-1.3.6.tar.gz
4>创建安装需要的目录,编译前配置和检查:
mkdir proftpd
mkdir /var/ftp
cd proftpd-1.3.6
./configure --prefix=/usr/local/proftpd --sysconfdir=/usr/local/proftpd
5>编译和安装:
make & make install
6>修改配置:
修改proftpd.conf配置文件,其中:
①Port为控制端口,默认为21。要保证该端口号-1之后的端口可用,因为在主动模式下,数据端口为控制端口-1得到。如果数据端口不可用,则导致无法连接到FTP服务器;
②Group默认为nogroup,会导致报错,需要改为nobody;
示例如下:
7>关闭防火墙:
systemctl stop firewalld.service
systemctl disable firewalld.service
8>启动服务器:
/usr/local/proftpd/sbin/proftpd
如果希望在每次系统启动后自动运行,则将上述命令配置在/etc/rc.local中。
- proftpd.conf配置项说明
配置项 | 默认值 | 说明 |
---|---|---|
ServerName | "ProFTPD Default Installation" | 服务器的名字 |
ServerType | standalone | proftpd运行的方式,有standalone和inetd |
DefaultServer | on | 是否是默认服务器,只有在需要配置虚拟主机时才将 该参数配置为off |
UseIPv6 | off | 是否支持IPv6 |
Port | 21 | ftp控制端口号 |
User | nobody | 运行ftp的用户 |
Group | nogroup | 运行ftp的用户组 |
DefaultRoot | ~ | 每个用户登录ftp后的目录, 在默认情况下每个用户登录到Proftpd后, 会被引导到该用户的家目录。 ~限制用户只能访问自己的家目录 |
RootLogin | off | 是否允许root用户登录,默认是不允许的, 安全起见不推荐将此选项设置为on |
ServerIdent | on | 是否显示服务器的ServerName等信息, 推荐设置为on。 |
IdentLookups | 是否开启反向查询客户端的用户名 | |
UseReverseDNS | 是否开启DNS反向查询 | |
DeleteAbortedStores | 是否自动删除未传完的文件 | |
DirFakeUser | 是否显示真实的文件所有者信息 | |
DirFakeGroup | 是否显示真实的文件的拥有组信息 | |
DirFakeMode | 是否显示真实的文件的读写操作信息 | |
HideNoAccess | 是否隐藏没有访问权限的文件 | |
RequireValidShell | 用户是否可以执行shell | |
AllowRetrieveRestart | 下载时是否允许断点续传 | |
AllowStoreRestart | 上传时是否允许断点续传 | |
AllowOverwrite | on | 文件是否允许覆盖写内容 |
WtmpLog | 是否要把FTP记录在日志中 | |
Umask | 022 | 通过Proftpd上传文件的默认Umask值 |
UserAlias | 别名 用户名 | 为用户名指定一个别名 |
TransferRate | STOR|RETR 速率(Kbytes/s)user|group 用户或组 | 指定用户或组上传(STOR) 或下载(RETR)最大传输速率, user表示其后指定的是用户, group表示其后指定的是组 |
UserRatio | 用户 fileratio filequota byteratio bytequota | ileratio指定以文件为准的比例 (该参数一般很少使用,所以通常设置为0); filequota指定可以下载多少文件 (设置为0表示不限制); byteratio指定上传、下载比例 (设置一个正整数,表示当上传为1时, 下载的比例; 设置一个负整数,表示当下载为1时, 上传的比例); bytequota指定可以下载多少KB的数据 |
GroupRatio | 组 fileratio filequota byteratio bytequota | 同上 |
MaxHostsPerUser | 设置每个帐号只能有N个来源IP, 为提高FTP用户账号的安全, 将此参数配置为1 | |
MaxClientsPerUser | 设置每个帐号只能有N个连接 | |
MaxClientsPerHost | 设置每个ip只能有N个连接 | |
MaxClients | 设置最大连接数 | |
MaxLoginAttempts | 指定最大尝试连接次数, 匿名的话1就可以 | |
MaxInstances | 最大线程数 | |
TimeoutLogin | 120(秒) | 设置登录时允许等待的时间 |
TimeoutIdle | 600(秒) | 设置客户端空闲断开时间 |
TimeoutNoTransfer | 设置客户端数据传输超时时间 | |
PassivePorts | 最小端口 最大端口 | 设置被动模式下数据端口的范围,即开启被动模式 |
DeferWelcome | on | 是否显示欢迎信息 |
DisplayLogin | welcome.msg | 设置~/welcome.msg中的欢迎信息。 可以编辑welcome.msg定制欢迎信息, 可使用格式字符串: %T:当前的时间 %L:服务端的主机名称 %t:本次上传+下载的文件数量 |
DisplayChdir | .message | 设置每个子目录的欢迎信息,同上 |
CommandBufferSize | 128 | 设置命令的最大长度 |
TransferLog | 设置记录文件传输的日志的路径 | |
SystemLog | 设置系统日志路径 | |
ExtendedLog | 示例 /var/proftpd/access.log WRITE,READ write 以write的日志格式记录READ, WRITE的日志 | |
LogFormat | myxfer "%h %u %t ""%r"" %s %b" default "%h %a %u %t ""%r"" %s %b $$ '%F'" auth "%h %a %t ""%r"" %s" write "%h %a %t ""%r"" %s %b" | 日志格式,可自定义,可使用格式字符串: %a:客户ip |
<Limit 权限> 授权 </Limit> | <Limit>块内有以下权限: SITE_CHMOD:执行chmod命令修改权限
结合以下授权一起使用: Order allow,deny:设置Allow和Deny的优先顺序 Allow from 具体IP:只允许某IP,多个时用,分隔 Deny from 具体IP:不允许某IP,多个时用,分隔 | 一般单独使用或放在
如果出现相同的目录权限配置时后面的配置会将前面的配置覆盖。
示例: <Limit DELE> DenyAll 限制所有用户不能删除文件
|
<Directory <Directory> | 配合<Limit>块设置指定目录的权限 示例: <Directory /usr/local> <Limit RMD DELE SITE_CHMOD> </Directory> 限制用户组pubfxp不能对/usr/local目录进行删除目录、删除文件以及修改权限操作 | |
<Anonymous "匿名登陆的家目录"> </Anonymous> | ~ftp(表示目录:/var/ftp) | 设置匿名用户登录后的家目录,可包含: User ftp 匿名用户登录的账号 Group ftp 匿名用户登录的账号所属组 UserAlias anonymous ftp 设置anonymous和ftp一样可以匿名登录
<Anonymous>块中可放<Limit>块和<Directory>块
示例: <Anonymous ~ftp> User ftp Group ftp DenyAll |
3、vsftpd:全称Very secure FTP daemon。比Proftpd具有更高的安全性。vsftpd使用一般身份启动服务,降低了FTP服务的PID权限,使该服务即使被入侵也无法得到有效的系统管理权限。同时vsftpd利用chroot来改变登录者的根目录,使登录者只能在这个目录中活动,限制了登录者的执行权限。vsftpd通过配置vsftpd.conf文件来完成安装,设置简单。可以使用standalone和super daemon的方式启动。登录者仅分为anonymous和real user 两种。vsftpd无法控制每个目录的流量、不能控制上传下载的比例、不能针对不同的登陆者进行不同的权限设定。
- 安装步骤:
可以直接使用yum安装
yum -y install vsftpd
或者按如下步骤安装:
1>下载安装包
cd /usr/local
wget https://security.appspot.com/downloads/vsftpd-3.0.3.tar.gz
2>解压:
tar -xzvf vsftpd-3.0.3.tar.gz
3>进入解压目录,查看安装说明
cd vsftpd-3.0.3
more INSTALL
4>根据安装说明检查,不存在的目录、用户及用户组要创建
mkdir /usr/share/empty
mkdir /var/ftp
5>可以使用默认目录进行安装,也可修改解压缩目录中的Makefile配置文件,自定义修改安装目录,同时创建自定义指定的目录,否则如果指定的目录不存在会报错。
①修改/usr/local/vsftpd-3.0.3目录下的Makefile配置文件,install配置块修改为:
install:
$(INSTALL) -m 755 vsftpd /usr/local/vsftpd/vsftpd;
$(INSTALL) -m 644 vsftpd.8 /usr/local/vsftpd/man/man8/vsftpd.8;
$(INSTALL) -m 644 vsftpd.conf.5 /usr/local/vsftpd/man/man5/vsftpd.conf.5;
②创建自定义指定的目录:
mkdir -p /usr/local/vsftpd/man/man8/
mkdir -p /usr/local/vsftpd/man/man5/
6>编译:
make
编译过程中可能会出现/usr/bin/ld: cannot find -lxxx错误信息,是因为libxxx.so不存在或版本不匹配的原因,例如报:/usr/bin/ld: cannot find -lc,说明libc.so不存在或版本不匹配,安装或修改版本即可。
7>安装:
make install
8>复制配置文件到/etc/,如果不复制,vsftpd则使用默认配置只允许匿名登录,按实际要求修改配置:
cp vsftpd.conf /etc/
9>关闭防火墙:
systemctl stop firewalld.service
systemctl disable firewalld.service
10>根据实际需要修改/etc/vsftpd.conf,并启动vsftpd
/usr/local/vsftpd/vsftpd &
如果希望在每次系统启动后自动运行,则将上述命令配置在/etc/rc.local中。
部分发行版本还可以使用如下命令启动:
service vsftpd start
如果要设置为开机启动,可以:
chkconfig vsftpd on
#CentOS下已变为:
/bin/systemctl enable vsftpd.service
- PAM模块
出于安全考虑,vsftpd不希望共享本地系统的用户认证信息,而采用自己独立的用户认证数据库来认证虚拟用户,这样虚拟用户和本地用户就不必采用相同的用户名和口令。采用PAM作为后端,可插拔的认证模块来集成各种不同的认证方式:可以是本地系统的真实用户认证(模块pam_unix),也可以是独立的用户认证数据库(模块pam_userdb),还可以是网络上的LDAP数据库(模块pam_ldap)等。所有这些模块都存放在/lib/security/目录(AMD64则是/lib64/security/)下。安装完vsftpd之后,根据需要是否要启用虚拟用户登录。由于CentOS 7已不太支持mysql和pam_mysql,所以这里只介绍db_load方式:
1>db_load
①创建本地用户和密码,但不用于登录系统,后续的虚拟用户vuser1和vuser2都绑定到此用户上。
useradd vuser -s /sbin/nologin
passwd vuser
②在/etc/vsftpd/下创建两个目录,分别存放用户的认证文件和配置文件
mkdir /etc/vsftpd/vuser_db
mkdir /etc/vsftpd/vuser_dir
③在/etc/vsftpd/vuser_db目录中创建包启用户名及用户密码的数据库源文件
cd /etc/vsftpd/vuser_db
vi vuser_info
#以下为vuser_info中的内容,奇数行为用户名,偶数行为上一行用户的密码
vuser1
123456
vuser2
654321
④生成数据库文件
db_load -T -t hash -f /etc/vsftpd/vuser_db/vuser_info /etc/vsftpd/vuser_db/vuser_info.db
⑤编辑pam配置文件指定用户数据库文件
cd /etc/pam.d/
vi vsftpd.vuser
#vsftpd.vuser文件中内容为:
auth required /lib64/security/pam_userdb.so db=/etc/vsftpd/vuser_db/vuser_info
#此处注意不要加.db后缀
account required /lib64/security/pam_userdb.so db=/etc/vsftpd/vuser_db/vuser_info
⑥在/etc/vsftpd/vuser_dir目录中编辑每个虚拟用户的配置文件
cd /etc/vsftpd/vuser_dir
vi vuser1
#vuser1账户配置文件内容为:
local_root=/home/vuser
download_enable=YES
anon_other_write_enable=YES
anon_mkdir_write_enable=YES
cd /etc/vsftpd/vuser_dir
vi vuser2
#vuser2账户配置文件内容为:
local_root=/home/vuser
download_enable=NO
anon_other_write_enable=NO
anon_mkdir_write_enable=NO
⑦修改vsftpd.conf配置文件,开启虚拟用户登录,并指定pam文件路径,指定虚拟用户配置文件路径:
vi /etc/vsftpd/vsftpd.conf
#vsftpd.conf中涉及开启虚拟用户的配置有:
guest_enable=YES
guest_username=vuser
pam_service_name=/etc/pam.d/vsftpd.vuser
user_config_dir=/etc/vsftpd/vuser_dir
allow_writeable_chroot=YES
在安装过程中会遇到:500 OOPS: cannot change directory:/home/xxx,是因为SELinux会阻止ftp daemon读取用户家目录,解决方式有两种:
方案一:降低SELinux安全级别,把enforcing降低到permissive
vi /etc/sysconfig/selinux
#修改为如下内容:
SELINUX=permissive
方案二:关闭SELinux中相关ftp的设置
#查看SELinux中相关ftp设置
getsebool -a|grep ftp
#打开允许访问家目录,参数-P表示重启后仍然生效,如果不加该参数,每次重启会重置成0
setsebool -P allow_ftpd_full_access=1 tftp_home_dir=1
- vsftpd.conf配置项说明
配置项 | 默认值 | 说明 |
---|---|---|
listen | YES | 是否允许监听,如果设置为YES,则vsftpd将以独立模式运行,由vsftpd自己监听和处理IPv4端口的连接请求,与listen_ipv6不能同时开启 |
listen_ipv6 | NO | 设置是否支持IPv6,与listen不能同时开启 |
listen_port | 21 | 设置FTP服务端控制端口 |
ftp_data_port | 20 | 设置FTP服务端数据端口 |
port_enable | 是否开启主动模式 | |
pasv_enable | 是否开启被动模式 | |
pasv_min_port | 0 | 设置被动模式数据端口的最小端口,0表示30000~30999间的任意端口 |
pasv_max_port | 0 | 设置被动模式数据端口的最大端口,0表示30000~30999间的任意端口 |
max_clients | 设置FTP服务器所允许的最大客户端连接数,0表示不限制 | |
max_per_ip | 设置对于同一IP地址允许的最大客户端连接数,0表示不限制 | |
anonymous_enable | YES | 是否允许匿名登录 |
local_enable | NO | 是否允许本地用户(即linux系统中的用户帐号)登录 |
guest_enable | NO | 是否允许虚拟用户登录 |
ftp_username | ftp | 设置匿名登录的用户名称 |
guest_username | 设置虚拟用户对应的本地用户名 | |
no_anon_password | NO | 设置匿名用户登录时是否可不输密码 |
anon_root | /var/ftp | 设置匿名登录后的目录,该目录权限不能是777,否则会登录失败 |
local_root | ~ | 设置本地用户登录后的目录 |
virtual_use_local_privs | NO | 设置虚拟用户与本地用户权限是否相同,否则虚拟用户与匿名用户权限相同 |
chroot_local_user | NO | 所有本地用户是否执行chroot,开启后意味着本地用户不能切换到其他目录 |
chroot_list_enable | NO | 是否指定用户执行chroot |
chroot_list_file | /etc/vsftpd/chroot_list | 当chroot_list_enable=YES时,设置用户名单路径 |
allow_writeable_chroot | NO | 从2.3.5之后,vsftpd增强了安全检查,如果开启chroot,该用户的主目录不能再具有写权限了!如果检查发现还有写权限,就会报错误:500 OOPS: vsftpd: refusing to run with writable root inside chroot(),开启此选项则允许主目录有写权限 |
anon_max_rate | 设置匿名用户的最大传输速率,单位为B/s,0表示不限制 | |
local_max_rate | 设置本地用户的最大传输速率,单位为B/s,0表示不限制 | |
tcp_wrappers | 是否使用tcp_wrappers作为主机访问控制方式,即在/etc/hosts.allow和/etc/hosts.deny中进行控制 | |
pam_service_name | 指定PAM外挂模块提供的认证方式所使用的认证文件,即/etc/pam.d/vsftpd文件。此文件中file=/etc/vsftpd/ftpusers字段,说明了PAM模块能阻止的帐号来自文件/etc/vsftpd/ftpusers中 | |
user_config_dir | 设置虚拟用户配置文件目录 | |
userlist_enable | NO | 是否使用/etc/vsftpd/user_list文件控制用户登录,与/etc/vsftpd/ftpusers相比,/etc/vsftpd/user_list优先级更高 |
userlist_deny | YES | 当userlist_enable=YES时,设置是否阻止/etc/vsftpd/user_list文件中的用户登录FTP服务器。 如果userlist_deny=YES,则不允许etc/vsftpd/user_list文件中的用户登录; 如果userlist_deny=NO,则只允许etc/vsftpd/user_list文件中的用户登录。 |
nopriv_user | nobody | 设置运行vsftpd需要的非特权系统用户 |
deny_email_enable | NO | 是否开启邮箱地址黑名单设置 |
banned_email_file | /etc/vsftpd/banner_emails | 当deny_email_enable=YES时,设置黑名单文件路径,该文件中每行为一个邮箱地址 |
ftpd_banner | 设置登录FTP服务器时显示的欢迎信息 | |
banner_file | 设置欢迎信息内容所在的文件路径 | |
dirmessage_enable | YES | 是否激活目录欢迎信息功能,欢迎信息内容为.message中的内容 |
connect_from_port_20 | NO | 是否打开20数据端口进行传输(主动模式) |
chroot_list_enable | 用户登录FTP服务器后是否只能访问自己目录的文件 | |
chroot_list_file | /etc/vsftpd/chroot_list | 当chroot_list_enable=YES时,被列入此文件的用户,在登录后将不能切换到自己目录以外的其他目录 |
chown_uploads | NO | 是否允许改变上传文件的属主 |
chown_username |
| |
xferlog_enable | YES | 是否让系统自动维护上传和下载的日志文件 |
xferlog_file | /var/log/vsftpd.log | 设置系统维护上传和下载情况的日志文件路径 |
xferlog_std_format | NO | 是否以标准xferlog的格式书写日志内容 |
dual_log_enable | NO | 是否生成两个相似的日志文件,分别是/var/log/xferlog(wu_ftpd类型日志)和/var/log/vsftpd.log(vsftpd类型日志) |
syslog_enable | 是否将原本输出到/var/log/vsftpd.log中的日志,输出到系统日志 | |
idle_session_timeout | 设置数据传输中断的间隔时间(秒) | |
data_connection_timeout | 设置数据连接的超时时间(秒) | |
accept_timeout | 被动模式下连接超时时间(秒) | |
connect_timeout | 主动模式下连接超时时间(秒) | |
anon_umask | 022 | 设置匿名用户的umask |
local_umask | 022 | 设置本地用户的umask |
write_enable | YES | 用户是否具有写权限 |
file_open_mode | 0666 | 用户上传文件后的权限 |
anon_upload_enable | NO | 是否允许匿名用户上传文件,前提是write_enable=YES |
anon_mkdir_write_enable | NO | 是否允许匿名用户创建新文件夹,前提是write_enable=YES |
anon_other_write_enable | NO | 匿名用户是否具有上传和创建目录外的其他权限,比如删除或重命名权限 |
anon_world_readable_only | YES | 是否允许匿名用户下载可阅读的档案(可以下载到本机阅读,但不能直接在FTP服务器中打开阅读) |
async_abor_enable | YES | 是否识别异步ABOR请求 |
ascii_upload_enable | NO | 是否以ASCII方式上传数据,如果启用可能会导致由"SIZE /big/file"方式引起的DoS攻击 |
ascii_download_enable | NO | 是否以ASCII方式下载数据,如果启用可能会导致由"SIZE /big/file"方式引起的DoS攻击 |
ls_recurse_enable | NO | 是否允许递归查询 |
三、FTP常用命令:
ls:显示当前目录中所有文件和目录;
ls remotefile:显示指定文件或目录的信息;
ls/dir remotefile localfile:将指定文件或目录的信息放到指定的本地文件中;
get/reget remotefile:将指定的一文件下载到本地,前提是本地不存在同名文件,reget则为从上次中断处续传;
get/reget remotefile localfile:将指定的一文件下载到本地,并修改下载后文件的名称,reget则为从上次中断处续传;
mget remotefile1 remotefile2 ...:将指定的多个文件下载到本地,前提是本地不存在同名文件;
put/send localfile:将指定的一本地文件上传到FTP服务器,前提是FTP服务器不存在同名文件;
put/send localfile remotefile:将指定的一本地文件上传到FTP服务器,并修改上传后文件的名称,前提是FTP服务器不存在同名文件;
mput localfile1 localfile2 ...:将指定的多个本地文件上传到FTP服务器,前提是FTP服务器不存在同名文件;
delete remotefile:删除远程指定的一个文件;
mdelete remotefile1 remotefile2 ...:删除远程多个文件;
mkdir remotedir:在FTP服务器创建目录;
rmdir remotedir:在FTP服务器删除目录;
cd remotedir:切换FTP服务器目录;
cdup:返回FTP服务器当前目录的父目录;
lcd localdir:切换本地(客户端)目录;
pwd:显示FTP服务器当前目录;
size remotefile:显示指定远程文件的大小;
!command:在本地(客户端)环境中执行对应的command命令;
rename oldname newname:修改文件名称;
newer remotefile:从FTP服务器更新指定文件,如果FTP服务器的同名文件比本地文件内容更新,则更新到本地;如果本地不存在该文件,则下载该文件到本地;
rstatus remotefile:显示文件状态,如果不指定文件名,则显示远程主机的状态;
binary/bin:指定传输方式为二进制;
ascii/asc:指定传输方式为ASCII;
status:显示当前ftp状态;
system:显示FTP服务器的操作系统;
open:连接FTP服务器;
close:断开与FTP服务器连接;
bye/quit/exit:退出FTP命令;