技術分享 | MySQL 編寫指令碼時避免煩人的警告

愛可生雲資料庫發表於2022-06-21

作者:楊濤濤

資深資料庫專家,專研 MySQL 十餘年。擅長 MySQL、PostgreSQL、MongoDB 等開源資料庫相關的備份恢復、SQL 調優、監控運維、高可用架構設計等。目前任職於愛可生,為各大運營商及銀行金融企業提供 MySQL 相關技術支援、MySQL 相關課程培訓等工作。

本文來源:原創投稿

*愛可生開源社群出品,原創內容未經授權不得隨意使用,轉載請聯絡小編並註明來源。


有客戶在編寫前期資料庫安全規範時,就如何更安全的在 Linux Shell 端操作 MySQL 這一塊,讓我們幫忙出一份詳盡的說明文件。其中有一項內容就是如何在 Linux Shell 下呼叫 MySQL 各種命令列工具時遮蔽掉煩人的告警資訊輸出,諸如下面這樣:

root@ytt-ubuntu18:/home/ytt# mysql -uytt -proot -e "select version()"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-----------+
| version() |
+-----------+
| 8.0.29    |
+-----------+

其實這是一個非常古老的問題!百度隨便一搜,各種解決方法都有,但都寫的不是很完善。

這樣的告警資訊對命令執行結果的輸出非常不友好,那麼我們如何遮蔽掉它?下面我來羅列下幾種我能想到的方法,以供參考。

1、給使用者空密碼(不推薦)

給使用者賦予空密碼雖然可以遮蔽掉警告資訊,但是極不安全,類似於 MySQL 服務初始化時的 --initialize-insecure 選項。

root@ytt-ubuntu18:/home/ytt# mysql -u ytt_no_pass -e "select user()"
+-----------------------+
| user()                |
+-----------------------+
| ytt_no_pass@localhost |
+-----------------------+

2、配置檔案不同塊加入使用者名稱密碼(不推薦)

MySQL 的配置檔案有 my.cnf、mysql.cnf、mysqld.cnf 等等,只要在這些配置檔案裡的不同塊下新增對應的使用者名稱和密碼即可。

root@ytt-ubuntu18:/home/ytt# cat /etc/mysql/conf.d/mysql.cnf
[mysql]
prompt=mysql:\d:\v>
user=ytt
password=root
port=3340
[mysqldump]
user=ytt
password=root
port=3340
   
[mysqladmin]
user=ytt
password=root
port=3340

以上[mysql]塊下的內容表示對 mysql 命令列生效,[mysqldump]塊下的內容表示對 mysqldump 工具生效,[mysqladmin]塊下的內容表示對 mysqladmin 工具生效。

或者寫簡單點,統一加到【client】 裡,表示對所有客戶端生效。注意只能把共享的部分內容加到這裡。

root@ytt-ubuntu18:/home/ytt# cat /etc/mysql/conf.d/mysql.cnf
[mysql]
prompt=mysql:\d:\v>
[client]
user=ytt
password=root
port=3340

由於這些塊都是針對客戶端設定,不需要重啟 MySQL 服務,可立即生效。

root@ytt-ubuntu18:/home/ytt# mysql -e "select user()"
+---------------+
| user()        |
+---------------+
| ytt@localhost |
+---------------+

3、設定 MySQL 環境變數(不推薦)

MySQL 有一些內建環境變數,對所有客戶端生效。官方的環境變數列表如下:

https://dev.mysql.com/doc/ref...

給當前使用者設定所需的環境變數,之後再呼叫命令列工具即可。比如設定密碼環境變數 MYSQL_PWD 、傳統 TCP 埠環境變數 MYSQL_TCP_PORT 等。

root@ytt-ubuntu18:/home/ytt# export MYSQL_PWD=root MYSQL_TCP_PORT=3340 
   
root@ytt-ubuntu18:/home/ytt# mysql -uytt -e "select user()"
+---------------+
| user()        |
+---------------+
| ytt@localhost |
+---------------+

此方法也不推薦使用,環境變數 MYSQL_PWD 容易被其他使用者獲取。比如直接用 ps 命令就可以輕易獲取 MYSQL_PWD 的值。

使用者1執行如下命令:

root@ytt-ubuntu18:/home/ytt# mysql -uytt -e "select sleep(1000)"

使用者2執行 ps aex 就可以列印出環境變數 MYSQL_PWD 和 MYSQL_TCP_PORT 的值:

root@ytt-ubuntu18:/home/ytt# ps aex| grep MYSQL_PWD| grep -v 'grep'
7592 pts/0    S+     0:00 mysql -uytt -e select sleep(1000) LS_COLORS=rs=0:... MYSQL_PWD=root ...MYSQL_TCP_PORT=3340 ...

4、遮蔽標準錯誤輸出內容,重定向到空裝置檔案(推薦)

root@ytt-ubuntu18:/home/ytt# mysql -uytt -proot -P3340 -e"select version()"  2>/dev/null
+-----------+
| version() |
+-----------+
| 8.0.29    |
+-----------+

這裡利用 Linux 系統本身的特性來重定向 MySQL 錯誤資訊,其中數字2代表錯誤輸出的檔案描述符;/dev/null 代表空裝置。也就是說把執行這條命令的錯誤資訊重定向到空裝置而不是標準輸出,這樣就可以變相的把警告資訊遮蔽掉。

5、使用 mysql_config_edit 工具生成不同的 login_path (推薦)

mysql_config_edit 是 MySQL 官方釋出的一款工具,專門處理這類必須暴露使用者密碼的問題,可以進行一次設定,多次安全使用。

使用方法如下:設定一個 login_path ,名字為 user_ytt ,密碼按提示輸入即可。

root@ytt-ubuntu18:/home/ytt# mysql_config_editor set -G user_ytt -S /var/run/mysqld/mysqld.sock -u ytt -p
Enter password: 

接下來,呼叫任何 MySQL 命令列工具只需要帶上 --login-path 選項即可使用。

root@ytt-ubuntu18:/home/ytt# mysql --login-path=user_ytt -e 'select user()'
+---------------+
| user()        |
+---------------+
| ytt@localhost |
+---------------+
   
root@ytt-ubuntu18:/home/ytt# mysqladmin  --login-path=user_ytt ping
mysqld is alive

mysql_config_editor 工具也有一個缺點:同樣的 login_path 不能分享給所有系統使用者,其他使用者得重新新增自己的 login_path 才能正常使用。

6、使用 Unix socket 外掛(推薦,僅限本地)

auth_socket 外掛只根據本地 OS 登入使用者名稱和本地 linux socket 檔案來授權認證。比如修改使用者 ytt@localhost 外掛為 auth_socket :

   mysql> alter user ytt@localhost identified with auth_socket ;
   Query OK, 0 rows affected (0.00 sec)
   
   mysql> \q
   Bye

切換到 OS 使用者 ytt :

   root@ytt-pc-big:/home/ytt# su ytt
   
   ytt@ytt-pc-big:~$ mysql -e "select user(),current_user()"
   +---------------+----------------+
   | user()        | current_user() |
   +---------------+----------------+
   | ytt@localhost | ytt@localhost  |
   +---------------+----------------+

這裡需要提醒一句: 為了安全,操作 MySQL 的使用者許可權一定要做到按需分配。

相關文章