بهینه‌سازی nginx: gzip، کش و هدرهای امنیتی

سرعت سایت روی رتبهٔ گوگل و تجربهٔ کاربر تأثیر مستقیم دارد. سه تنظیم ساده در nginx حجم انتقال را به‌شدت کم می‌کند: فشرده‌سازی، کش مرورگر و هدرهای امنیتی.

وب‌سرور و SSLمتوسط8 دقیقه

۱فعال‌سازی gzip

این تنظیمات را در بلوک http (فایل nginx.conf) یا یک فایل conf.d بگذارید. HTML همیشه فشرده می‌شود و بقیه انواع را باید در gzip_types بنویسید.

nginx
sudo nano /etc/nginx/conf.d/gzip.conf

gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_vary on;
gzip_proxied any;
gzip_types
    text/plain
    text/css
    text/xml
    application/json
    application/javascript
    application/xml
    application/rss+xml
    image/svg+xml
    font/ttf
    font/otf;

تصاویر jpg، png و webp و فایل‌های فشرده مثل zip را gzip نکنید؛ از قبل فشرده‌اند و فقط CPU هدر می‌رود.

۲کش فایل‌های استاتیک

برای فایل‌هایی که نام آن‌ها با هش تغییر می‌کند (Next.js و Vite) می‌توانید یک سال کش بگذارید. immutable مرورگر را از پرسیدن دوباره منع می‌کند.

nginx
    location ~* \.(?:css|js|mjs|woff2?|ttf|otf|svg|png|jpe?g|gif|webp|avif|ico)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # صفحات HTML هرگز طولانی کش نشوند
    location ~* \.html$ {
        add_header Cache-Control "no-cache";
    }

add_header داخل location همهٔ add_header های سطح بالاتر (server) را نادیده می‌گیرد. هدرهای امنیتی را در آن location هم تکرار کنید یا از include استفاده کنید.

۳هدرهای امنیتی

این هدرها را در بلوک server بگذارید. always باعث می‌شود حتی در پاسخ‌های خطا هم ارسال شوند.

nginx
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Content-Security-Policy قدرتمند است ولی اگر اشتباه بنویسید سایت را می‌شکند؛ ابتدا با Content-Security-Policy-Report-Only تست کنید.

۴مخفی کردن نسخهٔ nginx

نشان ندادن نسخه در هدر Server و صفحه‌های خطا کار مهاجم را کمی سخت‌تر می‌کند.

nginx
# در بلوک http
server_tokens off;

۵اعمال و تست

پس از reload، هدرها و فشرده‌سازی را با curl بررسی کنید.

bash
sudo nginx -t && sudo systemctl reload nginx

# gzip فعال است؟ (باید Content-Encoding: gzip ببینید)
curl -sI -H "Accept-Encoding: gzip" https://example.com/main.css | grep -i -E 'content-encoding|cache-control'

# هدرهای امنیتی
curl -sI https://example.com | grep -i -E 'strict-transport|x-frame|x-content-type|referrer'

۶ارزیابی سرعت

پس از تغییرات با ابزارهایی مانند PageSpeed Insights یا Lighthouse سرعت را بسنجید و با نتیجهٔ قبلی مقایسه کنید. برای مقایسهٔ حجم انتقال:

bash
curl -s -o /dev/null -w "%{size_download} bytes\n" -H "Accept-Encoding: gzip" https://example.com/
curl -s -o /dev/null -w "%{size_download} bytes\n" https://example.com/

پرسش‌های پرتکرار دربارهٔ بهینه‌سازی nginx: gzip، کش و هدرهای امنیتی

آیا Brotli بهتر از gzip است؟

بله، معمولاً ۱۵ تا ۲۵ درصد فشرده‌تر است، ولی در nginx باید ماژول اضافه نصب شود (ngx_brotli). gzip همه‌جا بدون نیاز به نصب کار می‌کند و برای شروع کافی است.