عنوان:

‫مخفی‌سازی هویت سرور در NGINX (حذف هدرهای Server و X-Powered-By)


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۴/۰۵ ۰۸:۱۰
آدرس: www.dntips.ir
مقدمه: چرا باید یک "پوکر فیس" (Poker Face) داشته باشیم؟

تصور کنید در حال بازی پوکر هستید. یک بازیکن حرفه‌ای هرگز با حرکات چهره یا رفتارش، خوب یا بد بودن دستش را لو نمی‌دهد. او یک "Poker Face" دارد. در دنیای امنیت وب، سرور شما هم باید همین‌طور باشد. به صورت پیش‌فرض، وب سرورها دوست دارند خودشان را معرفی کنند. وقتی شما یک اپلیکیشن ASP.NET Core را با Kestrel یا IIS هاست می‌کنید، هدرهایی مانند این در پاسخ HTTP به مرورگر ارسال می‌شود:
Server: Kestrel
X-Powered-By: ASP.NET
وقتی NGINX را به عنوان Reverse Proxy اضافه می‌کنیم، این هدرها ممکن است تغییر کنند یا با هم ترکیب شوند:
Server: nginx/1.18.0 (Ubuntu)
X-Powered-By: ASP.NET
این هدرها مانند این است که بازیکن پوکر به حریفانش بگوید: "من یک جفت آس دارم و دارم از کتاب استراتژی پوکر سال ۲۰۲۰ استفاده می‌کنم!" شما دارید به یک مهاجم اطلاعات رایگان می‌دهید:
  • Server: nginx/1.18.0: به مهاجم می‌گوید شما از NGINX نسخه 1.18.0 استفاده می‌کنید. اگر یک حفره امنیتی (CVE) برای این نسخه خاص وجود داشته باشد، مهاجم مستقیماً به سراغ آن می‌رود.
  • X-Powered-By: ASP.NET: به مهاجم می‌گوید تکنولوژی سمت سرور شما ASP.NET است و باید از بردارهای حمله مخصوص این پلتفرم استفاده کند.
هدف ما این است که سرور خود را تا حد ممکن "ناشناس" کنیم و این اطلاعات را حذف یا دستکاری کنیم.

بخش اول: لایه اول - مخفی کردن نسخه NGINX با server_tokens
اولین و ساده‌ترین قدم، مخفی کردن شماره نسخه NGINX است.
  • مشکل: هدر Server: nginx/1.18.0 شماره نسخه را فاش می‌کند.
  • راه حل: استفاده از دستور server_tokens.
این دستور در فایل اصلی کانفیگ NGINX یعنی /etc/nginx/nginx.conf و داخل بلوک http قرار می‌گیرد.
# فایل: /etc/nginx/nginx.conf

http {
    # ... سایر تنظیمات

    # این دستور نسخه NGINX را از هدر Server حذف می‌کند
    server_tokens off;

    # ...
}
اثر دستور server_tokens off;:
  • قبل:Server: nginx/1.18.0
  • بعد:Server: nginx
این یک قدم خوب و ضروری است، اما همانطور که می‌بینید، هدر Server: nginx همچنان وجود دارد.

بخش دوم: لایه دوم - مخفی کردن هویت اپلیکیشن پشتیبان
حالا باید هدرهایی که از سمت اپلیکیشن ASP.NET Core (Kestrel) می‌آیند را حذف کنیم.
  • مشکل: NGINX به عنوان یک پراکسی وفادار، به صورت پیش‌فرض هدر X-Powered-By را از Kestrel گرفته و به کلاینت تحویل می‌دهد.
  • راه حل: استفاده از دستور proxy_hide_header.
این دستور به NGINX می‌گوید: "وقتی پاسخی از سرور پشتیبان دریافت کردی، قبل از ارسال آن به کلاینت، این هدر مشخص را از آن حذف کن."
این دستور را در بلوک server یا location سایت خود، جایی که proxy_pass را تعریف کرده‌اید، قرار دهید.
# فایل: /etc/nginx/sites-available/my-app.conf

