SELINUX配置Proftpd安全FTP服务器权限实操指南

我正在参与掘金创作者训练营第5期,点击了解活动详情

1. 概述

本文以proftpd为例描述了在Linux系统中为应用配置selinux权限的工作流。

2. selinux安装

博主的系统环境为:Ubuntu20.04

2.1 selinux安装情况查询

有些linux发行版自带selinux,有的需要单独安装,我们输入sestatus命令来查看一下selinux的运行情况。

zhoushimin@zsm:Downloads$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             default			# 策略类型targeted(default)
Current mode:                   permissive		# 当前工作模式为宽容模式,适用于调试
Mode from config file:          permissive		# 配置文件工作模式为宽容模式
Policy MLS status:              enabled			# 是否含有mls的模式机制
Policy deny_unknown status:     allowed			# 是否默认抵挡未知的主体程序
Memory protection checking:     requested (insecure)
Max kernel policy version:      33
复制代码

如果提示上面这个信息,说明selinux已经启用了。如果没有安装则按下如下步骤进行。

2.2 安装(适用Ubuntu20.04,其它版本未测试)

sudo apt install policycoreutils selinux-utils selinux-basics auditd
复制代码

2.3 激活selinux

sudo selinux-activate
复制代码

默认配置selinux为permissive模式

2.5 重启

sudo reboot
复制代码

注意事项:

  • 如果改变了政策则需要重新开机;
  • 如果由 enforcing 或 permissive 改成 disabled ,或由 disabled 改成其他两个,那也必须要重新开机,这是因为 SELinux 是整合到核心里面去的。
  • 在 SELinux 运行下切强制 (enforcing) 或宽容 (permissive) 模式可以互相切换,但不能够直接关闭 SELinux 的!
  • 从 disable 转到启动 SELinux 的模式时,将会给资源重新打上Lable,过程会比较缓慢。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UPsfOolV-1659701195656)(../images/c8b2e29a914eb324cfe99ba550a48604b2803ae6a9f9ff1431b657e9d201c8aa.png)]

2.6 重启后,查看状态

zhoushimin@zsm:Downloads$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             default
Current mode:                   permissive
Mode from config file:          permissive
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     requested (insecure)
Max kernel policy version:      33

复制代码

3. 安装Proftpd

具体请参考博主文章:开启TLS加密传输的Proftpd安全FTP服务器安装指南 - 掘金 (juejin.cn)

4. 基础认知

selinux的MAC强制访问权限的流程是这样的:

  • DAC访问权限验证。用户具有的属主、属组权限是否可以执行对应的操作。

  • selinux策略是否启动

  • selinux的安全上下文是否匹配。

5. selinux的基础配置

按照如下命令配置selinux:

vim /etc/selinux/config
复制代码

配置如下:

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these two values:
# default - equivalent to the old strict and targeted policies
# mls     - Multi-Level Security (for military and educational use)
# src     - Custom policy built from source
SELINUXTYPE=default

# SETLOCALDEFS= Check local definition changes
SETLOCALDEFS=0
复制代码

SELINUX为啥要先设置为permissive呢,首次启动时需要打标签,另外即使规则没有配置好,也不影响运行。

SELINUXTYPE选择default,它对应的就是targeted.

6. 为proftpd配置权限

6.1 DAC访问权限位配置

ls -l /home/ftproot
复制代码
book@100ask:/home$ sudo ls -l /home/ftproot/
total 8
drwxrwx---. 2 2001 200 4096 Aug  5 05:49 down
drwxrwx---. 2 2001 200 4096 Aug  5 06:57 upload
复制代码

文件是否赋予了用户访问权限,在这里,文件的权限控制位为0771,是满足读写权限控制的,属主、属组用户均有读写执行权限,其它用户无权限。

6.2 首先查看ftp相关的selinux bool规则开关

seinfo -b | grep ftp
复制代码
   allow_ftpd_anon_write
   allow_ftpd_full_access
   allow_ftpd_use_cifs
   allow_ftpd_use_nfs
   ftp_home_dir
   ftpd_connect_all_unreserved
   ftpd_connect_db
   ftpd_use_passive_mode
   httpd_enable_ftp_server
   sftpd_anon_write
   sftpd_enable_homedirs
   sftpd_full_access
   sftpd_write_ssh_home
   tftp_anon_write
   tftp_enable_homedir
复制代码

可以看到ftp相关的bool规则挺多的,查一下它们的开关状态。

