數據庫安全使用規則
1. 數據庫版本及運行要求
- 使用穩定的解決了已知漏洞的版本,如5.6.39或5.7.20 (更新 於2018.2)
- 以--skip-symbolic-links選項啟動數據庫:禁止在創建索引和創建表的時候,將索引文件和數據文件鏈接到其他文件。
2. 通用加固項
- 刪除冗余數據庫, 如test。
drop database if exists ${dbname};
- 清除無用用戶(沒有用戶名的用戶)。
drop user ''
- 修改超級用戶的密碼。
set password for <user>@<hostname> = password('<yourpassword>')
- 配置密碼復雜度
使用validate_password.so插件:
Installing the MySQL Password Validation Plugin
配置后,舉例:
mysql> create user testuser;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> CREATE USER 'test'@'localhost' IDENTIFIED BY '123456';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> grant all privileges on *.* to testuser@"%" Identified by "123456";
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> use mysql; update user set password =PASSWORD('123456') where user ='system';
Database changed
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
自問: 使用insert能夠繞過 !?
mysql> insert into user(Host,User,Password,ssl_cipher,x509_issuer,x509_subject) values('%','testuser','123456','BLOB','BLOB','BLOB');
Query OK, 1 row affected (0.00 sec)
自答:
. insert直接插入的123456雖然可以插入成功但表中保存的應是加密后的內容,不能用123456進行登錄;
. 使用PASSWORD('123456'),PASSWORD方法會進行校驗,校驗通過情況下insert方式(insert后記得flush privileges;)添加用戶有效!
. 補充:即便使用UPPER(SHA1(UNHEX(SHA1('123456')))) ,插入其加密之后的值,也不能使用“123456”進行登錄。
mysql> insert into user(Host,User,Password,ssl_cipher,x509_issuer,x509_subject) values('%','testuser',PASSWORD('123456'),'BOLOB','BLOB','BLOB');
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> update user set password=UPPER(SHA1(UNHEX(SHA1('123456')))) where user='testuser';
...
mysql> select user,host,password from user;
+-------------+-----------+-------------------------------------------+
| user | host | password |
+-------------+-----------+-------------------------------------------+
| root | 127.0.0.1 | *936A04AEF6CF3742E2F327C1970D875C588546F2 |
| testuser | % | 6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9|
| system | % | *197D257ACCF6E52954DAA9A406D6B58EA95FCF45|
+-------------+-----------+-------------------------------------------+
# mysql -utestuser -p123456
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'testuser'@'localhost' (using password: YES)
3. 用戶權限
Mysql提供的用戶權限參考: Permissible Privileges for GRANT and REVOKE
-
mysql.user表只有管理員(root)用戶才能操作
說明:實際應用中,有修改mysql.user的用戶都算超級用戶,都禁止遠程連接數據庫。【mysql用戶權限管理體系】
mysql.user表:記錄用戶的全局操作權限。GRANT ALL ON .和REVOKE ALL ON .
mysql.db表:記錄用戶對指定數據庫的操作權限。 GRANT ALL ON db_name.和REVOKE ALL ON db_name.
mysql.talbes_priv表: 記錄用戶對指定表的操作權限。 GRANT ALL ON db_name.tbl_name和REVOKE ALL ON db_name.tbl_name
mysql.columns_priv表: 記錄用戶對表中具體列的操作權限。
注意: user表中沒有相應的操作權限時,才會繼續檢查對應的數據庫或表是否有操作權限。 -
避免以管理員用戶創建存儲過程和函數
-
以下權限只能賦予超級用戶(root):
Shutdown_priv、Process_priv、File_priv、Grant_priv、Reload_priv、Super_priv 、Create_user_priv 、Repl_slave_privupdate mysql.user set Shutdown_priv='N',Process_priv='N',File_priv='N',Grant_priv='N',Reload_priv='N',Super_priv ='N',Create_user_priv ='N',Repl_slave_priv='N' where mysql.user.User!='root';
遺留:多實例情況下用戶 multi_admin 也算管理員用戶? 和root用戶擁有一樣的權限?
- 更改MySQL root用戶的名字
update mysql.user set user='<your_account>' where user='root' flush privileges
4. 連接設置
-
監聽地址不允許包含*,0.0.0.0,::
[mysqld] bind-address=<’ServerIP’>
-
用戶主機名不使用通配符%
-
超級管理員只能本地登錄
驗證: select count(*) from mysql.user where Super_priv = 'Y' and host not in ('localhost','127.0.0.1','::1')
-
限制數據庫連接閑置等待時間
[mysqld] wait_timeout、interactive_timeout、slave-net-timeout
-
防暴力破解
Installing Connection Control Plugins修改my.cnf配置文件: plugin-load-add="connection_control.so" connection-control=FORCE_PLUS_PERMANENT connection-control-failed-login-attempts=FORCE_PLUS_PERMANENT connection-control-failed-connections-threshold=3 connection-control-min-connection-delay=1000 connection-control-max-connection-delay=2147483647
擴展
- 注意plugin-load-add 與plugin-load的區別: 參看: Installing and Uninstalling Plugins
5. ssl安全認證
- 確保對所有遠端用戶均設置了ssl_type參數
GRANT USAGE ON *.* TO <my_user>@<host> REQUIRE SSL; 驗證: SELECT user, host, ssl_type FROM mysql.user WHERE NOT HOST IN ('::1', '127.0.0.1', 'localhost');
>**注意**:服務端、客戶端都需要配置SSL證書!
## 6. 涉及操作系統相關配置
### 6.1 系統資源
1. 禁止數據庫啟動用戶交互式登錄
/etc/passwd文件,在mysql用戶對應行添加/sbin/nologin或/bin/false.
```bash
usermod -s /sbin/nologin mysql
```
### 6.2 文件權限
1. 禁止mysql_history文件記錄信息
```bash
rm <your_path>/.mysql_history
ln -s /dev/null <your_path>/.mysql_history
sed -i '$a readonly MYSQL_HISTFILE=/dev/null' /etc/profile
```
2. 限制安裝文件屬主和權限
MySQL初始安裝后,安裝目錄和文件屬主要求為MySQL運行用戶,目錄權限要求為700,二進制文件為500,庫文件為500,啟動文件(一般位於/etc/init.d目錄下)為500。
3. 限制數據庫數據文件屬主和權限
數據目錄和文件屬主為mysql用戶,數據目錄為700,數據文件為600。
```bash
#chmod 700 <data_dir Value>
#chown mysql:mysql <data_dir Value>
#chmod 600 <data_dir Value>/*
#chown mysql:mysql <data_dir Value>/*
```
4. 限制日志文件(含binlog)屬主(mysql)和權限(600)
MySQL數據庫中常見日志文件有:
- **錯誤日志**(log_error):
記錄了MySQL的啟停和運行過程。——有問題首先看這個文件。
'log_error=/opt/mysql/data/aaa.err'
- **二進制日志**(log_bin):
記錄了對數據庫執行更改的所有操作。
作用:數據恢復、復制、日志審計(如判斷有無注入攻擊)。
```
log_bin [=name] # 默認關閉,需要配置此參數開啟。不指定name默認文件名為'主機名.日志序號'。
```
備注:bin_log.00001即是二進制日志,bin_log.index為索引文件。二進制日志可使用自帶的**mysqlbinlog**工具查看。
- 慢查詢日志(slow_query_log_file):
記錄運行慢的sql,幫助進行sql優化。
```
slow_query_log=1 # 默認關閉,1啟用,0禁用 [log_slow_queries]
slow_query_log_file=slow.log # 指定文件路徑和名字;默認值是'主機名-slow.log',位於datadir目錄
long_query_time=3 # 執行時間超過設置閾值(s)的sql語句會被記錄在slow_query_log_file中
log_output=FILE,TABLE # 指定慢查詢的輸出方式,動態參數。 FILE:慢查詢日志;TABLE:mysql.slow_log表
```
Tips: 可以借助**mysqldumpslow**命令幫助分析慢查詢日志。
- 查詢日志(general_log_file)
記錄了所有對數據庫請求的信息。
```
general_log=1 # 默認關閉,配置此參數開啟查詢日志。
general_log_file=/opt/mysql/data/general.log
```
按照log=/opt/mysql/data/xxx.log 配置,mysql服務啟動失敗。
可以動態開啟:
```
mysql>set global general_log_file='/tmp/general.log';
mysql>set global general_log=on;
mysql>set global general_log=off;
```
與slow_log一樣,可以將查詢日志放入mysql.general_log表中。
5. 限制my.cnf文件屬主和權限
```bash
#chmod 600 /xxx/my.cnf
#chown mysql:mysql /xxx/my.cnf
```
6. 限制Plugin目錄及其文件權限
取得Plugin目錄路徑:
```
show variables where variable_name = 'plugin_dir';
```
目錄權限為500, 目錄下的文件權限為400:
```bash
#chmod 500 <plugin_dir Value>
#chown mysql:mysql <plugin_dir Value>
#chmod 400 <plugin_dir Value>/*
#chown mysql:mysql <plugin_dir Value>/*
```
7. 限制SSLfile文件權限
數據庫運行用戶,權限是否為400。
取得ssl_ca、ssl_cert、ssl_crl、ssl_key文件路徑:
```bash
show variables like 'ssl%';
```