server {
    # ...

    location / {
        proxy_pass http://my_aspnet_backend;

        # حذف هدرهای افشاگر از پاسخ سرور پشتیبان
        proxy_hide_header X-Powered-By;
        
        # ممکن است Kestrel هدر Server: Kestrel را هم بفرستد، آن را هم می‌توانیم حذف کنیم
        proxy_hide_header Server;

        # ... سایر تنظیمات پراکسی
    }
}
با این کار، هویت تکنولوژی سمت سرور شما (ASP.NET) به طور کامل از دید کاربر نهایی مخفی می‌شود.

بخش سوم: روش پیشرفته - حذف کامل هدر Server: nginx
تا اینجا نسخه NGINX و هویت ASP.NET Core را مخفی کرده‌ایم، اما هدر Server: nginx همچنان باقی است. اگر بخواهیم آن را هم به طور کامل حذف کنیم یا با یک نام دلخواه جایگزین کنیم، چه باید کرد؟
  • چالش: ماژول‌های استاندارد NGINX اجازه حذف یا تغییر کامل این هدر را نمی‌دهند. این رفتار در کد NGINX به صورت hard-coded تعریف شده است.
  • راه حل: استفاده از یک ماژول اضافی به نام ngx_headers_more که قابلیت‌های بسیار بیشتری برای دستکاری هدرها در اختیار ما قرار می‌دهد.
چگونه این ماژول را به دست آوریم؟ با نصب nginx-extras
در توزیع‌های مبتنی بر دبیان/اوبونتو، پکیجی به نام nginx-extras وجود دارد که نسخه‌ای از NGINX است که با تعداد زیادی ماژول اضافی و کاربردی (از جمله ngx_headers_more) از پیش کامپایل شده است.
۱. نصب nginx-extras:
# ابتدا NGINX قبلی را حذف کرده و نسخه کامل را نصب می‌کنیم
sudo apt update
sudo apt install nginx-extras
۲. استفاده از دستور more_set_headers:
این ماژول، دستور جدیدی به نام more_set_headers را در اختیار ما قرار می‌دهد که از دستور add_header استاندارد، بسیار قدرتمندتر است. با این دستور می‌توانیم هدر Server را پاک کرده یا بازنویسی کنیم. این دستور را در بلوک server خود قرار دهید.
# فایل: /etc/nginx/sites-available/my-app.conf

server {
    # ...
    server_tokens off; # همچنان بهترین رویه است

    # روش اول: حذف کامل هدر Server
    # ما مقدار آن را با یک رشته خالی جایگزین می‌کنیم
    more_set_headers 'Server: ';
    
    # -- یا --

    # روش دوم: جایگزین کردن هدر Server با یک نام دلخواه
    # more_set_headers 'Server: My-Secret-Web-Server';

    location / {
        # ...
        proxy_hide_header X-Powered-By;
        # ...
    }
}

جمع‌بندی و توصیه نهایی
برای داشتن یک "پوکر فیس" کامل در سرور NGINX خود، این سه مرحله را به ترتیب انجام دهید:
  • (ضروری) مخفی کردن نسخه NGINX: در فایل nginx.conf دستور server_tokens off; را قرار دهید. این حداقل کاری است که باید انجام شود.
  • (ضروری) مخفی کردن هویت Backend: در فایل کانفیگ سایت خود، با استفاده از proxy_hide_header X-Powered-By; (و در صورت نیاز proxy_hide_header Server;)، اطلاعات ارسالی از سمت Kestrel را حذف کنید.
  • (پیشرفته و اختیاری) حذف کامل نام NGINX: اگر به حداکثر پنهان‌کاری نیاز دارید، پکیج nginx-extras را نصب کرده و با استفاده از دستور more_set_headers 'Server: ';، هدر Server را به طور کامل از پاسخ‌های خود حذف کنید.

با اجرای این مراحل، شما یک لایه امنیتی مهم به نام "جلوگیری از افشای اطلاعات" را به درستی پیاده‌سازی کرده‌اید و کار را برای مهاجمان احتمالی دشوارتر ساخته‌اید.