| 方式 | 指令範例 | 風險等級 | 風險說明 |
|---|---|---|---|
| 1. 命令列明文 | mysql -u user -ppassword | 🔴 極高 | ps -ef 可見、Shell 歷史紀錄、進程表洩露 |
| 2. 互動式提示 | mysql -u user -p | 🟡 中 | 終端不顯示,但僅適用互動模式,腳本無法使用 |
| 3. 選項檔 | ~/.my.cnf [client] password=... | 🟢 低 | 檔案權限 600,僅擁有者可讀,自動化腳本首選 |
| 4. 環境變數 | MYSQL_PWD=password | 🔴 極高 | ps -e 可見環境變數,官方文檔明確不建議 |
$ mysql -u root -pSecret123 dbname &
$ ps -f
UID PID PPID C STIME TTY TIME CMD
root 1234 1000 0 10:00 pts/0 0:00 mysql -u root -pSecret123 dbname
# 密碼直接曝光!
雖然 MySQL 客戶端啟動後會嘗試用 0 覆寫 argv,但存在競態條件視窗,且背景執行時更明顯。
$ mysql -u root -p
Enter password: *********
# 終端不回顯,安全性較好
# 但:Shell 腳本無法自動化、首行輸入可能被誤讀為密碼
# ~/.my.cnf
[client]
user = myuser
password = "Str0ng!P@ssw0rd"
host = 127.0.0.1
port = 3306
# 嚴格權限!
chmod 600 ~/.my.cnf
ls -l ~/.my.cnf
# -rw------- 1 user user 68 Oct 15 10:00 .my.cnf
MySQL 讀取優先順序:
後讀取的覆蓋先讀取的同名選項。
"This method of specifying your MySQL password is insecure and should not be used." — MySQL 官方文檔
#!/bin/bash
# backup.sh - 安全備份腳本
CONFIG_FILE="/etc/mysql/backup.cnf" # 僅 root 可讀,600 權限
OUT_DIR="/backup/mysql"
DATE=$(date +%F_%H-%M)
mkdir -p "$OUT_DIR"
# 使用 --defaults-extra-file 指定專用配置,不依賴 ~/.my.cnf
mysqldump --defaults-extra-file="$CONFIG_FILE" \
--single-transaction --routines --triggers --events \
--all-databases | gzip > "$OUT_DIR/full_$DATE.sql.gz"
# 保留 7 天
find "$OUT_DIR" -name 'full_*.sql.gz' -mtime +7 -delete
# docker-compose.yml
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password # Docker Secrets
secrets:
- db_root_password
secrets:
db_root_password:
file: ./secrets/db_root_password.txt # 構建時注入,不進鏡像
MySQL 客戶端將執行指令記錄在 ~/.mysql_history,包含 SET PASSWORD 等敏感 SQL。
# 禁用歷史記錄
export MYSQL_HISTFILE=/dev/null
# 或
ln -sf /dev/null ~/.mysql_history
.cnf 檔 + chmod 600 + --defaults-extra-filemysql -u user -p 手動輸入