←Terug naar het blog

Hoe Nginx-toegangst logs te lezen

2025-08-20‱12 min lezen

Wanneer er iets misgaat, vertelt het toegangslogboek een verhaal. Wie de site bezocht. Wat ze vroegen. Welke URL's faalden. Wanneer een piek begon. Ik heb deze stappen op een echt project toegepast en ze werkten. De onderstaande voorbeelden zijn veilig om te kopiëren en uit te voeren, en vervolgens aan te passen voor uw setup.

Wat zijn Nginx-toegangst logs?

Nginx-toegangst logs zijn tekstbestanden die elke HTTP-verzoek registreren dat uw webserver ontvangt. Elke regel vertegenwoordigt één verzoek en bevat details zoals het IP-adres van de client, tijdstempel, HTTP-methode, URL-pad, statuscode, responsgrootte en meer.

Deze logs worden automatisch gegenereerd door Nginx terwijl het verzoeken verwerkt. Elke keer dat iemand uw site bezoekt, op een link klikt, een formulier verzendt of zelfs een kapotte URL raakt, schrijft Nginx een regel naar het toegangslogboek. Dit gebeurt in realtime, dus het logbestand groeit constant.

Hoe toegangst logs werken

Nginx gebruikt een configureerbaar logformaat dat is gedefinieerd in uw nginx.conf-bestand. Het standaardformaat ziet er als volgt uit:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent"';

Dit creëert logboekvermeldingen zoals:

192.168.1.100 - - [20/Aug/2025:10:30:45 +0000] "GET /blog/post HTTP/1.1" 200 1234 "https://example.com/" "Mozilla/5.0..."

Veel moderne setups gebruiken een gedetailleerder JSON-achtig formaat met key=value-paren, wat de voorbeelden in dit bericht aannemen.

CDN vs. Origin: Waar te zoeken naar logs

Als u een CDN gebruikt (zoals Cloudflare, CloudFront of Fastly), zijn er twee verschillende sets logs om te overwegen:

CDN edge logs: Toon verzoeken van daadwerkelijke gebruikers die het CDN raken. Deze bevatten de echte client-IP's, gebruikersagenten en geografische locaties.

Origin server logs (waar dit bericht over gaat): Toon verzoeken die via het CDN uw Nginx-server hebben bereikt. Deze logs tonen vaak het IP-adres van het CDN als client, niet het IP van de eindgebruiker.

Voor probleemoplossing wilt u meestal eerst de CDN-logs. Controleer alleen origin-logs wanneer u wilt zien wat uw server daadwerkelijk heeft bereikt of bij het debuggen van server-side problemen.

Alle voorbeelden gaan uit van key=value logs (velden zoals status="404" en request="GET /path HTTP/1.1"), en bestanden onder /var/log/nginx/. Pas de namen indien nodig aan.

Wat u zult leren

  • Hoe u live en gzippete logs in één keer leest
  • Hoe u top-IP's en top-falende URL's vindt
  • Hoe u alles van één IP ophaalt
  • Hoe u inzoomt op een kort tijdsvenster
  • Hoe u toegangst logs koppelt aan WAF-blokkades
  • Hoe u resultaten snel en bruikbaar houdt

Quick start

Lees alles, ongeacht of het bestand .log of .gz is:

zgrep -h . /var/log/nginx/ssl-*.access.log*

Die zgrep-truc verwerkt zowel normale als geroteerde bestanden. Voeg filters toe na de opdracht.

Tools die u zult gebruiken

zgrep: Net als grep, maar werkt op zowel reguliere bestanden als gecomprimeerde (.gz) bestanden. Perfect voor logbestanden die worden geroteerd en gecomprimeerd.

awk: Een krachtige tekstverwerkingstool die regels kan splitsen op scheidingstekens en specifieke velden kan extraheren. Geweldig voor het parsen van gestructureerde logformaten.

