要讓宿主機上的 Fail2ban 能夠監控 phpMyAdmin(pure-pma)的登入失敗紀錄,我們必須把 phpMyAdmin 容器內的日誌檔案掛載到宿主機上。

phpMyAdmin 官方容器預設使用 Apache 網頁伺服器,其日誌路徑在容器內的 /var/log/apache2/。 [1]

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

第一步:修改 docker-compose.yml 掛載日誌

請在您的 phpmyadmin 服務下,將 volumes 區塊補上日誌資料夾的掛載路徑:

  # 🌟 容器 3:全新加入的 phpMyAdmin 服務
  phpmyadmin:
    image: phpmyadmin:latest
    container_name: pure-pma
    restart: always
    depends_on:
      - db
      - db-longfu  
    environment:
      - PMA_HOSTS=db,db-longfu
      - PMA_PORT=3306
      - TZ=Asia/Taipei
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./pma-logs:/var/log/apache2       # 🌟 新增這行:把 Apache 日誌掛載出來
    ports:
      - "8081:80"
    networks:
      - web-network

修改完成後,請重啟容器以建立資料夾:

docker compose down && docker compose up -d

重啟後,您會在專案目錄下看到一個新資料夾 pma-logs/,裡面會有 access.log 與 error.log。


第二步:建立 Fail2ban 過濾規則(Filter)

由於 phpMyAdmin 登入失敗的特徵是會在 access.log 中產生特定的錯誤代碼或導向,我們需要為它寫一個過濾規則。 [2]

  1. 在宿主機建立一個專用的過濾設定檔:

    sudo nano /etc/fail2ban/filter.d/phpmyadmin-docker.conf
    
  2. 貼入以下防禦特徵(這會捕捉到嘗試登入失敗、密碼錯誤時的網頁行為):(註:phpMyAdmin 登入失敗時依然會回傳 200 狀態碼,但網頁內容會帶有錯誤參數,以上正規表示式能精準抓到這些失敗行為。)

    [Definition]
    failregex = ^<HOST> -.*"POST /index.php.* HTTP/.*" 200 .* "pmaAuth_secret=.*
                ^<HOST> -.*"GET /index.php\?route=/&old_usr=.* HTTP/.*" 200 .*
    ignoreregex =
    

第三步:在 Fail2ban 中啟用 phpMyAdmin 防護

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

    sudo nano /etc/fail2ban/jail.local
    
  2. 在檔案最底部,加入 phpMyAdmin 的監控區塊(Jail):(注意:logpath 請務必填寫您主機上 pma-logs/access.log 的完整絕對路徑。)

    [phpmyadmin-docker]
    enabled  = true
    port     = 8081
    filter   = phpmyadmin-docker
    logpath  = /home/rich/pure-php-app/pma-logs/access.log
    maxretry = 4
    findtime = 600
    bantime  = 86400
    

第四步:重啟並驗證