
Meie kliendi esindaja, kelle rakenduste kogum asub Microsoft Azure'i pilves, pöördus murega: viimastel aegadel on osa mõnede Euroopa klientide päringutest hakanud lõppema veaga 400 (). Kõik rakendused on kirjutatud .NET-is, juurutatud Kubernetesesse…
Üks rakendustest on API, mille kaudu voolab kogu liiklus. Seda liiklust jälgib HTTP-server , mille kliendi .NET on konfigureerinud ja mis on paigutatud pod'i. Meie tõrkejälgimine õnnestus tänu sellele, et oli konkreetne kasutaja, kellel probleem pidevalt kordus. Kuid kogu asja keerulisemaks muutis liikluse ahel:

Ingressi viga nägi välja järgmine:
{
"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":{}
}Selle käigus Kestrel andis:
HTTP/1.1 400 Bad Request
Connection: close
Date: Wed, 06 Mar 2019 12:34:20 GMT
Server: Kestrel
Content-Length: 0I甚至在最大详情级别下,Kestrel的错误包含的有用信息极少 malo полезной информации:
{
"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":{}
}Tundub, et ainult tcpdump aitab selle probleemi lahendada... aga kordame üle liikluse ahela:

Uurimine
Ilmselgelt on liikluse kuulamine parem sellel konkreetsel sõlmel, kus Kubernetes on poodi juurutanud: dumpi maht on selline, et saad üsna kiiresti midagi leida. Ja tõepoolest, selle vaatamisel märgati sellist raami:
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 Dumppi hoolika vaatamise käigus märgati sõna M.laga. Lihtne arvata, et Hispaanias ei ole linna M.laga (aga on ). Haarates sellest ideest, vaatasime Ingressi konfigureerimisi, kus nägime klientide taotluse alusel kuu aega tagasi lisatud „kahjutut” snippet'i:
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;Kui need päised kinni keerati, oli kõik korras! (Varsti selgus ka, et neid päiseid ei vajatud enam rakendusele.)
Nüüd vaatame probleemi üldisemalt. Seda on lihtne reprodutseerida rakenduses, kui teha telneti päring 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 … tagastatakse 401 Unauthorized, nagu oodata oli. Aga mis juhtub, kui me teeme:
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?
Tagastatakse 400 Bad request — rakenduse logis saame tuttava vea:
{
"@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
}Summary
Kestrel korrektset HTTP-pealkirjade töötlemist, mis sisaldavad õigeid märke UTF-8-s, mis esinevad paljude linnade nimedes.
Lisafaktor meie juhtumis — rakenduse klient ei plaani hetkel Kestrel'i teostust muuta. Siiski, AspNetCore'i enda probleemid (, ) näitavad, et see ei aita…
Kokkuvõtteks: märkmed ei käsitle enam Kestrel'i või UTF-8 spetsiifilisi probleeme (2019. aastal?!), vaid et tähelepanu ja järjepidev probleemide uurimine igal sammul probleemide leidmisel toovad varem või hiljem vilja. Edu!
P.S.
Lugege ka meie blogist:
- «»;
- «»;
- «»;
- «»;
- «».
Allikas: habr.com
