实现基于MYSQL验证的vsftpd虚拟用户访问 早些年FTP普遍被用于企事业单位内部临时共享和交互文件,FTP的账户和操作系统账户是无关联的,它可以以DB文件或者SQL方式保存,DB方式前文已介
实现基于MYSQL验证的vsftpd虚拟用户访问
早些年FTP普遍被用于企事业单位内部临时共享和交互文件,FTP的账户和操作系统账户是无关联的,它可以以DB文件或者SQL方式保存,DB方式前文已介绍了,本文将详细演示用MariaDB保存FTP虚拟账户搭建FTP服务器的过程。用数据库保存账户需要在vsftp和数据之间有类API接口,PAM-MySQL可以实现数据库和vsftp之间的数据通信。
官网: https://sourceforge.net/projects/pam-mysql/
下载:https://udomain.dl.sourceforge.net/project/pam-mysql/pam-mysql/0.7RC1/pam_mysql-0.7RC1.tar.gz
1. 架构及主机
两台服务器及客户端1 vsftpd服务器 :
主机名:ftpserver-ip7
CentOS 7.9
IP: 192.168.250.7
vsftpd 3.0.2
2 数据库服务器 :
主机名: MariaDB-IP8
CentOS 8.4
IP: 192.168.250.8
mariadb-server-10.3.28
3 客户端 :
CentOS 8.4 或者 WIN10
IP: 192.168.250.X/24
FileZilla专用客户端软件
2. 配置数据库服务器
基本过程:服务器基础环境准备好;安装好数据库软件并创建FTP虚拟账户库和表;创建用户和密码;建立局域网内连接账号等
# 服务器基础环境准备,关闭防火墙和SELINUX;同步时间;修改服务器名[root@CentOS84 ]#hostnamectl set-hostname MariaDB-IP8
[root@CentOS84 ]#exit
[root@MariaDB-IP8 ]#systemctl enable --now chronyd.service
# 在服务器上安装mysql数据库
[root@MariaDB-IP8 ]#dnf -y install mariadb-server
[root@MariaDB-IP8 ]#rpm -ql mariadb
[root@MariaDB-IP8 ]#rpm -qi mariadb
# 启动mariadb服务
[root@MariaDB-IP8 ]#systemctl enable --now mariadb
# 建好存放ftp虚拟账户的mysql库和表
[root@MariaDB-IP8 ]#mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.3.28-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> CREATE DATABASE vsftpd;
Query OK, 1 row affected (0.001 sec)
MariaDB [(none)]> USE vsftpd;
Database changed
MariaDB [vsftpd]> CREATE TABLE users (
-> id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> name CHAR(50) BINARY NOT NULL,
-> password CHAR(48) BINARY NOT NULL
-> );
Query OK, 0 rows affected (0.065 sec)
# 添加ftp虚拟账户和密码,为安全计,用PASSWORD函数对密码加密后存储在数据库内,这样在运营的生产环境中很重要,避免很多用户不同网站用相同的账户和密码,对于个别无底线的运维管理人员也做好隔离工作,避免发生用户数据泄密事件
MariaDB [vsftpd]> INSERT INTO users(name,password) values('ftp_sabrina',password('shone2022'));
Query OK, 1 row affected (0.002 sec)
MariaDB [vsftpd]> INSERT INTO users(name,password) values('ftp_angela',password('shone2022'));
Query OK, 1 row affected (0.001 sec)
MariaDB [vsftpd]> select * from users;
+----+-------------+-------------------------------------------+
| id | name | password |
+----+-------------+-------------------------------------------+
| 1 | ftp_sabrina | *DFF4E2345EA33CC7AA637BAE30A787DD8E2C6606 |
| 2 | ftp_angela | *DFF4E2345EA33CC7AA637BAE30A787DD8E2C6606 |
+----+-------------+-------------------------------------------+
2 rows in set (0.001 sec)
# 创建vsftpd连接数据库的用户和地址段等做好限制
MariaDB [vsftpd]> GRANT SELECT ON vsftpd.* TO vsftpd@'192.168.250.%' IDENTIFIED BY 'shone2022';
Query OK, 0 rows affected (0.001 sec)
# flush privileges 命令本质上的作用是将当前user和privilige表中的用户信息/权限设置从mysql库(MySQL数据库的内置库)中提取到内存里。
MariaDB [vsftpd]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.001 sec)
MariaDB [vsftpd]>
3. 配置vsftpd服务器
基本过程:在服务器上yum安装好vsftpd 和 编译安装好pam_mysql包;在FTP服务器上建立pam认证所需文件;建立相应用户和修改vsftpd配置文件;在FTP服务器上配置虚拟用户具有不同的访问权限。
3.1 配置ftp虚拟账户访问全局ftp目录
基本任务:在vsftpd的全局配置文件 /etc/vsftpd/vsftpd.conf 中,为所有用户先配置好全局根目录和pam配置文件名及登录线管选项,先实现虚拟账户登录ftp全局目录的目标。
3.1.1 配置过程
# 服务器基础环境准备;修改服务器名;同步时间[root@centos79 <sub>]# hostnamectl set-hostname FtpServer-IP7
[root@centos79 </sub>]# exit
logout
[root@ftpserver-ip7 <sub>]# ntpdate ntp1.aliyun.com
[root@ftpserver-ip7 </sub>]# date
# 在服务器上yum安装好vsftpd
[root@ftpserver-ip7 <sub>]# yum -y install vsftpd
# 准备并安装好编译安装pam_mysql的依赖包
[root@ftpserver-ip7 </sub>]# yum -y install gcc gcc-c++ make mariadb-devel pam-devel
# 下载pam_mysql源码包---pam_mysql-0.7RC1.tar.gz
[root@ftpserver-ip7 data]# cd /data
[root@ftpserver-ip7 data]# wget http://prdownloads.sourceforge.net/pam-mysql/pam_mysql-0.7RC1.tar.gz
# 解压源码包到 /data/目录下
[root@ftpserver-ip7 data]# tar xvf pam_mysql-0.7RC1.tar.gz
[root@ftpserver-ip7 data]# ll
total 364
drwxrwxrwx 2 1000 1000 4096 Jan 9 2006 pam_mysql-0.7RC1
-rw-r--r-- 1 root root 335240 Jan 9 2006 pam_mysql-0.7RC1.tar.gz
-rwxr-xr-x. 1 root root 28775 Dec 26 14:02 reset2022.sh
# 进入源码包目录,编译安装pam_mysql
[root@ftpserver-ip7 data]# cd pam_mysql-0.7RC1/
[root@ftpserver-ip7 pam_mysql-0.7RC1]# ./configure --with-pam-mods-dir=/lib64/security
#如果上面命令不带 --with-pam-mods-dir=/lib64/security 会报下面的错误 :
checking if the second argument of pam_conv.conv() takes const pointer... no
configure: error: Your system doesn't appear to be configured to use PAM.
Perhaps you need to specify the correct location where the PAM modules reside.
[root@ftpserver-ip7 pam_mysql-0.7RC1]# make install
# 查看编译安装后的模块
[root@ftpserver-ip7 pam_mysql-0.7RC1]#ll /lib64/security/pam_mysql*
-rwxr-xr-x 1 root root 882 Mar 18 23:13 /lib64/security/pam_mysql.la
-rwxr-xr-x 1 root root 141712 Mar 18 23:13 /lib64/security/pam_mysql.so
# 创建pam认证所需文件
[root@ftpserver-ip7 pam_mysql-0.7RC1]# vi /etc/pam.d/vsftpd.mysql
[root@ftpserver-ip7 pam_mysql-0.7RC1]# cat /etc/pam.d/vsftpd.mysql
auth required pam_mysql.so user=vsftpd passwd=shone2022 host=192.168.250.8 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
account required pam_mysql.so user=vsftpd passwd=shone2022 host=192.168.250.8 db=vsftpd table=users usercolumn=name passwdcolumn=password crypt=2
# 创建操作系统账户vsftpuser,此账户用于ftp虚拟账户的映射,并指定全局默认根目录 /data/ftproot ,此目录按照vsftpd官方文档要求权限最高只能只读不可以授予可写,否则就报错。
[root@ftpserver-ip7 pam_mysql-0.7RC1]# useradd -d /data/ftproot -s /sbin/nologin -r vsftpuser
[root@ftpserver-ip7 pam_mysql-0.7RC1]# getent passwd vsftpuser
vsftpuser:x:997:995::/data/ftproot:/sbin/nologin
# 在全局根目录下创建一个可写的二级目录upload
[root@ftpserver-ip7 pam_mysql-0.7RC1]# mkdir -pv /data/ftproot/upload
[root@ftpserver-ip7 pam_mysql-0.7RC1]# setfacl -m u:vsftpuser:rwx /data/ftproot/upload
[root@ftpserver-ip7 pam_mysql-0.7RC1]# ll /data/ftproot
total 0
drwxrwxr-x+ 2 root root 6 Mar 18 23:41 upload
[root@ftpserver-ip7 pam_mysql-0.7RC1]# tree /data/ftproot
/data/ftproot
└── upload
1 directory, 0 files
[root@ftpserver-ip7 pam_mysql-0.7RC1]# getfacl /data/ftproot
getfacl: Removing leading '/' from absolute path names
# file: data/ftproot
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
[root@ftpserver-ip7 pam_mysql-0.7RC1]# getfacl /data/ftproot/upload
getfacl: Removing leading '/' from absolute path names
# file: data/ftproot/upload
# owner: root
# group: root
user::rwx
user:vsftpuser:rwx
group::r-x
mask::rwx
other::r-x
# 配置vsftpd的配置文件,确保开启以下几项
[root@ftpserver-ip7 pam_mysql-0.7RC1]# vim /etc/vsftpd/vsftpd.conf
........... #省略一部分默认配置
#匿名登录
anonymous_enable=YES
guest_enable=YES
# 用于专门映射ftp虚拟账户的操作系统账户
guest_username=vsftpuser
# 定义并指定pam认证文件
pam_service_name=vsftpd.mysql
userlist_enable=YES
"/etc/vsftpd/vsftpd.conf" 133L, 5187C written
# 通过grep过滤出生效的配置行
[root@ftpserver-ip7 pam_mysql-0.7RC1]# grep -v "^#" /etc/vsftpd/vsftpd.conf
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
anonymous_enable=YES
guest_enable=YES
guest_username=vsftpuser
pam_service_name=vsftpd.mysql
userlist_enable=YES
tcp_wrappers=YES
[root@ftpserver-ip7 pam_mysql-0.7RC1]# systemctl enable --now vsftpd
# 到此可以在客户端登录测试了,应该sabrina和angela账户都可以登录,并能看到全局根目录下的文件,见下图
3.1.2 ftp客户端sabrina账户登录,可见全局ftp根目录
3.2 ftp虚拟账户访问各自私有ftp目录
基本任务:vsftpd可以在配置文件目录中为每个用户提供单独的配置文件以定义其ftp服务访问权限,每个虚拟用户的配置文件名同虚拟用户的用户名。配置文件目录可以是任意未使用目录,只需要在vsftpd.conf指定其路径及名称即可
3.2.1 配置过程
[root@ftpserver-ip7 pam_mysql-0.7RC1]# mkdir /etc/vsftpd/conf.d/[root@ftpserver-ip7 pam_mysql-0.7RC1]# vim /etc/vsftpd/vsftpd.conf
# 增加下面一行,目的是指定每个用户的各自配置文件的路径
user_config_dir=/etc/vsftpd/conf.d/
[root@ftpserver-ip7 pam_mysql-0.7RC1]# grep -v "^#" /etc/vsftpd/vsftpd.conf
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
anonymous_enable=YES
guest_enable=YES
guest_username=vsftpuser
pam_service_name=vsftpd.mysql
user_config_dir=/etc/vsftpd/conf.d/
userlist_enable=YES
tcp_wrappers=YES
# 配置好后重启服务
[root@ftpserver-ip7 pam_mysql-0.7RC1]# systemctl restart vsftpd
### 解读性注释:配置ftp虚拟用户ftp_sabrina和ftp_angela的访问权限。虚拟用户对vsftpd服务的访问权限是通过匿名用户的相关指令进行的。如要让用户ftp_sabrina具有上传文件的权限,可修改 /etc/vsftpd/vusers.d/ftp_sabrina和/etc/vsftpd/vusers.d/ftp_angela文件,在里面添加如下选项并设置为YES即可,只读则设为NO,完成ftp配置文件设定后,还要确保对应的映射用户vsftpuser对于文件系统有写权限。
## ftp_angela用户的相关专属化配置
[root@ftpserver-ip7 ]# vim /etc/vsftpd/conf.d/ftp_angela
[root@ftpserver-ip7 ]# cat /etc/vsftpd/conf.d/ftp_angela
#登录到ftp_angela用户独自享有的目录
local_root=/data/ftpangela
#写权限
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
[root@ftpserver-ip7 ]# mkdir -pv /data/ftpangela/upfiles
[root@ftpserver-ip7 ]# setfacl -m u:vsftpuser:rwx /data/ftpangela/upfiles
[root@ftpserver-ip7 pam_mysql-0.7RC1]# getfacl /data/ftpangela/
getfacl: Removing leading '/' from absolute path names
# file: data/ftpangela/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
[root@ftpserver-ip7 pam_mysql-0.7RC1]# getfacl /data/ftpangela/upfiles
getfacl: Removing leading '/' from absolute path names
# file: data/ftpangela/upfiles
# owner: root
# group: root
user::rwx
user:vsftpuser:rwx
group::r-x
mask::rwx
other::r-x
## ftp_sabrina 用户的相关专属化配置
[root@ftpserver-ip7 pam_mysql-0.7RC1]# vim /etc/vsftpd/conf.d/ftp_sabrina
[root@ftpserver-ip7 pam_mysql-0.7RC1]# cat /etc/vsftpd/conf.d/ftp_sabrina
local_root=/data/ftpsabrina
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
[root@ftpserver-ip7 pam_mysql-0.7RC1]# mkdir -pv /data/ftpsabrina/upload
[root@ftpserver-ip7 pam_mysql-0.7RC1]# setfacl -m u:vsftpuser:rwx /data/ftpsabrina/upload
[root@ftpserver-ip7 pam_mysql-0.7RC1]# getfacl /data/ftpsabrina/
getfacl: Removing leading '/' from absolute path names
# file: data/ftpsabrina/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
[root@ftpserver-ip7 pam_mysql-0.7RC1]# getfacl /data/ftpsabrina/upload
getfacl: Removing leading '/' from absolute path names
# file: data/ftpsabrina/upload
# owner: root
# group: root
user::rwx
user:vsftpuser:rwx
group::r-x
mask::rwx
other::r-x
# 在每个目录内创建一个和目录路径关联的文件,便于后面的测试看得很直观
[root@ftpserver-ip7 ]# touch /data/ftpangela/ftpangelaDIR.txt
[root@ftpserver-ip7 ]# touch /data/ftpangela/upfiles/ftpangela-upfiles-DIR.txt
[root@ftpserver-ip7 ]# touch /data/ftproot/ftproot-DIR.txt
[root@ftpserver-ip7 ]# touch /data/ftproot/upload/ftproot-upload-DIR.txt
[root@ftpserver-ip7 ]# touch /data/ftpsabrina/upload/ftpsabrina-upload-DIR.txt
[root@ftpserver-ip7 ]# touch /data/ftpsabrina/ftpsabrina-DIR.txt
[root@ftpserver-ip7 ]# tree /data/
/data/
├── ftpangela
│ ├── ftpangelaDIR.txt
│ └── upfiles
│ └── ftpangela-upfiles-DIR.txt
├── ftproot
│ ├── ftproot-DIR.txt
│ └── upload
│ └── ftproot-upload-DIR.txt
└── ftpsabrina
├── ftpsabrina-DIR.txt
└── upload
└── ftpsabrina-upload-DIR.txt
[root@ftpserver-ip7 ]# tree /etc/vsftpd/
/etc/vsftpd/
├── conf.d
│ ├── ftp_angela
│ └── ftp_sabrina
├── ftpusers
├── user_list
├── vsftpd.conf
└── vsftpd_conf_migrate.sh
1 directory, 6 files
# 至此个性化每个用户目录及权限得配置化全部完成了,下面开始测试。
3.2.2 测试验证
- ftp虚拟账户sabrina访问私有ftp只读目录
- ftp虚拟账户sabrina访问私有ftp可写二级目录
- ftp虚拟账户angela访问私有ftp只读目录
- ftp虚拟账户angela访问私有ftp可写二级目录
- ftp虚拟账户angela上传文件到ftp可写的目录,验证可写性