前言
隨著云計(jì)算的發(fā)展,Linux 發(fā)行版像 RHEL、Debian、Ubuntu、SUSE 開(kāi)始廣泛的被使用,在很多新上手的用戶(hù)可能會(huì)查看相關(guān)教程或者一鍵包,一般這些教程、一鍵包的開(kāi)頭第一件事情可能是升級(jí)軟件,第二件事情就可能是關(guān)閉 SELinux 或 AppArmor,那這兩個(gè)軟件是不是真的就那么影響系統(tǒng)使用嗎?這兩個(gè)軟件有什么用?
先說(shuō)是不是
SELinux 即 Security Enhanced Linux,是由美國(guó)國(guó)家安全局(NSA)設(shè)計(jì)出來(lái)的一個(gè)靈活的強(qiáng)制訪(fǎng)問(wèn)控制系統(tǒng),來(lái)限制標(biāo)準(zhǔn)的權(quán)限之外的種種權(quán)限,在仍然允許對(duì)這個(gè)控制模型后續(xù)修改的情況下,讓進(jìn)程盡可能以最小權(quán)限訪(fǎng)問(wèn)或在系統(tǒng)對(duì)象(如文件,文件夾,網(wǎng)絡(luò)端口等)上執(zhí)行其他操作。
簡(jiǎn)而言之就是 SELinux 相對(duì)于一鍵包、教程來(lái)說(shuō)“太過(guò)于安全”而不是和新手,新手對(duì) Linux 的使用并不穩(wěn)定,網(wǎng)站建設(shè)也不穩(wěn)定,如果使用了 SElinux 限制權(quán)限反而可能導(dǎo)致新手遇到權(quán)限不夠的問(wèn)題,比如說(shuō) 監(jiān)聽(tīng)不到 mysqld.sock 導(dǎo)致 phpMyAdmin 默認(rèn)配置下無(wú)法登入這樣的尷尬,又或者說(shuō) 監(jiān)聽(tīng)不到php.sock 導(dǎo)致 Nginx 無(wú)法反代 unix socket 模式的 PHP-FPM。
SELinux 在 RHEL 及其社區(qū)版 CentOS 上有著非常的應(yīng)用,而在 Ubuntu 和 Debian 上,AppArmor 也有著非常好的支持,特別是 Ubuntu Server 上。
AppArmor (Application Armor) 是一個(gè)類(lèi)似于 SELinux 的一個(gè)強(qiáng)制訪(fǎng)問(wèn)控制方法,通過(guò)它你可以指定程序可以讀、寫(xiě)或運(yùn)行哪些文件,是否可以打開(kāi)網(wǎng)絡(luò)端口等。AppArmor 配置比 SELinux 更加方便比較適合學(xué)習(xí)。
介紹
Apparmor 有兩種工作模式:Complain(抱怨)和Enforcement(強(qiáng)制)
Complain– 即抱怨模式,在這種模式下,配置文件中的限制規(guī)則并不執(zhí)行,僅僅對(duì)程序的行為進(jìn)行記錄,所以抱怨還是很貼切的。
Enforcement– 即強(qiáng)制模式,顧名思義在這種模式下,配置文件中的限制規(guī)則會(huì)執(zhí)行,并且對(duì)違反限制規(guī)則的軟件行為進(jìn)行記錄。
那 Complain 既然不能限制程序,那為什么還需要這種模式呢? 因?yàn)椤绻硞€(gè)程序的行為不符合其配置文件的限制,可以將其行為記錄到系統(tǒng)日志,就可以根據(jù)日志轉(zhuǎn)換成配置文件,因此 Complain 在一些地方也被稱(chēng)為Complain/Learning模式
教程
OpenResty 篇
這里將以 Ubuntu Server 16.04 LTS 并使用 OpenResty 為例,在過(guò)程中介紹 AppArmor 的一些使用細(xì)節(jié)和方法。
下面使用的是 OpenResty 官方提供的二進(jìn)制軟件包,編譯教程可以查看:Ubuntu 編譯安裝 OpenResty 及拓展支持
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
sudo apt-get -y install software-properties-common
add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
sudo apt-get update
sudo apt-get install openresty
配置目錄
一、創(chuàng)建演示用目錄
sudo mkdir -p /data/wwwroot/safe
sudo mkdir -p /data/wwwroot/unsafe
[font=-apple-system, system-ui, "]二、創(chuàng)建演示文件
cat >> /data/wwwroot/safe/index.html <
Safe 文件
該文件允許被訪(fǎng)問(wèn)
EOF
cat >> /data/wwwroot/unsafe/index.html <
Unsafe 文件
該文件不允許被訪(fǎng)問(wèn)
EOF
修改 nginx.conf
編輯 /usr/local/openresty/nginx/conf/nginx.conf 文件,在末尾 } 前添加:
server {
listen 8080;
server_name??_;
location / {
root /data/wwwroot;
}
}
[font=-apple-system, system-ui, "]保存后,重新 OpenResty:
systemctl restart openresty
[font=-apple-system, system-ui, "]訪(fǎng)問(wèn)http://yourdomain/safe/[font=-apple-system, system-ui, "] 和http://yourdomain/unsafe/[font=-apple-system, system-ui, "] 就可以看到結(jié)果頁(yè),目前兩個(gè)頁(yè)面均可以訪(fǎng)問(wèn)。
AppArmor 篇
安裝 AppArmor
sudo apt-get install apparmor-profiles apparmor-utils
創(chuàng)建配置文件, 使用 aa-autodep 命令創(chuàng)建 OpenResty 的空白配置文件:
引用
cd /etc/apparmor.d/
sudo aa-autodep openresty
切換為 Complain 模式,使用 aa-complain 命令:
sudo aa-complain openresty
重啟 Openresty
sudo systemctl restart openresty
配置規(guī)則
訪(fǎng)問(wèn)網(wǎng)頁(yè),訪(fǎng)問(wèn)http://yourdomain/safe/和http://yourdomain/unsafe/來(lái)觸發(fā)軟件記錄相關(guān)日志。
配置規(guī)則,運(yùn)行 sudo aa-logprof 通過(guò)日志的記錄來(lái)獲得日志,例如:
Profile:????????/usr/local/openresty/nginx/sbin/nginx
Network Family: inet
Socket Type:????stream
[1 - #include ]
2 - #include
3 - #include
4 - #include
5 - network inet stream,
(A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish
Adding #include to profile.
看到相關(guān)提示,一般來(lái)說(shuō)走 A 即 Allow 同意就可以走全程了,不過(guò)要讓 unsafe 目錄無(wú)法被訪(fǎng)問(wèn),所以 unsafe 目錄需要 D 即 Deny全部過(guò)了以后查看 /etc/apparmor.d/usr.local.openresty.nginx.sbin.nginx 內(nèi)容:
root@www.mf8.biz:~# cat /etc/apparmor.d/usr.local.openresty.nginx.sbin.nginx
# Last Modified: Sat Jul 15 15:36:02 2017
# From www.mf8.biz
#include
/usr/local/openresty/nginx/sbin/nginx flags=(complain) {
#include
#include
/data/wwwroot/safe/* r,
deny /data/wwwroot/unsafe/* r,
/usr/local/openresty/luajit/lib/libluajit-5.1.so.* r,
/usr/local/openresty/nginx/conf/mime.types r,
/usr/local/openresty/nginx/conf/nginx.conf r,
/usr/local/openresty/nginx/logs/error.log w,
/usr/local/openresty/nginx/sbin/nginx mr,
/usr/local/openresty/openssl/lib/libcrypto.so.* r,
/usr/local/openresty/openssl/lib/libssl.so.* r,
/usr/local/openresty/openssl/openssl.cnf r,
/usr/local/openresty/pcre/lib/libpcre.so.* r,
/usr/local/openresty/zlib/lib/libz.so.* r,
}
不過(guò)通過(guò)日志判斷的內(nèi)容還是不夠用的,我們還要繼續(xù)遇到錯(cuò)誤改正錯(cuò)誤。注:其實(shí) AppArmor 的 # 不一定是注釋?zhuān)纾?include 就是記載 abstractions/base 文件的規(guī)則。
切換為 Enforce 模式
sudo aa-enforce openresty
[font=-apple-system, system-ui, "]重啟使規(guī)則生效
sudo /etc/init.d/apparmor reload
sudo service openresty restart
[font=-apple-system, system-ui, "]哈哈,這時(shí)候可能會(huì)報(bào)錯(cuò),例如:
root@www.mf8.biz:~# systemctl restart??openresty
Job for openresty.service failed because the control process exited with error code. See "systemctl status openresty.service" and "journalctl -xe" for details.
那我們就需要來(lái)判斷是那里出錯(cuò)了,以 OpenResty 為例,可以查看錯(cuò)誤的地方有:
openresty -t 的錯(cuò)誤提示
/var/log/syslog 文件中的錯(cuò)誤日志
/nginx/logs/error.log 中的錯(cuò)誤日志
排錯(cuò),例如我的錯(cuò)誤是:
root@www.mf8.biz:~# openresty -t
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: [emerg] open() "/usr/local/openresty/nginx/logs/nginx.pid" failed (13: Permission denied)
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test failed
即 /usr/local/openresty/nginx/logs/nginx.pid 沒(méi)有權(quán)限,
那么編輯 /etc/apparmor.d/usr.local.openresty.nginx.sbin.nginx 文件,加入:
/usr/local/openresty/nginx/logs/error.log w,
繼續(xù)重啟 apparmor 和 openresty
sudo /etc/init.d/apparmor reload
sudo service openresty restart
還報(bào)錯(cuò):
root@www.mf8.biz:~# openresty -t
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: [emerg] open() "/usr/local/openresty/nginx/logs/access.log" failed (13: Permission denied)
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test failed
加入:
/usr/local/openresty/nginx/logs/access.log w,
重啟后,終于正常了,再訪(fǎng)問(wèn)http://yourdomain/safe/和http://yourdomain/unsafe/,發(fā)現(xiàn)http://yourdomain/unsafe/403 報(bào)錯(cuò)了,也就是無(wú)法訪(fǎng)問(wèn)了,很棒!
我的最終規(guī)則以供大家參考:
# Last Modified: Sat Jul 15 15:36:02 2017
# From www.mf8.biz
#include
/usr/local/openresty/nginx/sbin/nginx {
#include
#include
/data/wwwroot/safe/* r,
deny /data/wwwroot/unsafe/* r,
/usr/local/openresty/luajit/lib/libluajit-5.1.so.* r,
/usr/local/openresty/nginx/conf/mime.types r,
/usr/local/openresty/nginx/conf/nginx.conf r,
/usr/local/openresty/nginx/logs/error.log w,
/usr/local/openresty/nginx/sbin/nginx mr,
/usr/local/openresty/openssl/lib/libcrypto.so.* r,
/usr/local/openresty/openssl/lib/libssl.so.* r,
/usr/local/openresty/openssl/openssl.cnf r,
/usr/local/openresty/pcre/lib/libpcre.so.* r,
/usr/local/openresty/zlib/lib/libz.so.* r,
/usr/local/openresty/nginx/logs/nginx.pid rw,
/usr/local/openresty/nginx/logs/access.log w,
}
結(jié)語(yǔ)
AppArmor 配置 OpenResty 的教程就到這里結(jié)束了,AppArmor 的安全配置還是比較復(fù)雜的,因?yàn)椴煌?wù)器勢(shì)必用法不同,所以不可能千篇一律所以自己的服務(wù)器還是需要自己進(jìn)行針對(duì)性規(guī)則配置,而且往往越復(fù)雜,功能越多的服務(wù)配置規(guī)則越麻煩越容易出現(xiàn)小問(wèn)題。
一般來(lái)說(shuō),建議在 Complain 模式下積累個(gè)一星期的 “抱怨” 再做判斷可能會(huì)更好。當(dāng)然還需要多結(jié)合日志進(jìn)行管理。
再解釋一下權(quán)限的意思:
引用
r: 讀
w: 寫(xiě)
m: 存儲(chǔ)器映射,
k: 文件鎖定
l: 創(chuàng)建硬鏈接
ix: 執(zhí)行并繼承該安全配置
Px: 在清理環(huán)境之后,執(zhí)行并使用其他安全配置
Ux: 在清理環(huán)境之后,執(zhí)行不做限制