爲了提高 Linux 系統的安全性,在 Linux 上通常會使用 SELinux 或 AppArmor 實現強制訪問控制(Mandatory Access Control MAC)。對於 MySQL 數據庫的強制訪問控制策略通常是激活的,如果用戶採用默認的配置,並不會感到強制訪問控制策略對 MySQL 數據庫的影響,一旦用戶修改了 MySQL 數據庫的默認配置,例如默認的數據目錄或監聽端口,MySQL 數據庫的活動就會被 SELinux 或 AppArmor 阻止,數據庫無法啓動,本文簡單介紹 SELinux 對 MySQL 數據庫的影響。
一、簡介
SELinux(Secure Enhanced Linux)是一個內核級的安全機制,從 2.6 內核之後,集成到 Linux 內核中。它允許管理員細粒度地定義訪問控制,未經定義的訪問一律禁止。
SELinux 有三種工作模式:
-
enforcing:強制模式。任何違反策略的行爲都會被禁止,並且產生警告信息。 -
permissive:允許模式。違反策略的行爲不會被禁止,只產生警告信息。 -
disabled:關閉 SELinux。
/etc/selinux/config
配置文件並設置 SELINUX 變量爲 enforcing、permissive 或 disabled,保存設置讓其重啓後也有效。
[root@redhat7 ~]# sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 28
二、查看 MySQL 的 SELinux 的上下文
可以使用 ps -Z
查看 mysqld 進程的 SELinux 的上下文:
[root@redhat7 ~]# ps -eZ | grep mysqld
system_u:system_r:mysqld_t:s0 2381 ? 00:01:00 mysqld
也可以使用 ls -Z
查看 MySQL 數據目錄的 SELinux 的上下文:
[root@redhat7 ~]# ls -dZ /var/lib/mysql
drwxr-x--x. mysql mysql system_u:object_r:mysqld_db_t:s0 /var/lib/mysql
參數說明:
system_u 是系統進程和對象的 SELinux 用戶標識。
system_r 是用於系統進程的 SELinux 角色。
objects_r 是用於系統對象的 SELinux 角色。
mysqld_t 是與 mysqld 進程相關的 SELinux 類型。
mysqld_db_t 是與 MySQL 數據目錄相關的 SELinux 類型。
三、修改對 MySQL 數據目錄的訪問控制
如果我們把 MySQL 數據目錄從默認的 /var/lib/mysql
改成其他目錄,SELinux 將會阻止 mysqld 進程訪問 MySQL 數據目錄,從而造成 MySQL 無法啓動,相關拒絕訪問的信息記錄在 /var/log/audit/audit.log
文件中:
[root@redhat7 ~]# grep mysql /var/log/audit/audit.log |grep denied
type=AVC msg=audit(1609212427.622:104): avc: denied { write } for pid=2218 comm="mysqld" name="data" dev="dm-0" ino=217976179 scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:object_r:default_t:s0 tclass=dir
type=AVC msg=audit(1609212427.627:105): avc: denied { write } for pid=2218 comm="mysqld" name="data" dev="dm-0" ino=217976179 scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:object_r:default_t:s0 tclass=dir
type=AVC msg=audit(1609212427.628:106): avc: denied { read write } for pid=2218 comm="mysqld" name="binlog.index" dev="dm-0" ino=202759631 scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:object_r:default_t:s0 tclass=file
我們可以 SELinux 關閉或改成允許模式後再啓動 MySQL 數據庫,但這種方法通常不推薦,因爲這樣會把所有的 SELinux 的安全策略都終止了,留下了安全隱患。專業的做法是把新的 MySQL 數據目錄增加到mysqld_db_t 這個 SELinux 類型中,例如使用 semanage fcontext
命令的 -a
選項增加一個目錄爲 /disk1/data
的 MySQL 數據目錄,然後使用命令 restorecon
恢復這個數據目錄對應的 SELinux 上下文,代碼如圖所示:
root@redhat7 ~]# semanage fcontext -a -t mysqld_db_t “/disk1/data(/.*)?”
root@redhat7 ~]# restorecon -Rv /disk1/data
然後可以用 semanage fcontext
命令的 -l
選項進行檢查,發現 mysqld_db_t 這個類型現在有兩條記錄,分別是系統默認的和剛纔增加的:
[root@redhat7 ~]# semanage fcontext -l|grep mysqld_db_t
/var/lib/mysql(/.*)? all files system_u:object_r:mysqld_db_t:s0
/disk1/data(/.*)? all files system_u:object_r:mysqld_db_t:s0
再啓動 mysqld 即可成功!
四、修改對 MySQL 其他對象的訪問控制
除了可以修改對 MySQL 數據目錄的訪問控制外,還可以採用類似的方法修改對其他 MySQL 對象的訪問控制,例如:控制 MySQL 的錯誤日誌的類型是 mysqld_log_t,採用下面的命令增加 MySQL 的錯誤日誌的記錄:
semanage fcontext -a -t mysqld_log_t "/path/to/my/custom/error.log"
restorecon -Rv /path/to/my/custom/error.log
控制 MySQL 的 PID 文件的類型是 mysqld_var_run_t,採用下面的命令增加 MySQL 的 PID 文件的記錄:
semanage fcontext -a -t mysqld_var_run_t "/path/to/my/custom/pidfile/directory/.*?"
restorecon -Rv /path/to/my/custom/pidfile/directory
控制 MySQL 的監聽端口的類型是 mysqld_port_t,採用下面的命令增加一個 3307 的監聽端口:
semanage port -a -t mysqld_port_t -p tcp 3307
文章推薦:
社區近期動態
本文分享自微信公衆號 - 愛可生開源社區(ActiontechOSS)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。