 Autor: [Robert Zasilny](/autorzy/robert-zasilny) Ekspert bezpieczeństwa i compliance · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  Nginx — hardening bezpieczeństwa

# Nginx — hardening i konfiguracja bezpieczeństwa

Opublikowano: 9 kwietnia 2026 · Kategoria: Serwer VPS

Świeżo zainstalowany Nginx jest bezpieczny w podstawach, ale daleki od wytrzymałości produkcyjnej — ujawnia wersję serwera, nie wysyła security headers i nie ma limitów żądań. Ten przewodnik pokazuje pełny hardening: od ukrycia wersji po HSTS i blokowanie złych botów, z gotowymi blokami konfiguracji do skopiowania.

## Krok 1: Ukrycie wersji serwera

Domyślny Nginx ujawnia swoją wersję w nagłówkach HTTP i stronach błędów. Wyłącz to globalnie w `/etc/nginx/nginx.conf`:

http {
    # Ukryj wersję Nginx w nagłówkach i stronach błędów
    server\_tokens off;

    # Opcjonalnie: całkowite ukrycie "nginx" (wymaga modułu headers-more)
    # more\_set\_headers "Server: webserver";

    include /etc/nginx/conf.d/\*.conf;
    include /etc/nginx/sites-enabled/\*;
}

## Krok 2: Security Headers

Dodaj security headers do bloku `server` każdej wirtualnej domeny lub globalnie w nginx.conf. Kompletna konfiguracja:

server {
    listen 443 ssl;
    server\_name twojadomena.pl;

    # Zapobiega osadzaniu strony w ifranie (clickjacking)
    add\_header X-Frame-Options "SAMEORIGIN" always;

    # Blokuje MIME-type sniffing w IE/Chrome
    add\_header X-Content-Type-Options "nosniff" always;

    # Wymusza HTTPS przez 1 rok, rozszerza na subdomeny
    add\_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # Polityka referera — nie ujawniaj URL po kliknięciu linku zewnętrznego
    add\_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Ograniczenie uprawnień przeglądarki (geolokacja, kamera, mikrofon)
    add\_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always;

    # Content Security Policy — dostosuj do swoich zasobów
    add\_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self'; frame-ancestors 'none';" always;
}

Nagłówek

Co chroni

Priorytet

`X-Frame-Options`

Clickjacking przez iframe

Wysoki

`X-Content-Type-Options`

MIME sniffing attacks

Wysoki

`Strict-Transport-Security`

SSL stripping, downgrade attacks

Wysoki

`Referrer-Policy`

Wyciek URL do zewnętrznych serwisów

Średni

`Content-Security-Policy`

XSS, code injection

Wysoki (trudne we wdrożeniu)

`Permissions-Policy`

Dostęp do API przeglądarki

Niski/Średni

## Krok 3: SSL/TLS Hardening

Domyślna konfiguracja SSL często akceptuje przestarzałe protokoły (TLS 1.0, 1.1) i słabe szyfry. Zaostrz konfigurację:

server {
    listen 443 ssl http2;

    # Ścieżki certyfikatów (Let's Encrypt)
    ssl\_certificate /etc/letsencrypt/live/twojadomena.pl/fullchain.pem;
    ssl\_certificate\_key /etc/letsencrypt/live/twojadomena.pl/privkey.pem;

    # Tylko TLS 1.2 i 1.3 (TLS 1.0 i 1.1 są przestarzałe)
    ssl\_protocols TLSv1.2 TLSv1.3;

    # Mocne szyfry — preferuj szyfry serwera
    ssl\_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl\_prefer\_server\_ciphers off;

    # Sesja SSL — cache i czas życia
    ssl\_session\_cache shared:SSL:10m;
    ssl\_session\_timeout 1d;
    ssl\_session\_tickets off;

    # OCSP Stapling — szybsza weryfikacja certyfikatu przez przeglądarkę
    ssl\_stapling on;
    ssl\_stapling\_verify on;
    ssl\_trusted\_certificate /etc/letsencrypt/live/twojadomena.pl/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver\_timeout 5s;

    # Diffie-Hellman parameters (wygeneruj raz: openssl dhparam -out /etc/nginx/dhparam.pem 2048)
    ssl\_dhparam /etc/nginx/dhparam.pem;
}

## Krok 4: Rate Limiting

Ogranicz liczbę żądań per IP — chroni przed brute force i prostymi atakami DDoS:

http {
    # Definicja stref rate limiting
    # 10m = 10 MB pamięci (ok. 160 000 IP), 10r/s = 10 żądań/sekundę per IP
    limit\_req\_zone $binary\_remote\_addr zone=global:10m rate=10r/s;
    limit\_req\_zone $binary\_remote\_addr zone=login:10m rate=1r/s;

    # Odpowiedź przy przekroczeniu limitu
    limit\_req\_status 429;
}

server {
    # Globalny limit — wszystkie requesty
    limit\_req zone=global burst=20 nodelay;

    # Ostrzejszy limit dla formularza logowania (WordPress, phpMyAdmin)
    location = /wp-login.php {
        limit\_req zone=login burst=5 nodelay;
        include fastcgi\_params;
        fastcgi\_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi\_param SCRIPT\_FILENAME $document\_root$fastcgi\_script\_name;
    }

    # Limit dla API REST
    location /wp-json/ {
        limit\_req zone=global burst=30 nodelay;
    }
}