6.3 查看selinux相关bool规则的开关状态

getsebool -a | grep ftp
复制代码
book@100ask:/etc/proftpd$ getsebool -a | grep ftp
allow_ftpd_anon_write --> off
allow_ftpd_full_access --> off
allow_ftpd_use_cifs --> off
allow_ftpd_use_nfs --> off
ftp_home_dir --> on
ftpd_connect_all_unreserved --> off
ftpd_connect_db --> off
ftpd_use_passive_mode --> off
httpd_enable_ftp_server --> off
sftpd_anon_write --> off
sftpd_enable_homedirs --> off
sftpd_full_access --> off
sftpd_write_ssh_home --> off
tftp_anon_write --> off
tftp_enable_homedir --> off
复制代码

可以看到有的时开启的,有的是关闭的。

因为我部署的ftp服务器是既可以上传,也可以下载,且需要密码访问,因此不开启匿名访问。这里仅开启ftp_home_dir即可。为啥要开启呢?因为它影响着进程安全上下文和文件安全上下文的允许规则,可以查看它到底管控了什么?

6.4 查看bool规则影响的访问规则

sesearch -A -b ftp_home_dir
复制代码
book@100ask:/etc/proftpd$ sesearch -A -b ftp_home_dir
allow ftpd_t cifs_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write }; [ use_samba_home_dirs && ftp_home_dir ]:True
allow ftpd_t cifs_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ use_samba_home_dirs && ftp_home_dir ]:True
allow ftpd_t cifs_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ use_samba_home_dirs && ftp_home_dir ]:True
allow ftpd_t cifs_t:file { append create getattr ioctl link lock open read rename setattr unlink write }; [ use_samba_home_dirs && ftp_home_dir ]:True
allow ftpd_t cifs_t:lnk_file { create getattr ioctl link lock read rename setattr unlink write }; [ use_samba_home_dirs && ftp_home_dir ]:True
allow ftpd_t ftpd_t:capability { dac_override dac_read_search }; [ ftp_home_dir ]:True
allow ftpd_t home_root_t:dir { getattr open search }; [ ftp_home_dir ]:False
allow ftpd_t home_root_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t home_root_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t home_root_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t home_root_t:lnk_file { getattr read }; [ ftp_home_dir ]:False
allow ftpd_t home_root_t:lnk_file { getattr read }; [ ftp_home_dir ]:True
allow ftpd_t home_root_t:lnk_file { getattr read }; [ ftp_home_dir ]:True
allow ftpd_t home_root_t:lnk_file { getattr read }; [ ftp_home_dir ]:True
allow ftpd_t httpd_sys_content_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t nfs_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write }; [ use_nfs_home_dirs && ftp_home_dir ]:True
allow ftpd_t nfs_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ use_nfs_home_dirs && ftp_home_dir ]:True
allow ftpd_t nfs_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ use_nfs_home_dirs && ftp_home_dir ]:True
allow ftpd_t nfs_t:file { append create getattr ioctl link lock open read rename setattr unlink write }; [ use_nfs_home_dirs && ftp_home_dir ]:True
allow ftpd_t nfs_t:lnk_file { create getattr ioctl link lock read rename setattr unlink write }; [ use_nfs_home_dirs && ftp_home_dir ]:True
allow ftpd_t tmp_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:False
allow ftpd_t tmp_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t tmp_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t tmp_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_home_dir_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:False
allow ftpd_t user_home_dir_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_dir_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_dir_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:file { append create getattr ioctl link lock open read rename setattr unlink write }; [ ftp_home_dir ]:True
allow ftpd_t user_runtime_root_t:dir { getattr open search }; [ ftp_home_dir ]:False
allow ftpd_t user_runtime_root_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_runtime_root_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_runtime_root_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_runtime_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:False
allow ftpd_t user_runtime_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_runtime_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_runtime_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_tmp_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write }; [ ftp_home_dir ]:True
allow ftpd_t user_tmp_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_tmp_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_tmp_t:file { append create getattr ioctl link lock open read rename setattr unlink write }; [ ftp_home_dir ]:True
allow ftpd_t var_run_t:dir { getattr open search }; [ ftp_home_dir ]:False
allow ftpd_t var_run_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t var_run_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t var_run_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t var_run_t:lnk_file { getattr read }; [ ftp_home_dir ]:False
allow ftpd_t var_run_t:lnk_file { getattr read }; [ ftp_home_dir ]:True
allow ftpd_t var_run_t:lnk_file { getattr read }; [ ftp_home_dir ]:True
allow ftpd_t var_run_t:lnk_file { getattr read }; [ ftp_home_dir ]:True
allow ftpd_t var_t:dir { getattr open search }; [ ftp_home_dir ]:False
allow ftpd_t var_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t var_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t var_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t var_t:dir { getattr open search }; [ ftp_home_dir ]:True
复制代码

