Linux 中的安全子模块 SELinux 与防火墙

作者:Évariste Gao

防火墙 Firewall-cmd

CentOS7 以上的防火墙一般都是 firewall-cmdsystemctl 对应的服务名称为 firewalld

常见参数

参数 功能 示例
--state 查看 firewall-cmd 当前的状态
--add-port=xxx/yyy 打开 yyy 的 xxx 端口 , yyy 可选为 tpc/udp firewall-cmd --add-port=10000/tcp
--add-port=xxx/yyy 打开 yyy 的 xxx 端口 firewall-cmd --add-port=10000/tcp
--permanent 永久,否则 --reload 后修改就没了
--reload 重新加载
--list-all 列出已开放的端口
--list-all 列出已开放的端口
--query-service xxx 查询目前是否支持 xxx 服务 firewall-cmd --query-service http
--add-service=xxx 增加对 xxx 服务的支持 --add-service=http

完整的文档可以参考这里

完整示例

开启 8090 端口供 nginx 使用.

# firewall-cmd --state 查看是否启动
# 如果未启动可以通过 sudo systemctl start firewalld 启动
$ sudo firewall-cmd --query-service http # 查询目前是否开启了支持 http 服务
$ sudo firewall-cmd --add-service=http # 若没有的话,增加
$ sudo firewall-cmd --list-all # 列出当前开放的所有端口
$ sudo firewall-cmd --add-port=8090/tcp # 若没有的话,增加

该示例是临时开放 8090 端口,如果要保证开机后启动或是 --reload 之后仍然生效,在添加服务和端口时使用 --permanent

SELinux

SELinux 的介绍

鸟哥
红帽
CentOS wiki

用法

主要参考这里,不过要注意的是在安装 semanage 的时候,该作者是 CentOS7 环境,安装的是 policycoreutils-python,而我是 CentOS8 环境,查阅后发现应该安装 python3-policycoreutils

Nginx 示例

作为静态网站,一般需要 SELinux 为其开放文件的权限以及端口的权限.
启动 nginx 时候可能发生的问题有很多,最好先排除一些问题,比如 nginx 的启动用户有没有权限访问 http 服务的根目录(就是 index.html 之类的),确定其他都没问题之后再来修改 SELinux 安全上下文

文件

nginx 默认的 html 入口在 /usr/share/nginx/html,一般是没有问题的,可以通过 ls -Z /usr/share/nginx/html 开查看其 SELinux 安全上下文,得到

$ ls -lZ /usr/share/nginx/html
total 24
-rw-r--r--. 1 root root system_u:object_r:httpd_sys_content_t:s0 3971 Oct  7 21:16 404.html
-rw-r--r--. 1 root root system_u:object_r:httpd_sys_content_t:s0 4020 Oct  7 21:16 50x.html
-rw-r--r--. 1 root root system_u:object_r:httpd_sys_content_t:s0 4057 Oct  7 21:16 index.html
-rw-r--r--. 1 root root system_u:object_r:httpd_sys_content_t:s0  368 Oct  7 21:16 nginx-logo.png
-rw-r--r--. 1 root root system_u:object_r:httpd_sys_content_t:s0 4148 Oct  7 21:16 poweredby.png

发现有一个 httpd_sys_content_t 字段,然后我们依葫芦画瓢就行了.

$ chcon -R -t httpd_sys_content_t /you/server/path/

端口

查询已开放的端口

$ sudo semanage port -l

增加端口作为 http 服务

$ sudo semanage port -a -t http_port_t -p tcp 8090

其他

  • 关闭 SELinux,将 /etc/selinux/config 中的 SELINUX=enforcing 改为 SELINUX=disabled,然后重启