Uit het leven met Kubernetes: hoe de HTTP-server de Spanjaarden niet bevoordeelde

Uit het leven met Kubernetes: hoe de HTTP-server de Spanjaarden niet bevoordeelde

Een vertegenwoordiger van onze klant, wiens applicatiestack zich in de Microsoft-cloud (Azure) bevindt, heeft een probleem opgelost: onlangs begonnen sommige verzoeken van sommige klanten uit Europa te eindigen met fout 400 (Bad Request). Alle applicaties zijn geschreven in .NET, geΓ―mplementeerd in Kubernetes...

EΓ©n van de toepassingen is de API, waar uiteindelijk al het verkeer doorheen komt. Dit verkeer wordt beluisterd door de HTTP-server Torenvalk, geconfigureerd door de .NET-client en gehost in een pod. Met het debuggen hadden we geluk in die zin dat er een specifieke gebruiker was die het probleem consequent reproduceerde. Alles werd echter gecompliceerd door de verkeersketen:

Uit het leven met Kubernetes: hoe de HTTP-server de Spanjaarden niet bevoordeelde

De fout in Ingress zag er als volgt uit:

{
   "number_fields":{
      "status":400,
      "request_time":0.001,
      "bytes_sent":465,
      "upstream_response_time":0,
      "upstream_retries":0,
      "bytes_received":2328
   },
   "stream":"stdout",
   "string_fields":{
      "ingress":"app",
      "protocol":"HTTP/1.1",
      "request_id":"f9ab8540407208a119463975afda90bc",
      "path":"/api/sign-in",
      "nginx_upstream_status":"400",
      "service":"app",
      "namespace":"production",
      "location":"/front",
      "scheme":"https",
      "method":"POST",
      "nginx_upstream_response_time":"0.000",
      "nginx_upstream_bytes_received":"120",
      "vhost":"api.app.example.com",
      "host":"api.app.example.com",
      "user":"",
      "address":"83.41.81.250",
      "nginx_upstream_addr":"10.240.0.110:80",
      "referrer":"https://api.app.example.com/auth/login?long_encrypted_header",
      "service_port":"http",
      "user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36",
      "time":"2019-03-06T18:29:16+00:00",
      "content_kind":"cache-headers-not-present",
      "request_query":""
   },
   "timestamp":"2019-03-06 18:29:16",
   "labels":{
      "app":"nginx",
      "pod-template-generation":"6",
      "controller-revision-hash":"1682636041"
   },
   "namespace":"kube-nginx-ingress",
   "nsec":6726612,
   "source":"kubernetes",
   "host":"k8s-node-55555-0",
   "pod_name":"nginx-v2hcb",
   "container_name":"nginx",
   "boolean_fields":{}
}

Tegelijkertijd gaf Torenvalk:

HTTP/1.1 400 Bad Request
Connection: close
Date: Wed, 06 Mar 2019 12:34:20 GMT
Server: Kestrel
Content-Length: 0

Zelfs met maximale breedsprakigheid bevatte de Torenvalkfout extreem veel weinig nuttige informatie:

{
   "number_fields":{"ThreadId":76},
   "stream":"stdout",
   "string_fields":{
      "EventId":"{"Id"=>17, "Name"=>"ConnectionBadRequest"}",
      "SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
      "ConnectionId":"0HLL2VJSST5KV",
      "@mt":"Connection id "{ConnectionId}" bad request data: "{message}"",
      "@t":"2019-03-07T13:06:48.1449083Z",
      "@x":"Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.n   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)n   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<ProcessRequestsAsync>d__185`1.MoveNext()",
      "message":"Malformed request: invalid headers."
   },
   "timestamp":"2019-03-07 13:06:48",
   "labels":{
      "pod-template-hash":"2368795483",
      "service":"app"
   },
   "namespace":"production",
   "nsec":145341848,
   "source":"kubernetes",
   "host":"k8s-node-55555-1",
   "pod_name":"app-67bdcf98d7-mhktx",
   "container_name":"app",
   "boolean_fields":{}
}

Het lijkt erop dat alleen tcpdump dit probleem zal helpen oplossen... maar ik zal het herhalen over de verkeersketen:

Uit het leven met Kubernetes: hoe de HTTP-server de Spanjaarden niet bevoordeelde

