MySQL 在 Docker 中的日誌處理方式與 Nginx、phpMyAdmin 稍微有些不同。官方的 mysql:8.0 鏡像預設會將所有錯誤日誌直接輸出到控制台(docker logs),且預設不會開啟一般查詢日誌(General Log)與慢查詢日誌(Slow Query Log)。

如果要讓 Fail2ban 能夠監控 MySQL 的暴力破解(例如有人一直嘗試猜您的資料庫密碼),我們需要先開啟 MySQL 的錯誤日誌檔案寫入。

請按照以下步驟完成設定:

第一步:修改 docker-compose.yml 掛載並啟用 MySQL 日誌

我們必須透過指令參數告訴 MySQL 把日誌寫成檔案,並將資料夾掛載到宿主機:

  db:
    image: mysql:8.0
    container_name: pure-mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=XXXXX
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=rich
      - MYSQL_PASSWORD=xxxxx
      - TZ=Asia/Taipei
    # 🌟 新增 command:強制 MySQL 將錯誤日誌寫入特定檔案
    command: --log-error=/var/log/mysql/error.log
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./mysql-data:/var/lib/mysql
      - ./mysql-logs:/var/log/mysql       # 🌟 新增這行:把日誌資料夾掛載出來
    networks:
      - web-network

  # 🌟 龍福宮的資料庫也請同步修改:
  db-longfu:
    image: mysql:8.0
    container_name: pure-mysql-longfu
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=XXXXX
      - MYSQL_DATABASE=wordpress_longfu
      - MYSQL_USER=rich
      - MYSQL_PASSWORD=xxxxx
      - TZ=Asia/Taipei
    command: --log-error=/var/log/mysql/error.log  # 🌟 新增
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./mysql-data-longfu:/var/lib/mysql
      - ./mysql-logs-longfu:/var/log/mysql # 🌟 新增
    networks:
      - web-network

修改完成後,請重啟容器:

docker compose down && docker compose up -d

重啟後,在您的專案目錄下會看見 mysql-logs/error.log 與 mysql-logs-longfu/error.log。


第二步:在 Fail2ban 中設定 MySQL 防護

MySQL 密碼輸入錯誤時,日誌中會出現 Access denied for user... 的關鍵字。Fail2ban 內建就自帶了 MySQL 的過濾規則(mysqld-auth),我們可以直接調用。

  1. 打開您宿主機的 Fail2ban 設定檔:

    sudo nano /etc/fail2ban/jail.local
    
  2. 在檔案最底部,加入這兩個資料庫的監控區塊(Jail):(注意:logpath 請務必填寫主機上的完整絕對路徑。)

    [mysql-pure]
    enabled  = true
    port     = 3306
    filter   = mysqld-auth
    logpath  = /home/rich/pure-php-app/mysql-logs/error.log
    maxretry = 3
    findtime = 600
    bantime  = 86400
    
    [mysql-longfu]
    enabled  = true
    port     = 3306
    filter   = mysqld-auth
    logpath  = /home/rich/pure-php-app/mysql-logs-longfu/error.log
    maxretry = 3
    findtime = 600
    bantime  = 86400
    

第三步:重啟並驗證 Fail2ban

  1. 重新載入 Fail2ban 設定:

    sudo fail2ban-client reload
    
  2. 檢查 MySQL 防禦是否成功連線並上線:

    sudo fail2ban-client status mysql-pure
    

💡 核心安全觀念提示