FTP服务器搭建:Linux下vsftpd实现基于Berkeley DB文件存放虚拟用户的案例 任务内容:利用vsftpd构建好基于Berkeley DB文件存放虚拟用户的FTP服务器。 创建FTP的全局根目录 /data/ftproot ,全局可
FTP服务器搭建:Linux下vsftpd实现基于Berkeley DB文件存放虚拟用户的案例
任务内容:利用vsftpd构建好基于Berkeley DB文件存放虚拟用户的FTP服务器。
创建FTP的全局根目录 /data/ftproot ,全局可上传目录 /data/ftproot/upload ,将其授予给FTP虚拟账户sabrina读和写;再创建angela专有根目录 /data/ftpangela/ 和 专有可上传目录 /data/ftpangela/upfiles/ ,并授予读写权限给FTP虚拟账户angela 使用。
1. 架构及主机
基本思路:
- FTP账户是虚拟账户,不能作为系统用户保存在Linux系统内,先创建奇数行FTP账户和偶数行密&码的格式文本文件(vsftpusers.txt),并转换成Berkeley DB文件(vsftpusers.db),再在vsftpd内通过pam模块调用。每次新增用户都必须先编辑vsftpusers.txt,再转换更新vsftpusers.db文件,令其生效。
- 因为vsftpd搭建的FTP服务内的FTP账户是虚拟账户,Linux的目录和文件只能对系统帐户(本例创建的账号名称vsftpuser)授于读写修改执行等权限,这样就需要将FTP虚拟账户(本例创建两个ftp虚拟账户sabrina和angela)和vsftpuser建立映射关系,间接建立起FTP虚拟账户(sabrina和angela)和Linux目录和文件的权属关系。
- 为了解决目录授权的问题,所有虚拟FTP虚拟账户都被映射到同一个vsftpuser账户,为了进一步区别每个虚拟FTP账号的读写权限和各自拥有的目录,需结合/etc/vsftpd/conf.d/下的用户配置文件来实现。
1. FTP服务器 :
主机名:FptServerIP18
CentOS 8.4
IP: 192.168.250.18/24
# 软件包:
vsftpd-3.0.3-34.el8.x86_64.rpm
libdb-utils-5.3.28-40.el8.x86_64
2. 创建用户数据库文件
# 同步时间、修改服务器名、查看依赖包[root@CentOS84 ]#hostnamectl set-hostname FptServerIP18
[root@CentOS84 ]#exit
[root@FptServerIP18 ]#systemctl enable --now chronyd.service
[root@FptServerIP18 ]#rpm -qf `which db_load`
libdb-utils-5.3.28-40.el8.x86_64
# 安装vsftpd 服务器端文件
[root@FptServerIP18 ]#yum -y install vsftpd
[root@FptServerIP18 ]#rpm -ql vsftpd
/etc/logrotate.d/vsftpd
/etc/pam.d/vsftpd #pam 模块控制ftp的账号等
/etc/vsftpd
/etc/vsftpd/ftpusers
/etc/vsftpd/user_list
/etc/vsftpd/vsftpd.conf #配置文件
...............
/usr/lib/systemd/system/vsftpd.service # 服务文件
...............
/var/ftp
/var/ftp/pub
# 查看安装是否成功及版本等信息
[root@FptServerIP18 ]#rpm -qi vsftpd
Name : vsftpd
Version : 3.0.3
...................
# 启动ftp服务
[root@FptServerIP18 ]#systemctl enable --now vsftpd
# 查看端口监听
[root@FptServerIP18 ]#ss -tln
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 32 *:21 *:*
# 查看vsftp的进程关系,便于更好理解ftp工作原理
[root@FptServerIP18 ]#pstree -p |grep vsftpd
[root@FptServerIP18 ]#ps auxf|grep vsftpd
# 过滤默认配置文件内的非注释行
[root@FptServerIP18 ]#grep -v "^#" /etc/vsftpd/vsftpd.conf
anonymous_enable=NO
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
pam_service_name=vsftpd
userlist_enable=YES
[root@FptServerIP18 ]#
# 创建ftp虚拟用户账号和密&码文件
[root@FptServerIP18 ]#vim /etc/vsftpd/vsftpusers.txt
[root@FptServerIP18 ]#cat /etc/vsftpd/vsftpusers.txt
sabrina
sabrina2022
angela
angela2022
# 文本格式的账号和密&码,转换成Berkeley DB文件(vsftpusers.db)
[root@FptServerIP18 ]#db_load -T -t hash -f /etc/vsftpd/vsftpusers.txt /etc/vsftpd/vsftpusers.db
[root@FptServerIP18 ]#ll /etc/vsftpd/
total 36
-rw------- 1 root root 125 Apr 22 2021 ftpusers
-rw------- 1 root root 361 Apr 22 2021 user_list
-rw------- 1 root root 5059 Mar 14 21:43 vsftpd.conf
-rwxr--r-- 1 root root 348 Apr 22 2021 vsftpd_conf_migrate.sh
-rw-r--r-- 1 root root 12288 Mar 14 21:54 vsftpusers.db
-rw-r--r-- 1 root root 38 Mar 14 21:52 vsftpusers.txt
# 账号和密&码文件修改成权限,只有管理员可读写,保证安全
[root@FptServerIP18 ]#chmod 600 /etc/vsftpd/vsftpusers.*
[root@FptServerIP18 ]#ll /etc/vsftpd/
total 36
-rw------- 1 root root 125 Apr 22 2021 ftpusers
-rw------- 1 root root 361 Apr 22 2021 user_list
-rw------- 1 root root 5059 Mar 14 21:43 vsftpd.conf
-rwxr--r-- 1 root root 348 Apr 22 2021 vsftpd_conf_migrate.sh
-rw------- 1 root root 12288 Mar 14 21:54 vsftpusers.db
-rw------- 1 root root 38 Mar 14 21:52 vsftpusers.txt
[root@FptServerIP18 ]#
[root@FptServerIP18 ]#getent passwd ftp
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
2. 创建Linux系统FTP映射用账号和FTP目录
# 创建ftp根目录及可写目录[root@FptServerIP18 ]#mkdir -pv /data/ftproot/upload
mkdir: created directory '/data/ftproot'
mkdir: created directory '/data/ftproot/upload'
# 创建 Linux系统内的ftp虚拟账户映射用的账号 vsftpuser,并设定为非登录,并指定相应的ftp根目录
[root@FptServerIP18 ]#useradd -d /data/ftproot -s /sbin/nologin -r vsftpuser
[root@FptServerIP18 ]#getent passwd vsftpuser
vsftpuser:x:975:974::/data/ftproot:/sbin/nologin
# 授权vsftpuser账户对/data/ftproot/upload目录的可写权限
[root@FptServerIP18 ]#setfacl -m u:vsftpuser:rwx /data/ftproot/upload
[root@FptServerIP18 ]#ll /data/ftproot
total 0
drwxrwxr-x+ 2 root root 6 Mar 14 22:08 upload
[root@FptServerIP18 ]#tree /data/ftproot
/data/ftproot
└── upload
1 directory, 0 files
# 设定ftp根目录只有读权限没有写权限,新版本的vsftpd有相应的安全规则,如果根目录给了写权限在客户端登录时候会报错,不让登录,后面有演示
[root@FptServerIP18 ]#chmod a=rx /data/ftproot/
[root@FptServerIP18 ]#ll /data/
drwxr-xr-x 3 root root 20 Mar 14 22:08 ftproot
## 查看目录权限,目录权限的理解非常重要
# ftp全局根目录 /data/ftproot/ 对所有的用户只有读权限,没有写权限
[root@FptServerIP18 ]#getfacl /data/ftproot/
getfacl: Removing leading '/' from absolute path names
# file: data/ftproot/
# owner: root
# group: root
user::r-x
group::r-x
other::r-x
# ftp全局根目录下的/upload/目录,可以通过 setfacl命令授写权限,在上面已经完成了,下面也验证了设置成功了
[root@FptServerIP18 ]#getfacl /data/ftproot/upload/
getfacl: Removing leading '/' from absolute path names
# file: data/ftproot/upload/
# owner: root
# group: root
user::rwx
user:vsftpuser:rwx #上行是root有读写执行权限,这行是vsftpuser有读写执行权限
group::r-x
mask::rwx
other::r-x
[root@FptServerIP18 ]#
3. 创建并引用pam配置文件
## 创建自定义的pam配置文件# 查看pam.d文件的默认关联关系
[root@FptServerIP18 ]#ll /etc/pam.d/
total 108
........
-rw-r--r-- 1 root root 335 Apr 22 2021 vsftpd #默认的pam配置文件,本实验不用默认,采用自定义的pam配置文件
# 自定义pam配置文件,并引用
[root@FptServerIP18 ]#vim /etc/pam.d/vsftpd.db
[root@FptServerIP18 ]#cat /etc/pam.d/vsftpd.db
auth required pam_userdb.so db=/etc/vsftpd/vsftpusers
account required pam_userdb.so db=/etc/vsftpd/vsftpusers
## 在ftp的conf配置文件内引用自定义的pam配置文件vsftpd.db、指定映射账户vsftpuser
[root@FptServerIP18 ]#vim /etc/vsftpd/vsftpd.conf
anonymous_enable=YES
#pam_service_name=vsftpd
guest_enable=YES
guest_username=vsftpuser
pam_service_name=vsftpd.db
# 列出vsftpd.conf非注释行的有效配置行
[root@FptServerIP18 ]#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
userlist_enable=YES
guest_enable=YES
guest_username=vsftpuser
pam_service_name=vsftpd.db
# 重启 vsftpd 服务
[root@FptServerIP18 ]#systemctl restart vsftpd
4. 建立虚拟用户各自独立的配置文件
# 创建各个ftp虚拟用户的配置文件存放的目录[root@FptServerIP18 ]#mkdir /etc/vsftpd/conf.d/
# 指定ftp虚拟用户的配置文件存放的目录路径
[root@FptServerIP18 ]#vim /etc/vsftpd/vsftpd.conf
user_config_dir=/etc/vsftpd/conf.d/
#创建angela虚拟ftp账户的专有配置文件,指定angela用户的ftp根目录为/data/ftpangela,此目录允许angela用户可读不可写,但其下的二级目录/data/ftpangela/upfiles可写可读,这些限制将通过setfacl -m命令实现。
[root@FptServerIP18 ]#vim /etc/vsftpd/conf.d/angela
[root@FptServerIP18 ]#cat /etc/vsftpd/conf.d/angela
local_root=/data/ftpangela
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
[root@FptServerIP18 ]#
[root@FptServerIP18 ]#mkdir -pv /data/ftpangela/upfiles
[root@FptServerIP18 ]#setfacl -m u:vsftpuser:rwx /data/ftpangela/upfiles
[root@FptServerIP18 ]#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@FptServerIP18 ]#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
[root@FptServerIP18 ]#
#创建sabrina虚拟ftp账户的专有配置文件,不指定sabrina用户的ftp专属根目录,默认为/data/ftproot/ 用户可读不可写,但其下/data/ftproot/upload 可写可读,通过setfacl -m命令来实现控权。
[root@FptServerIP18 ]#vim /etc/vsftpd/conf.d/sabrina
[root@FptServerIP18 ]#cat /etc/vsftpd/conf.d/sabrina
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
# 虽然sabrina虚拟ftp账户使用的默认的 /data/ftproot/ 为根目录,我们仍然为其建立好专用目录备用,后面会修改根目录为/data/ftpsabrina/,同时让这个目录可读可写,在客户端用sabrina账户登录会发现报错,以便更好理解vsftpd的安全设置原理。
[root@FptServerIP18 ]#mkdir -pv /data/ftpsabrina/upload
[root@FptServerIP18 ]#setfacl -m u:vsftpuser:rwx /data/ftpsabrina/
[root@FptServerIP18 ]#getfacl /data/ftpsabrina/
getfacl: Removing leading '/' from absolute path names
# file: data/ftpsabrina/
# owner: root
# group: root
user::rwx
user:vsftpuser:rwx
group::r-x
mask::rwx
other::r-x
[root@FptServerIP18 ]#getfacl /data/ftpsabrina/upload/
getfacl: Removing leading '/' from absolute path names
# file: data/ftpsabrina/upload/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
# ftp目录结构全景展示
[root@FptServerIP18 ]#tree /data/
/data/
├── ftpangela
│ ├── angelaDIR.txt
│ └── upfiles
│ └── angela-upfiles-DIR.txt
├── ftproot
│ ├── a.txt
│ └── upload
│ └── ftproot-upload-DIR.txt
└── ftpsabrina
├── sabrinaDIR.txt
└── upload
└── sabrina-upload-DIR.txt
6 directories, 6 files
[root@FptServerIP18 ]#ll /data/
total 0
drwxr-xr-x 3 root root 42 Mar 15 19:05 ftpangela
dr-xr-xr-x 3 root root 33 Mar 14 22:43 ftproot
drwxrwxr-x+ 3 root root 42 Mar 16 01:18 ftpsabrina
[root@FptServerIP18 ]#ll /data/ftpangela/
total 0
-rw-r--r-- 1 root root 0 Mar 14 23:10 angelaDIR.txt
drwxrwxr-x+ 2 root root 36 Mar 16 01:14 upfiles
[root@FptServerIP18 ]#ll /data/ftpsabrina/
total 0
-rw-r--r-- 1 root root 0 Mar 14 23:10 sabrinaDIR.txt
drwxr-xr-x 2 root root 36 Mar 16 01:15 upload
[root@FptServerIP18 ]#ll /data/ftproot/
total 0
-rw-r--r-- 1 root root 0 Mar 14 22:43 a.txt
drwxrwxr-x+ 2 root root 36 Mar 16 01:16 upload
[root@FptServerIP18 ]#
5. 登录验证
5.1 sabrina账户登录情况
5.2 angela账户登录情况
6. 根目录可写登录报错演示
6.1 修改sabrina账户的ftp根目录路径及权限
# 将sabrina的虚拟账户的根ftp目录修改为/data/ftpsabrina,此目录又是可写可读的[root@FptServerIP18 ]#cat /etc/vsftpd/conf.d/sabrina
local_root=/data/ftpsabrina
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
[root@FptServerIP18 ]#getfacl /data/ftpsabrina/
getfacl: Removing leading '/' from absolute path names
# file: data/ftpsabrina/
# owner: root
# group: root
user::rwx
user:vsftpuser:rwx
group::r-x
mask::rwx
other::r-x
[root@FptServerIP18 ]#
[root@FptServerIP18 ]#systemctl restart vsftpd
6.2 验证登录
基本操作方法:退出ftp客户端软件,重新打开并用sabrina账户登录,就出现下图的报错信息,不能登录ftp服务器了。