阿里云
服务器地域选择
发表主题 回复主题
  • 782阅读
  • 0回复

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

级别: 论坛版主
发帖
9211
云币
13341
— 本帖被 不靠谱贝贝 设置为精华(2017-09-18) —
' T]oV~H  
+QX>:z  
前言 @nu/0+8h{  
AX+d?M  
]aNnY?qW5  
随着云计算的发展,Linux 发行版像 RHEL、Debian、Ubuntu、SUSE 开始广泛的被使用,在很多新上手的用户可能会查看相关教程或者一键包,一般这些教程、一键包的开头第一件事情可能是升级软件,第二件事情就可能是关闭 SELinux 或 AppArmor,那这两个软件是不是真的就那么影响系统使用吗?这两个软件有什么用? sd53 _s V  
sFK<:ka  
先说是不是 4Z }{hc\J  
5>)jNtZ  
T;@>O^  
SELinux 即 Security Enhanced Linux,是由美国国家安全局(NSA)设计出来的一个灵活的强制访问控制系统,来限制标准的权限之外的种种权限,在仍然允许对这个控制模型后续修改的情况下,让进程尽可能以最小权限访问或在系统对象(如文件,文件夹,网络端口等)上执行其他操作。
LltguNM$  
简而言之就是 SELinux 相对于一键包、教程来说 “太过于安全” 而不是和新手,新手对 Linux 的使用并不稳定,网站建设也不稳定,如果使用了 SElinux 限制权限反而可能导致新手遇到权限不够的问题,比如说 监听不到 mysqld.sock 导致 phpMyAdmin 默认配置下无法登入这样的尴尬,又或者说 监听不到 php.sock 导致 Nginx 无法反代 unix socket 模式的 PHP-FPM。 \BXVWE|  
SELinux 在 RHEL 及其社区版 CentOS 上有着非常的应用,而在 Ubuntu 和 Debian 上,AppArmor 也有着非常好的支持,特别是 Ubuntu Server 上。
)/"7$2Aoy  
AppArmor (Application Armor) 是一个类似于 SELinux 的一个强制访问控制方法,通过它你可以指定程序可以读、写或运行哪些文件,是否可以打开网络端口等。AppArmor 配置比 SELinux 更加方便比较适合学习。
aUK4{F ;  
I})t  
介绍 \F~Cbj+'Nu  
RFY!o<   
+o]BjgG  
Apparmor 有两种工作模式:Complain (抱怨)和 Enforcement (强制) CDnz &?  
Complain – 即抱怨模式,在这种模式下,配置文件中的限制规则并不执行,仅仅对程序的行为进行记录,所以抱怨还是很贴切的。 gqRTv_;  
Enforcement – 即强制模式,顾名思义在这种模式下,配置文件中的限制规则会执行,并且对违反限制规则的软件行为进行记录。 493i*j5r)l  
那 Complain 既然不能限制程序,那为什么还需要这种模式? 因为——如果某个程序的行为不符合其配置文件的限制,可以将其行为记录到系统日志,就可以根据日志转换成配置文件,因此 Complain 在一些地方也被称为 Complain/Learning 模式 y PYJc  
MdZgS#`  
教程 SzX~;pFM0  
"H<#91^|  
OpenResty 篇 ?3TV:fx"X  
*)1Vs'!-  
这里将以 Ubuntu Server 16.04 LTS 并使用 OpenResty 为例,在过程中介绍 AppArmor 的一些使用细节和方法。 siYRRr  
下面使用的是 OpenResty 官方提供的二进制软件包,编译教程可以查看:Ubuntu 编译安装 OpenResty 及拓展支持 ^!o}>ls['  
FK# E7 K  
  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
D1~x  
PMhhPw]  
 x9"4vp  
配置目录 V9u\;5oL  
,Bw)n,  
`(/saq*  
一、创建演示用目录 6F.7Ws <  
  1. sudo mkdir -p /data/wwwroot/safe
  2. sudo mkdir -p /data/wwwroot/unsafe
[font=-apple-system, system-ui, &quot]二、创建演示文件 wZ8 MhE  
_iJXp0g  
ikN!ut  
  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
=yX&p:-&  
zX [ r  
修改 nginx.conf s^YTI\L \  
编辑 /usr/local/openresty/nginx/conf/nginx.conf 文件,在末尾 } 前添加: a`b zFu{  
  1. server {
  2.         listen 8080;
  3.         server_name  _;
  4.         location / {
  5.             root /data/wwwroot;
  6.         }
  7.     }
|W*@}D  
[font=-apple-system, system-ui, &quot]保存后,重新 OpenResty: 6$s0-{^  
  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] 就可以看到结果页,目前两个页面均可以访问。 G yAgPz  
