好久没有写东西了,今天五一在家抽空写点。
FTP的PORT(主动模式)和PASV(被动模式)
- 主动模式(PORT)
PORT中文称为主动模式,工作的原理: FTP客户端连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,客户端随机开放一个端口(1024以上),发送 PORT命令到FTP服务器,告诉服务器客户端采用主动模式并开放端口;FTP服务器收到PORT主动模式命令和端口号后,通过服务器的20端口和客户端开放的端口连接,发送数据,原理如下图:
- 被动模式(PASV)
工作原理:FTP客户端连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,发送PASV命令到FTP服务器, 服务器在本地随机开放一个端口(1024以上),然后把开放的端口告诉客户端, 客户端再连接到服务器开放的端口进行数据传输,原理图如下图:
-
两种模式比较
从上面的运行原来看到,主动模式和被动模式的不同简单概述为: 主动模式传送数据时是“服务器”连接到“客户端”的端口;被动模式传送数据是“客户端”连接到“服务器”的端口。主动模式需要客户端必须开放端口给服务器,很多客户端都是在防火墙内,开放端口给FTP服务器访问比较困难。
被动模式只需要服务器端开放端口给客户端连接就行了。
-
如何设置哪种工作模式
有人可能会问FTP服务器如何设置工作模式?实时上FTP服务器一般都支持主动和被动模式,连接采用何种模式是有FTP客户端软件决定
<h4>安装vstpd</h4>
1.这里我们直接采用最简单的yum安装
<pre>yum -y install vsftpd
chkconfig on vsftpd #开机启动</pre>
<h4>基于虚拟用户的配置</h4>
所谓虚拟用户就是没有使用真实的帐户,只是通过映射到真实帐户和设置权限的目的。虚拟用户不能登录CentOS系统。
- 修改配置文件
<pre>vi /etc/vsftpd/vsftpd.conf
服务器独立运行
listen=YES
设定不允许匿名访问
anonymous_enable=NO
设定本地用户可以访问。注:如使用虚拟宿主用户,在该项目设定为NO的情况下所有虚拟用户将无法访问
local_enable=YES
使用户不能离开主目录
chroot_list_enable=YES
设定支持ASCII模式的上传和下载功能
ascii_upload_enable=YES
ascii_download_enable=YES
PAM认证文件名。PAM将根据/etc/pam.d/vsftpd进行认证
pam_service_name=vsftpd
设定启用虚拟用户功能
guest_enable=YES
指定虚拟用户的宿主用户,CentOS中已经有内置的ftp用户了
guest_username=ftp
设定虚拟用户个人vsftp的CentOS FTP服务文件存放路径。存放虚拟用户个性的CentOS FTP服务文件(配置文件名=虚拟用户名)
user_config_dir=/etc/vsftpd/vuser_conf
配置vsftpd日志(可选)
xferlog_enable=YES
xferlog_std_format=YES
xferlog_file=/var/log/xferlog
dual_log_enable=YES
vsftpd_log_file=/var/log/vsftpd.log
</pre>
- 进行认证
<pre>#安装Berkeley DB工具,很多人找不到db_load的问题就是没有安装这个包
yum install db4 db4-utils
<p>
创建用户密码文本,注意奇行是用户名,偶行是密码
vi /etc/vsftpd/vuser_passwd.txt
test
123456
<p>
生成虚拟用户认证的db文件
db_load -T -t hash -f /etc/vsftpd/vuser_passwd.txt /etc/vsftpd/vuser_passwd.d
<p>
编辑认证文件,全部注释掉原来语句,再增加以下两句
vi /etc/pam.d/vsftpd
auth required pam_userdb.so db=/etc/vsftpd/vuser_passwd
account required pam_userdb.so db=/etc/vsftpd/vuser_passwd
<p>
创建虚拟用户配置文件
mkdir /etc/vsftpd/vuser_conf/ #文件名等于vuser_passwd.txt里面的账户名,否则下面设置无效
<p>
vi /etc/vsftpd/vuser_conf/test #虚拟用户根目录,根据实际情况修改
local_root=/data/ftp
write_enable=YES
anon_umask=022
anon_world_readable_only=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES</pre>
3.设置FTP根目录的权限、
<pre>#最新的vsftpd要求对主目录不能有写的权限所以ftp为755,主目录下面的子目录再设置777权限
mkdir /data/ftp
chmod -R 755 /data
chmod -R 777 /data/ftp
<p>
建立限制用户访问目录的空文件
touch /etc/vsftpd/chroot_list
<p>
如果启用vsftpd日志需手动建立日志文件
touch /var/log/xferlog
touch /var/log/vsftpd.log
</pre>
4.PAVS模式配置
vsftpd默认没有开启PASV模式,现在FTP只能通过PORT模式连接,要开启PASV默认需要通过下面的配置
<pre>打开/etc/vsftpd/vsftpd.conf,在末尾添加
开启PASV模式
pasv_enable=YES
最小端口号
pasv_min_port=30000
最大端口号
pasv_max_port=30999
pasv_promiscuous=YES
</pre>
5.关闭selinux
<pre>vim /etc/sysconfig/selinux
selinxu=disabled #改为disabled</pre>
6.开启防火墙及转发模块
<pre># modprobe -l | grep ftp #这一步重要
vim /etc/sysconfig/iptables-config
IPTABLES_MODULES="ip_conntrack_ftp ip_nat_ftp"
<p>
vim /etc/sysconfig/iptables
-A INPUT -p tcp -m state --state NEW -m tcp --dport 20 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 30000:30999 -j ACCEPT #与PASV模式开启的端口范围一致
<p>
service iptables restart #重启iptables</pre>
7.结束
截止到以上,vsftp即可实现基于虚拟用户的登陆认证
<h4>增加ssl加密功能</h4>
如果vsftpd不跑在tls上,那么直接抓包的话,数据都会暴露在网络上,被人截取窃听,所以为了实现安全传输,下面添加ssl加密功能
- 检查vsftpd是否支持ssl模块
一般yun安装的都带有ssl模块,编译安装的话需要加上对应选项
<pre># ldd $(which vsftpd) | grep ssl
libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007f0587879000)
</pre>
- 建立专门给vsftpd使用的凭证数据。CentOS有一个建立凭证的地方/etc/pki/tls/certs/
<pre># cd /etc/pki/tls/certs
make vsftpd.pem
下面按照提示填写响应的签名信息就行了</pre>
<pre># cp -a vsftpd.pem /etc/vsftpd/
ll /etc/vsftpd/vsftpd.pem
-rw-------. 1 root root 3116 2011-08-08 16:52 /etc/vsftpd/vsftpd.pem //要注意权限
</pre>
-
修改vstpd.conf配置文件内容
在尾部追加
<pre>ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=YES
ssl_sslv3=YES
rsa_cert_file=/etc/vsftpd/vsftpd.pem
ssl_ciphers=HIGH #这个是解决图形客户端Filezila软件的一个报错 下面提到</pre> -
结束
按照上述配置好了,当你用ftp命令登陆时,会提示不允许匿名用户登陆,必须通过客户端软件登陆。这里我使用Filezlia软件。当第一次登陆时,客户端会提示你保存证书。至此,vstpd实现ssl加密功能,保证数据安全传输。
<h4>vsftd结合openldap实现账号认证登陆</h4>
openldap的相关配置这里我不介绍。
此处是结合pam认证方式来实现
-
安装pam_ldap
<pre>yum install pam_ldap</pre> -
编辑/etc/pam.d/vsftpd配置文件
<pre>#%PAM-1.0
auth sufficient /lib64/security/pam_ldap.so #增加这项
account sufficient /lib64/security/pam_ldap.so #增加这项
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</pre> -
编辑/etc/vsftpd/vsftpd.conf文件,在之前基础上添加以下几项
<pre>anon_upload_enable=YES #这一段很重要,因为后面创建的ldap账号的权限都是这几个条目来控制的,也就是说这几个条目控制guest账户权限;
anon_mkdir_write_enable=YES
chown_uploads=NO
anon_umask=022
guest_enable=YES #启动guest访问,必须启用,不然ldap认证失败
guest_username=share #将ldap用户映射到此系统用户 这里我自己建的share用户
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
anon_other_write_enable=YES #控制删除、重名等权限
syslog_enable=yes
local_root=/home/share/pub #指定用户登陆后所处的根目录
user_config_dir=/etc/vsftpd/user_conf #与前面配置虚拟用户相同,也可以为每个ldap用户分配具体的权限</pre> -
文件共享问题解决(重要)
我的理想需求:让每个用户都在同一个目录/home/share下,但是用户只能删除自己上传的文件,不可以删除其他人上传的文件,可以下载别人上传的文件。
现实残酷 :vsftpd因为结合了ldap,最终将ldap用户都映射到了同一个系统用户,所以文件的权限其实对每一个ldap用户都一样,所以无法达到我上面提到的理想需求。
解决方法:
- 在<code>/etc/vsftd/user_conf/</code>文件夹下创建为每个ldap用户的个人权限,让他们只能在自己的家目录下活动同时拥有增删查改权限,这样只能对自己的文件操作,不能看到别人的文件。
- 在创建pub目录,<code>/etc/home/share/pub</code>下,注意修改文件属组属主为share。
- 同时在每个ldap用户家目录下,创建pub目录,<code>mkdir -pv /home/share/ldap_user/pub</code>。
- 将<code>/home./share/pub</code>目录挂载到每个ldapuser家目录下,即挂载到<code>/home/share/ldap_user/pub</code>.具体方法如下<code>mount --bind /home/share/pub /home/share/ldap_user/pub</code>
- 注意<code>/home/share</code>目录及下面所有文件属组属主均为share用户。<code>chown -R share:share /home/share</code>
6.为每个ldap用户分配权限并让禁锢在其家目录下
<pre>$ vim /etc/vsftpd/user_conf/tiantian #假设ldap用户为tiantian
local_root=/home/share/tiantian #让其禁锢在家目录下
write_enable=YES
anon_umask=022
anon_world_readable_only=NO
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
</pre>
其他ldap用户只要改变下家目录位置,这里我不再给出。
<p>
<h4>一些报错解决及注意事项:</h4>
- ftp: connect: No route to host
<pre># modprobe -l | grep ftp
vim /etc/sysconfig/iptables-config
IPTABLES_MODULES="ip_conntrack_ftp ip_nat_ftp" </pre>
-
Filezila有报错。
The default SSL ciphers is DES-CBC3-SHA, but FileZilla regards it as
unsafe and rejects it. Therefore you should modify it.
<pre>ssl_ciphers=HIGH</pre> -
pam_ldap.conf报错(mark)
若LDAP服务器不允许匿名绑定,则需要配置binddn和bindpw
binddn和bindpw开始我配置的时候,死活验证不成功,后来我注释掉没配后,就成功了。可能我写的binddn格式不对。很是奇怪。我写的是binddn cn=users,cn=accounts,dc=in66,dc=cc。这里mark下。 -
Filezilla客户端不能自动读出已创建文件及文件夹
这里之前我们已经创建了用于登陆ftp的系统用户,这里假设用户为share
<pre>share:x:502:502::/home/share:/sbin/nologin</pre>
赋予/home/share目录其他用户读和执行权限即可
<pre>chmod o+rx /home/share</pre>
解释:因为ldap用户映射到ftp的账号,权限其实是匿名用户权限。所以对other需要修改权限。 -
需要手动给每个ldap用户创建家目录及家目录下的pub目录
<pre>mkdir -pv /home/share/ldap_user/pub</pre> -
<code>/home/share</code>目录及子目录文件属主属组均为share
<pre>chown -R share:share /home/share</pre>
<h4>一些思考</h4>
-
虚拟用户及结合openldap都是将自己创建的用户,映射到本地系统上的一个用户,这样更安全些
-
结合openldap认证后,openldap用户的权限属于匿名用户,所以要开启匿名用户的相关权限,才能进行增删查改等操作。
-
<code>anon_other_write_enable=YES</code> #控制ldap用户删除、重名等权限
-
虚拟用户的pam.d/vsftpd配置
<pre>auth required pam_userdb.so db=/etc/vsftpd/vuser_passwd
account required pam_userdb.so db=/etc/vsftpd/vuser_passwd</pre> -
集成ldap的pam.d/vsftpd配置
<pre>auth sufficient /lib64/security/pam_ldap.so #增加这项
account sufficient /lib64/security/pam_ldap.so #增加这项
剩余的是自带的保持默认即可</pre>
结尾:
贴下我整个ldap+vsftd+ssl配置文件内容
/etc/vsftpd/vsftpd.conf配置文件,其他默认即可
<pre>
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
anon_upload_enable=YES
anon_mkdir_write_enable=YES
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
chown_uploads=NO
xferlog_file=/var/log/xferlog
xferlog_std_format=YES
ascii_upload_enable=YES
ascii_download_enable=YES
listen=YES
guest_enable=YES
guest_username=share
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=YES
ssl_sslv3=YES
rsa_cert_file=/etc/vsftpd/vsftpd.pem
ssl_ciphers=HIGH
#startup PASSIVE MODE
pasv_min_port=30000
pasv_max_port=30999
#stop the PASSIVE MODE and choose the ACTIVE MODE
#pasv_enable=NO
#是否开启删除等权限
anon_other_write_enable=YES
anon_umask=022
syslog_enable=yes
local_root=/home/share/pub
user_config_dir=/etc/vsftpd/user_conf</pre>