## Krok 5: Blokowanie złych botów i wrażliwych lokalizacji

server {
    # Blokuj dostęp do plików konfiguracyjnych
    location ~ /\\.(git|env|htaccess|htpasswd|svn|DS\_Store) {
        deny all;
        return 404;
    }

    # Blokuj dostęp do plików z kopiami zapasowymi i logami
    location ~\* \\.(bak|conf|log|sql|tar|gz|zip|old)$ {
        deny all;
        return 404;
    }

    # Blokuj złe user-agenty (boty, skanery)
    if ($http\_user\_agent ~\* (masscan|nikto|sqlmap|nmap|zgrab|dirbuster|havij|acunetix)) {
        return 403;
    }

    # Blokuj puste user-agenty
    if ($http\_user\_agent = "") {
        return 403;
    }

    # Blokuj metody HTTP inne niż GET, HEAD, POST
    if ($request\_method !~ ^(GET|HEAD|POST|PUT|DELETE|OPTIONS)$) {
        return 405;
    }

    # Ogranicz rozmiar żądania (ochrona przed atakami przez duże body)
    client\_max\_body\_size 10M;
}

## Weryfikacja konfiguracji

\# Sprawdź składnię konfiguracji przed przeładowaniem
nginx -t

# Przeładuj (bez przerwy w działaniu)
systemctl reload nginx

# Sprawdź nagłówki bezpieczeństwa
curl -I https://twojadomena.pl

# Test SSL online
# https://www.ssllabs.com/ssltest/ — celuj w ocenę A+
# https://securityheaders.com/ — sprawdź wszystkie security headers

Po wdrożeniu sprawdź ocenę na **SSL Labs** (cel: A+) i **SecurityHeaders.com** (cel: A). Pełne A+ wymaga między innymi HSTS z preload i wyłączonych TLS 1.0/1.1. ModSecurity jako WAF to kolejny krok — rozważ go jeśli obsługujesz aplikacje webowe z danymi użytkowników.

## Najczęstsze pytania

Dlaczego warto ukryć wersję Nginx w nagłówkach? +

Domyślnie Nginx wysyła nagłówek "Server: nginx/1.24.0" ujawniając dokładną wersję. Atakujący mogą automatycznie wyszukiwać serwery z określoną podatną wersją i celować w nie z gotowymi exploitami. Dyrektywa "server\_tokens off" w bloku http usuwa numer wersji — serwer nadal identyfikuje się jako nginx, ale bez szczegółów. To security through obscurity, ale eliminuje najprostsze wektory ataku.

Co daje nagłówek HSTS (Strict-Transport-Security)? +

HSTS nakazuje przeglądarce łączyć się z Twoją domeną WYŁĄCZNIE przez HTTPS przez określony czas (max-age). Chroni przed atakami SSL stripping, gdzie atakujący na sieci Wi-Fi obniża połączenie do HTTP. Minimalna wartość to max-age=31536000 (1 rok). Flaga includeSubDomains rozszerza ochronę na subdomeny. preload + rejestracja na hstspreload.org sprawia że przeglądarki znają Twoją domenę jako HTTPS-only jeszcze przed pierwszym połączeniem.

Jak działa rate limiting w Nginx i przed czym chroni? +

Dyrektywa limit\_req\_zone definiuje strefę z limitem żądań (np. 10r/s per IP). limit\_req w bloku location egzekwuje ten limit — żądania powyżej limitu otrzymują odpowiedź 429 Too Many Requests. Chroni przed brute force na formularzu logowania, atakami DDoS, scrapowaniem treści i przeciążeniem serwera. Parametr burst pozwala na krótkie przekroczenia limitu (bufor kolejkowy), nodelay przetwarza burst bez opóźnień.

Czy Content Security Policy (CSP) może zepsuć moją stronę? +

Tak — zbyt restrykcyjne CSP blokuje legalne zasoby (inline skrypty, zewnętrzne fonty, widgety). Przed wdrożeniem użyj trybu "Content-Security-Policy-Report-Only: ..." — przeglądarka raportuje naruszenia do /csp-report ale NIE blokuje. Zbierz raporty przez 1-2 tygodnie, dodaj brakujące domeny do whitelist, dopiero potem zmień na właściwy CSP. W WordPress inline skrypty wymagają specjalnego podejścia — nonce lub hash dla każdego skryptu.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS z pełną kontrolą nad konfiguracją Nginx — root access, własne ssl\_ciphers

Root access

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

Mikrus

Tani VPS do testowania konfiguracji Nginx przed wdrożeniem produkcyjnym

Dev/Test

[Aktywuj rabat →](/out/mikrus)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

LH.pl

Hosting z LiteSpeed i wbudowanymi security headers — bez konfiguracji Nginx

Managed security

[Aktywuj rabat →](/out/lh-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/lh-pl)

## Powiązane strony

-   [Nginx — konfiguracja wirtualnych hostów](/baza-wiedzy/nginx-vhost-konfiguracja)
-   [Nginx jako load balancer](/baza-wiedzy/nginx-load-balancer-konfiguracja)
-   [SSL Let's Encrypt — automatyzacja certyfikatów](/baza-wiedzy/ssl-lets-encrypt-automatyzacja)
-   [Wszystkie artykuły](/baza-wiedzy/)