虛擬主機環境常見問題:FTP 用戶無法刪除 PHP 程式上傳/產生的檔案,因檔案擁有者為 apache/www-data (PHP-FPM 執行身分),而 FTP 用戶屬於不同群組,權限不足導致 Permission Denied。本文提供一支自助式 PHP 清理腳本,透過 Web 介面以 Apache 身分遞迴刪除指定目錄/檔案,並內建安全防護 (Token 驗證、路徑限制、操作日誌、用完即刪)。
一、問題根因分析
| 實體 | 身分 | 權限 |
| PHP 上傳/縮圖/快取 | apache / www-data (PHP-FPM user) | 檔案 644、目錄 755,擁有者 apache |
| FTP 登入用戶 | ftpuser (獨立系統帳號) | 屬於 ftp 群組,非 apache 群組 |
| 結果 | FTP 用戶無寫入權限 → 無法刪除/重命名/移動 | |
虛擬主機通常不提供 SSH,無法 chown/chmod,需借助 Web 執行身分清理。
二、PHP 清理腳本完整程式碼 (delete_files.php)
isFile() || $item->isLink()) {
@unlink($item->getPathname());
} elseif ($item->isDir()) {
@rmdir($item->getPathname());
}
}
return @rmdir($dir);
}
// === Token 驗證 ===
$token = isset($_GET['token']) ? $_GET['token'] : (isset($_POST['token']) ? $_POST['token'] : '');
if ($token !== $ALLOWED_TOKEN) {
http_response_code(403);
die('Invalid token. Access denied.');
}
// === 處理刪除請求 ===
$results = [];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 刪除目錄
if (!empty($_POST['dirs'])) {
$dirs = array_filter(array_map('trim', explode(';', $_POST['dirs'])));
foreach ($dirs as $dir) {
$path = safe_path($dir);
if ($path && delete_dir($path)) {
$results[] = "✅ 目錄刪除成功: $dir";
log_action("DELETE_DIR $dir by {$_SERVER['REMOTE_ADDR']}");
} else {
$results[] = "❌ 目錄刪除失敗/路徑非法: $dir";
log_action("FAIL_DELETE_DIR $dir by {$_SERVER['REMOTE_ADDR']}");
}
}
}
// 刪除檔案
if (!empty($_POST['files'])) {
$files = array_filter(array_map('trim', explode(';', $_POST['files'])));
foreach ($files as $file) {
$path = safe_path($file);
if ($path && is_file($path) && @unlink($path)) {
$results[] = "✅ 檔案刪除成功: $file";
log_action("DELETE_FILE $file by {$_SERVER['REMOTE_ADDR']}");
} else {
$results[] = "❌ 檔案刪除失敗/不存在/路徑非法: $file";
log_action("FAIL_DELETE_FILE $file by {$_SERVER['REMOTE_ADDR']}");
}
}
}
}
// === 自毀機制 (可選) ===
if (isset($_GET['self_destruct'])) {
@unlink(__FILE__);
log_action("SELF_DESTRUCT by {$_SERVER['REMOTE_ADDR']}");
die('Script self-destructed.');
}
?>
虛擬主機檔案清理工具
🗑️ 虛擬主機檔案/目錄刪除工具
⚠️ 高危操作警告: 本工具以 Apache/PHP-FPM 身分執行,可刪除 FTP 無法刪除的檔案。
- 僅限
及其子目錄
- 請確認路徑無誤,刪除無法復原
- 操作完成後請立即點擊「自我銷毀」或手動刪除本檔案
審計日誌:
三、部署與使用步驟
- 修改
$ALLOWED_TOKEN 為高強度隨機字串 (如 openssl rand -hex 32)
- 將腳本上傳至網站根目錄 (如
public_html/delete_files.php)
- 瀏覽器訪問
https://yourdomain.com/delete_files.php?token=你的token
- 在表單輸入相對路徑 (多個用
; 分隔),送出刪除
- 確認結果無誤後,點擊 自我銷毀 按鈕移除腳本
- 檢查
logs/delete_audit.log 審計紀錄
四、安全強化清單 (必做)
- ✅ Token 機制防止未授權存取
- ✅
realpath() + strpos($real, $BASE_PATH) === 0 防路徑遍歷 (../../etc/passwd)
- ✅ 僅允許 POST 刪除,GET 僅供檢視/自我銷毀
- ✅ 操作審計日誌含時間、IP、路徑、結果
- ✅ 自我銷毀功能避免殘留後門
- ✅ 部署後立即驗證
.htaccess 或 Nginx 規則禁止直接下載 PHP 原始碼
五、替代方案對比
| 方案 | 優點 | 缺點 | 適用場景 |
| PHP 清理腳本 (本文) | 無需 SSH、Web 介面直觀、可審計 | 需部署 PHP 檔案、有殘留風險 | 虛擬主機、無 SSH 權限 |
| SSH + chown/chmod | 徹底解決權限、一次設定永久有效 | 需 SSH 權限、虛擬主機通常無 | VPS/獨立伺服器 |
| 控制面板檔案管理器 | 圖形介面、整合權限管理 | 功能受限、大量檔案操作慢 | cPanel/DirectAdmin/Plesk 用戶 |
| Cron 定期清理腳本 | 自動化、無人值守 | 需預知路徑模式、誤刪風險 | 固定快取/暫存目錄 |