nginx reverse proxy configureren: stap voor stap
Leer hoe u een nginx reverse proxy opzet voor Ubuntu 24.04. Wij leggen uit hoe u proxy_pass, headers, websockets en uploads correct configureert voor een stabiele verbinding.
Wat een nginx reverse proxy-configuratie doet
Een nginx reverse proxy ontvangt verzoeken op poort 80 en poort 443, stuurt deze door naar een applicatie die op een lokale poort luistert, en geeft het antwoord van die applicatie terug aan de browser. De configuratie bestaat uit één server-blok, en dit blok is kort. Vrijwel alle complexiteit zit in vijf of zes regels die uw applicatie vertellen wie de werkelijke client was en welk protocol deze gebruikte.
Alles hieronder is vanaf nul opgebouwd op Ubuntu 24.04, met gebruik van het nginx-pakket uit de distributie. Het uitgangspunt is een applicatie die al antwoordt op 127.0.0.1:3000. Als u nog geen keuze heeft gemaakt voor een proxy, is hoe nginx zich verhoudt tot Caddy en Traefik de vergelijking die u eerst moet lezen. Hieronder volgt hoe de nginx-configuratie er regel voor regel uitziet.
Voer deze configuraties uit op uw eigen server. Test elke wijziging met sudo nginx -t voordat u de configuratie opnieuw laadt, en lees wat de output aangeeft.
Waar nginx de configuratie bewaart op Ubuntu
sudo apt update
sudo apt install -y nginx
ls -l /etc/nginx/sites-enabled/Het hoofdbestand is /etc/nginx/nginx.conf. Dit stelt globale opties in binnen een http { }-blok en laadt vervolgens twee mappen: /etc/nginx/conf.d/*.conf en /etc/nginx/sites-enabled/*. Op Ubuntu en Debian schrijft u één bestand per site in /etc/nginx/sites-available/ en schakelt u deze in met een symbolische koppeling naar /etc/nginx/sites-enabled/. Het verwijderen van de symbolische koppeling schakelt de site uit en behoudt het bestand.
Twee richtlijnen die later worden gebruikt, werken alleen in de http-context, nooit binnen een server-blok: map en upstream. Plaats deze in een eigen bestand onder /etc/nginx/conf.d/, omdat die map op het http-niveau wordt ingeladen.
Het pakket bevat standaard een ingeschakelde site genaamd default. Deze is gemarkeerd als default_server, wat betekent dat deze reageert op elk verzoek waarvan de Host-header met geen enkele server_name in uw configuratie overeenkomt. Zolang deze ingeschakeld blijft, komt een verzoek dat niet aan uw domeinnamen voldoet hier terecht in plaats van bij uw applicatie. Verwijder de symbolische koppeling zodra uw eigen site werkt.
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginxHet kleinste serverblok dat één applicatie proxied
server {
listen 80;
listen [::]:80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
}
}Sla dit op als /etc/nginx/sites-available/app.example.com, schakel het vervolgens in en laad de configuratie.
sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
curl -sI -H 'Host: app.example.com' http://127.0.0.1/listen 80; bindt IPv4 en listen [::]:80; bindt IPv6. Laat de tweede regel weg en een bezoeker wiens DNS (domain name system)-opzoeking een AAAA-record voor uw server retourneert, krijgt een verbindingsweigering, terwijl iedereen op IPv4 een werkende site ziet. Het bugrapport dat u ontvangt zegt dan "bij mij werkt het wel".
server_name wordt vergeleken met de Host-header die de browser meestuurt. Meerdere namen kunnen worden vermeld, gescheiden door spaties. Als er geen blok overeenkomt, gebruikt nginx het blok dat default_server is; dit is de reden waarom de standaard meegeleverde site moest worden verwijderd.
location / is een prefix-match op het verzoekpad en / komt overeen met elk pad. proxy_pass is het adres waarmee nginx een verbinding opent. Zorg dat de applicatie gebonden blijft aan 127.0.0.1, zodat de enige toegangsweg via nginx verloopt. Als de applicatie in een container draait, publiceer deze dan als 127.0.0.1:3000:3000 en niet als 3000:3000, omdat Docker zijn eigen regels schrijft en poorten direct langs ufw publiceert; een openlijk gepubliceerde poort is daardoor vanaf het internet bereikbaar, ongeacht wat uw firewall aangeeft.
De curl-regel verstuurt de juiste Host-header vanaf de server zelf, zodat u het blok kunt testen voordat DNS naar een locatie verwijst.
Wat nginx naar de upstream stuurt als u niets anders configureert
proxy_pass verbergt standaard vier zaken voor uw applicatie.
nginx spreekt standaard HTTP/1.0 met de backend en stuurt Connection: close mee, waardoor elk verzoek een nieuwe upstream-verbinding opent en een protocol-upgrade onmogelijk is.
De header Host wordt herschreven naar de waarde in proxy_pass, wat 127.0.0.1:3000 is. Een applicatie die absolute links opbouwt op basis van Host, genereert nu links die niemand buiten de server kan openen.
De verbinding die de applicatie bereikt, is afkomstig van nginx; de applicatie ziet daarom 127.0.0.1 als clientadres. Elke logregel en elke rate limit binnen de applicatie registreert vervolgens de proxy in plaats van de bezoeker.
De applicatie kan niet zien dat de browser HTTPS gebruikte, omdat de ontvangen verbinding platte HTTP is op een loopback-adres.
Vier regels lossen dit alles op.
De vier in te stellen headers en wat ze de backend laten zien
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}Host bevat de naam die de bezoeker heeft ingevoerd. $host is de naam uit het verzoek, zonder poortnummer en in kleine letters. Stel deze in zodat uw applicatie correcte absolute URL's genereert: de redirect na een login of de link in een e-mail voor het opnieuw instellen van een wachtwoord. Laat u deze weg, dan verwijzen die URL's naar 127.0.0.1:3000, waardoor inloggen de browser naar een adres stuurt dat de verbinding weigert. Als uw applicatie ook de poort nodig heeft, omdat u deze op 8080 aanbiedt, gebruik dan $http_host; dit is de header exact zoals de client deze heeft verzonden.
X-Real-IP bevat één waarde: $remote_addr, het adres waarvan nginx de verbinding heeft geaccepteerd. Applicaties lezen dit voor hun eigen toegangslogs en rate limiting.
X-Forwarded-For bevat een lijst. $proxy_add_x_forwarded_for voegt $remote_addr toe aan wat de client al in die header had geplaatst, zodat de waarde door komma's gescheiden is en de door nginx toegevoegde vermelding de laatste is. Dit detail bepaalt of de header vertrouwd kan worden: een client kan elke gewenste X-Forwarded-For sturen, waardoor een applicatie die de eerste vermelding leest, elk willekeurig adres kan worden voorgespiegeld. Wanneer nginx de edge-server is, schrijf dan $remote_addr en negeer de versie van de client. Wanneer er een CDN of een andere proxy voor staat, gebruik dan set_real_ip_from en real_ip_header uit de realip-module, zodat $remote_addr zelf het werkelijke clientadres wordt.
X-Forwarded-Proto bevat http of https. Frameworks lezen dit om te bepalen of cookies als Secure moeten worden gemarkeerd en of een redirect naar HTTPS moet worden afgedwongen. Laat u dit weg op een TLS-site, dan ziet een applicatie die HTTPS afdwingt http, antwoordt met een redirect naar het HTTPS-adres, ontvangt het volgende verzoek via nginx, ziet nog steeds http en redirect opnieuw. De browser geeft het op en toont ERR_TOO_MANY_REDIRECTS.
Het herhalen van deze vier regels in elke locatie zorgt ervoor dat ze na verloop van tijd gaan afwijken. Plaats ze in één bestand en includeer dit.
# /etc/nginx/snippets/proxy-headers.conf
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;location / {
include snippets/proxy-headers.conf;
proxy_pass http://127.0.0.1:3000;
}Overerving kent hier een valkuil. Een locatie erft de proxy_set_header-richtlijnen van het serverblok alleen zolang die locatie er zelf geen definieert. Voeg één proxy_set_header toe binnen de locatie en elke header die op serverniveau is gedefinieerd, vervalt voor die locatie. Houd ze daarom allemaal op hetzelfde niveau, of include het fragment in elke locatie die als proxy fungeert.
Waarom maakt mijn WebSocket-applicatie verbinding en verbreekt deze vervolgens weer?
De standaardinstellingen staan de upgrade niet toe en de standaard read timeout sluit een inactieve tunnel na 60 seconden. Een WebSocket begint als een HTTP-verzoek met Upgrade: websocket en Connection: Upgrade. Dit zijn hop-by-hop headers; dit betekent dat een proxy deze hoort te verwerken in plaats van door te sturen, en HTTP/1.0 beschikt helemaal niet over een upgrade-mechanisme. Beide moeten handmatig worden teruggeplaatst.
De map-configuratie wordt in de http-context geplaatst, in een eigen bestand.
# /etc/nginx/conf.d/websocket.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}Vervolgens de location-configuratie.
location / {
include snippets/proxy-headers.conf;
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}De map-configuratie is aanwezig zodat één location beide soorten verkeer kan afhandelen. Bij een gewoon verzoek is $http_upgrade leeg, waardoor $connection_upgrade verandert in close. Bij een upgrade-verzoek bevat deze websocket, waardoor de header die naar de upstream wordt gestuurd Connection: upgrade is. Het hardcoderen van proxy_set_header Connection "upgrade"; stuurt die header ook bij elk gewoon paginabezoek mee, en sommige backends reageren op een dergelijk verzoek met een 400-foutmelding.
proxy_read_timeout is de oorzaak van meldingen zoals "het laadt, maar stopt daarna met updaten". De standaardwaarde is 60 seconden en deze meet de tijd tussen twee leesacties van de backend, niet de totale levensduur van de verbinding. Een WebSocket die 60 seconden stil blijft, wordt door nginx gesloten en de browserconsole toont dat de socket sluit met code 1006. Applicaties die vaker dan eens per minuut een eigen heartbeat sturen, merken hier niets van. Applicaties die dit niet doen, verbreken de verbinding na een minuut. Live editors en dashboards zijn de plekken waar dit als eerste optreedt, waarbij een zelfgehoste n8n-instantie achter HTTPS een veelvoorkomend voorbeeld is.
Waarom verandert een afsluitende slash in proxy_pass mijn URL's?
De regel is simpel. Als proxy_pass eindigt met een URI (uniform resource identifier), zelfs een enkele /, verwijdert nginx het deel van het aanvraagpad dat overeenkwam met het location-prefix en plaatst die URI daarvoor in de plaats. Als proxy_pass stopt bij de host en poort, wordt het aanvraagpad ongewijzigd doorgegeven.
location /app/ {
proxy_pass http://127.0.0.1:3000/;
}Een aanvraag voor /app/status bereikt de backend als /status.
location /app/ {
proxy_pass http://127.0.0.1:3000;
}Een aanvraag voor /app/status bereikt de backend als /app/status.
Welke vorm u nodig heeft, hangt af van de applicatie. Een applicatie met een instelling voor een basispad of submap vereist de tweede vorm, waarbij de instelling op de hoogte is van /app. Een applicatie die niets weet van prefixes heeft de eerste vorm nodig. De eerste vorm heeft een direct zichtbaar nadeel: de HTML die de applicatie teruggeeft, bevat nog steeds absolute paden zoals /static/main.css, de browser vraagt deze op bij de root van de site, er is geen overeenkomende locatie, en de pagina wordt zonder styling weergegeven. Het netwerktabblad van de browser toont dat deze asset-aanvragen resulteren in een 404-fout. De oplossing is de instelling voor het basispad in de applicatie zelf, of een tweede location /static/ die naar dezelfde backend wijst.
Een regex-locatie kan geen URI bevatten in proxy_pass. sudo nginx -t weigert de configuratie en geeft de reden aan: "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block.
Deze hele categorie problemen verdwijnt wanneer elke applicatie een eigen naam krijgt, app.example.com, geproxyed vanaf location /. Subpaden zijn alleen de moeite waard als u geen DNS-records kunt toevoegen.
Hoe plaats ik meer dan één backend achter één naam?
Dit doet u met een upstream-blok. Dit blok hoort bij de http-context; plaats het daarom boven het server-blok in hetzelfde bestand, of in /etc/nginx/conf.d/.
upstream app_backend {
least_conn;
server 127.0.0.1:3000 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3001 max_fails=3 fail_timeout=30s;
keepalive 32;
}De location verwijst er vervolgens naar met: proxy_pass http://app_backend;.
De standaardmethode is round robin. least_conn stuurt elk verzoek naar de backend met het laagste aantal actieve verbindingen, wat geschikt is voor verzoeken van ongelijke duur. ip_hash koppelt één clientadres aan één backend. U heeft ip_hash nodig wanneer de applicatie sessies in het eigen geheugen bijhoudt. Round robin over twee van dergelijke backends logt gebruikers namelijk willekeurig uit, omdat hun verzoeken terechtkomen op de instantie die de sessie niet kent. Het verplaatsen van sessies naar gedeelde opslag is de betere oplossing.
max_fails=3 fail_timeout=30s betekent dat drie mislukte pogingen binnen 30 seconden de server voor 30 seconden uit de roulatie halen. Wanneer elke server in het blok in die status verkeert, krijgen clients een 502-foutmelding en vermeldt het foutenlogboek no live upstreams while connecting to upstream.
keepalive 32 houdt tot 32 inactieve verbindingen met de backends open per worker-proces, wat bij de meeste verzoeken een TCP-handshake bespaart. Dit werkt alleen met proxy_http_version 1.1 en zonder Connection: close naar de upstream. Als dezelfde location ook de WebSocket-map gebruikt, wijzig dan het lege geval van close naar een lege string. Hierdoor bevatten normale verzoeken geen Connection-header en wordt de gepoolde verbinding hergebruikt.
map $http_upgrade $connection_upgrade {
default upgrade;
'' '';
}Namen binnen een upstream-blok worden opgelost wanneer nginx start. Als uw backend een container is die een nieuw adres krijgt bij een herstart, blijft nginx het oude adres gebruiken totdat u de configuratie herlaadt. Binnen een Docker-netwerk kunt u de opzoekactie verplaatsen naar het moment van het verzoek met de ingebouwde resolver.
resolver 127.0.0.11 valid=10s;
set $backend http://app:3000;
proxy_pass $backend;Zodra containers zo vaak verschijnen en verdwijnen dat u nginx handmatig moet bijwerken, is een proxy die container-labels leest het betere gereedschap. Traefik voor meerdere Docker Compose-applicaties bouwt zijn routes op basis van de containers zelf.
Waarom mislukken uploads met 413 Request Entity Too Large?
client_max_body_size staat standaard op 1 megabyte. Een grotere request body wordt door nginx geweigerd voordat uw applicatie deze ontvangt, en het foutenlogboek registreert client intended to send too large body. Verhoog deze waarde in het server-blok of in de locatie waar de uploads plaatsvinden.
client_max_body_size 512m;Een waarde van 0 schakelt de controle volledig uit. De applicatie heeft zelf ook een limiet; als een 413-fout blijft optreden na deze wijziging, is de fout afkomstig van de backend en moet u de uploadinstellingen van de applicatie zelf controleren.
Standaard leest nginx de volledige request body voordat de upstream-verbinding wordt geopend, waarbij grote bestanden eerst naar een tijdelijk bestand op de schijf worden geschreven. Dit beschermt de applicatie tegen trage clients, omdat de backend de upload op volledige lokale snelheid ontvangt. Voor zeer grote uploads kunt u streaming gebruiken.
proxy_request_buffering off;De backend ontvangt de body vervolgens zodra deze binnenkomt en moet in staat zijn dit te verwerken. nginx verliest hierbij de mogelijkheid om het verzoek opnieuw te proberen bij een andere upstream, omdat de body al is verwerkt.
client_body_timeout, standaard 60 seconden, is van toepassing op de tijd tussen twee opeenvolgende leesacties van de body in plaats van op de gehele upload. Een trage maar constante upload blijft hierdoor behouden. Een vastgelopen upload wordt afgebroken.
Response buffering en de instelling die live output blokkeert
proxy_buffering staat standaard aan en is in de meeste gevallen de gewenste instelling. Nginx leest de response van uw applicatie zo snel als de applicatie deze kan schrijven, slaat deze op en voert de data in het tempo van de trage client aan de client door. De app-worker is hierdoor eerder klaar in plaats van dat deze bezet blijft gedurende de gehele trage download.
Dit blokkeert streaming responses. Server-sent events en live log-output tonen de lezer niets totdat een buffer vol is. Schakel buffering in dat specifieke location-blok uit.
proxy_buffering off;Als u de applicatie beheert, is het beter om de header X-Accel-Buffering: no enkel mee te sturen bij streaming responses. Nginx leest deze header per response en schakelt buffering alleen voor die specifieke response uit, waardoor gewone pagina's van de voordelen blijven profiteren.
Wanneer het error log de melding upstream sent too big header while reading response header from upstream geeft, pasten de response headers niet in één buffer. proxy_buffer_size is standaard ingesteld op één geheugenpagina, 4 of 8 kilobyte afhankelijk van het platform, en lange cookies of grote authenticatie-headers veroorzaken een overflow. Verhoog beide waarden.
proxy_buffer_size 16k;
proxy_buffers 8 16k;Waar hoort TLS in deze configuratie thuis?
Bij nginx, vóór alles wat hierboven staat. TLS (transport layer security) wordt beëindigd bij de proxy, en de verbinding van nginx naar de applicatie blijft standaard HTTP via het loopback-adres, waar niemand anders op het netwerk deze kan inzien. De applicatie verneemt dat de bezoeker HTTPS heeft gebruikt via X-Forwarded-Proto, de vierde van de vier headers.
Schrijf certificaatpaden niet handmatig. Wijs het DNS-record naar de server, open de firewall en laat Certbot dit serverblok bewerken: het voegt de regel listen 443 ssl toe met de ssl_certificate paden, plus een redirect vanaf poort 80. Een Let's Encrypt-certificaat uitgeven voor nginx met Certbot behandelt de uitgifte en de timer voor vernieuwing.
sudo ufw allow 'Nginx Full'
sudo ufw statusNginx Full is een applicatieprofiel dat het nginx-pakket installeert, en dit opent poort 80 en poort 443 tegelijkertijd. Poort 80 moet open blijven voor de HTTP-01 vernieuwingschallenge, zelfs nadat elke bezoeker is omgeleid naar HTTPS.
Test de configuratie en herlaad vervolgens
sudo nginx -t
sudo systemctl reload nginxnginx -t parseert elk opgenomen bestand en rapporteert of de test is geslaagd, of toont het bestand en de regel waar de fout optrad. Lees deze uitvoer voordat u de configuratie herlaadt. Een herlaadactie met een defecte configuratie wordt niet toegepast: Nginx blijft de vorige configuratie gebruiken, waardoor de site online blijft terwijl uw wijziging stilzwijgend niets doet. systemctl restart gedraagt zich anders en minder gunstig, omdat een herstart de draaiende server eerst afsluit; een configuratiefout zorgt er in dat geval voor dat Nginx helemaal niet meer draait. Gebruik standaard de herlaadfunctie en bewaar de herstart voor de zeldzame wijzigingen die dit vereisen.
sudo tail -f /var/log/nginx/error.log
sudo ss -lntp | grep -E ':(80|443|3000)'De regel ss toont welk proces welke poort bezet houdt, zodat u kunt bevestigen dat de applicatie daadwerkelijk luistert op de poort waar proxy_pass naar verwijst.
De fouten die u daadwerkelijk zult tegenkomen
502 Bad Gateway, met connect() failed (111: Connection refused) while connecting to upstream in het foutenlogboek. Er luistert niets op het adres in proxy_pass. De applicatie is gestopt, gebonden aan een andere poort, of gebonden aan een intern containeradres dat de host niet kan bereiken.
502 met no live upstreams while connecting to upstream. Elke server in het upstream-blok is momenteel door max_fails gemarkeerd als defect. Herstel de backends. nginx probeert ze opnieuw zodra fail_timeout is verlopen.
504 Gateway Time-out, met upstream timed out (110: Connection timed out) while reading response header from upstream. De backend accepteerde de verbinding en stuurde vervolgens gedurende proxy_read_timeout seconden niets terug. Het verhogen van de time-out is correct voor een daadwerkelijk traag rapport, maar onjuist voor een applicatie die vastgelopen is.
Elk pad geeft een 404-foutmelding vanuit de applicatie. De regel voor de afsluitende slash heeft het pad herschreven. Vergelijk het pad dat de applicatie logt met het pad dat u heeft opgevraagd.
Een andere site antwoordt. server_name komt niet overeen met de Host-header, waardoor het verzoek is doorgevallen naar het default_server-blok.
De pagina laadt, maar de interface bevriest na ongeveer een minuut. Dit is het WebSocket-scenario: de Upgrade-afhandeling ontbreekt, of proxy_read_timeout staat nog op 60 seconden.
FAQ
Waarom geeft nginx een 502 Bad Gateway na het toevoegen van proxy_pass?
nginx kon geen verbinding openen met het adres in proxy_pass. Het foutenlogboek op /var/log/nginx/error.log benoemt de oorzaak: connect() failed (111: Connection refused) while connecting to upstream betekent dat er niets luistert op dat adres, en no live upstreams betekent dat elke server in een upstream-blok als gefaald is gemarkeerd. Voer sudo ss -lntp | grep 3000 uit om te zien welk proces de poort bezet houdt en aan welk adres het is gebonden. Een applicatie die is gebonden aan een intern containeradres, of aan een andere poort dan die u heeft opgegeven, geeft telkens deze foutmelding.
Waarom verbreekt mijn applicatie na ongeveer een minuut de verbinding achter nginx?
De verbinding is een WebSocket en proxy_read_timeout staat nog op de standaardwaarde van 60 seconden, wat de tijd meet tussen twee leesacties van de backend. Een inactieve socket wordt door nginx gesloten en de browserconsole rapporteert sluitingscode 1006. Stel proxy_http_version 1.1 in, geef Upgrade en Connection door met een map op $http_upgrade, en verhoog proxy_read_timeout naar bijvoorbeeld 3600s. Zonder de Upgrade-header vindt de upgrade nooit plaats, waardoor de applicatie terugvalt op polling of geen live-updates toont.
Maakt de slash aan het einde van proxy_pass uit?
Ja, dit verandert het pad dat uw backend ontvangt. Bij location /app/ en proxy_pass http://127.0.0.1:3000/ komt een verzoek voor /app/status aan bij de backend als /status, omdat elke URI na de host en poort het gematchte locatie-prefix vervangt. Verwijder die laatste slash en hetzelfde verzoek komt aan als /app/status. Het strippen van het prefix breekt vaak de asset-links van de applicatie zelf, die absoluut blijven en vervolgens een 404-fout geven op de root van de site. Een applicatie met een basispad-instelling werkt daarom beter met de vorm die het pad volledig doorgeeft.
Waarom logt mijn applicatie 127.0.0.1 als IP-adres van elke bezoeker?
Omdat de verbinding die de applicatie ontvangt daadwerkelijk afkomstig is van nginx op het loopback-adres. Het adres van de bezoeker bereikt de applicatie alleen via een header die u instelt: proxy_set_header X-Real-IP $remote_addr; voor een enkele waarde, en proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; voor de toegevoegde keten. De applicatie moet vervolgens worden geconfigureerd om die headers te vertrouwen. Onthoud dat een client zijn eigen X-Forwarded-For kan sturen; wanneer nginx de edge-server is, overschrijf deze dan met $remote_addr in plaats van deze toe te voegen.
Heb ik TLS nodig op de verbinding tussen nginx en mijn applicatie?
Niet wanneer de applicatie op dezelfde server draait en is gebonden aan 127.0.0.1, omdat dat verkeer de machine nooit verlaat. Beëindig TLS bij nginx, houd proxy_pass op gewone HTTP via loopback, en stuur X-Forwarded-Proto $scheme mee zodat de applicatie weet dat de bezoeker HTTPS heeft gebruikt. Als de backend op een andere host staat via een netwerk dat u niet beheert, heeft die verbinding eigen beveiliging nodig, hetzij HTTPS naar de backend of een privétunnel tussen de twee machines.