cut: Extraheert specifieke kolommen of velden uit tekst. Gebruik -d om een scheidingsteken (zoals aanhalingstekens of komma's) op te geven en -f om te kiezen welk veldnummer u wilt.

Vind top-IP's achter 404-stormen

Wanneer redacteuren "veel gebroken links" melden, begin hier.

zgrep -h . /var/log/nginx/ssl-*.access.log* \
| awk -F'status="' '$2 ~ /^404"/' \
| awk -F'x_forwarded_for="' '{print $2}' \
| cut -d'"' -f1 | cut -d',' -f1 \
| LC_ALL=C sort | uniq -c | sort -nr | head

Waarom het helpt. U ziet eerst de ergste overtreders. Als een IP willekeurige paden scant, zult u het snel opmerken.

Bekijk alles wat een enkel IP heeft gedaan

Handig als u een blokkade of een piek van één bron moet uitleggen.

IP="112.134.209.112"
zgrep -h . /var/log/nginx/ssl-*.access.log* \
| grep -F 'x_forwarded_for="'$IP

Tip. In sommige stacks kan het client-IP zich in src of src_ip bevinden. Als dat zo is, wissel dan de veldnaam in de grep-opdracht.

Top-URL's geraakt door dat IP (negeer query-strings)

IP="112.134.209.112"
zgrep -h . /var/log/nginx/ssl-*.access.log* \
| grep -F 'x_forwarded_for="'$IP \
| awk -F'request="' '{print $2}' | cut -d'"' -f1 \
| awk '{print $2}' | cut -d'?' -f1 \
| LC_ALL=C sort | uniq -c | sort -nr | head

Waarom het helpt. Het weglaten van de query-string groepeert "dezelfde pagina met verschillende parameters" samen, wat patronen duidelijk maakt.

Top falende URL's per status

404's:

zgrep -h . /var/log/nginx/ssl-*.access.log* \
| awk -F'status="' '$2 ~ /^404"/' \
| awk -F'request="' '{print $2}' | cut -d'"' -f1 \
| awk '{print $2}' | cut -d'?' -f1 \
| LC_ALL=C sort | uniq -c | sort -nr | head

5xx:

zgrep -h . /var/log/nginx/ssl-*.access.log* \
| awk -F'status="' '{split($2,a,"\""); if (a[1] ~ /^5[0-9][0-9]$/) print}' \
| awk -F'request="' '{print $2}' | cut -d'"' -f1 \
| awk '{print $2}' | cut -d'?' -f1 \
| LC_ALL=C sort | uniq -c | sort -nr | head

Waarom het helpt. Dit geeft u een gerangschikte lijst van probleempaden. Als u de top vijf oplost, lost u vaak het meeste leed op.

Zoom in op een kort tijdsvenster

Wanneer een piek op een bekend tijdstip optreedt, wilt u de periode ervoor en erna bekijken.

Eenvoudig en snel (goed genoeg voor een venster van 10 minuten binnen hetzelfde uur):

# Voorbeeld: 09/Aug/2025 23:15–23:25
zgrep -h 'time_local="' /var/log/nginx/ssl-*.access.log* \
| egrep '09/Aug/2025:23:1[5-9]|09/Aug/2025:23:2[0-5]'

Pipe het resultaat naar een van de bovenstaande tellingen.

Waarom het helpt. U vergelijkt het verkeer vlak voor en vlak na een gebeurtenis, wat vaak alles is wat u nodig hebt om te zien wat er is veranderd.

Formulierposts en grote body's

Grote POST-verzoeken naar een formulier kunnen WAF-regels activeren. Meet ze.

PATH_RE="/about/.*speaker-request-form"
zgrep -h . /var/log/nginx/ssl-*.access.log* \
| awk -F'request="' -v r="$PATH_RE" '
  { split($2,a,"\""); split(a[1],b," "); m=b[1]; u=b[2];
    if (m=="POST" && u ~ r) print }' \
| awk -F'request_length="' '{print $2}' | cut -d'"' -f1 \
| awk '{sum+=$1; c++} END{print "POST count="c, "avg_request_length=" (c?sum/c:0)}'

Waarom het helpt. Als de gemiddelde verzoekgrootte hoog is, kan uw WAF inspectie blokkeren. U heeft nu bewijs en cijfers.

Koppel toegangst logs aan WAF-blokkades

  1. Pak de exacte tijd en regel van uw WAF-gebeurtenis.
  2. Filter toegangst logs voor dat venster met de "tijdsvenster"-truc.
  3. Zoek naar hetzelfde pad, hetzelfde IP-adres of een grote request_length.
  4. Als de WAF-regel spreekt over body-grootte of inspectielimieten, bevestig dit dan met de POST-analyse hierboven.

Dit sluit de cirkel. U kunt zeggen wat er is gebeurd en waarom het is gebeurd.

Snelheidstips die ertoe doen

  • Filter vroeg. Voeg grep 'status="404"' toe voordat u sorteert.
  • Gebruik LC_ALL=C sort voor sneller en stabieler sorteren.
  • Verwijder query-strings om pagina's per pad te groeperen.
  • Sample eerst. Voer head uit op een pipeline om te controleren of u het juiste veld selecteert.
  • Documenteer uw log_format in de repository. Uw toekomstige zelf zal u dankbaar zijn.

Veelvoorkomende valkuilen

  • Tellen op remote_addr wanneer uw app achter een proxy draait. Gebruik x_forwarded_for of uw echte client-IP-veld.
  • Aannemen dat alle logbestanden hetzelfde formaat gebruiken. Controleer uw nginx.conf log_format voordat u gaat parsen.
  • Vergeten dat geroteerde logs (.gz-bestanden) zgrep nodig hebben, geen grep.
  • Gebruik maken van complexe regex-patronen die breken wanneer logformaten veranderen. Houd het simpel.

Takeaways

Logs beantwoorden snel echte vragen. Begin met een duidelijke vraag, pipe alleen wat u nodig hebt en tel. Koppel wat u ziet in Nginx aan wat uw WAF rapporteert. U gaat van "iets voelde traag" naar "deze URL faalde 2.379 keer vanaf één IP in tien minuten, en hier is de oplossing."