- FTP协议简介
- FTP软件介绍
- vsftpd服务简介
- vsftpd配置
- vsftpd虚拟用户
一、FTP协议简介
(一)特点
基于C/S架构
双通道协议:数据和命令连接
-
数据传输格式:二进制(默认)和文本
- 注意:传输非文本时使用文本格式可能因操作系统不同导致文件内容变化,故应慎用
(二)两种模式
从建立数据连接时服务器的角色,分为主动模式(PORT Style) 和被动模式(PASV Style)
无论主动模式还是被动模式,命令连接都是相同的,服务器端口为21
(1)被动模式(linux客户端默认)
建立数据连接时,先由服务器端通过命令连接将198和165两个随机数发送给客户端,客户端据此计算出服务器的端口号50853=198*256+165,并主动向服务器发出数据连接请求
(2)主动模式(windows客户端默认)
建立数据连接时,服务器主动在20端口向客户端发起请求
二、FTP软件介绍
(一)FTP服务器
- Wu-ftpd, Proftpd, Pureftpd, ServU, IIS
- vsftpd(Very Secure FTP Daemon): CentOS默认FTP服务器
高速,稳定,下载速度是WU-FTP的两倍
(二)客户端软件
命令行工具
ftp, lftp, lftpget, wget, curl
ftp -A ftpserver:port -A主动模式 -p 被动模式
lftp -u username ftpserver
lftp username@ftpserver
lftpget ftp://ftpserver/pub/file图形界面工具
filezilla, CuteFtp, FlashFXP, LeapFtp
浏览器 ftp://username:password@ftpserver
(三)FTP状态码
- 1XX:信息
125:数据连接打开 - 2XX:成功类状态
200:命令OK ;230:登录成功 - 3XX:补充类
331:用户名OK - 4XX:客户端错误
425:不能打开数据连接 - 5XX:服务器错误
530:不能登录
(四)用户认证:三种方式
匿名用户:ftp, anonymous, 对应Linux用户ftp
系统用户:Linux用户, 用户/etc/passwd, 密码/etc/shadow
-
虚拟用户:特定服务的专用用户,独立的用户/密码文件,需要配合的组件
- nsswitch: network service switch名称解析框架
- pam: pluggable authentication module 用户认证
/lib64/security /etc/pam.d/ /etc/pam.conf
三、vsftpd服务简介
用户认证配置文件:/etc/pam.d/vsftpd
服务脚本:
CentOS 7:/usr/lib/systemd/system/vsftpd.service
CentOS 6:/etc/rc.d/init.d/vsftpd-
配置文件:/etc/vsftpd/vsftpd.conf
- 查询帮助:man 5 vsftpd.conf
- 格式:option=value
注意:=前后不要有空格
-
共享文件位置:
- 匿名用户(映射为系统用户ftp)共享文件位置:ftp用户家目录/var/ftp
- 系统用户共享文件位置:用户家目录
- 虚拟用户共享文件位置:为其映射的系统用户的家目录
四、vsftpd配置
(一)端口设置
(1)命令端口
listen_port=21
(2)主动模式端口
- 配置条目
connect_from_port_20=YES` // 主动模式端口为20
// 注意即使指定其他端口此时值仍是YES,不可修改为NO
ftp_data_port=20` // 指定主动模式的端口
- 实验1-1:将主动模式的端口修改为2020
// 服务器编辑配置文件
vim /etc/vsftpd/vsftpd.conf
connect_from_port_20=YES //本行下添加如下内容
ftp_data_port=2020
service vsftpd restart
// 服务器增加共享文件
cd /var/ftp/pub
dd if=/dev/zero of=file1 bs=1M count=1024
// 客户端匿名登录,下载文件
ftp 192.168.136.229
Name (192.168.136.229:root): ftp
Password:
ftp> cd pub
ftp> ls
ftp> passive //关闭被动模式,开启主动模式
ftp> get file1
// 服务器端查看端口活动,数据传输时打开了2020端口
ss -ntp
(3)被动模式端口范围
- 配置条目
pasv_min_port=6000` // 端口起始范围,0为随机分配
pasv_max_port=6010` // 端口结束范围
- 实验1-2:设置被动模式的端口范围为6000-6010
// 服务器编辑配置文件
vim /etc/vsftpd/vsftpd.conf
connect_from_port_20=YES //本行下添加如下内容
pasv_min_port=6000
pasv_max_port=6010
service vsftpd restart
// 服务器增加共享文件
cd /var/ftp/pub
dd if=/dev/zero of=file1 bs=1M count=1024
dd if=/dev/zero of=file2 bs=1M count=512
dd if=/dev/zero of=file3 bs=1M count=256
// 分别在三个客户端匿名登录,下载文件
ftp 192.168.136.229
Name (192.168.136.229:root): ftp
Password:
ftp> cd pub
ftp> get file1|file2|file3 //三个客户端各自下载file1/2/3
// 服务器端查看端口活动,数据传输时打开了3个在设置范围内的端口
ss -ntp
(二)时间设置
-
use_localtime=YES
:使用当地时间(默认为NO,使用GMT,但当前设置值NO为正确时间)
(三)匿名用户
(1)配置条目
anonymous_enable=YES // 支持匿名用户
no_anon_password=YES // 匿名用户略过口令检查,默认NO
anon_world_readable_only=NO // 只能下载所有者、所属组、其他人都有读权限的文件,默认YES
anon_upload_enable=YES // 匿名上传,注意文件系统权限
anon_mkdir_write_enable=YES // 匿名创建目录
anon_other_write_enable=YES // 可删除和修改上传的文件
anon_umask=077 // 指定匿名上传umask
// 指定上传文件的默认所有者和权限
chown_uploads=YES //默认NO
chown_username=wang
chown_upload_mode=0644
(2)实验:修改vsftpd服务匿名登录配置
-
实验3-1,输入用户名ftp后,自动登陆成功
vim /etc/vsftpd/vsftpd.conf no_anon_password=YES service vsftpd restart
-
实验3-2,实现匿名上传文件
vim /etc/vsftpd/vsftpd.conf anon_upload_enable=YES // 取消行首的注释符 mkdir /var/ftp/upload setfacl -m u:ftp:rwx /var/ftp/upload/ service vsftpd restart
匿名登录的根目录不能上传文件,创建子目录并赋予相应权限,实现文件上传
注意匿名登录时根目录不能拥有所属组和其他人的写权限,否则会报错
-
实验3-3,实现匿名环境下:上传、删除、下载文件,建立目录,上传文件权限为644
vim /etc/vsftpd/vsftpd.conf anon_world_readable_only=NO anon_mkdir_write_enable=YES anon_other_write_enable=YES anon_umask=022 service vsftpd restart
- 实现匿名上传文件的权限被设定为644(umask 022)
- 实现匿名下载文件
- 实现匿名删除ftp共享的文件
- 实现匿名建立目录
-
实验3-4,实现确定匿名上传文件的所有者和权限
chown_uploads=YES chown_username=hellopeiyang chown_upload_mode=0644
- 上传后的文件的权限符合设置要求
(四)系统用户
- 配置条目
guest_enable=YES // 所有系统用户都映射成guest用户
guest_username=ftp // 配合上面选项才生效,指定guest用户
local_enable=YES // 是否允许linux用户登录
write_enable=YES // 允许linux用户上传文件
local_umask=022 // 指定系统用户上传文件的默认权限
local_root=/ftproot // 非匿名用户登录所在目录
// 禁锢所有系统用户在家目录中
chroot_local_user=YES // 禁锢系统用户,默认NO
// 禁锢或不禁锢特定的系统用户在家目录中,与上面设置功能相反
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
// 当chroot_local_user=YES时,则chroot_list中用户不禁锢,白名单
// 当chroot_local_user=NO时,则chroot_list中用户禁锢,黑名单
-
实验4-1:将用户hellopeiyang禁锢在家目录
vim /etc/vsftpd/vsftpd.conf chroot_local_user=NO chroot_list_enable=YES chroot_list_file=/etc/vsftpd/chroot_list echo "hellopeiyang" > /etc/vsftpd/chroot_list service vsftpd restart
- 以hellopeiyang账户登录,被禁锢在家目录,显示目录为根目录,无法再向上切换
- 以bob账户登录,没有禁锢目录,很轻松切换到了/etc目录,非常危险
(五)日志
- wu-ftp日志:默认启用
xferlog_enable=YES // (默认)启用记录上传下载日志
xferlog_std_format=YES // (默认)使用wu-ftp日志格式
xferlog_file=/var/log/xferlog // (默认)可自动生成
- vsftpd日志:默认不启用
dual_log_enable=YES // 使用vsftpd日志格式,默认不启用
vsftpd_log_file=/var/log/vsftpd.log // (默认)可自动生成
-
实验5-1:开启vsftpd.log日志文件
vim /etc/vsftpd/vsftpd.conf dual_log_enable=YES service vsftpd restart
- vsftpd.log文件内容:记录登录情况
- xferlog文件内容:记录上传下载情况
(六)提示信息
- 登录提示信息
ftpd_banner=“welcometo mage ftp server"
banner_file=/etc/vsftpd/ftpbanner.txt //本条记录优先生效
- 目录访问提示信息
dirmessage_enable=YES // (默认)
message_file=.message // (默认)信息存放在指定目录下.message
- 实验6-1:设置欢迎信息,登录时显示:"this is hellopeiyang ftp service", 进入pub子目录时显示"public directory",进入upload子目录时显示"upload directory"
vim /etc/vsftpd/vsftpd.conf
banner_file=/etc/vsftpd/ftpbanner.txt
echo "this is hellopeiyang ftp service" > /etc/vsftpd/ftpbanner.txt
echo "public directory" > /var/ftp/pub/.message
echo "upload directory" > /var/ftp/upload/.message
service vsftpd restart
(七)登录控制
- 使用pam完成用户认证
- 在/etc/vsfptd/vsftpd.conf配置文件中:
pam_service_name=vsftpd
:指明引用的pam配置文件路径 - pam配置文件路径:/etc/pam.d/vsftpd,格式如下
- 在/etc/vsfptd/vsftpd.conf配置文件中:
auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
// 当sense=deny时,拒绝/etc/vsftpd/ftpusers文件中用户登录
// 当sense=allow时,允许/etc/vsftpd/ftpusers文件中用户登录
- 启用控制用户登录的列表文件
userlist_enable=YES // 默认有此设置
userlist_deny=YES // 黑名单,默认值,不提供输入口令的机会,NO为白名单
userlist_file=/etc/vsftpd/users_list // 用户列表文件,此为默认值
- 连接限制
max_clients=0 // 最大并发连接数,0为无限制
max_per_ip=0 // 每个IP同时发起的最大连接数,0为无限制
vsftpd服务指定用户身份运行:
nopriv_user=nobody
-
实验:实现用户登录控制
- 实验7-1:使用pam禁止用户hellopeiyang登录ftp服务
vim /etc/pam.d/vsftpd // 保证sense=deny auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed echo "hellopeiyang" >> /etc/vsftpd/ftpusers //追加用户hellopeiyang service vsftpd restart
- 实验7-2:使用用户列表禁止用户bob登录ftp服务
echo bob >> /etc/vsftpd/user_list service vsftpd restart
- 实验7-3:限制最大并发连接数为2,相同IP同时连接数为2
vim /etc/vsftpd/vsftpd.conf max_clients=5 max_per_ip=2 service vsftpd restart
(八)传输控制
- 传输速率:字节/秒
anon_max_rate=0 // 匿名用户的最大传输速率
local_max_rate=0 // 本地用户的最大传输速率
- 连接时间:秒为单位
connect_timeout=60 // 主动模式数据连接超时时长
accept_timeout=60 // 被动模式数据连接超时时长
data_connection_timeout=300 // 数据连接无数据传输超时时长
idle_session_timeout=60 // 无命令操作超时时长
- 优先以文本方式传输
ascii_upload_enable=YES
ascii_download_enable=YES
- 实验8-1:限制匿名登录用户传输速度为1M/s,限制系统登录用户传输速度为2M/s
vim /etc/vsftpd/vsftpd.conf
anon_max_rate=1024000
local_max_rate=2048000
service vsftpd restart
// 准备bob家目录的共享文件,设置相关权限
mkdir /home/bob/pub
setfacl -m u:bob:rwx /home/bob/pub/
cp /var/ftp/pub/file1 /home/bob/pub/
(九)vftpd服务配置
实现CentOS 6环境下vsftpd以非独立服务方式运行(CentOS 7所有服务由systemd管理,都是以非独立方式运行)
- 修改vsftpd配置文件
vim /etc/vsftpd/vsftpd.conf
listen=NO
- 配置xinted服务
vim /etc/xinetd.d/vsftpd
{
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/vsftpd
log_on_failure += USERID
disable = no
}
service vsftpd stop
service xinetd start
ss -ntlp
(十)实现基于SSL的ftps
- 查看是否支持SSL,确实存在
ldd `which vsftpd`
- 创建自签名证书
cd /etc/pki/tls/certs
make vsftpd.pem // 生成自签名证书
openssl x509 -in vsftpd.pem -noout -text // 查看证书内容
cp vsftpd.pem /etc/vsftpd/
- 配置vsftpd服务
/etc/vsftpd/vsftpd.conf
ssl_enable=YES
allow_anon_ssl=NO
force_local_logins_ssl=YES
force_local_data_ssl=YES
rsa_cert_file=/etc/vsftpd/vsftpd.pem
service vsftp restart
- 使用FileZilla建立ftp连接
- 核实证书信息正确
- 登录成功
五、vsftpd虚拟用户
(一)vsftpd虚拟用户介绍
(1)定义
所有虚拟用户会统一映射为一个指定的系统帐号
访问共享位置:此系统帐号的家目录
各虚拟用户可被赋予不同的访问权限,通过匿名用户的权限控制参数进行指定
(2)虚拟用户账号的存储方式
文件:编辑文本文件,此文件需要被编码为hash格式
奇数行:用户名,偶数行:密码
将文本转换为berkerly db数据库格式:db_load -T -t hash -f vusers.txt vusers.db
关系型数据库中的表中:
实时查询数据库完成用户认证
(二)实现基于DB的FTP虚拟用户
(1)创建DB数据库文件,存放虚拟用户和密码
vim /etc/vsftpd/ftpvusers
ftpuser1
ftp1
ftpuser2
ftp2
cd /etc/vsftpd/
db_load -T -t hash -f ftpvusers ftpvusers.db
chmod 600 ftpvusers.db
(2)建立系统用户
useradd -d /var/ftpsite -s /sbin/nologin ftpvuser
chmod 555 /var/ftpsite/ //CentOS 7下根目录谁也不能有写权限
// 建立专属上传子目录upload
mkdir /var/ftpsite/upload
setfacl -m u:ftpvuser:rwx /var/ftpsite/upload/
(3)创建pam配置文件
vim /etc/pam.d/vsftpd.vuser // 指定虚拟用户DB数据库文件目录
auth required pam_userdb.so db=/etc/vsftpd/ftpvusers
account required pam_userdb.so db=/etc/vsftpd/ftpvusers
(4)指定pam配置文件
vim /etc/vsftpd/vsftpd.conf
pam_service_name=vsftpd.vuser // 指定pam配置文件路径
guest_enable=YES
guest_username=ftpvuser // 将虚拟用户映射为系统用户ftpvuser
user_config_dir=/etc/vsftpd/ftpvusers.conf.d/ //指定每个虚拟用户独立配置文件路径
(5)建立每个虚拟用户的独立配置文件
mkdir /etc/vsftpd/ftpvusers.conf.d
cd /etc/vsftpd/ftpvusers.conf.d/
vim ftpuser1 // 配置文件名称必须与虚拟账户名称完全相同
anon_upload_enable=YES
anon_mkdir_write_enable=YES
vim ftpuser2 // 配置文件名称必须与虚拟账户名称完全相同
local_root=/app/ftp2 // 指定共享根目录为/app/ftp2
anon_upload_enable=YES
anon_mkdir_write_enable=YES
(6)配置共享根目录,重启vsftpd服务
touch /var/ftpsite/ftp1file //用于测试时验证是否登录进入了相应的目录
mkdir -p /app/ftp2/upload
chmod 555 /app/ftp2
setfacl -m u:ftpvuser:rwx /app/ftp2/upload/
touch /app/ftp2/ftp2file //用于测试时验证是否登录进入了相应的目录
systemctl restart vsftpd
(7)测试
- 从根目录下文件ftp1file证明ftpuser1登录到了相应的目录
- ftpuser1登录ftp服务可以在/upload子目录下建立目录,上传文件
- 从根目录下文件ftp2file证明ftpuser2登录到了相应的目录
- ftpuser2登录ftp服务可以在/upload子目录下建立目录,上传文件
(三)实现基于MYSQL的FTP虚拟用户
- 本实验需要两台主机,一台充当FTP服务器,一台充当MySQL服务器
FTP服务器:CentOS 7系统,IP地址为192.168.136.230
MySQL服务器:CentOS 7系统,IP地址为192.168.136.130
(1)FTP服务器上安装vsftpd和pam_mysql
CentOS 6的epel源中存在pam_mysql安装包,可以直接安装
yum install vsftpd pam_mysql
在CentOS 7中需要编译安装pam_mysql,即在本实验中需要编译安装
// 安装并启动vsftpd服务
yum install vsftpd
systemctl start vsftpd
// 编译安装pam_mysql
yum groupinstall "development tools"
yum install mariadb-devel pam-devel
tar xvf pam_mysql-0.7RC1.tar.gz -C /usr/local/src/
cd /usr/local/src/pam_mysql-0.7RC1/
./configure --with-mysql=/usr --with-pam=/usr --with-pam-mods-dir=/lib64/security
make && make install
(2)FTP服务器上建立系统用户
useradd -d /app/ftpsite -s /sbin/nologin ftpvuser
chmod 555 /app/ftpsite/
cd /app/ftpsite/
mkdir /app/ftpsite/upload
setfacl -m u:ftpvuser:rwx /app/ftpsite/upload
(3)MySQL服务器上配置虚拟用户的数据库
// 安装MariaDB并启动服务
yum install mariadb-server
systemctl start mariadb
mysql_secure_installation
// 建立虚拟用户数据库
mysql -uroot -pmagedu
MariaDB [(none)]> create database ftpdb;
MariaDB [(none)]> use ftpdb;
MariaDB [ftpdb]> create table ftpvusers (id int unsigned auto_increment primary key,username char(30),password char(48));
// 使用password()函数加密密码,避免明文存储密码
MariaDB [ftpdb]> insert ftpvusers (username,password) values ('ftpuser1',password('centos')),('ftpuser2',password('centos'));
MariaDB [ftpdb]> grant all on ftpdb.* to ftpuser@'192.168.136.%' identified by 'centos';
MariaDB [ftpdb]> flush privileges;
(4)FTP服务器上创建pam配置文件
vim /etc/pam.d/vsftpd.mysql
auth required pam_mysql.so user=ftpuser passwd=centos host=192.168.136.130 db=ftpdb table=ftpvusers usercolumn=username passwdcolumn=pas
sword crypt=2
account required pam_mysql.so user=ftpuser passwd=centos host=192.168.136.130 db=ftpdb table=ftpvusers usercolumn=username passwdcolumn=
password crypt=2
- crypt是加密方式,0表示不加密,1表示crypt(3)加密,2表示使用mysql password()函数加密,3表示md5加密,4表示sha1加密
(5)FTP服务器上指定pam配置文件
vim /etc/vsftpd/vsftpd.conf
pam_service_name=vsftpd.mysql
guest_enable=YES
guest_username=ftpvuser
user_config_dir=/etc/vsftpd/vusers.conf.d/
(6)FTP服务器上建立每个虚拟用户的独立配置文件
mkdir /etc/vsftpd/vusers.conf.d
vim /etc/vsftpd/vusers.conf.d/ftpuser1
anon_upload_enable=YES
vim /etc/vsftpd/vusers.conf.d/ftpuser2
anon_upload_enable=YES
local_root=/app/ftpsite2/
(7)FTP服务器上配置共享根目录,重启vsftpd服务
mkdir -p /app/ftpsite2/upload
chmod 555 /app/ftpsite2
setfacl -m u:ftpvuser:rwx /app/ftpsite2/upload/
touch /app/ftpsite/ftpfile1
touch /app/ftpsite2/ftpfile2
(8)测试
- ftpuser1账户登录测试,进入了正确的目录,可以在子目录/upload上传文件
- ftpuser2账户登录测试,进入了正确的目录,可以在子目录/upload上传文件