MySQL資料庫安全評估工具MySQL Database Security Assessment Tool MySAT執行多項測試以分析資料庫配置和安全策略。MySAT可以幫助評估並因此提高MySQL資料庫的安全性。MySAT是一個簡單的SQL腳本,它易於理解,易於維護。MySAT的結果是一份HTM ...
MySQL資料庫安全評估工具MySQL Database Security Assessment Tool
MySAT執行多項測試以分析資料庫配置和安全策略。MySAT可以幫助評估並因此提高MySQL資料庫的安全性。
MySAT是一個簡單的SQL腳本,它易於理解,易於維護。MySAT的結果是一份HTML格式的報告。
MySQL資料庫安全評估工具 https://github.com/meob/MySAT
MySAT在HTML中生成一個簡單明瞭的報告。MySAT報告包含3個部分:
安全檢查結果
配置摘要和細節
與GDPR文章和CIS基準以及CVE短名單的交叉引用
以下是mysql 8.0.33資料庫為例,容器實例名c2mysql
mysql docker容器內執行
複製SQL到容器內
docker cp mysat.80.sql c2mysql:/home
docker cp mysat.css c2mysql:/home
#進入容器
docker exec -it c2mysql /bin/bash
#執行生成檢測報告
mysql --user=root -pxxxxxxxxxxxx --skip-column-names -f < mysat.80.sql > MySAT.htm
#把結果導出
docker cp c2mysql:/home/MySAT.htm MySAT.htm
報告示例:
MySQL加固
MySQL所使用的 SQL 語言是用於訪問資料庫的最常用標準化語言。MySQL 軟體採用了雙授權政策,分為社區版和商業版,由於其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,一般中小型網站的開發都選擇 MySQL 作為網站資料庫。
mysql目錄結構
配置文件,也就是尾碼為.cnf
的文件,大家自己看看文件內容就知道每個文件的作用了。
我們來看mysql的幫助信息,裡面有一條指明瞭mysql的配置文件是哪個,然後根據我們的情況就可以確定,mysql配置文件為/etc/mysql/my.cnf
,因為其它兩個文件不存在。
root@NF:~# mysql --help |grep -A 1 'Default options'
Default options are read from the following files in the given order:
/etc/my.cnf etc/mysql/my.cnf ~/.my.cnf
那我們查看一下/etc/mysql/my.cnf
文件的內容(跟/etc/mysql/mysql.cnf
內容一樣)主要有下麵這些信息,也說明瞭/etc/mysql/my.cnf
是全局配置,~/.my.cnf
(隱藏文件本環境下無此文件)是個人用戶設置。
# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
!includedir /etc/mysql/conf.d/
#表示包含/etc/mysql/conf.d/這個路徑下麵的配置文件,前提是必須以為.cnf為尾碼
!includedir /etc/mysql/mysql.conf.d/
#表示包含/etc/mysql/mysql.conf.d/這個路徑下麵的配置文件,前提是必須以為.cnf為尾碼
然後我們看/etc/mysql/mysql.conf.d/mysql.conf.d,這個文件裡面提供了mysql常用的基本配置。
那我們在此文件編輯mysql的配置,發現是可以失效的,它包含於/etc/mysql/my.cnf文件,所以編輯mysql配置的時候就編輯/etc/mysql/mysql.conf.d/mysql.conf.d文件即可。
其它的相關文件,其實就是理解linux各個主要目錄是什麼作用的。
/usr/lib/mysql # 動態庫文件(.so文件,so=shared object)
/usr/bin/mysql # mysql命令,安裝的軟體的命令,usr指Unix System Resource
/usr/share/mysql # mysql共用數據,主要是一些幫助文檔
/etc/mysql # mysql配置文件目錄
/etc/init.d/mysql # 服務管理腳本(啟動,停止,關閉等)
/var/lib/mysql # 預設的數據文檔存儲目錄
/var/log/mysql # mysql日誌文件(查詢語句記錄,報錯日誌,慢查詢日誌等)
00 關註官方安全更新公告
在不影響業務正常運行的情況下,及時更新軟體,打補丁。
https://www.oracle.com/security-alerts/
01 禁止資料庫用戶的密碼為空並設置密碼有效期
執行如下執行SQL語句檢查密碼是否為空:
select user,host from mysql.user where length(authentication_string) = 0;
或
select user,host,authentication_string,password_lifetime,account_locked from mysql.user;
若存在空密碼的資料庫用戶,則執行如下命令設置資料庫用戶密碼,且密碼必須滿足密碼策略的要求:
set password for 'user'@'host' = password('yourpassword');
set password for 'testtest'@'192.168.56.1' = password('testtest');
另外還要註意:
禁用或限制匿名、預設賬戶、測試賬戶的訪問許可權;(禁用賬戶)
應重命名或刪除預設賬戶,修改預設賬戶的預設口令;
應及時刪除或停用多餘的、過期的賬戶,避免共用賬戶的存在;
刪除了預設資料庫TEST。(舊版本會有預設的測試資料庫)
禁用資料庫用戶的語句
ALTER USER 'user'@'host' ACCOUNT LOCK;
查看密碼有效期(全局變數)
mysql> show global variables like 'default_password_lifetime';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| default_password_lifetime | 0 |
+---------------------------+-------+
1 row in set (0.00 sec)
配置密碼有效期全局變數,編輯mysql配置文件,添加下麵內容。
default_password_lifetime = 180
配置某個用戶的密碼有效期,使用ALTER USER命令為每個具體的用戶賬戶單獨設置特定的值,它會自動覆蓋密碼過期的全局策略。要註意ALTER USER語句的INTERVAL的單位是“天”。
ALTER USER 'root'@'localhost' PASSWORD EXPIRE INTERVAL 180 DAY;
02 檢查資料庫用戶的密碼是否為弱口令
有些人為了方便,可能會把資料庫用戶的密碼設置為弱口令,現在的資料庫會以mysql5加密演算法加密口令,可以去MD5解密的平臺輸入密文,看能否得出明文。
https://www.cmd5.com/
https://www.somd5.com/
如果是弱口令,則要求更改其資料庫用戶的口令。
關於MySQL密碼你應該知道的那些事 - cenalulu
MySQL:密碼加密方式 - xuejianbest
03 密碼複雜度配置
在資料庫配置文件/etc/mysql/mysql.conf.d/mysqld.cnf中添加如下配置(根據自身業務需要設置密碼複雜度策略)
[mysqld]
plugin-load = "validate_password.so"
validate-password = FORCE_PLUS_PERMANENT
validate_password_length = 8
validate_password_policy = 1
validate_password_mixed_case_count = 1
validate_password_number_count = 1
validate_password_special_char_count = 1
validate-password = FORCE_PLUS_PERMANENT
值為FORCE_PLUS_PERMANENT
表示強制啟用該插件,並且不能被卸載。
validate_password_policy
表示密碼策略,有三個值,與其對應的策略見下表:
值
密碼策略
0 或 LOW
校驗密碼長度變數
1 或 MEDIUM
校驗密碼長度、數字、小寫/大寫和特殊字元4個變數
2 或 STRONG
校驗密碼長度、數字、小寫/大寫、特殊字元和字典文件5個變數
簡言之,對於密碼數字、小寫/大寫和特殊字元這三個變數,只有當密碼策略為中或強時才是有效的。
其它參數含義見下麵的引用文章。
那麼最低要求配置如下
效果:密碼不能與用戶名一致,密碼長度8位以上(包含8位)、至少有一個數字、一個大寫字母、一個小寫字母、一個特殊字元。
mysql> show variables like '%validate_password%';
+--------------------------------------+--------+
| Variable_name | Value |
+--------------------------------------+--------+
| validate_password_check_user_name | OFF |
| validate_password_dictionary_file | |
| validate_password_length | 8 |
| validate_password_mixed_case_count | 1 |
| validate_password_number_count | 1 |
| validate_password_policy | MEDIUM |
| validate_password_special_char_count | 1 |
+--------------------------------------+--------+
7 rows in set (0.00 sec)
安裝和卸載插件
validate_password插件相關參數的介紹
MySql5.6使用validate password 插件加強密碼強度的安裝及使用方法 - wangmm0218
04 登錄失敗和連接超時設置
mysql有個連接超時的插件,相當於登錄失敗鎖定策略,可根據業務需要進行最低配置。
預設配置如下:
mysql> show variables like "%connection_control%";
+-------------------------------------------------+-------+
| Variable_name | Value |
+-------------------------------------------------+-------+
| connection_control_failed_connections_threshold | 3 |
| connection_control_max_connection_delay | 86400 |
| connection_control_min_connection_delay | 1000 |
+-------------------------------------------------+-------+
3 rows in set (0.00 sec)
connection_control_failed_connections_threshold
失敗嘗試的次數,預設為3,表示當連接失敗3次後啟用連接控制0表示不開啟
connection_control_max_connection_delay
響應延遲的最大時間
connection_control_min_connection_delay
響應延遲的最小時間,預設1000微秒,1秒
然後是超時時間設置。
查看和設置 連接超時相關的兩個參數interactive_timeout和wait_timeout,其值應當至多為30分鐘。
show global variables like 'interactive_timeout';
show global variables like 'wait_timeout';
set global interactive_timeout=1800;
set global wait_timeout=1800;
interactive_timeout:互動式連接超時時間(mysql工具、mysqldump等)
wait_timeout:非互動式連接超時時間、預設的連接mysql api程式、jdbc連接資料庫等
簡單來說,通過mysql客戶端連接資料庫是互動式連接,通過jdbc連接資料庫是非互動式連接。
連接控制插件安裝
MySQL安全插件:Connection-Control Plugins 的利與弊 - leonpenn
MySQL 插件之 連接控制插件(Connection-Control) - ZhenXing_Yu
MySQL連接超時相關的兩個參數interactive_timeout和wait_timeout的區別和解釋 - young5201314
MySQL參數max_connect_errors分析釋疑 - 瀟湘隱者
MySQL狀態變數Aborted_connects與Aborted_clients淺析 -海東潮
05 啟用SSL
查看是否啟用SSL(如果啟用了SSL需要進行配置才能正常遠程連接管理)。
validate-password = FORCE_PLUS_PERMANENT
值為FORCE_PLUS_PERMANENT
表示強制啟用該插件,並且不能被卸載。
validate_password_policy
表示密碼策略,有三個值,與其對應的策略見下表:
值
密碼策略
0 或 LOW
校驗密碼長度變數
1 或 MEDIUM
校驗密碼長度、數字、小寫/大寫和特殊字元4個變數
2 或 STRONG
校驗密碼長度、數字、小寫/大寫、特殊字元和字典文件5個變數
簡言之,對於密碼數字、小寫/大寫和特殊字元這三個變數,只有當密碼策略為中或強時才是有效的。
其它參數含義見下麵的引用文章。
那麼最低要求配置如下
效果:密碼不能與用戶名一致,密碼長度8位以上(包含8位)、至少有一個數字、一個大寫字母、一個小寫字母、一個特殊字元。
mysql> show variables like '%validate_password%';
+--------------------------------------+--------+
| Variable_name | Value |
+--------------------------------------+--------+
| validate_password_check_user_name | OFF |
| validate_password_dictionary_file | |
| validate_password_length | 8 |
| validate_password_mixed_case_count | 1 |
| validate_password_number_count | 1 |
| validate_password_policy | MEDIUM |
| validate_password_special_char_count | 1 |
+--------------------------------------+--------+
7 rows in set (0.00 sec)
安裝和卸載插件
validate_password插件相關參數的介紹
MySql5.6使用validate password 插件加強密碼強度的安裝及使用方法 - wangmm0218
04 登錄失敗和連接超時設置
mysql有個連接超時的插件,相當於登錄失敗鎖定策略,可根據業務需要進行最低配置。
預設配置如下:
mysql> show variables like "%connection_control%";
+-------------------------------------------------+-------+
| Variable_name | Value |
+-------------------------------------------------+-------+
| connection_control_failed_connections_threshold | 3 |
| connection_control_max_connection_delay | 86400 |
| connection_control_min_connection_delay | 1000 |
+-------------------------------------------------+-------+
3 rows in set (0.00 sec)
connection_control_failed_connections_threshold
失敗嘗試的次數,預設為3,表示當連接失敗3次後啟用連接控制,0表示不開啟
connection_control_max_connection_delay
響應延遲的最大時間
connection_control_min_connection_delay
響應延遲的最小時間,預設1000微秒,1秒
然後是超時時間設置。
查看和設置 連接超時相關的兩個參數interactive_timeout和wait_timeout,其值應當至多為30分鐘。
show global variables like 'interactive_timeout';
show global variables like 'wait_timeout';
set global interactive_timeout=1800;
set global wait_timeout=1800;
interactive_timeout:互動式連接超時時間(mysql工具、mysqldump等)
wait_timeout:非互動式連接超時時間、預設的連接mysql api程式、jdbc連接資料庫等
簡單來說,通過mysql客戶端連接資料庫是互動式連接,通過jdbc連接資料庫是非互動式連接。
連接控制插件安裝
MySQL安全插件:Connection-Control Plugins 的利與弊 - leonpenn
MySQL 插件之 連接控制插件(Connection-Control) - ZhenXing_Yu
MySQL連接超時相關的兩個參數interactive_timeout和wait_timeout的區別和解釋 - young5201314
MySQL參數max_connect_errors分析釋疑 - 瀟湘隱者
MySQL狀態變數Aborted_connects與Aborted_clients淺析 -海東潮
05 啟用SSL
查看是否啟用SSL(如果啟用了SSL需要進行配置才能正常遠程連接管理)。
mysql> show variables like '%ssl';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| have_openssl | DISABLED |
| have_ssl | DISABLED |
+---------------+----------+
2 rows in set (0.01 sec)
說明:如果資料庫禁止遠程管理(select user,host from mysql.user;
),則已經符合安全要求,此情況下已無需啟用SSL。
MySQL SSL配置(mysql5.7和mysql5.6) - Yuki_xiong
MYSQL SSL配置與使用 - 德萊華
06 遠程管理限制
其實最好還是應當禁止遠程登錄至少要禁止root直接遠程登錄管理資料庫。
執行select user,host from mysql.user where user='root';
看訪問地址是否僅為 127.0.0.1 或 localhost 或 ::1
其它用戶如需遠程連接,應做訪問範圍限制。
執行select user,host from mysql.user where host = '%';
若host欄位為:% (允許任何IP連接),則說明不合規。
遠程連接管理配置方法:
GRANT ALL PRIVILEGES ON <databases-name>.* TO 'user'@'<ip>' IDENTIFIED BY '<password>' WITH GRANT OPTION;
FLUSH PRIVILEGES;
<databases-name> 指定單個資料庫名 也可以用 *(即所有資料庫名)
user 指定一個資料庫用戶名
<ip> 指定一個IP、一個網段(包括B段、C段 192.168.1.%)、%(所有IP)
<password> 指定遠程連接時使用的密碼,與本地密碼可不同(但需符合密碼複雜度要求)
# 舉例,給資料庫用戶teacher分配student資料庫,只允許192.168.56.%網段遠程連接並設置口令為Admin123。
GRANT ALL PRIVILEGES ON student.* TO 'teacher'@'192.168.56.%' IDENTIFIED BY 'Admin123' WITH GRANT OPTION;
FLUSH PRIVILEGES;
效果如下
最後可以在mysql.user表中看到賬號的情況,也是從這裡刪除。
select user,host from mysql.user where account_locked='N' and host!='localhost';
drop user 'user'@'host';
知識補充-drop和delete的區別
drop
drop user XXX;刪除已存在的用戶,預設刪除的是'XXX'@'%'這個用戶,如果還有其他的用戶(其它主機名),如'XXX'@'localhost'等,不會一起被刪除。如果要刪除'XXX'@'localhost',使用drop刪除時需要加上host即drop user 'XXX'@'localhost'。
delete
delete from user where user='XXX' and host='localhost';其中XXX為用戶名,localhost為主機名(即需指定主機名)。
drop和delete的區別
drop不僅會將user表中的數據刪除,還會刪除其他許可權表的內容。而delete只刪除user表中的內容,所以使用delete刪除用戶後需要執行FLUSH PRIVILEGES;刷新許可權,否則下次使用create語句創建用戶時會報錯。
07 會話連接數配置
配置同樣是在mysql配置文件中添加相關參數(max_connections = 100)。
mysql> show variables like "%connections";
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| max_connections | 100 |
| max_user_connections | 0 |
+----------------------+-------+
2 rows in set (0.01 sec)
max_connections是對整個伺服器的用戶做出限制,
max_user_connections是對每個用戶的限制,
為0表示不限制。
root@NF:~$ grep max_connections etc/mysql/mysql.conf.d/mysqld.cnf
max_connections = 100
MySQL參數最大連接數max_connections - paul_hch
08 啟用日誌審計
mysql預設啟用日誌審計,記錄的內容也符合相關安全要求,此項預設符合。
查看日誌啟用情況
查看變數,看相關日誌是否啟用show variables like 'log%';
或看mysql的配置文件,看相關日誌的配置情況(根據業務需要啟用相關日誌和設置日誌保存路徑。)
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#通用日誌,將所有到達MySQL Server的SQL語句記錄下來
general_log_file = var/log/mysql/mysql.log
general_log = 1
log_timestamps = SYSTEM
#
# Error log - should be very few entries.
#錯誤日誌,文件內容不會很多
log_error = var/log/mysql/error.log
#
# Here you can see queries with especially long duration
#慢查詢日誌,記錄SQL執行語句(執行時間超過2秒才會記錄)
slow_query_log = 1
slow_query_log_file = var/log/mysql/mysql-slow.log
long_query_time = 2
log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
# other settings you may need to change.
#二進位日誌
server-id = 1
log_bin = var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
#binlog_do_db = include_database_name
#binlog_ignore_db = include_database_name
來看一下日誌內容,日誌預設是分天存儲的,一天一個文件並壓縮保存。
相關日誌(主要是查詢日誌和錯誤日誌)應留存6個月以上。
日誌記錄的日期和時間應當是正確的,伺服器需開啟了NTP服務進行時間校對。
#Linux 檢查NTP服務時間同步情況
ntpq -p -n
ntpstat
09 禁止.mysql_history文件記錄信息
.mysql_history文件會記錄MySQL操作歷史(即資料庫查詢語句),包含敏感信息。為了避免敏感信息泄露,需要禁止使用。
檢查所有.mysql_history文件是否鏈接到dev/null,若沒連接到,則以root用戶執行如下命令:
find -name ".mysql_history" | xargs
rm <your_path>/.mysql_history
ln -s dev/null <your_path>/.mysql_history
10 禁止mysql對系統文件進行讀寫操作
local_infile變數表示能否使用load data local infile命令。該變數預設為ON。該變數為OFF時,禁用客戶端使用load data local infile命令。避免通過資料庫查詢語句造成的任意文件讀寫漏洞。
執行如下SQL語句:
show variables like 'local_infile';
若返回結果不為OFF,則在/etc/my.cnf配置文件中修改
[mysqld]
local_infile = 0
11 用戶許可權合理分配
執行下麵語句,查看各賬戶和許可權分配情況。請根據業務需求進行合理的許可權分配,應遵循三權分立原則(分為系統管理員、安全管理員、安全審計員等,並檢查系統各用戶所屬的許可權組。如:系統管理員不能進行業務操作、審計操作審計員不能進行業務操作、系統管理操作安全員不能進行添加賬號操作等)
select user,host,account_locked from mysql.user;
show grants for 'user'@'host';
select * from mysql.user where user='user' and host='host' \G;
不能存在特權用戶
不存在越權訪問情況(繞過訪問控制策略)
mysql 資料庫應當只允許root用戶進行訪問和管理
others
1.其它建議
最小許可權原則
1.對於資料庫,可以一個資料庫用戶分配一個資料庫
2.對於mysql進程,不得以root用戶運行,預設是採用了mysql用戶運行。
更改預設開放埠3306
站庫分離
2.一些常見語句記錄
SET GLOBAL default_password_lifetime = 180;
#設置全局變數及賦值。
INSTALL PLUGIN validate_password SONAME 'validate_password.so';
#安裝插件,這裡是安裝配置密碼複雜度策略的插件。
3.關於更改資料庫用戶密碼
update user set password=password('123') where user='root' and host='localhost';
# mysql 5.7以下
update mysql.user set authentication_string=PASSWORD('newpassword') where user='username' and host='localhost';
# mysql 5.7以上
alter user 'root'@'localhost' identified by 'newpassword';
# mysql 8.0以上
其實就是要註意密碼的列名是什麼,版本不一樣,列名不同,可使select * from mysql.user \G;查看密碼的列名。(\G 即把列數據逐行顯示)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
今天先到這兒,希望對雲原生,技術領導力, 企業管理,系統架構設計與評估,團隊管理, 項目管理, 產品管理,團隊建設 有參考作用 , 您可能感興趣的文章:
領導人怎樣帶領好團隊
構建創業公司突擊小團隊
國際化環境下系統架構演化
微服務架構設計
視頻直播平臺的系統架構演化
微服務與Docker介紹
Docker與CI持續集成/CD
互聯網電商購物車架構演變案例
互聯網業務場景下消息隊列架構
互聯網高效研發團隊管理演進之一
消息系統架構設計演進
互聯網電商搜索架構演化之一
企業信息化與軟體工程的迷思
企業項目化管理介紹
軟體項目成功之要素
人際溝通風格介紹一
精益IT組織與分享式領導
學習型組織與企業
企業創新文化與等級觀念
組織目標與個人目標
初創公司人才招聘與管理
人才公司環境與企業文化
企業文化、團隊文化與知識共用
高效能的團隊建設
項目管理溝通計劃
構建高效的研發與自動化運維
某大型電商雲平臺實踐
互聯網資料庫架構設計思路
IT基礎架構規劃方案一(網路系統規劃)
餐飲行業解決方案之客戶分析流程
餐飲行業解決方案之採購戰略制定與實施流程
餐飲行業解決方案之業務設計流程
供應鏈需求調研CheckList
企業應用之性能實時度量系統演變
Openshift與Kubernetes的區別
如有想瞭解更多軟體設計與架構, 系統IT,企業信息化, 團隊管理 資訊,請關註我的微信訂閱號:
作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
該文章也同時發佈在我的獨立博客中-Petter Liu Blog。