Dari kehidupan dengan Kubernetes: Bagaimana server HTTP tidak menyukai orang Spanyol

Dari kehidupan dengan Kubernetes: Bagaimana server HTTP tidak menyukai orang Spanyol

Perwakilan klien kami, yang tumpukan aplikasinya berada di cloud Microsoft (Azure), mengatasi masalah: baru-baru ini, beberapa permintaan dari beberapa klien dari Eropa mulai berakhir dengan kesalahan 400 (Permintaan yang buruk). Semua aplikasi ditulis dalam .NET, diterapkan di Kubernetes...

Salah satu aplikasinya adalah API, yang melaluinya semua lalu lintas pada akhirnya datang. Lalu lintas ini didengarkan oleh server HTTP alap-alap, dikonfigurasi oleh klien .NET dan dihosting di sebuah pod. Dengan debugging, kami beruntung karena ada pengguna tertentu yang secara konsisten mereproduksi masalah tersebut. Namun, semuanya menjadi rumit karena rantai lalu lintas:

Dari kehidupan dengan Kubernetes: Bagaimana server HTTP tidak menyukai orang Spanyol

Kesalahan di Ingress terlihat seperti ini:

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

Pada saat yang sama, Kestrel memberikan:

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

Bahkan dengan verbositas maksimum, kesalahan Kestrel tetap ada sedikit informasi berguna:

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

Tampaknya hanya tcpdump yang akan membantu menyelesaikan masalah ini... tapi saya akan ulangi tentang rantai lalu lintas:

Dari kehidupan dengan Kubernetes: Bagaimana server HTTP tidak menyukai orang Spanyol

Investigasi

Tentu saja, lebih baik mendengarkan lalu lintas pada node tertentu itu, di mana Kubernetes telah menyebarkan sebuah pod: volume dump akan sedemikian rupa sehingga memungkinkan untuk menemukan setidaknya sesuatu dengan cukup cepat. Dan memang, ketika diperiksa, terlihat bingkai berikut:

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

Setelah memeriksa tempat pembuangan sampah lebih dekat, kata itu diketahui M.laga. Mudah ditebak bahwa tidak ada kota M.laga di Spanyol (tetapi memang ada Malaga). Memanfaatkan ide ini, kami melihat konfigurasi Ingress, di mana kami melihat konfigurasi tersebut dimasukkan sebulan yang lalu (atas permintaan klien) cuplikan "tidak berbahaya".:

    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;

Setelah menonaktifkan penerusan header ini, semuanya menjadi baik-baik saja! (Segera menjadi jelas bahwa aplikasi itu sendiri tidak lagi memerlukan header ini.)

Sekarang mari kita lihat masalahnya secara lebih umum. Itu dapat dengan mudah direproduksi di dalam aplikasi dengan membuat permintaan telnet ke 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

... kembali 401 Unauthorized, seperti yang diharapkan. Apa yang terjadi jika kita melakukan:

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

?

Akan kembali 400 Bad request β€” di log aplikasi kita akan menerima kesalahan yang sudah tidak asing lagi bagi kita:

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

Hasil

Khususnya Kestrel tidak bisa memproses header HTTP dengan benar dengan karakter UTF-8 yang benar, yang terdapat dalam nama sejumlah besar kota.

Faktor tambahan dalam kasus kami adalah klien saat ini tidak berencana mengubah penerapan Kestrel dalam aplikasi. Namun, masalah di AspNetCore itu sendiri (β„– 4318, β„– 7707) mereka mengatakan bahwa ini tidak akan membantu...

Ringkasnya: catatannya bukan lagi tentang masalah spesifik Kestrel atau UTF-8 (pada tahun 2019?!), tetapi tentang fakta bahwa perhatian dan belajar secara konsisten Setiap langkah yang Anda ambil saat mencari masalah cepat atau lambat akan membuahkan hasil. Semoga beruntung!

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komentar