可以看到这里有很多的访问权限规则的配置。那么到底哪个规则才是我们所需要的呢?

6.5 查看文件的安全上下文

首先看一下文件的安全上下文:

ll -Z /home/
复制代码
book@100ask:/etc/proftpd$ ll -Z /home/
total 40
drwxr-xr-x.  7 root root system_u:object_r:home_root_t:s0      4096 Aug  5 05:12 ./
drwxr-xr-x. 26 root root system_u:object_r:root_t:s0           4096 Aug  5 04:13 ../
drwxr-xr-x.  4 2001  200 system_u:object_r:user_home_dir_t:s0  4096 Aug  5 06:44 ftproot/
复制代码

可以看到目录文件的安全上下文为user_home_dir_t,如果不是这个可以使用restorecon命令重置一下规则

restorecon -R /home/ftproot
复制代码

6.6 查看进程的安全上下文

ps -eZ | grep proftpd
复制代码
book@100ask:~$ ps auxZ | grep proftpd
system_u:system_r:ftpd_t:s0     proftpd    1316  0.0  0.1  68244  3144 ?        Ss   07:39   0:00 proftpd: (accepting connections)
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 book 1703 0.0  0.0 14428 1040 pts/0 S+ 07:40   0:00 grep --color=auto proftpd
复制代码

可以看到进程的安全上下文为ftpd_t。

6.7 查看进程上下文和文件安全上下文是否匹配

还记得6.3节,ftp_home_dir影响很多访问规则,哪项才是我们需要的呢?

sesearch -A -b ftp_home_dir -s ftpd_t | grep user_home
复制代码
book@100ask:~$ sesearch -A -b ftp_home_dir -s ftpd_t | grep user_home
allow ftpd_t user_home_dir_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:False
allow ftpd_t user_home_dir_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_dir_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_dir_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:file { append create getattr ioctl link lock open read rename setattr unlink write }; [ ftp_home_dir ]:True
复制代码

可以看到有目录的访问权限

allow ftpd_t user_home_dir_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_dir_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_dir_t:dir { getattr open search }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name create getattr ioctl link lock open read remove_name rename reparent rmdir search setattr unlink write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
allow ftpd_t user_home_t:dir { add_name getattr ioctl lock open read remove_name search write }; [ ftp_home_dir ]:True
复制代码

也有文件的访问权限:

allow ftpd_t user_home_t:file { append create getattr ioctl link lock open read rename setattr unlink write }; [ ftp_home_dir ]:True
复制代码

ftproot目录下的文件的默认安全上下文就是这个user_home_t,继承父目录的安全上下文。

到这里,proftpd的访问权限就配置好了。

使用filezilla可以正常访问proftpd。

7. 开启强制访问控制

sudo setenforce 1
复制代码

注意事项:记得先切换到命令行模式下运行,否则在桌面下开启会导致桌面环境无访问权限崩溃

CTRL+ALT+F1-F6
复制代码

8. 测试

image-20220805200059739

7. 关闭访问权限

如果需要关闭访问权限,则只需要ftp_home_dir开关关闭即可。

setsebool -P ftp_home_dir 0
复制代码

8. 问题排查

如果权限与设计的需求不符,可以查看selinux日志分析问题原因。

日志所在目录为:

/var/log/audit/audit.log.x
复制代码

9. 常用的selinux实用命令工具

  • getenforce - 查看当前的工作模式

  • setenforce - 设置当前的工作模式,重启后会恢复成/etc/selinux/config中配置的模式

  • seinfo - 查看selinux支持的所有规则信息

  • sestatus - 查看selinux的运行状态

  • sesearch - 搜索selinux规则

  • setsebool - 设置bool规则开关

  • getsebool - 读取bool规则开关

  • restorecon - 重置文件安全上下文

  • chcon - 设置文件安全上下文

具体命令的使用参考:sestatus命令 – 显示SELinux状态 – Linux命令大全(手册) (linuxcool.com)

猜你喜欢

转载自juejin.im/post/7129398459550924831