
A ügyfelünk képviselője, akinek alkalmazáskészlete a Microsoft (Azure) felhőjében működik, problémával keresett meg minket: az utóbbi időben néhány európai ügyféltől érkező kérések egy része 400-as hibával zárult le (). Minden alkalmazás .NET nyelven íródott, Kubernetes környezetben fut…
Az egyik alkalmazás egy API, amelyen keresztül végül az összes forgalom érkezik. Ezt a forgalmat a , amelyet a .NET kliens konfigurált, pod-ban helyezik el. A hibaelhárítás során szerencsénk volt, mert volt egy konkrét felhasználó, akinél a probléma stabilan reprodukálható volt. Azonban a forgalom láncolata bonyolította a helyzetet:

Az Ingress hiba a következőképpen nézett ki:
{
"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":{}
}A Kestrel a következő választ adta:
HTTP/1.1 400 Helytelen kérés
Kapcsolat: zárva
Dátum: 2019. március 6. 12:34:20 GMT
Szerver: Kestrel
Tartalom hossza: 0Még maximális részletesség mellett is a Kestrel hiba rendkívül kevés hasznos információt tartalmazott:
{
"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.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":{}
}Képzeljük el, hogy csak a tcpdump segíthet a probléma megoldásában… de ismételjük meg a forgalom láncát:

Nyomozás
Nyilvánvaló, hogy a forgalom figyelése a legjobb azon a konkrét csomóponton, ahol a Kubernetes telepítette a podot: a dump mérete annyi lesz, hogy viszonylag könnyen találhatunk valamit. Valóban, a megvizsgálása során észrevettük ezt a keretet:
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: Spanyolország
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 A dump alapos megvizsgálásánál észrevettük a szót M.laga. Könnyen kitalálható, hogy Spanyolországban nincs város M.laga (viszont van ). Ezt az ötletet megfogva megnéztük az Ingress konfigurációkat, ahol egy hónappal ezelőtt (a kliens kérésére) láttunk egy beillesztett "ártalmatlan" snippetet:
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;A fenti fejlécek átirányításának letiltásával minden jól ment! (Hamarosan kiderült, hogy ezek a fejlécek már nem is voltak szükségesek az alkalmazás számára.)
Most nézzük meg a problémát átfogóbb kontextusban. Könnyen reprodukálható az alkalmazáson belül, ha telnet kérést küldünk. Most nyissa meg a böngészőt, és navigáljon az alábbi címre::
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 … visszatér 401 Unauthorized, ahogy várható. Mi történik, ha ezt csináljuk:
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?
Visszatér 400 Helytelen kérés — az alkalmazás naplóban már ismerős hibaüzenetet kapunk:
{
"@t":"2019-03-31T12:59:54.3746446Z",
"@mt":"Connection id "{ConnectionId}" helytelen kérés adatok: "{message}"",
"@x":"Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Rosszul formázott kérés: érvénytelen fejléc.',
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":"Rosszul formázott kérés: érvénytelen fejléc.",
"EventId":{
"Id":17,
"Name":"ConnectionBadRequest"
},
"SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
"ThreadId":71
}Összegzés
Kifejezetten Kestrel helyesen kezeli a HTTP-fejléceket a megfelelő UTF-8 karakterekkel, amelyek számos város nevében találhatóak.
További tényező ebben az esetben — a Kestrel megvalósítását a kliens alkalmazás jelenleg nem tervezi megváltoztatni. Azonban az AspNetCore-ban lévő kérdések (, ) azt sugallják, hogy ez nem segít...
Összefoglalva: a megjegyzés már nem a Kestrel vagy a UTF-8 specifikus problémáiról szól (2019-ben?!), hanem arról, hogy a figyelem és a problémakeresés lépésről lépésre történő tanulmányozása előbb vagy utóbb gyümölcsöző eredményeket hoz. Sok sikert!
P.S.
Olvasson további információkat a blogunkban:
- «»;
- «»;
- «»;
- «»;
- «».
Forrás: habr.com
