Apache配置實現(xiàn)對海量圖片資源的深度防盜鏈與防下載策略
針對海量圖片資源的防盜鏈與防下載,需要構(gòu)建多層防御體系。以下是經(jīng)過實戰(zhàn)驗證的 Apache 深度防護策略:
一、基礎(chǔ)層:Referer 防盜鏈(第一層過濾)
<IfModule mod_rewrite.c>
RewriteEngine On
# 定義允許的白名單域名(正則匹配,支持子域名)
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?partner-site\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?cdn\.yourdomain\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?localhost [NC]
# 對圖片資源應(yīng)用防盜鏈
RewriteRule \.(jpg|jpeg|png|gif|webp|bmp|svg|ico)$ - [F,L]
</IfModule>說明:!^$ 允許空 Referer(部分客戶端/郵件客戶端),如需嚴(yán)格可移除。[F] 返回 403 Forbidden,[L] 終止后續(xù)規(guī)則。
二、核心層:Token 簽名驗證(防直鏈 + 防篡改)
1. 服務(wù)端 Token 生成邏輯(PHP/Python 示例)
<?php
// 密鑰必須與服務(wù)端一致
$secret = 'YourStrongSecretKey_2024!';
$expire = time() + 300; // 5分鐘有效期
function generateImageToken($path, $expire, $secret) {
$data = $path . '|' . $expire;
return hash_hmac('sha256', $data, $secret);
}
$imagePath = '/uploads/2024/photo.jpg';
$token = generateImageToken($imagePath, $expire, $secret);
$url = "https://img.yourdomain.com{$imagePath}?t={$token}&e={$expire}";
// 輸出: https://img.yourdomain.com/uploads/2024/photo.jpg?t=abc123&e=1715000000
?>2. Apache 配置(驗證 Token + 過期時間)
<IfModule mod_rewrite.c>
RewriteEngine On
# 僅對圖片目錄啟用
<Directory "/var/www/images">
# 提取 URL 參數(shù)
RewriteCond %{QUERY_STRING} ^(?:.*&)?t=([^&]+)(?:&.*)?$ [NC]
RewriteRule .* - [E=TOKEN:%1]
RewriteCond %{QUERY_STRING} ^(?:.*&)?e=([^&]+)(?:&.*)?$ [NC]
RewriteRule .* - [E=EXPIRE:%1]
# 構(gòu)建驗證字符串:路徑|過期時間
RewriteRule .* - [E=VERIFY_STRING:%{REQUEST_URI}|%{ENV:EXPIRE}]
# 計算期望的 HMAC(需要 mod_setenvif 或外部程序,這里用 Lua/外部腳本)
# 方案A:使用 mod_lua(推薦,高性能)
<IfModule mod_lua.c>
LuaHookAccessChecker /etc/apache2/scripts/verify_token.lua verify_token
</IfModule>
# 方案B:使用外部程序驗證(性能較低,適合低頻)
# RewriteMap token_verify prg:/etc/apache2/scripts/verify_token.py
# RewriteCond ${token_verify:%{ENV:VERIFY_STRING}|%{ENV:TOKEN}} !^VALID$
# RewriteRule .* - [F,L]
# 檢查過期時間
RewriteCond %{TIME} > %{ENV:EXPIRE}
RewriteRule .* - [F,L]
</Directory>
</IfModule>3. Lua 驗證腳本(/etc/apache2/scripts/verify_token.lua)
-- 需要安裝 libapache2-mod-lua
require "apache2"
require "hash"
require "string"
local secret = "YourStrongSecretKey_2024!"
function verify_token(r)
local token = r.subprocess_env["TOKEN"]
local expire = r.subprocess_env["EXPIRE"]
local path = r.uri
if not token or not expire then
return apache2.DECLINED -- 讓 Rewrite 規(guī)則處理(返回403)
end
-- 檢查是否過期
local now = os.time()
if tonumber(expire) < now then
return apache2.HTTP_FORBIDDEN
end
-- 計算 HMAC
local data = path .. "|" .. expire
local expected = hash.hmac_sha256(data, secret)
-- 安全比較(防時序攻擊)
if not secure_compare(token, expected) then
return apache2.HTTP_FORBIDDEN
end
return apache2.OK
end
function secure_compare(a, b)
if #a ~= #b then return false end
local result = 0
for i = 1, #a do
result = result | (string.byte(a, i) ~ string.byte(b, i))
end
return result == 0
end三、傳輸層:防直接下載 + 防右鍵保存
1. 禁用圖片直接保存(Content-Disposition)
<IfModule mod_headers.c>
# 對圖片強制 inline 顯示,但阻止"另存為"對話框的默認(rèn)行為
<FilesMatch "\.(jpg|jpeg|png|gif|webp)$">
Header set Content-Disposition "inline"
# 禁止瀏覽器緩存圖片到本地(減少離線查看)
Header set Cache-Control "private, no-store, max-age=0"
</FilesMatch>
</IfModule>2. 添加水?。ㄍㄟ^ mod_pagespeed 或后端處理)
# 使用 mod_pagespeed 自動添加水?。ㄐ璋惭b)
<IfModule pagespeed_module>
ModPagespeedEnableFilters rewrite_images
ModPagespeedEnableFilters insert_image_dimensions
# 自定義水印濾鏡
ModPagespeedImageMaxBytes 2097152
</IfModule>四、行為層:反爬蟲與異常檢測
1. 頻率限制(mod_evasive 或 mod_security)
# 使用 mod_evasive 限制單 IP 圖片請求頻率
<IfModule mod_evasive24.c>
DOSHashTableSize 3097
DOSPageCount 5 # 同一頁面5秒內(nèi)超過5次
DOSSiteCount 50 # 同一站點5秒內(nèi)超過50次
DOSPageInterval 5
DOSSiteInterval 5
DOSBlockingPeriod 600 # 封禁10分鐘
DOSEmailNotify admin@yourdomain.com
DOSLogDir "/var/log/mod_evasive"
</IfModule>2. 使用 ModSecurity 高級防護
<IfModule security2_module>
# 攔截?zé)o Referer 的批量請求(爬蟲特征)
SecRule REQUEST_FILENAME "@rx \.(jpg|jpeg|png|gif|webp)$" \
"id:1001,phase:1,block,log,msg:'Image access without referer',\
chain"
SecRule REQUEST_HEADERS:Referer "@streq" \
"setvar:ip.image_requests=+1,expirevar:ip.image_requests=60"
# 單 IP 60秒內(nèi)超過100次圖片請求則封禁
SecRule IP:IMAGE_REQUESTS "@gt 100" \
"id:1002,phase:1,deny,status:403,msg:'Rate limit exceeded for images'"
# 攔截常見爬蟲 User-Agent
SecRule REQUEST_HEADERS:User-Agent "@pm wget curl python scrapy" \
"id:1003,phase:1,deny,status:403,msg:'Bot detected'"
</IfModule>五、應(yīng)用層:前端 + 后端協(xié)同防護
1. 圖片通過 Canvas 渲染(防右鍵保存)
<!-- 前端示例:圖片通過 Canvas 繪制,DOM 中不暴露真實 img 標(biāo)簽 -->
<canvas id="protected-img" width="800" height="600"></canvas>
<script>
fetch('/api/get-image-token?path=/uploads/photo.jpg')
.then(r => r.json())
.then(data => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = function() {
const canvas = document.getElementById('protected-img');
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
// 添加視覺水印
ctx.font = '14px Arial';
ctx.fillStyle = 'rgba(255,255,255,0.5)';
ctx.fillText('? YourDomain ' + new Date().getFullYear(), 10, 30);
};
img.src = data.url; // 帶 Token 的 URL
});
</script>2. 動態(tài)縮略圖 + 防盜鏈(防止原圖泄露)
# 使用 mod_rewrite + mod_proxy 將縮略圖請求代理到處理服務(wù)
RewriteRule ^/thumb/(\d+)x(\d+)/(.*)$ \
http://localhost:8080/thumbnail?w=$1&h=$2&path=$3 [P,L]六、完整配置匯總
# ==================== 全局設(shè)置 ====================
ServerTokens Prod
ServerSignature Off
# ==================== 模塊加載 ====================
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule headers_module modules/mod_headers.so
LoadModule lua_module modules/mod_lua.so
# ==================== 圖片目錄防護 ====================
<Directory "/var/www/images">
Options -Indexes -FollowSymLinks
AllowOverride None
Require all granted
RewriteEngine On
# ---- Layer 1: Referer 白名單 ----
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?yourdomain\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?cdn\.yourdomain\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?localhost [NC]
RewriteRule \.(jpg|jpeg|png|gif|webp|bmp|svg)$ - [F,L]
# ---- Layer 2: Token 驗證 ----
RewriteCond %{QUERY_STRING} ^(?:.*&)?t=([^&]+)(?:&.*)?$ [NC]
RewriteRule .* - [E=TOKEN:%1]
RewriteCond %{QUERY_STRING} ^(?:.*&)?e=([^&]+)(?:&.*)?$ [NC]
RewriteRule .* - [E=EXPIRE:%1]
# 過期檢查
RewriteCond %{TIME} > %{ENV:EXPIRE}
RewriteRule .* - [F,L]
# Lua HMAC 驗證
<IfModule mod_lua.c>
LuaHookAccessChecker /etc/apache2/scripts/verify_token.lua verify_token
</IfModule>
# ---- Layer 3: 響應(yīng)頭加固 ----
<IfModule mod_headers.c>
Header set Content-Disposition "inline"
Header set Cache-Control "private, max-age=300"
Header set X-Content-Type-Options "nosniff"
# 禁止圖片被嵌入 iframe(點擊劫持防護)
Header set X-Frame-Options "DENY"
# CSP 限制圖片加載來源
Header set Content-Security-Policy "img-src 'self' data:; default-src 'none'"
</IfModule>
# ---- Layer 4: 頻率限制(需 mod_evasive)----
<IfModule mod_evasive24.c>
DOSPageCount 10
DOSSiteCount 100
DOSBlockingPeriod 300
</IfModule>
</Directory>
# ==================== 日志記錄 ====================
CustomLog "/var/log/apache2/image_access.log" "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %{UNIQUE_ID}e"防護效果總結(jié)
| 層級 | 防護手段 | 防御目標(biāo) |
|---|---|---|
| Layer 1 | Referer 白名單 | 阻止第三方網(wǎng)站直接引用 |
| Layer 2 | Token + HMAC + 過期時間 | 防止 URL 分享、直鏈訪問 |
| Layer 3 | 響應(yīng)頭控制 + CSP | 防止右鍵保存、iframe 嵌入 |
| Layer 4 | 頻率限制 + WAF | 阻止爬蟲批量抓取 |
| Layer 5 | Canvas 渲染 + 動態(tài)水印 | 前端防保存、溯源追蹤 |
這套方案的核心是 Token 簽名機制——即使攻擊者獲取了圖片 URL,Token 會在短時間內(nèi)過期,且無法偽造簽名,從根本上杜絕了盜鏈和批量下載。
到此這篇關(guān)于Apache配置實現(xiàn)對海量圖片資源的深度防盜鏈與防下載策略的文章就介紹到這了,更多相關(guān)Apache海量圖片防盜鏈與防下載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Apache Shiro 使用手冊(五) Shiro 配置說明
這篇文章主要為大家分享了Apache Shiro 配置說明,需要的朋友可以參考下2014-06-06
Ubuntu系統(tǒng)的備份和恢復(fù)實現(xiàn)方式
Timeshift是Linux系統(tǒng)備份與恢復(fù)工具,支持增量式備份和Btrfs快照,備份位置可選擇非系統(tǒng)硬盤或移動U盤,用戶可以通過圖形界面或終端命令進行操作,包括全備份和選擇性備份,恢復(fù)系統(tǒng)時,可以使用LiveCD進行操作2025-12-12
如何在Linux服務(wù)器上安裝CVAT (Docker 28.5.1)
本文詳細(xì)介紹了如何在Linux服務(wù)器上安裝CVAT,并確保其與Docker 28.5.1版本的兼容性,步驟包括安裝Docker、配置國內(nèi)鏡像源、安裝CVAT、啟動服務(wù)、創(chuàng)建管理員賬戶以及驗證安裝,感興趣的朋友跟隨小編一起看看吧2025-11-11

