FTP是什么
ftp是一个文件传输协议,他和http协议一样是应用层的协议,但是比http古老的多。tcp协议刚诞生不就就有ftp协议了,它是用来完成各主机之间的数据传送的。ftp上的一次数据传输有两个连接,首先,客户端向服务端固定端口发请求,服务端响应,二者之间建立会话。当客户端向服务端发起get下载文件命令时,服务端的一个端口会连接客户端的一个固定端口,双方三次握手建立起来后,开始传输数据,数据传输完成后连接被拆除。第二次进行get下载时,服务端和客户端建立新的连接,此时客户端的端口会随机变化。而使用mget下载文件时,能在一个连接上传输多个文件。
FTP的主动模式和被动模式
FTP的数据连接有两种工作模式:
-
主动模式:服务端主动连接客户端
比如客户端用一个随机端口44004连接服务端的一个固定端口21/tcp,双方的此时建立连接,客户端在端口44004上发起get操作的时候,会建立一个新的连接,叫做数据(data)连接,此连接是服务端通过20端口去连接客户端的44005端口完成数据的传输。如果44005被占用,会向44006等端口号+1依次去请求,一直请求到合适的端口为止。但是现在的客户端都有防火墙,所以这样的连接并不容易实现。
-
被动模式:服务端告诉客户端一个随机端口,让客户端来被动连接服务端
首先客户端连接服务端的21端口建立第一个连接,当客户端发起get请求时,服务端通过21端口之前建立的连接告诉客户端一个新的端口,客户端向这个新端口发送请求建立第二个连接传输数据。现在的防火墙有连接追踪功能,服务器提供随机端口,建立新的请求,会知道这个请求与第一个连接有关联性,会被允许通过防火墙,而莫名其妙的访问一个端口建立连接是不允许通过防火墙的。
PAM认证,提供插入式认证模块。
PAM是一个认证框架,整个框架是向外提供一个接口和服务进行的,它有个库,任何程序如要用pam来认证在开发时调用pam库就可以了,pam自己有相应的api,可以给各种程序都提供认证功能,不同的程序使用pam不同的模块,每个程序都有自己专用的模块配置文件。所有用户调用pam完成认证时,要用到专门的自己的配置文件接口,这个配置文件在etc/pam.d目录下,为了见名知意,通常用和服务名同名的文件来作为对应的认证配置。他在这些服务文件中定义调用哪些模块,不同的模块适配到不同的存储上,不同的模块还能在适配到存储上以后来检查账号密码是否符合规范。当账号密码能认证成功时,也并不意味账号密码能登录成功,也许账号过期了,所以在认证的时候不光要检查账户密码是否正确,还要检查账户是否在有效期内。用户登录后可以用passwd修改密码,但是pam用pam_cracklib.so来检查密码是不是够复杂,简单的话不给改,而且还检查自带的字典中有没有相应的密码,如有则也不让修改。
对于ftp的任何共享服务来说,,每一种服务的检查两个地方
1.远程账号有没有文件系统权限,没有文件系统权限不能删除创建文件
2.ftp配置中有没有开启删除权限,这个删除权限叫做共享权限
FTP有三种用户类别:
1.匿名用户:默认不需密码就可以登录的用户,目录在/var/ftp
2.系统用户:用户帐号也可以登录系统的用户,目录在用户家目录
3.虚拟用户:用户帐号不在/etc/passwd里,非系统用户的账户
安装vsftpd
[root@localhost ~]# yum -y install vsftpd
[root@localhost ~]# systemctl start vsftpd.service
浏览器用匿名账户访问ftp成功
实现开放匿名用户上传,删除等权限来操作ftp
[root@localhost ~]# cd /var/ftp
[root@localhost ftp]# mkdir upload
[root@localhost ftp]# chown ftp.ftp upload
[root@localhost ftp]# vim /etc/vsftpd/vsftpd.conf
anon_upload_enable=YES #启动匿名用户上传权限
anon_mkdir_write_enable=YES #启动匿名用户新建目录权限
anon_other_write_enable=YES #启动匿名用户新建其他权限
[root@localhost ftp]# systemctl start vsftpd.service
测试
[root@localhost user1]# cd /etc
[root@localhost etc]# lftp 192.168.10.10
lftp 192.168.10.10:~> cd upload/
lftp 192.168.10.10:/upload> mkdir aaaaa
mkdir ok, `aaaaa' created
lftp 192.168.10.10:/upload> put issue
23 bytes transferred
lftp 192.168.10.10:/upload> rm -rf aaaaa/ issue
rm ok, 2 files removed
实现基于白名单的系统用户操作ftp
新建系统账户user1当作ftp登录账户
[root@localhost ~]# useradd user1
[root@localhost ~]# echo "112233" | passwd --stdin user1
[root@localhost ~]# cd /home/user1
[root@localhost user1]# mkdir upload
[root@localhost user1]# chown user1.user1 upload
把用户user1的家目录写权限移除,让它虽然是系统账户也只能访问自己的家目录
[root@localhost ~]# chmod a-w /home/user1
[root@localhost ~]# ll /home/
total 0
dr-x------ 2 user1 user1 62 Jun 13 02:52 user1
开启ftp登录用户白名单
[root@localhost ~]# vim /etc/vsftpd/vsftpd.conf
chroot_list_enable=YES #启用用户家目录下写入列表的功能
chroot_list_file=/etc/vsftpd/user_list #列表路径
userlist_deny=NO
#在userlist_enable=YES之后添加,NO开启白名单,YES开启黑名单
[root@localhost ~]# vim /etc/vsftpd/user_list #白名单中添加账户
user1
[root@localhost ~]# systemctl restart vsftpd.service
使用另外一台主机登录测试
[root@localhost ~]# cd /etc
[root@localhost ~]# lftp -u user1 192.168.10.13
Password:
lftp user1@192.168.10.13:~> cd upload
cd ok, cwd=/upload
lftp user1@192.168.10.13:/upload> mkdir aaaaa
mkdir ok, `aaaaa' created
lftp user1@192.168.10.13:/upload> put issue fstab
488 bytes transferred
Total 2 files transferred
lftp user1@192.168.10.13:/upload> ls
drwxr-xr-x 2 1000 1000 6 Jun 13 08:20 aaaaa
-rw-r--r-- 1 1000 1000 465 Jun 13 08:20 fstab
-rw-r--r-- 1 1000 1000 23 Jun 13 08:20 issue
lftp user1@192.168.10.13:/upload> rm -rf aaaaa/ fstab issue
rm ok, 3 files removed
实现用pam_mysql认证ftp虚拟用户账号
要完成ftp的用户虚拟认证,需要修改/etc/pam.d/vsftpd文件参数不让他去调用系统用户。虚拟用户可以利用很多种方式来配置pam认证,只要pam能驱动的服务,自己作为客户端能连接这个服务就行。下面我们来利用mysql中的账号来当作ftp的存储账号密码。centos6中有pam模块,直接使用即可,而centos7没有pam模块,要进行编译才可以,编译之前要安装依赖mysql的开发环境。
安装需要的软件的组件
[root@localhost ~]# yum -y install mariadb-server
[root@localhost ~]# yum -y install mariadb-devel pam-devel
[root@localhost ~]# yum groupinstall "Development Tools" "Server Platform Development" -y
[root@localhost ~]# yum -y install vsftpd
centos7中编译pam模块
[root@localhost ~]# tar xf pam_mysql-0.7RC1.tar.gz
[root@localhost ~]# cd pam_mysql-0.7RC1
[root@localhost pam_mysql-0.7RC1]# ./configure --with-mysql=/usr --with-pam=/usr --with-pam-mods-dir=/usr/lib64/security/
[root@localhost pam_mysql-0.7RC1]# make && make install
[root@localhost pam_mysql-0.7RC1]# cd /usr/lib64/security/
[root@localhost security]# ls | grep pam_mysql
pam_mysql.la
pam_mysql.so
配置mariadb
[root@localhost security]# vim /etc/my.cnf.d/server.cnf
[mysqld]
skip_name_resolve=ON
innodb_file_per_table=ON
log_bin=mysql-bin
[root@localhost pam_mysql-0.7RC1]# systemctl start mariadb.service
授权数据库账号权限,登录新账号操作数据库
[root@localhost pam_mysql-0.7RC1]# mysql
MariaDB [(none)]> GRANT ALL ON vsftpd.* TO vsftpd@'127.0.0.1' IDENTIFIED BY 'vsftpd';
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> \q
[root@localhost pam_mysql-0.7RC1]# mysql -uvsftpd -pvsftpd -h127.0.0.1
MariaDB [(none)]> CREATE DATABASE vsftpd;
MariaDB [(none)]> use vsftpd;
MariaDB [vsftpd]> CREATE TABLE users(id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,password CHAR(48) NOT NULL,UNIQUE KEY(name));
MariaDB [vsftpd]> DESC users;
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | UNI | NULL | |
| password | char(48) | NO | | NULL | |
+----------+------------------+------+-----+---------+----------------+
MariaDB [vsftpd]> INSERT INTO users(name,password) VALUES ('tom',PASSWORD('mageedu')),('jerry',PASSWORD('jerry'));
MariaDB [vsftpd]> SELECT * FROM users;
+----+-------+-------------------------------------------+
| id | name | password |
+----+-------+-------------------------------------------+
| 1 | tom | *9A94EE7D14C10908118B62D2DA88E6932E11E438 |
| 2 | jerry | *09FB9E6E2AA0750E9D8A8D22B6AA8D86C85BF3D0 |
+----+-------+-------------------------------------------+
创建一个pam文件,使用mysql来认证
[root@localhost ~]# vim /etc/pam.d/vsftpd.vusers
auth required /usr/lib64/security/pam_mysql.so user=vsftpd passwd=vsftpd host=127.0.0.1 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
#用pam_mysql.so模块来检查,以vsftpd用户的身份用密码登录到mysql服务器,登录完检查登录vsftpd数据库的users表,这个表中用户名哪个字段,密码哪个字段,密码是靠哪种加密
account required /usr/lib64/security/pam_mysql.so user=vsftpd passwd=vsftpd host=127.0.0.1 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
配置vsftpd
[root@localhost ~]# mkdir /ftproot/
[root@localhost ~]# useradd -d /ftproot/vuser vuser
[root@localhost ~]# finger vuser
Directory: /ftproot/vuser Shell: /bin/bash
[root@localhost ~]# mkdir /ftproot/vuser/pub
#按照习惯会有一个pub目录
[root@localhost vsftpd]# cp vsftpd.conf{,.bak}
[root@localhost vsftpd]# vim vsftpd.conf
pam_service_name=vsftpd.vusers #pam文件名
guest_enable=YES #开启来宾账号
guest_username=vuser #来宾账号映射为系统用户名
user_config_dir=/etc/vsftpd/vusers_config/
[root@localhost vsftpd]# chmod a-w /ftproot/vuser/ #移除用户家目录属主写权限
[root@localhost vsftpd]# mkdir /ftproot/vuser/upload
[root@localhost vsftpd]# chown vuser.vuser /ftproot/vuser/upload
[root@localhost vsftpd]# mkdir vusers_config
[root@localhost vsftpd]# vim vusers_config/tom
anon_upload_enable=YES
#tom账号开启上传权限
[root@localhost vsftpd]# cd vusers_config/
[root@localhost vusers_config]# cp tom jerry
[root@localhost vusers_config]# vim jerry
anon_upload_enable=YES
anon_mkdir_write_enable=YES
#jerry账号开启创建目录权限
[root@localhost vusers_config]# systemctl start vsftpd.service
登录tom账号测试
[root@localhost etc]# lftp -u tom 192.168.10.13
Password:
lftp tom@192.168.10.13:~> cd upload
cd ok, cwd=/upload
lftp tom@192.168.10.13:/upload> put issue
23 bytes transferred
lftp tom@192.168.10.13:/upload> ls
-rw------- 1 1000 1000 23 Jun 15 03:32 issue
lftp tom@192.168.10.13:/upload> mkdir test
mkdir: Access failed: 550 Permission denied. (test)
登录jerry账号测试
[root@localhost etc]# lftp -u jerry 192.168.10.13
Password:
lftp jerry@192.168.10.13:~> cd upload
cd ok, cwd=/upload
lftp jerry@192.168.10.13:/upload>
lftp jerry@192.168.10.13:/upload> put fstab
465 bytes transferred
lftp jerry@192.168.10.13:/upload> mkdir test
mkdir ok, `test' created
lftp jerry@192.168.10.13:/upload> ls
-rw------- 1 1000 1000 465 Jun 15 03:40 fstab
-rw------- 1 1000 1000 23 Jun 15 03:32 issue
drwx------ 2 1000 1000 6 Jun 15 03:41 test
#这个账号可以创建目录
tom和jerry虽然映射的是同一个账号,但是他们拥有了不同的权限