Jak skonfigurować Nginx do nasłuchiwania na wielu portach
Nginx może nasłuchiwać na wielu portach jednocześnie, dodając wiele dyrektyw `listen` wewnątrz jednego lub więcej bloków `server` w swojej konfiguracji. Każda dyrektywa `listen` wiąże Nginx z określoną kombinacją IP/portu, umożliwiając jednej instancji serwera obsługę ruchu HTTP, HTTPS i niestandardowych aplikacji na różnych portach bez uruchamiania oddzielnych procesów.
Ta możliwość jest niezbędna w środowiskach wielodostępnych, separacji portów staging/produkcja, architekturach reverse proxy i routingu mikroserwisów — wszystko z jednej instancji VPS Hosting.
Wymagania wstępne
Przed kontynuowaniem potwierdź następujące kwestie:
- Nginx jest zainstalowany i usługa jest aktywna (`systemctl status nginx`)
- Posiadasz uprawnienia `root` lub `sudo` na serwerze
- Rozumiesz różnicę między `/etc/nginx/nginx.conf` (konfiguracja globalna) a `/etc/nginx/sites-available/` (bloki konfiguracji per-strona)
- Reguły zapory sieciowej (`ufw`, `iptables` lub chmurowa grupa zabezpieczeń) zezwalają na ruch na portach, które zamierzasz otworzyć
- Ważne certyfikaty SSL są dostępne w przypadku konfigurowania portów HTTPS (samopodpisane lub wydane przez CA)
Architektura konfiguracji Nginx: Co musisz wiedzieć na początku
Nginx używa hierarchicznego modelu konfiguracji: kontekst `http` zawiera jeden lub więcej bloków `server`, z których każdy może zawierać jedną lub więcej dyrektyw `listen`. Zrozumienie tej hierarchii zapobiega najczęstszym błędom konfiguracji.
Kluczowe dyrektywy:
- `listen [address:]port [ssl] [http2] [default_server]` — wiąże blok serwera z określonym portem i opcjonalnym IP
- `server_name` — dopasowuje nagłówek `Host` w celu kierowania żądań do właściwego bloku
- `default_server` — wyznacza, który blok serwera obsługuje żądania, które nie pasują do żadnego innego `server_name`
Lokalizacje plików konfiguracyjnych według dystrybucji:
| Dystrybucja | Główna konfiguracja | Konfiguracje stron |
|---|
| — | — | — |
|---|
| Ubuntu / Debian | `/etc/nginx/nginx.conf` | `/etc/nginx/sites-available/` |
|---|
| CentOS / RHEL / AlmaLinux | `/etc/nginx/nginx.conf` | `/etc/nginx/conf.d/` |
|---|
| Arch Linux | `/etc/nginx/nginx.conf` | `/etc/nginx/sites-available/` |
|---|
| Docker (oficjalny obraz) | `/etc/nginx/nginx.conf` | `/etc/nginx/conf.d/` |
|---|
W systemach opartych na Debianie pliki w `sites-available/` muszą być dowiązane symbolicznym linkiem do `sites-enabled/`, aby weszły w życie:
“`bash
sudo ln -s /etc/nginx/sites-available/example.conf /etc/nginx/sites-enabled/
“`
Krok 1: Otwórz plik konfiguracyjny Nginx
Dla globalnej zmiany wpływającej na wszystkie wirtualne hosty:
“`bash
sudo nano /etc/nginx/nginx.conf
“`
Dla konfiguracji specyficznej dla strony (zalecane dla środowiska produkcyjnego):
“`bash
sudo nano /etc/nginx/sites-available/example.conf
“`
Używanie plików specyficznych dla strony jest zdecydowanie preferowane. Izoluje zmiany, upraszcza wycofywanie zmian i zapobiega sytuacji, w której pojedyncza błędna konfiguracja powoduje wyłączenie wszystkich hostowanych usług.
Krok 2: Skonfiguruj wiele dyrektyw listen w jednym bloku serwera
Najprostsza konfiguracja wieloportowa wiąże jeden blok serwera z kilkoma portami. Nginx zastosuje identyczną logikę routingu niezależnie od tego, przez który port połączył się klient.
“`nginx
server {
listen 80;
listen 8080;
server_name example.com;
root /var/www/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/example_access.log;
error_log /var/log/nginx/example_error.log warn;
}
“`
Co to robi:
- `listen 80;` — akceptuje standardowy ruch HTTP
- `listen 8080;` — akceptuje ruch na alternatywnym porcie HTTP (powszechne w środowiskach deweloperskich, wewnętrznych API lub kontrolach stanu load balancera)
- Oba porty serwują identyczną zawartość z `/var/www/html`
Przypadek brzegowy — powiązanie z określonym adresem IP: Na serwerze z wieloma interfejsami sieciowymi (np. publicznym IP i prywatnym IP sieci LAN) możesz ograniczyć, na którym interfejsie nasłuchuje Nginx:
“`nginx
listen 192.168.1.10:8080;
listen 0.0.0.0:80;
“`
Jest to kluczowe w konfiguracjach serwerów wieloadresowych, aby zapobiec niezamierzonemu publicznemu ujawnieniu wewnętrznych usług.
Krok 3: Skonfiguruj HTTPS na wielu portach
HTTPS wymaga parametru `ssl` w dyrektywie `listen` oraz prawidłowych ścieżek do certyfikatu i klucza. Poniższy przykład wiąże HTTPS zarówno ze standardowym portem 443, jak i niestandardowym portem 8443:
“`nginx
server {
listen 443 ssl;
listen 8443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
Modern TLS hardening
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
“`
Dlaczego port 8443 jest powszechnie używany:
- Umożliwia ruch HTTPS w środowiskach, gdzie port 443 jest blokowany przez nadrzędne zapory sieciowe
- Używany w środowiskach deweloperskich/staging do uruchamiania bezpiecznego serwera bez konfliktu z usługą produkcyjną na porcie 443
- Wymagany przez niektóre frameworki aplikacyjne (Tomcat, proxy Node.js), które udostępniają HTTPS na niestandardowych portach
Krytyczna pułapka: Pominięcie `ssl_protocols` i `ssl_ciphers` pozostawia Nginx z potencjalnie słabymi ustawieniami domyślnymi. Zawsze jawnie definiuj parametry TLS, szczególnie na serwerach obsługujących wrażliwe dane. Jeśli potrzebujesz zaufanego certyfikatu zamiast samopodpisanego, certyfikaty SSL od uznanego CA eliminują ostrzeżenia przeglądarki i spełniają nowoczesne wymagania HSTS.
Krok 4: Serwuj różną zawartość na różnych portach
Gdy porty muszą obsługiwać różne aplikacje — na przykład publiczna strona internetowa na porcie 80 i wewnętrzny panel administracyjny na porcie 8080 — użyj oddzielnych bloków `server`:
“`nginx
server {
listen 80;
server_name example.com;
root /var/www/public;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 8080;
server_name example.com;
root /var/www/admin;
index index.html;
Restrict admin panel to internal network only
location / {
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
try_files $uri $uri/ =404;
}
}
“`
Rzeczywiste przypadki użycia separacji zawartości opartej na portach:
- Port 80/443: Publiczna strona internetowa
- Port 8080: Wewnętrzne REST API lub punkt końcowy mikroserwisu
- Port 8443: Bezpieczny panel administracyjny ograniczony listą dozwolonych IP
- Port 9000: Punkt końcowy metryk do scrapowania przez Prometheus (nigdy nie wystawiany publicznie)
- Port 3000/5000: Reverse proxy do aplikacji Node.js lub Python
Krok 5: Używanie Nginx jako reverse proxy na wielu portach
Powszechnym wzorcem produkcyjnym jest używanie Nginx do proxy różnych portów do różnych backendowych serwerów aplikacji:
“`nginx
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 8080;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
“`
Ten wzorzec stanowi podstawę konteneryzowanych wdrożeń na Serwerze Dedykowanym, gdzie wiele kontenerów Docker działa na różnych wewnętrznych portach, a Nginx pełni rolę jedynego zewnętrznego punktu wejścia.
Krok 6: Zweryfikuj konfigurację
Nigdy nie restartuj Nginx bez uprzedniego przetestowania składni konfiguracji. Błąd składni spowoduje, że usługa nie zdoła się przeładować, wyłączając wszystkie hostowane strony.
“`bash
sudo nginx -t
“`
Oczekiwany wynik po sukcesie:
“`
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
“`
Jeśli pojawią się błędy, wynik wskaże plik i numer linii. Napraw wszystkie zgłoszone problemy przed kontynuowaniem.
Dla przeładowania bez przestojów (preferowane zamiast pełnego restartu w środowisku produkcyjnym):
“`bash
sudo systemctl reload nginx
“`
Pełny restart jest konieczny tylko przy zmianie `worker_processes`, `user` lub innych dyrektyw na poziomie procesu głównego:
“`bash
sudo systemctl restart nginx
“`
Krok 7: Sprawdź, czy Nginx nasłuchuje na właściwych portach
Po zastosowaniu konfiguracji potwierdź, że Nginx powiązał się z oczekiwanymi portami, używając `ss` (preferowane zamiast przestarzałego `netstat`):
“`bash
sudo ss -tlnp | grep nginx
“`
Przykładowy wynik:
“`
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))
LISTEN 0 511 0.0.0.0:8080 0.0.0.0:* users:(("nginx",pid=1234,fd=7))
LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1234,fd=8))
LISTEN 0 511 0.0.0.0:8443 0.0.0.0:* users:(("nginx",pid=1234,fd=9))
“`
Jeśli port nie pojawia się, sprawdź:
- Składnię dyrektywy `listen` w pliku konfiguracyjnym
- Czy inny proces nie zajmuje już tego portu: `sudo ss -tlnp | grep :8080`
- Czy `nginx -t` przeszło bez błędów
- Polityki SELinux lub AppArmor, które mogą blokować powiązanie z niestandardowym portem
Testowanie za pomocą curl z wiersza poleceń (bardziej niezawodne niż przeglądarka do debugowania):
“`bash
curl -I http://example.com
curl -I http://example.com:8080
curl -Ik https://example.com
curl -Ik https://example.com:8443
“`
Flaga `-I` pobiera tylko nagłówki. Odpowiedź `200 OK` lub `301 Moved Permanently` potwierdza, że port jest aktywny i Nginx odpowiada prawidłowo.
Krok 8: Otwórz porty w zaporze sieciowej
Nasłuchiwanie na porcie w Nginx jest niewystarczające, jeśli zapora sieciowa hosta blokuje połączenia przychodzące. Upewnij się, że porty są dozwolone:
UFW (Ubuntu/Debian):
“`bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8080/tcp
sudo ufw allow 8443/tcp
sudo ufw reload
“`
firewalld (CentOS/RHEL/AlmaLinux):
“`bash
sudo firewall-cmd –permanent –add-port=8080/tcp
sudo firewall-cmd –permanent –add-port=8443/tcp
sudo firewall-cmd –reload
“`
iptables (bezpośrednio):
“`bash
sudo iptables -A INPUT -p tcp –dport 8080 -j ACCEPT
sudo iptables -A INPUT -p tcp –dport 8443 -j ACCEPT
“`
W infrastrukturze chmurowej (AWS EC2, DigitalOcean, Hetzner) musisz również zaktualizować grupę zabezpieczeń lub reguły zapory chmurowej na poziomie dostawcy — same zmiany zapory na poziomie hosta nie są wystarczające.
Porównanie: konfiguracje Nginx z jednym portem a wieloma portami
| Funkcja | Jeden port | Wiele portów (ten sam blok) | Wiele portów (oddzielne bloki) |
|---|
| — | — | — | — |
|---|
| Złożoność konfiguracji | Niska | Niska | Średnia |
|---|
| Izolacja zawartości | Brak | Brak | Pełna |
|---|
| Kontrola dostępu per port | Nie dotyczy | Niemożliwa | W pełni obsługiwana |
|---|
| Przypadek użycia | Proste strony internetowe | Kopie dev/staging | Mikroserwisy, panele administracyjne |
|---|
| Reverse proxy per port | Jeden upstream | Jeden upstream | Niezależne upstreamy |
|---|
| Terminacja SSL | Per blok | Współdzielony certyfikat | Niezależne certyfikaty per blok |
|---|
| Separacja logów | Jeden log | Jeden log | Pliki logów per port |
|---|
Typowe pułapki i jak ich unikać
Konflikt portów z istniejącymi usługami: Port 80 może być już zajęty przez Apache. Uruchom `sudo ss -tlnp | grep :80` przed konfigurowaniem. Zatrzymaj kolidujące usługi lub skonfiguruj je ponownie, aby używały innych portów.
Konflikty `default_server`: Jeśli wiele bloków serwera pomija `default_server` lub wiele bloków rości sobie do niego prawo dla tego samego portu, Nginx użyje pierwszego bloku w kolejności pliku. Bądź precyzyjny:
“`nginx
listen 80 default_server;
“`
IPv6 nie jest objęty: Dodanie `listen 80;` wiąże tylko z IPv4. Dla serwerów dual-stack dodaj:
“`nginx
listen [::]:80;
listen [::]:8080;
“`
SELinux blokuje niestandardowe porty: Na RHEL/CentOS z wymuszaniem SELinux, Nginx nie może powiązać się z portami spoza swojej polityki bez wyraźnego zezwolenia:
“`bash
sudo semanage port -a -t http_port_t -p tcp 8080
sudo semanage port -a -t http_port_t -p tcp 8443
“`
Zapomnienie o przeładowaniu po zmianach: Edycje konfiguracji nie mają żadnego efektu, dopóki Nginx nie zostanie przeładowany. Zautomatyzuj to w potokach CI/CD za pomocą kroku `nginx -t && systemctl reload nginx` po wdrożeniu.
Praktyczna macierz decyzyjna
Użyj tej listy kontrolnej, aby określić właściwy wzorzec konfiguracji wieloportowej dla swojego scenariusza:
- Ta sama zawartość, wiele portów — Użyj wielu dyrektyw `listen` w jednym bloku `server`
- Różna zawartość per port — Użyj oddzielnych bloków `server` z odrębnymi katalogami `root`
- Różne aplikacje backendowe per port — Użyj oddzielnych bloków `server` z `proxy_pass` wskazującym na różne adresy upstream
- Zabezpieczenie niestandardowego portu — Dodaj `ssl` do dyrektywy `listen` i odwołaj się do ścieżek certyfikatu; upewnij się, że SAN certyfikatu obejmuje domenę
- Ograniczenie portu do ruchu wewnętrznego — Dodaj dyrektywy `allow`/`deny` lub powiąż `listen` tylko z prywatnym IP
- Działanie na VPS z cPanel — Sprawdź, czy wbudowana konfiguracja Apache/Nginx cPanel nie powoduje konfliktów; użyj „Include Editor” cPanel lub dedykowanego katalogu drop-in konfiguracji Nginx
- Zarządzanie wieloma opcjami panelu sterowania — Przejrzyj dostępne panele sterowania VPS, aby znaleźć taki, który udostępnia zarządzanie portami Nginx przez GUI
FAQ
Czy Nginx może nasłuchiwać na tym samym porcie w wielu blokach serwera?
Tak. Wiele bloków `server` może współdzielić ten sam port. Nginx rozróżnia je za pomocą dyrektywy `server_name`, która dopasowuje nagłówek HTTP `Host`. Jeśli żaden `server_name` nie pasuje, żądanie obsługuje blok `default_server`.
Czy dodanie większej liczby portów nasłuchiwania wpływa na wydajność Nginx?
Narzut jest pomijalny. Każda dyrektywa `listen` dodaje deskryptor pliku do procesu głównego Nginx. Praktyczny limit to systemowy pułap otwartych deskryptorów plików (`ulimit -n`), a nie liczba portów. W przypadku wdrożeń o dużym ruchu dostosuj `worker_rlimit_nofile` i `worker_connections` w `nginx.conf`.
Jak przekierować cały ruch z portu 8080 na port 80?
Użyj dedykowanego bloku serwera z dyrektywą `return`:
“`nginx
server {
listen 8080;
server_name example.com;
return 301 http://example.com$request_uri;
}
“`
Dlaczego Nginx nie nasłuchuje na porcie, mimo że konfiguracja wygląda poprawnie?
Cztery najczęstsze przyczyny to: (1) konfiguracja nie została przeładowana po edycji, (2) inny proces jest już powiązany z tym portem, (3) reguła zapory sieciowej blokuje port lub (4) SELinux/AppArmor uniemożliwia powiązanie. Systematycznie sprawdzaj każdą przyczynę, używając `ss -tlnp`, `nginx -t` i poleceń stanu zapory sieciowej.
Czy mogę używać różnych certyfikatów SSL dla różnych portów HTTPS w tej samej domenie?
Tak. Każdy blok `server` ma własne dyrektywy `ssl_certificate` i `ssl_certificate_key`. Dwa bloki serwera mogą nasłuchiwać odpowiednio na portach 443 i 8443 i odwoływać się do zupełnie różnych plików certyfikatów, nawet dla tej samej `server_name`. Jest to przydatne podczas rotacji certyfikatów lub uruchamiania starszego certyfikatu obok nowego w okresie przejściowym.