B$TChc3B  
X";Z Up  
M&/aJRBS  
$dh4T";  
T<+ht8&M8  
AppArmor 篇 !@<@QG-  
xDGS`U  
g:DTVq  
安装 AppArmor =v4r M0m,  
  1. sudo apt-get install apparmor-profiles apparmor-utils
创建配置文件 , 使用 aa-autodep 命令创建 OpenResty 的空白配置文件: 1%spzkE 3P  
引用
cd /etc/apparmor.d/ qwF*(pTHq  
sudo aa-autodep openresty
jc&/}o$K  
切换为 Complain 模式 ,使用 aa-complain 命令: 7AO3-; l]  
  1. sudo aa-complain openresty
重启 Openresty
  1. sudo systemctl restart openresty
hB7pR"P  
l{6` k<J(  
配置规则 Yn4)Zhkk  
_+\:OB[Y  
lH)em.#  
访问网页 ,访问 http://yourdomain/safe/http://yourdomain/unsafe/ 来触发软件记录相关日志。 UOWIiu  
配置规则 ,运行 sudo aa-logprof 通过日志的记录来获得日志,例如: +~ 3w5.8  
  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.
Du^x=;  
看到相关提示,一般来说走 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. }
VX;zZ`BJ  
不过通过日志判断的内容还是不够用的,我们还要继续遇到错误改正错误。注: 其实 AppArmor 的 # 不一定是注释,例如:#include <abstractions/base> 就是记载 abstractions/base 文件的规则。 B6ed,($&  
切换为 Enforce 模式
  1. sudo aa-enforce openresty
[font=-apple-system, system-ui, &quot]重启使规则生效 ESD<8 OR  
  1. sudo /etc/init.d/apparmor reload
  2. sudo service openresty restart
[font=-apple-system, system-ui, &quot]哈哈,这时候可能会报错,例如: @P_C%}(<  
#d Z/UM(u  
xvR?~  
  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.
< TR/ `  
那我们就需要来判断是那里出错了,以 OpenResty 为例,可以查看错误的地方有:
  1. openresty -t 的错误提示
  2. /var/log/syslog 文件中的错误日志
  3. /nginx/logs/error.log 中的错误日志
7|QGY7Tf  
排错 ,例如我的错误是: qRPc %"  
  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
j|[(*i%7|  
即 /usr/local/openresty/nginx/logs/nginx.pid 没有权限, 2cCWQ"_,  
那么编辑 /etc/apparmor.d/usr.local.openresty.nginx.sbin.nginx 文件,加入: .-SF$U_P*a  
  1. /usr/local/openresty/nginx/logs/error.log w,
继续重启 apparmor 和 openresty .pM &jni Y  
  1. sudo /etc/init.d/apparmor reload
  2. sudo service openresty restart
还报错: R:w %2Y  
fJLf7+q  
  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
加入: u0XP(d H  
  1. /usr/local/openresty/nginx/logs/access.log w,
重启后,终于正常了,再访问 http://yourdomain/safe/http://yourdomain/unsafe/,发现 http://yourdomain/unsafe/ 403 报错了,也就是无法访问了,很棒! XogvtK*  
2{t)DUs  
D =r-  
我的最终规则以供大家参考: T?X^0UdJj  
  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. }
CAUijMI@  
~`t%M?l  
结语 m|]j'g?{}(  
>Hi h  
i8Fs0U4"  
AppArmor 配置 OpenResty 的教程就到这里结束了,AppArmor 的安全配置还是比较复杂的,因为不同服务势必用法不同,所以不可能千篇一律所以己的服务器还是需要自己进行针对性规则配置,而且往往越复杂,功能越多的服务配置规则越麻烦越容易出现小问题。 #)GW}U]X  
一般来说,建议在 Complain 模式下积累个一星期的 “抱怨” 再做判断可能会更好。当然还需要多结合日志进行管理。 s$DGd T)  
再解释一下权限的意思: ?k{|Lk  
引用
r: 读 2)wAFO6u  
w: 写 /Q?~Q0{)es  
m: 存储器映射, Dd| "iA  
k: 文件锁定 0iYP  
l: 创建硬链接 U;\S(s}  
ix: 执行并继承该安全配置 tM&n3MWQ  
Px: 在清理环境之后,执行并使用其他安全配置 $^}[g9]1  
Ux: 在清理环境之后,执行不做限制
yeh8z:5Z O  
sN m,Fmuz:  
i90}Xyt  
发表主题 回复主题
« 返回列表上一主题下一主题

限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
验证问题: ECS是阿里云提供的什么服务? 正确答案:云服务器
上一个 下一个