• 【安全利器SELinux快速入门系列】SELINUX配置Proftpd安全FTP服务器权限实操指南


    这是机器未来的第42篇文章

    原文首发地址:https://blog.csdn.net/RobotFutures/article/details/126184816

    在这里插入图片描述

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

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

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

    sudo apt install policycoreutils selinux-utils selinux-basics auditd
    
    • 1

    2.3 激活selinux

    sudo selinux-activate
    
    • 1

    默认配置selinux为permissive模式

    2.5 重启

    sudo reboot
    
    • 1

    注意事项:

    • 如果改变了政策则需要重新开机;
    • 如果由 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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. 安装Proftpd

    具体请参考博主文章:开启TLS加密传输的Proftpd安全FTP服务器安装指南_机器未来的博客-CSDN博客

    4. 基础认知

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

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

    • selinux策略是否启动

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

    5. selinux的基础配置

    按照如下命令配置selinux:

    vim /etc/selinux/config
    
    • 1

    配置如下:

    # 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

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

    6. 为proftpd配置权限

    6.1 DAC访问权限位配置

    ls -l /home/ftproot
    
    • 1
    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
    
    • 1
    • 2
    • 3
    • 4

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

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

    seinfo -b | grep ftp
    
    • 1
       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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

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

    getsebool -a | grep ftp
    
    • 1
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

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

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

    sesearch -A -b ftp_home_dir
    
    • 1
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

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

    6.5 查看文件的安全上下文

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

    ll -Z /home/
    
    • 1
    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/
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    restorecon -R /home/ftproot
    
    • 1

    6.6 查看进程的安全上下文

    ps -eZ | grep proftpd
    
    • 1
    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
    
    • 1
    • 2
    • 3

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

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

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

    sesearch -A -b ftp_home_dir -s ftpd_t | grep user_home
    
    • 1
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    也有文件的访问权限:

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

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

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

    使用filezilla可以正常访问proftpd。

    7. 开启强制访问控制

    sudo setenforce 1
    
    • 1

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

    CTRL+ALT+F1-F6
    
    • 1

    8. 测试

    image-20220805200059739

    7. 关闭访问权限

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

    setsebool -P ftp_home_dir 0
    
    • 1

    8. 问题排查

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

    日志所在目录为:

    /var/log/audit/audit.log.x
    
    • 1

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

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

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

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

    • sestatus - 查看selinux的运行状态

    • sesearch - 搜索selinux规则

    • setsebool - 设置bool规则开关

    • getsebool - 读取bool规则开关

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

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

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

    写在末尾:

    • 博客简介:专注AIoT领域,追逐未来时代的脉搏,记录路途中的技术成长!
    • 专栏简介:从0到1掌握SELinux的使用。
    • 面向人群:嵌入式Linux软件工程师
    • 专栏计划:接下来会逐步发布跨入人工智能的系列博文,敬请期待

  • 相关阅读:
    Vue-依赖注入(provide-inject)
    自动化测试selenium篇
    技巧分享:wps文件怎么转换成word格式?
    无人机--行业生命周期分析
    第9章:React Hooks
    音频转文字怎么操作?快来看看这几个方法吧
    centos 部署 xray 漏洞扫描器
    集群路径规划学习(一)之EGO-swarm仿真
    JS-10-es6常用知识-对象扩展
    【踩坑专栏】多模块项目boot模块启动后web模块404
  • 原文地址:https://blog.csdn.net/RobotFutures/article/details/126184816