科技數碼
WordPress 安裝路徑安全指南:public_html 根目錄 vs 子目錄 vs 外部資料夾

將 WordPress 安裝在 wp.yourdomain.com/public_html/ 根目錄,而非 /public_html/wp/ 子目錄或 ~/projects/wp 外部資料夾。
為何避免 /public_html/wp/ 子目錄
- WordPress 核心路徑混亂:REST API 變為
/wp/wp-json/、登入頁變為/wp/wp-login.php home與siteurl選項需額外重寫規則- 部分外掛與佈景主題預設根目錄路徑,導致功能異常
- 「路徑混淆」僅為虛假安全感,實際安全來自強化措施而非隱藏路徑
為何避免 ~/projects/wp 外部資料夾
- Web 伺服器僅服務
~/domains/<domain>/public_html/內容 ~/projects/預設無法透過 HTTPS 存取- 需建立 symbolic link 或修改 Apache 設定才能連線
- 一旦連回 public_html,等同直接暴露,安全效益為零
推薦目錄結構
wp.yourdomain.com/
├── wp-config.php ← 移至 public_html 上一層
└── public_html/ ← WordPress 核心直接安裝於此
├── index.php
├── wp-admin/
├── wp-content/
├── wp-includes/
└── wp-login.php
Symbolic Link 無安全效益的真相
symlink 的實際運作
- Apache 解析 symlink 後,PHP-FPM 於真實路徑執行檔案
- 攻擊者視角:
https://wp.yourdomain.com/wp-login.php同樣可達 - 執行路徑、檔案權限、PHP 讀寫範圍完全相同
- 僅改變磁碟儲存位置,未改變 HTTP 攻擊表面
symlink 的額外缺點
- 共享主環境中
SymLinksIfOwnerMatch增加每次請求的stat()開銷 - 更多移動部件 = 更高設定錯誤風險
真正有效的「移出 web root」技術
安全提升的關鍵判準:檔案是否可透過 HTTP 存取
| 操作 | HTTP 可達性 | 安全效果 |
|---|---|---|
| wp-config.php 移至 web root 上方,不建立連結 | ❌ 無 URL 對應 | ✅ 實質增益 |
| 整體移出後以 symlink 連回 public_html | ✅ 可透過 symlink 存取 | ⚖️ 零改變 |
| 全部保留於 public_html | ✅ 基準狀態 | (基準線) |
wp-config.php 上移的運作機制
- WordPress 自動於 web root 上一層目錄尋找
wp-config.php - Apache 文件根目錄限制為
public_html/,拒絕服務上層路徑 - 極端情境(PHP 停止執行、直接輸出 .php 原始碼)下,憑證仍不暴露
- 前提條件:無 symlink 指回該檔案
Headless WordPress 安全強化清單
- 資料庫隔離:建立專用最小權限 DB 使用者
- 管理後台限制:以
.htaccess或外掛將/wp-admin/、wp-login.php限制於可信 IP - 停用內建佈景主題:使用極簡 headless 主題,無前端渲染需求
- REST API 認證:採用 Application Passwords 或 JWT 外掛,禁止未認證寫入
- 強制 HTTPS:雙域名 SSL 強制跳轉
- 關閉 XML-RPC:無需使用時停用或限制
- 精簡外掛:核心 + headless 主題 + WP REST API Cache + 可選 ACF + 可選 JWT auth
- wp-config.php 強化:唯一 salts、
DISALLOW_FILE_EDIT、生產環境關閉WP_DEBUG - CORS 限制:僅允許
www.yourdomain.com讀取 API - 前端分離:靜態 HTML 檔案不存放於 WordPress,置於
www.yourdomain.com - 上傳目錄防護:
wp-content/uploads/禁止 PHP 執行 - 檔案權限:目錄 755、檔案 644、
wp-config.php640 或 600
雙域名架構範例
# WordPress 後端(API 來源)
wp.yourdomain.com/
├── wp-config.php
└── public_html/
├── index.php
├── wp-admin/
├── wp-content/
├── wp-includes/
└── wp-login.php
# 靜態前端(API 消費者)
www.yourdomain.com/
└── public_html/
├── index.html
├── assets/
└── ... 你的 HTML+JS 前端
# 前端讀取端點
https://wp.yourdomain.com/wp-json/wp/v2/posts
一條規則總結
安全來自「不可觸達性」,而非「不同位置」。 移出 web root 有效,是因為移除 HTTP 可達性;symlink 失效,是因為恢復了可達性。WordPress 核心檔案必須可服務,故無法隱藏——以強化措施保護;wp-config.php 無需服務,故可真正上移——這才是「移出 public directory」建議的正確應用。


