Very Secure FTP Daemon
FTP支持两种模式:Standard (PORT方式,主动方式),Passive (PASV,被动方式)。
控制连接:TCP21,用于发送FTP命令信息
数据连接:TCP20,用于上传,下载数据
anonymous_enable=YES # 允许匿名用户登录
local_enable=YES # 允许本地用户登录
write_enable=YES # 允许本地用户上传
local_umask=o22 # 允许本地用户上传umask值(权限)
dirmessage_enable=YES # 用户进入目录是,显示.message文件中的信息
message_file=.message # 指定信息文件
xferlog_enable=YES # 激活记录日志
connect_from_port_20=YES # 主动模式数据传输接口
xferlog_std_format=YES # 使用标准的FTP日志格式
ftpd_banner # 欢迎登陆信息
listen=YES # 允许被监听
# 设置.PAM外挂模块提供的认证服务所使用的配置文件:/etc/pam.d/vsftpd
pam_service_name=vsftpd
userlist_enable=YES # 用户登录权限
tcp_wrappers=YES #是否使用tcp_wrappers作为网络访问控制限制
# global
listen_address=192.168.1.102 # 设置监听的IP地址,仅允许连接
listen_port=21 # 设置监听FTP服务的端口
download_enable=YES # 是否允许下载文件
max_clients=0 # 限制并发客户端连接数
max_per_ip=0 限制同一IP地址的并发连接数
被动
pasv_enable=YES # 开启被动模式
pasv_min_port=24500 #端口范围
pasv_max_port=24600
安全配置
accept_timeout=06 # 被动模式,连接超时时间
connetct_timeout=60 # 主动模式,连接超时时间
idle_session_timeout=600 # 600秒没有任何操作断开连接
data_connection_timeout=500 # 资料传输时,超过500秒没有完成,就断开传输
Port模式
FTP 客户端首先和服务器的TCP 21端口建立连接,用来发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。PORT命令包含了客户端用什么端口接收数据。在传送数据的时候,服务器端通过自己的TCP 20端口连接至客户端的指定端口发送数据。FTP server必须和客户端建立一个新的连接用来传送数据。
Passive模式
建立控制通道和Standard模式类似,但建立连接后发送Pasv命令。服务器收到Pasv命令后,打开一个临时端口(端口号大于1023小于65535)并且通知客户端在这个端口上传送数据的请求,客户端连接FTP服务器此端口,然后FTP服务器将通过这个端口传送数据。
----------------------------------------------------------------------------------
linux:
yum install vsftpd
systemctl start vsftpd
yum install tcpdump
tcpdump -i ens33 -nnx port 21
useradd footstep
passwd footstep # 123456
win:
FlashFXP # 稳定和强大的档案传输程序工具
----------------------------
=======================================
启动服务:
win:
需要关闭客户端防火墙:
200 PORT command successful. Consider using PASV.
425 Failed to establish connection.
linux:
-------------------------------------------------------------------------------------------
匿名用户访问:
anonmous_enable=YES # 允许匿名用户访问
anon_upload_enable=YES # 允许匿名用户上传(文件)
anon_mkdir_write_enable=YES # 允许匿名用户建立(目录)
;anon_umask # 设置上传的默认文件权限(默认是600)
server:
默认上传目录:/var/ftp/pub/ # 需要服务权限和系统权限:服务用户:ftp
chown ftp /var/ftp/pub
修改/var/ftp 权限导致:
win:
-----------------------------------------------------------------------------
本地用户访问:
chroot_local_user=YES # 限制用户访问在家目录中;
write_enable=YES # 允许本地用户上传
local_umask=022
local_root=/test # 设置本地用户的FTP根目录(权限)
local_max_rate=0 # 限制最大传输速率(字节/秒)
-----------------------------------
chroot_local_user=YES
chroot_local_user=YES
allow_writeable_chroot=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list # 切换目录 ws
# 写入/etc/vsftpd/chroot_list文件中的用户可以访问任何目录,其他用户限制在用户的主目录
--------------------------
用户控制列表文件:
/etc/vsftpd/ftpusers # 黑名单
/etc/vsftpd/user_list # 是否登录
local_root=/test # * 本地用户
ws:
访问控制:
userlist_enable=YES * # 用户访问控制
userlist_deny=YES(黑名单) / NO(白名单)
userlist_file=/etc/vsftpd/user_list
# 写入/etc/vsftpd/user_list文件中的用户不能访问ftp服务器,没有写入的用户可以访问(默认)
==========================
虚拟用户访问-配置虚拟用户
local_enable=YES # 虚拟用户映射本地模拟用户
# 添加虚拟用户口令文件
vim /etc/vsftpd/vuser.txt(自定义)# 用于生产数据库文件(二进制)
ws # 用户名
ws # 密码
footstep # 用户名
footstep # 密码
# 生成虚拟用户口令认证文件
yum install db4-utils # 安装口令认证命令
# 把文本文档转变为认证的数据库
db_load -T -t hash -f /etc/vsftpd/vuser.txt /etc/vsftpd/vuser.db
换算 制定算法 hash算法 制定文件 生产文件
# 编辑vsftpd的PAM认证文件
vim /etc/pam.d/vsftpd
:2,8s/^/#/g
auth required /lib(64)/security/pam_userdb.so db=/etc/vsftpd/vuser
account required /lib(64)/security/pam_userdb.so db=/etc/vsftpd/vuser
#注释掉其他行,可以禁止本地用户登录,因为本地用户登录时的验证依然依赖这个文件
# 本地用户也不能登录,只能虚拟用户登录
# 建立本地映射用户并设置宿主目录权限
useradd -d /home/vftproot -s /sbin/nologin vuser # 所有用户默认家目录
# 此用户不需要登录,只是映射用户,用户名必须和下一步配置文件中一致
chmod 755 /home/vftproot
# 修改配置文件:vim /etc/vsftpd/vsftpd.conf
guest_enable=YES # 开启虚拟用户
guest_username=vuser # FTP虚拟用户对应的系统用户
pam_service_name=vsftpd # PAM认证文件(默认存在)
#重启vsftpd服务
#此时虚拟用户可以登录,查看,下载,不能上传;
#默认上传文件的位置是宿主用户的家目录
#权限使用的是匿名用户权限进行管理
# 调整虚拟用户权限
vim /etc/vsftpd/vsftpd.conf
anonymous_enable=NO # 关闭匿名用户登录,更加安全(不影响匿名用户登录)
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES(其他文件)
# 给虚拟用户设定权限,允许所有虚拟用户上传
# 虚拟用户访问-单独定义虚拟用户权限
#可以为每个虚拟用户单独建立目录并建立自己的配置文件,这样方便单独配置权限,并可以单独指定上传目录
user_config_dir=/etc/vsftpd/vusers_dir # 指定保存虚拟用户配置文件目录
vim /etc/vsftpd/vuser_dir/ws
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
# 允许此用户上传
local_root=/test/ws # 给ws指定独立的上传目录
chown vuser /test/ws
---------------------------------
主动 FTP :
命令连接:客户端 >1024 端口 → 服务器 21 端口
数据连接:客户端 >1024 端口 ← 服务器 20 端口
被动 FTP :
命令连接:客户端 >1024 端口 → 服务器 21 端口
数据连接:客户端 >1024 端口 ← 服务器 >1024 端口
PORT(主动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时, 客户端在命令链路上用PORT命令告诉服务器:“我打开了***X端口,你过来连接我”。于是服务器从20端口向客户端的***X端口发送连接请求,建立一条数据链路来传送数据。
PASV(被动)方式的连接过程是:客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时, 服务器在命令链路上用PASV命令告诉客户端:“我打开了***X端口,你过来连接我”。于是客户端向服务器的***X端口发送连接请求,建立一条数据链 路来传送数据。
由于我的本地FTP服务器在内网,只是从外网映射了两个端口(20,21),所以无法使用PASV方式,解决此问题的办法也很简单,关闭客户端的PASV方式,强制其用PORT方式访问服务器,登录FTP服务器后用passive命令关闭客户端的PASV方式,如下:
ftp> passive
Passive mode off.
ftp> passive (再次运行命令可打开)
Passive mode on.
---------------------------------------------------------------------------------------------
public function upload($file){
$localfile = realpath($file);
$fp = fopen($localfile,'r');
$basename = pathInfo($localfile, PATHINFO_BASENAME);
$url = "ftp://192.168.0.56/".$basename;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
# ftp: user,pwd
curl_setopt($curl, CURLOPT_USERPWD, 'footstep:footstep');
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_FTP);
curl_setopt($curl,CURLOPT_UPLOAD,1);
curl_setopt($curl,CURLOPT_INFILE,$fp);
curl_setopt($curl,CURLOPT_INFILESIZE,filesize($localfile));
$data = curl_exec($curl);
var_dump(curl_error($curl));
fclose($fp);
curl_close($curl);
return;
}