close
資料來源於墨天輪
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_PERMANENTvalidate_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的區別
dropdrop user XXX;
刪除已存在的用戶,默認刪除的是'XXX'@'%'這個用戶,如果還有其他的用戶(其它主機名),如'XXX'@'localhost'等,不會一起被刪除。如果要刪除'XXX'@'localhost',使用drop刪除時需要加上host即drop user 'XXX'@'localhost'。
deletedelete 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.cnfmax_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.loggeneral_log = 1log_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 = 1slow_query_log_file = var/log/mysql/mysql-slow.loglong_query_time = 2log-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 = 1log_bin = var/log/mysql/mysql-bin.logexpire_logs_days = 10max_binlog_size = 100M#binlog_do_db = include_database_name#binlog_ignore_db = include_database_name

來看一下日誌內容,日誌默認是分天存儲的,一天一個文件並壓縮保存。
相關日誌(主要是查詢日誌和錯誤日誌)應留存6個月以上。
日誌記錄的日期和時間應當是正確的,服務器需開啟了NTP服務進行時間校對。

#Linux 檢查NTP服務時間同步情況ntpq -p -nntpstat

09 禁止.mysql_history文件記錄信息

.mysql_history文件會記錄MySQL操作歷史(即數據庫查詢語句),包含敏感信息。為了避免敏感信息泄露,需要禁止使用。檢查所有.mysql_history文件是否鏈接到dev/null,若沒連接到,則以root用戶執行如下命令:
find -name ".mysql_history" | xargsrm <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 即把列數據逐行顯示)

侵權請私聊公眾號刪文

熱文推薦

藍隊應急響應姿勢之Linux
通過DNSLOG回顯驗證漏洞
記一次服務器被種挖礦溯源
內網滲透初探 | 小白簡單學習內網滲透
實戰|通過惡意 pdf 執行 xss 漏洞
免殺技術有一套(免殺方法大集結)(Anti-AntiVirus)
內網滲透之內網信息查看常用命令
關於漏洞的基礎知識
任意賬號密碼重置的6種方法
乾貨 | 橫向移動與域控權限維持方法總匯
手把手教你Linux提權

歡迎關注LemonSec

覺得不錯點個「贊」、「在看「
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 鑽石舞台 的頭像
    鑽石舞台

    鑽石舞台

    鑽石舞台 發表在 痞客邦 留言(0) 人氣()