Elu Kubernetesega: Kuidas hispaanlaste HTTP-serverit ei kiidetud

Elu Kubernetesega: Kuidas hispaanlaste HTTP-serverit ei kiidetud

Ühe meie kliendi esindaja, kelle rakenduste kogum tegutseb Microsofti (Azure) pilves, pöördus probleemiga: hiljuti on osa mĂ”nede Euroopa klientide pĂ€ringutest lĂ”ppenud veaga 400 (Vale pĂ€ring). KĂ”ik rakendused on kirjutatud .NET-is, juurutatud Kuberneteses


Üks rakendustest on API, mille kaudu tuleb kogu liiklus. Seda liiklust kuulab HTTP-server Kestrel, mis on klient .NET-i poolt konfigureeritud ja paigutatud pod'i. Meil oli Ă”nne silumisega, kuna oli konkreetne kasutaja, kellel probleem pidevalt kordus. Siiski komplitseeris kĂ”ike liikluse ahel:

Elu Kubernetesega: Kuidas hispaanlaste HTTP-serverit ei kiidetud

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":{}
}

Sellega Kestrel edastas:

HTTP/1.1 400 Vale pÀring
Connection: close
Date: Kol, 06 MĂ€r 2019 12:34:20 GMT
Server: Kestrel
Content-Length: 0

Isegi maksimaalse verbosity korral sisaldas Kestrel'i viga ÀÀrmiselt vÀhe kasulikku teavet:

{
   "number_fields":{"ThreadId":76},
   "stream":"stdout",
   "string_fields":{
      "EventId":"{"Id"=>17, "Name"=>"ConnectionBadRequest"}",
      "SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
      "ConnectionId":"0HLL2VJSST5KV",
      "@mt":"Ühenduse ID "{ConnectionId}" vale pĂ€ringu andmed: "{message}"",
      "@t":"2019-03-07T13:06:48.1449083Z",
      "@x":"Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Valesti vormindatud pÀring: vale pÀised.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":"Valesti vormindatud pÀring: vale pÀised."
   },
   "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 lahendamisel
 aga kordaksin trafiku ahelat:

Elu Kubernetesega: Kuidas hispaanlaste HTTP-serverit ei kiidetud

Uurimine

Ilmselgelt on parem kuulata trafikut sellel konkreetsel sÔlmedel, kus Kubernetes on paigaldanud pod: dump'i maht on selline, et suudab kiiresti leida midagi. Ja tÔepoolest, seda uurides 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: Hispaania
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

Pöörates tÀhelepanu dumpile, mÀrgati sÔna Målaga. Lihtne on arvata, et Hispaanias pole linn nimega M.laga (aga on Målaga). haarates sellest ideest, vaatasime Ingressi konfiguratsioone, kus nÀgime kuus tagasi (klientide taotlusel) lisatud «kahjutuks» snippet:

    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 ei olnud enam edastatud, lÀks kÔik hÀsti! (Peagi selgus, et need pÀised rakendusele enam ei olnud vajalikud.)

NĂŒĂŒd vaatame probleemi ĂŒldisemalt. Seda on lihtne rakenduses taasesitada, tehes telnet-pĂ€ringu 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 vÔib. Aga mis juhtub, kui 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 juba tuttava vea:

{
   "@t":"2019-03-31T12:59:54.3746446Z",
   "@mt":"Yhenduse id "{ConnectionId}" vale pÀringu andmed: "{message}"",
   "@x":"Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Valesti vormistatud pÀring: kehtetud pÀised.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":"Valesti vormistatud pÀring: kehtetud pÀised.",
   "EventId":{
      "Id":17,
      "Name":"ConnectionBadRequest"
   },
   "SourceContext":"Microsoft.AspNetCore.Server.Kestrel",
   "ThreadId":71
}

KokkuvÔte

Konkreetsemalt Kestrel saa korrektselt töödelda HTTP-pealkirju, mis sisaldavad baklasid, mis on UTF-8, mida leidub ĂŒsna paljude linnade nimedes.

TÀiendav tegur meie juhul on, et klient ei plaani praegu muuta Kestrel'i rakenduse teostust. Siiski, AspNetCore'i probleemide (nr 4318, nr 7707) osas rÀÀgivad, et see ei aita...

KokkuvÔtteks: mÀrkmed ei kÀsitle enam Kestrel'i vÔi UTF-8 spetsiifilisi probleeme (2019. aastal?!), vaid need nÀitavad, et tÀhelepanelikkus ja jÀrjepidev Ôppimine iga sammu jooksul probleemi otsimise ajal toovad varem vÔi hiljem vilja. Edu!

P.S.

Lugege ka meie blogist:

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster