在 Ubuntu 上配置 AppArmor 实现强制访问控制(MAC)

前言  
 
 
随着云计算的发展,Linux 发行版像 RHEL、Debian、Ubuntu、SUSE 开始广泛的被使用,在很多新上手的用户可能会查看相关教程或者一键包,一般这些教程、一键包的开头第一件事情可能是升级软件,第二件事情就可能是关闭 SELinux 或 AppArmor,那这两个软件是不是真的就那么影响 系统 使用吗?这两个软件有什么用?  
 
先说是不是  
 
 
SELinux 即 Security Enhanced Linux,是由美国国家安全局(NSA)设计出来的一个灵活的强制访问控制系统,来限制标准的权限之外的种种权限,在仍然允许对这个控制模型后续修改的情况下,让进程尽可能以最小权限访问或在系统对象(如文件,文件夹,网络端口等)上执行其他操作。
 
简而言之就是 SELinux 相对于一键包、教程来说  “太过于安全”  而不是和新手,新手对 Linux 的使用并不稳定, 网站 建设也不稳定,如果使用了 SElinux 限制权限反而可能导致新手遇到权限不够的 问题 ,比如说 监听不到 mysqld.sock 导致 phpMyAdmin 默认 配置 下无法登入这样的尴尬,又或者说 监听不到  php .sock 导致 Nginx 无法反代 unix socket 模式的 PHP-FPM。  
SELinux 在 RHEL 及其社区版 CentOS 上有着非常的应用,而在 Ubuntu 和 Debian 上,AppArmor 也有着非常好的支持,特别是 Ubuntu Server 上。
 
AppArmor (Application Armor) 是一个类似于 SELinux 的一个强制访问控制方法,通过它你可以指定程序可以读、写或运行哪些文件,是否可以打开网络端口等。AppArmor 配置比 SELinux 更加方便比较适合学习。
 
 
介绍  
 
 
Apparmor 有两种工作模式: Complain  (抱怨)和  Enforcement  (强制)  
Complain  – 即抱怨模式,在这种模式下,配置文件中的限制规则并不执行,仅仅对程序的行为进行记录,所以抱怨还是很贴切的。  
Enforcement  – 即强制模式,顾名思义在这种模式下,配置文件中的限制规则会执行,并且对违反限制规则的软件行为进行记录。  
那 Complain 既然不能限制程序,那为什么还需要这种模式 ? 因为——如果某个程序的行为不符合其配置文件的限制,可以将其行为记录到系统日志,就可以根据日志转换成配置文件,因此 Complain 在一些地方也被称为  Complain/Learning  模式  
 
教程  
 
OpenResty 篇  
 
这里将以 Ubuntu Server 16.04 LTS 并使用 OpenResty 为例,在过程中介绍 AppArmor 的一些使用细节和方法。  
下面使用的是 OpenResty 官方提供的二进制软件包,编译教程可以查看: Ubuntu 编译安装 OpenResty 及拓展支持    
 
  1. wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
  2. sudo apt-get -y install software-properties-common
  3. add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
  4. sudo apt-get update
  5. sudo apt-get install openresty
 
 
 
配置目录  
 
 
一、创建演示用目录  
  1. sudo mkdir -p /data/wwwroot/safe
  2. sudo mkdir -p /data/wwwroot/unsafe
[font=-apple-system, system-ui, &quot]二、创建演示文件  
 
 
  1. cat >> /data/wwwroot/safe/index.html <<EOF
  2. <!doctype html>
  3. <html>
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Safe 文件</title>
  7. </head>
  8. <body>
  9.     <b>该文件允许被访问</b>
  10. </body>
  11. </html>
  12. EOF
  1. cat >> /data/wwwroot/unsafe/index.html <<EOF
  2. <!doctype html>
  3. <html>
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Unsafe 文件</title>
  7. </head>
  8. <body>
  9.     <b>该文件不允许被访问</b>
  10. </body>
  11. </html>
  12. EOF
 
 
修改 nginx.conf  
编辑 /usr/local/openresty/nginx/conf/nginx.conf 文件,在末尾 } 前添加:  
  1. server {
  2.         listen 8080;
  3.         server_name  _;
  4.         location / {
  5.             root /data/wwwroot;
  6.         }
  7.     }
 
[font=-apple-system, system-ui, &quot]保存后,重新 OpenResty:  
  1. systemctl restart openresty
[font=-apple-system, system-ui, &quot]访问  http://yourdomain/safe/ [font=-apple-system, system-ui, &quot] 和  http://yourdomain/unsafe/ [font=-apple-system, system-ui, &quot] 就可以看到结果页,目前两个页面均可以访问。  
 
 
 
 
 
AppArmor 篇  
 
 
安装 AppArmor  
  1. sudo apt-get install apparmor-profiles apparmor-utils
创建配置文件  , 使用 aa-autodep 命令创建 OpenResty 的空白配置文件:  
引用
cd /etc/apparmor.d/ 
sudo aa-autodep openresty
 
切换为 Complain 模式  ,使用 aa-complain 命令:  
  1. sudo aa-complain openresty
重启 Openresty
  1. sudo systemctl restart openresty
 
 
配置规则  
 
 
访问网页  ,访问  http://yourdomain/safe/  和  http://yourdomain/unsafe/  来触发软件记录相关日志。  
配置规则  ,运行 sudo aa-logprof 通过日志的记录来获得日志,例如:  
  1. Profile:        /usr/local/openresty/nginx/sbin/nginx
  2. Network Family: inet
  3. Socket Type:    stream
  4. [1 - #include <abstractions/apache2-common>]
  5.   2 - #include <abstractions/lxc/container-base>
  6.   3 - #include <abstractions/lxc/start-container>
  7.   4 - #include <abstractions/nameservice>
  8.   5 - network inet stream,
  9. (A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish
  10. Adding #include <abstractions/apache2-common> to profile.
 
看到相关提示,一般来说走 A 即 Allow 同意就可以走全程了,不过要让 unsafe 目录无法被访问,所以 unsafe 目录需要 D 即 Deny全部过了以后查看 /etc/apparmor.d/usr.local.openresty.nginx.sbin.nginx 内容:
  1. root@www.mf8.biz:~# cat /etc/apparmor.d/usr.local.openresty.nginx.sbin.nginx
  2. # Last Modified: Sat Jul 15 15:36:02 2017
  3. # From www.mf8.biz
  4. #include <tunables/global>
  5. /usr/local/openresty/nginx/sbin/nginx flags=(complain) {
  6.   #include <abstractions/apache2-common>
  7.   #include <abstractions/base>
  8.   /data/wwwroot/safe/* r,
  9.   deny /data/wwwroot/unsafe/* r,
  10.   /usr/local/openresty/luajit/lib/libluajit-5.1.so.* r,
  11.   /usr/local/openresty/nginx/conf/mime.types r,
  12.   /usr/local/openresty/nginx/conf/nginx.conf r,
  13.   /usr/local/openresty/nginx/logs/error.log w,
  14.   /usr/local/openresty/nginx/sbin/nginx mr,
  15.   /usr/local/openresty/openssl/lib/libcrypto.so.* r,
  16.   /usr/local/openresty/openssl/lib/libssl.so.* r,
  17.   /usr/local/openresty/openssl/openssl.cnf r,
  18.   /usr/local/openresty/pcre/lib/libpcre.so.* r,
  19.   /usr/local/openresty/zlib/lib/libz.so.* r,
  20. }
 
不过通过日志判断的内容还是不够用的,我们还要继续遇到 错误 改正错误。 注:  其实 AppArmor 的 # 不一定是注释,例如:#include <abstractions/base> 就是记载 abstractions/base 文件的规则。  
切换为 Enforce 模式
  1. sudo aa-enforce openresty
[font=-apple-system, system-ui, &quot]重启使规则生效  
  1. sudo /etc/init.d/apparmor reload
  2. sudo service openresty restart
[font=-apple-system, system-ui, &quot]哈哈,这时候可能会报错,例如:  
 
 
  1. root@www.mf8.biz:~# systemctl restart  openresty
  2. Job for openresty.service failed because the control process exited with error code. See "systemctl status openresty.service" and "journalctl -xe" for details.
 
那我们就需要来判断是那里出错了,以 OpenResty 为例,可以查看错误的地方有:
  1. openresty -t 的错误提示
  2. /var/log/syslog 文件中的错误日志
  3. /nginx/logs/error.log 中的错误日志
 
排错  ,例如我的错误是:  
  1. root@www.mf8.biz:~# openresty -t
  2. nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
  3. nginx: [emerg] open() "/usr/local/openresty/nginx/logs/nginx.pid" failed (13: Permission denied)
  4. nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test failed
 
即 /usr/local/openresty/nginx/logs/nginx.pid 没有权限,  
那么编辑 /etc/apparmor.d/usr.local.openresty.nginx.sbin.nginx 文件,加入:  
  1. /usr/local/openresty/nginx/logs/error.log w,
继续重启 apparmor 和 openresty  
  1. sudo /etc/init.d/apparmor reload
  2. sudo service openresty restart
还报错:  
 
  1. root@www.mf8.biz:~# openresty -t
  2. nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
  3. nginx: [emerg] open() "/usr/local/openresty/nginx/logs/access.log" failed (13: Permission denied)
  4. nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test failed
加入:  
  1. /usr/local/openresty/nginx/logs/access.log w,
重启后,终于正常了,再访问  http://yourdomain/safe/  和  http://yourdomain/unsafe/ ,发现  http://yourdomain/unsafe/  403 报错了,也就是无法访问了,很棒!  
 
 
我的最终规则以供大家参考:  
  1. # Last Modified: Sat Jul 15 15:36:02 2017
  2. # From www.mf8.biz
  3. #include <tunables/global>
  4. /usr/local/openresty/nginx/sbin/nginx {
  5.   #include <abstractions/apache2-common>
  6.   #include <abstractions/base>
  7.   /data/wwwroot/safe/* r,
  8.   deny /data/wwwroot/unsafe/* r,
  9.   /usr/local/openresty/luajit/lib/libluajit-5.1.so.* r,
  10.   /usr/local/openresty/nginx/conf/mime.types r,
  11.   /usr/local/openresty/nginx/conf/nginx.conf r,
  12.   /usr/local/openresty/nginx/logs/error.log w,
  13.   /usr/local/openresty/nginx/sbin/nginx mr,
  14.   /usr/local/openresty/openssl/lib/libcrypto.so.* r,
  15.   /usr/local/openresty/openssl/lib/libssl.so.* r,
  16.   /usr/local/openresty/openssl/openssl.cnf r,
  17.   /usr/local/openresty/pcre/lib/libpcre.so.* r,
  18.   /usr/local/openresty/zlib/lib/libz.so.* r,
  19.   /usr/local/openresty/nginx/logs/nginx.pid rw,
  20.   /usr/local/openresty/nginx/logs/access.log w,
  21. }
 
 
结语  
 
 
AppArmor 配置 OpenResty 的教程就到这里结束了,AppArmor 的安全配置还是比较复杂的,因为不同 服务 势必用法不同,所以不可能千篇一律所以 己的服务器还是需要自己进行针对性规则配置,而且往往越复杂,功能越多的服务配置规则越麻烦越容易出现小问题。  
一般来说,建议在 Complain 模式下积累个一星期的 “抱怨” 再做判断可能会更好。当然还需要多结合日志进行管理。  
再解释一下权限的意思:  
引用
r: 读 
w: 写 
m: 存储器映射, 
k: 文件锁定 
l: 创建硬链接 
ix: 执行并继承该安全配置 
Px: 在清理环境之后,执行并使用其他安全配置 

Ux: 在清理环境之后,执行不做限制

原文链接

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值