onderzoek

Uiteraard is het beter om naar het verkeer te luisteren op dat specifieke knooppunt, waar Kubernetes een pod heeft ingezet: het volume van de dump zal zodanig zijn dat het mogelijk zal zijn om in ieder geval vrij snel iets te vinden. En inderdaad, bij onderzoek werd het volgende frame opgemerkt:

GET /back/user HTTP/1.1
Host: api.app.example.com
X-Request-ID: 27ceb14972da8c21a8f92904b3eff1e5
X-Real-IP: 83.41.81.250
X-Forwarded-For: 83.41.81.250
X-Forwarded-Host: api.app.example.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Original-URI: /front/back/user
X-Scheme: https
X-Original-Forwarded-For: 83.41.81.250
X-Nginx-Geo-Client-Country: Spain
X-Nginx-Geo-Client-City: M.laga
Accept-Encoding: gzip
CF-IPCountry: ES
CF-RAY: 4b345cfd1c4ac691-MAD
CF-Visitor: {"scheme":"https"}
pragma: no-cache
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36
referer: https://app.example.com/auth/login
accept-language: en-US,en;q=0.9,en-GB;q=0.8,pl;q=0.7
cookie: many_encrypted_cookies; .AspNetCore.Identity.Application=something_encrypted; 
CF-Connecting-IP: 83.41.81.250
True-Client-IP: 83.41.81.250
CDN-Loop: cloudflare

HTTP/1.1 400 Bad Request
Connection: close
Date: Wed, 06 Mar 2019 12:34:20 GMT
Server: Kestrel
Content-Length: 0

Bij nadere inspectie van de stortplaats werd het woord opgemerkt M.laga. Het is gemakkelijk te raden dat er geen M.laga-stad in Spanje is (maar dat is er wel). Malaga). We grepen dit idee aan en keken naar de Ingress-configuraties, waar we die van een maand geleden zagen ingevoegd (op verzoek van de klant) "onschadelijk" fragment:

    ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header X-Nginx-Geo-Client-Country $geoip_country_name;
      proxy_set_header X-Nginx-Geo-Client-City $geoip_city;

Na het uitschakelen van het doorsturen van deze headers werd alles in orde! (Het werd al snel duidelijk dat de applicatie zelf deze headers niet langer nodig had.)

Laten we nu eens naar het probleem kijken algemener. Het kan eenvoudig binnen de applicatie worden gereproduceerd door een telnet-verzoek in te dienen localhost:80:

GET /back/user HTTP/1.1
Host: api.app.example.com
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
Cookie: test=Desiree

... geeft terug 401 Unauthorized, zoals verwacht. Wat gebeurt er als we het volgende doen:

GET /back/user HTTP/1.1
Host: api.app.example.com
cache-control: no-cache
accept: application/json, text/plain, */*
origin: https://app.example.com
Cookie: test=DΓ©sirΓ©e

?

Zal terugkeren 400 Bad request β€” in het applicatielogboek ontvangen we een foutmelding die ons al bekend is:

{
   "@t":"2019-03-31T12:59:54.3746446Z",
   "@mt":"Connection id "{ConnectionId}" bad request data: "{message}"",
   "@x":"Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.n   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)n   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<ProcessRequestsAsync>d__185`1.MoveNext()",
   "ConnectionId":"0HLLLR1J974L9",
   "message":"Malformed request: invalid headers.",
   "EventId":{
      "Id":17,
      "Name":"ConnectionBadRequest"
   },
   "SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
   "ThreadId":71
}

Resultaten van

Specifiek Torenvalk kan niet HTTP-headers met de juiste tekens correct verwerken in UTF-8, die voorkomen in de namen van een vrij groot aantal steden.

Bijkomend speelt in ons geval mee dat de opdrachtgever op dit moment niet van plan is de implementatie van Kestrel in de applicatie te veranderen. Er zijn echter problemen in AspNetCore zelf (β„– 4318, β„– 7707) zeggen ze dat dit niet zal helpen...

Samenvattend: de nota gaat niet meer over de specifieke problemen van Kestrel of UTF-8 (in 2019?!), maar over het feit dat mindfulness en consistente studie Elke stap die u zet bij het zoeken naar problemen zal vroeg of laat vruchten afwerpen. Succes!

PS

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie