محافظت از هات‌لینک: جلوگیری از سرقت پهنای باند تصاویر

اگر پهنای باند هاستت بی‌دلیل تمام می‌شود، احتمالاً سایت‌های دیگر تصاویرت را هات‌لینک می‌کنند. اینجا یاد می‌گیری چطور جلوی آن را بگیری، بدون اینکه پیش‌نمایش شبکه‌های اجتماعی خراب شود.

۶ دقیقه به‌روزرسانی ۱۸ مهر ۱۴۰۵

پهنای باند ماهانه‌ات را نگاه می‌کنی و می‌بینی سه برابر ماه قبل مصرف شده. ترافیک سایتت بالا نرفته، حمله‌ای هم در لاگ‌ها نیست، اما فایل‌های تصویری‌ات دارند از سرور تو برای سایت‌های دیگر سرو می‌شوند. این دقیقاً همان چیزی است که hotlink protection برایش ساخته شده: جلوگیری از اینکه سایت‌های دیگر تصاویر تو را مستقیم در صفحات خودشان لود کنند و پهنای باندت را بخورند.

قبل از هر کاری، باید مطمئن شوی مشکل واقعاً هات‌لینک است و نه چیز دیگر. یک راه سریع: در لاگ دسترسی سرور، دنبال درخواست‌هایی بگرد که Referer آن‌ها دامنه‌ی خودت نیست.

grep -i "\.jpg\|\.png\|\.webp" /var/log/nginx/access.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -20

اگر دامنه‌های غریبه در صدر لیست بودند، مشکل تأیید می‌شود. اگر فقط دامنه‌ی خودت و موتورهای جستجو بودند، جای دیگری را باید بگردی؛ مثلاً ربات‌های اسکرپینگ یا حمله‌ی DDoS لایه‌ی ۷.

چرا hotlink protection روی Apache و Nginx فرق دارد

روی Apache، ابزار اصلی فایل .htaccess است. روی Nginx، این کار در بلاک location انجام می‌شود و .htaccess اصلاً خوانده نمی‌شود. اگر روی هاست اشتراکی لینوکس هستی، تقریباً همیشه با Apache یا LiteSpeed طرفی و .htaccess کار می‌کند. روی سرور اختصاصی با Nginx، باید مستقیم کانفیگ را ویرایش کنی.

روی Apache با htaccess

این بلاک را در ریشه‌ی سایت یا پوشه‌ی تصاویر بگذار:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?google\. [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?bing\. [NC]
RewriteRule \.(jpe?g|png|gif|webp|svg)$ - [F,NC,L]

خط اول شرط را برای درخواست‌های بدون Referer غیرفعال می‌کند. این مهم است چون بعضی کاربران Referer را در مرورگر خاموش می‌کنند و اگر آن خط را حذف کنی، برایشان تصویر لود نمی‌شود. خطوط بعدی دامنه‌ی خودت و موتورهای جستجو را استثنا می‌کنند. خط آخر با کد 403 Forbidden جلوی بقیه را می‌گیرد.

اگر روی هاست اشتراکی هستی و مطمئن نیستی کدام دستورات .htaccess روی پلن تو فعال است، مرجع کامل دستورات htaccess برای هاست لینوکس فهرست دقیق ماژول‌های پشتیبانی‌شده را دارد.

روی Nginx

location ~* \.(jpe?g|png|gif|webp|svg)$ {
    valid_referers none blocked server_names
                   *.example.com
                   *.google.* *.bing.*;
    if ($invalid_referer) {
        return 403;
    }
}

دستور valid_referers همزمان چند حالت را پوشش می‌دهد: none برای درخواست بدون Referer، blocked برای Referer مخدوش، و server_names برای دامنه‌های تعریف‌شده در کانفیگ. بعد از هر تغییر، nginx -t بزن و بعد systemctl reload nginx. اگر nginx -t خطا داد و ریلود نکردی، سایتت با کانفیگ قدیمی بالا می‌ماند و فکر می‌کنی تغییرات اعمال نشده.

اثر جانبی‌ای که همه را غافلگیر می‌کند: پیش‌نمایش شبکه‌های اجتماعی

اینجا جایی است که خیلی‌ها به مشکل می‌خورند. وقتی کسی لینک مقاله‌ات را در تلگرام، واتساپ یا لینکدین می‌فرستد، سرور آن پلتفرم تصویر شاخص (og:image) را از سایت تو می‌کشد. Referer این درخواست یا خالی است یا دامنه‌ی خود پلتفرم است. اگر none را در Nginx حذف کرده باشی یا خط !^$ را در Apache برداشته باشی، آن درخواست با 403 رد می‌شود و لینکت بدون تصویر پیش‌نمایش نمایش داده می‌شود.

سymptomش این است: کاربر می‌گوید «لینکت را فرستادم ولی عکس نداشت». تو در مرورگر خودت تصویر را می‌بینی چون Referer داری. این تفاوت، دقیقاً همان چیزی است که تشخیص را سخت می‌کند.

راه‌حل: دامنه‌های شناخته‌شده‌ی پیش‌نمایش را استثنا کن. برای Apache:

RewriteCond %{HTTP_REFERER} !^https?://([^.]+\.)?(facebook|telegram|whatsapp|linkedin|twitter|x)\. [NC]

و برای Nginx، آن‌ها را به لیست valid_referers اضافه کن. اگر تعداد پلتفرم‌ها زیاد شد و نگهداری لیست سخت شد، گزینه‌ی دیگر این است که به‌جای 403، یک تصویر جایگزین کوچک برگردانی:

RewriteRule \.(jpe?g|png|gif|webp)$ /images/blocked.webp [R=302,L]

این روش پهنای باند کمتری از تصویر اصلی مصرف می‌کند و در عین حال صفحه‌ی سایت مهاجم را نمی‌شکند. اما یک هزینه دارد: هر درخواست هات‌لینک هنوز یک اتصال TCP و یک پاسخ HTTP می‌گیرد. اگر حجم درخواست‌های غریبه خیلی بالا باشد، همان 403 سبک‌تر است چون بدنه‌ی پاسخ ندارد.

این‌جا اشتباه می‌کنند

رایج‌ترین اشتباهی که در تیکت‌های پشتیبانی می‌بینم این است که مدیر سایت کل پوشه‌ی uploads را قفل می‌کند، بعد شکایت می‌کند که «فایل‌های PDF و ویدیوهای سایت باز نمی‌شوند». علتش این است که الگوی RewriteRule را روی همه‌ی پسوندها گذاشته، نه فقط تصاویر. اگر ویدیو یا PDF داری که از دامنه‌ی خودت لود می‌شود، مشکلی پیش نمی‌آید، اما اگر پلیر ویدیو از یک CDN جدا استفاده می‌کند، آن CDN هم به‌عنوان دامنه‌ی غریبه دیده می‌شود و فایل بلاک می‌شود.

علامتش این است: در مرورگر خودت همه‌چیز درست است، اما کاربران می‌گویند ویدیو پخش نمی‌شود. در تب Network مرورگر، پاسخ 403 روی فایل .mp4 می‌بینی و Referer همان CDN است. راه‌حل: دامنه‌ی CDN را هم به لیست استثناها اضافه کن.

مقایسه‌ی روش‌ها

روشمزیتهزینه
403 با htaccessسبک، بدون بدنه‌ی پاسخپیش‌نمایش شبکه‌های اجتماعی می‌شکند اگر none حذف شود
ریدایرکت به تصویر جایگزینصفحه‌ی مهاجم نمی‌شکند، پیام غیرمستقیم می‌دهدهنوز پهنای باند مصرف می‌شود
امضای URL با توکندقیق‌ترین کنترل، مناسب CDNنیاز به تغییر کد اپلیکیشن و مدیریت انقضای توکن
Watermark روی تصاویرارزش برند را حفظ می‌کندپهنای باند را کم نمی‌کند، فقط اثر سرقت را کم‌رنگ می‌کند

اگر فقط می‌خواهی پهنای باندت را نجات دهی، 403 با htaccess را انتخاب می‌کنم. اگر تصاویرت ارزش تجاری دارند و می‌خواهی کسی نتواند حتی یک نسخه‌ی سالم بردارد، امضای URL با توکن تنها راه واقعی است، ولی هزینه‌ی پیاده‌سازی‌اش را باید بپذیری.

بعد از فعال‌سازی، چه چیزی را باید چک کنی

  1. یک تصویر از سایتت را در یک سایت تست هات‌لینک بگذار و ببین 403 می‌گیرد.
  2. همان لینک را در تلگرام بفرست و مطمئن شو پیش‌نمایش تصویر دارد.
  3. در Search Console چک کن که گوگل‌بات تصاویر را ایندکس می‌کند.
  4. لاگ سرور را ۲۴ ساعت بعد نگاه کن و ببین مصرف پهنای باند چقدر افت کرده.

برای مرحله‌ی سوم، اگر مطمئن نیستی گوگل‌بات از چه IPهایی می‌آید، بررسی DNS و شبکه به‌کارت می‌آید. و اگر می‌خواهی مصرف پهنای باند را دقیق‌تر رصد کنی، ابزارهای رایگان وب‌مستر گزارش‌های تحلیلی خوبی می‌دهد.

یک نکته‌ی عملی: اگر سایتت روی هاست اشتراکی است و ترافیک تصاویرت بالاست، ممکن است بعد از فعال‌سازی hotlink protection هم پهنای باندت بالا بماند، چون ربات‌های اسکرپینگ Referer جعلی می‌فرستند. در آن حالت باید به فکر مهاجرت به سرور اختصاصی یا استفاده از CDN باشی. برای سایت‌های کوچک و متوسط، هاست لینوکس با پشتیبانی کامل از .htaccess کافی است و نیازی به تغییر زیرساخت نداری.

اگر بعد از فعال‌سازی، سایتت با خطای 500 بالا نیامد، احتمالاً یک خطای سینتکسی در .htaccess داری. فایل را از طریق FTP برگردان به حالت قبل و دوباره با یک بلاک کوچک‌تر تست کن. برای یادگیری دستورات بیشتر، مستندات و پایگاه دانش سرورنت مرجع خوبی است.

پرسش‌های پرتکرار

آیا hotlink protection روی سئو تأثیر منفی دارد؟

اگر موتورهای جستجو را استثنا کنی، نه. گوگل‌بات تصاویر را با Referer خودش درخواست می‌کند و اگر دامنه‌ی گوگل در لیست مجاز باشد، تصاویر همچنان ایندکس می‌شوند. مشکل وقتی پیش می‌آید که کل درخواست‌های بدون Referer را بلاک کنی؛ در آن حالت ممکن است بعضی خزنده‌ها نتوانند تصاویر را ببینند.

چرا بعد از فعال‌سازی، پیش‌نمایش لینک در تلگرام و واتساپ خراب شد؟

چون سرورهای این پلتفرم‌ها تصویر شاخص را با Referer خالی یا دامنه‌ی خودشان درخواست می‌کنند و در لیست مجاز تو نیستند. دامنه‌های telegram.org، whatsapp.com، facebook.com و linkedin.com را به لیست استثناها اضافه کن تا پیش‌نمایش برگردد.

آیا می‌توانم فقط برای یک پوشه خاص hotlink protection فعال کنم؟

بله. فایل .htaccess را داخل همان پوشه بگذار، نه در ریشه‌ی سایت. دستورات .htaccess به‌صورت بازگشتی روی زیرپوشه‌ها هم اعمال می‌شوند، پس اگر فقط پوشه‌ی images را می‌خواهی محافظت کنی، فایل را همان‌جا قرار بده و از ریشه حذف کن.

تفاوت hotlink protection با محدود کردن نرخ درخواست چیست؟

hotlink protection بر اساس Referer تصمیم می‌گیرد، یعنی منبع درخواست را بررسی می‌کند. محدود کردن نرخ درخواست (rate limiting) بر اساس تعداد درخواست در بازه‌ی زمانی کار می‌کند و به Referer کاری ندارد. این دو مکمل هم هستند: اولی جلوی سرقت پهنای باند را می‌گیرد، دومی جلوی حمله‌ی حجمی را.

آیا این مطلب برایتان مفید بود؟