在 Ubuntu 上配置 AppArmor 實(shí)現(xiàn)強(qiáng)制訪(fǎng)問(wèn)控制(MAC)

前言

隨著云計(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 及拓展支持

復(fù)制代碼

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)建演示用目錄

復(fù)制代碼

sudo mkdir -p /data/wwwroot/safe

sudo mkdir -p /data/wwwroot/unsafe

[font=-apple-system, system-ui, "]二、創(chuàng)建演示文件

復(fù)制代碼

cat >> /data/wwwroot/safe/index.html <

Safe 文件

該文件允許被訪(fǎng)問(wèn)

EOF

復(fù)制代碼

cat >> /data/wwwroot/unsafe/index.html <

Unsafe 文件

該文件不允許被訪(fǎng)問(wèn)

EOF

修改 nginx.conf

編輯 /usr/local/openresty/nginx/conf/nginx.conf 文件,在末尾 } 前添加:

復(fù)制代碼

server {

listen 8080;

server_name??_;

location / {

root /data/wwwroot;

}

}

[font=-apple-system, system-ui, "]保存后,重新 OpenResty:

復(fù)制代碼

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

復(fù)制代碼

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 命令:

復(fù)制代碼

sudo aa-complain openresty

重啟 Openresty

復(fù)制代碼

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)獲得日志,例如:

復(fù)制代碼

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)容:

復(fù)制代碼

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 模式

復(fù)制代碼

sudo aa-enforce openresty

[font=-apple-system, system-ui, "]重啟使規(guī)則生效

復(fù)制代碼

sudo /etc/init.d/apparmor reload

sudo service openresty restart

[font=-apple-system, system-ui, "]哈哈,這時(shí)候可能會(huì)報(bào)錯(cuò),例如:

復(fù)制代碼

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ò)誤是:

復(fù)制代碼

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 文件,加入:

復(fù)制代碼

/usr/local/openresty/nginx/logs/error.log w,

繼續(xù)重啟 apparmor 和 openresty

復(fù)制代碼

sudo /etc/init.d/apparmor reload

sudo service openresty restart

還報(bào)錯(cuò):

復(fù)制代碼

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

加入:

復(fù)制代碼

/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ī)則以供大家參考:

復(fù)制代碼

# 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í)行不做限制

原文鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容