'n Storie oor ontbrekende DNS-pakkies van Google Wolk se tegniese ondersteuning

Van Google Blog Editor: Het jy al ooit gewonder hoe Google Cloud Technical Solutions (TSE)-ingenieurs jou ondersteuningsversoeke hanteer? TSE Tegniese Ondersteuningsingenieurs is verantwoordelik vir die identifisering en regstelling van gebruikers-gerapporteerde bronne van probleme. Sommige van hierdie probleme is redelik eenvoudig, maar soms kom jy op 'n kaartjie af wat die aandag van verskeie ingenieurs tegelyk verg. In hierdie artikel sal een van die TSE-werknemers ons vertel van een baie moeilike probleem uit sy onlangse praktyk - geval van ontbrekende DNS-pakkies. In hierdie storie sal ons sien hoe die ingenieurs daarin geslaag het om die situasie op te los, en watter nuwe dinge hulle geleer het terwyl hulle die fout reggemaak het. Ons hoop hierdie storie leer jou nie net oor 'n diepliggende fout nie, maar gee jou ook insig in die prosesse wat gepaard gaan met die indiening van 'n ondersteuningskaartjie by Google Cloud.

'n Storie oor ontbrekende DNS-pakkies van Google Wolk se tegniese ondersteuning

Foutoplossing is beide 'n wetenskap en 'n kuns. Dit begin alles met die bou van 'n hipotese oor die rede vir die nie-standaard gedrag van die stelsel, waarna dit vir krag getoets word. Voordat ons egter 'n hipotese formuleer, moet ons die probleem duidelik definieer en presies formuleer. As die vraag te vaag klink, dan sal jy alles noukeurig moet ontleed; Dit is die "kuns" van probleemoplossing.

Onder Google Cloud word sulke prosesse eksponensieel meer kompleks, aangesien Google Cloud sy bes probeer om die privaatheid van sy gebruikers te waarborg. As gevolg hiervan het TSE-ingenieurs nie toegang om jou stelsels te wysig nie, en ook nie die vermoë om konfigurasies so wyd te sien as wat gebruikers dit doen nie. Daarom, om enige van ons hipoteses te toets, kan ons (ingenieurs) nie vinnig die stelsel verander nie.

Sommige gebruikers glo dat ons alles soos meganika in 'n motordiens sal regmaak, en bloot vir ons die ID van 'n virtuele masjien sal stuur, terwyl die proses in werklikheid in 'n gespreksformaat plaasvind: inligting versamel, hipoteses vorm en bevestig (of weerlê), en, op die ou end, 'n besluit probleme is gebaseer op kommunikasie met die kliënt.

Probleem ter sprake

Vandag het ons 'n storie met 'n goeie einde. Een van die redes vir die suksesvolle oplossing van die voorgestelde saak is 'n baie gedetailleerde en akkurate beskrywing van die probleem. Hieronder kan jy 'n kopie van die eerste kaartjie sien (geredigeer om vertroulike inligting te versteek):
'n Storie oor ontbrekende DNS-pakkies van Google Wolk se tegniese ondersteuning
Hierdie boodskap bevat baie nuttige inligting vir ons:

  • Spesifieke VM gespesifiseer
  • Die probleem self word aangedui - DNS werk nie
  • Dit word aangedui waar die probleem hom manifesteer - VM en houer
  • Die stappe wat die gebruiker gedoen het om die probleem te identifiseer, word aangedui.

Die versoek is geregistreer as “P1: Kritieke Impak - Diens onbruikbaar in produksie”, wat beteken dat die situasie konstant 24/7 gemonitor word volgens die “Volg die Son”-skema (jy kan meer lees oor prioriteite van gebruikersversoeke), met die oordrag van een tegniese ondersteuningspan na 'n ander met elke tydsoneverskuiwing. Om die waarheid te sê, teen die tyd dat die probleem ons span in Zürich bereik het, het dit reeds die aardbol gesirkel. Teen hierdie tyd het die gebruiker versagtende maatreëls getref, maar was bang vir 'n herhaling van die situasie in produksie, aangesien die grondoorsaak nog nie ontdek is nie.

Teen die tyd dat die kaartjie Zürich bereik het, het ons reeds die volgende inligting byderhand gehad:

  • inhoud /etc/hosts
  • inhoud /etc/resolv.conf
  • Output iptables-save
  • Saamgestel deur die span ngrep pcap lêer

Met hierdie data was ons gereed om die “ondersoek” en probleemoplossingsfase te begin.

Ons eerste treë

Eerstens het ons die logs en status van die metadata-bediener nagegaan en seker gemaak dat dit reg werk. Die metadata-bediener reageer op die IP-adres 169.254.169.254 en is onder andere verantwoordelik vir die beheer van domeinname. Ons het ook dubbel gekontroleer dat die firewall reg werk met die VM en nie pakkies blokkeer nie.

Dit was 'n soort vreemde probleem: die nmap-tjek het ons hoofhipotese oor die verlies van UDP-pakkies weerlê, so ons het geestelik met verskeie meer opsies en maniere vorendag gekom om dit na te gaan:

  • Word pakkies selektief laat val? => Gaan iptables-reëls na
  • Is dit nie te klein nie? MTU? => Gaan uitset na ip a show
  • Raak die probleem net UDP-pakkies of TCP ook? => Ry weg dig +tcp
  • Word grawe-gegenereerde pakkies teruggestuur? => Ry weg tcpdump
  • Werk libdns reg? => Ry weg strace om die oordrag van pakkies in beide rigtings na te gaan

Hier besluit ons om die gebruiker te bel om probleme regstreeks op te los.

Tydens die oproep kan ons verskeie dinge nagaan:

  • Na verskeie kontroles sluit ons iptables-reëls uit van die lys redes
  • Ons gaan netwerkkoppelvlakke en roeteertabelle na, en maak dubbel seker dat die MTU korrek is
  • Ons ontdek dit dig +tcp google.com (TCP) werk soos dit moet, maar dig google.com (UDP) werk nie
  • Het weggery tcpdump dit werk nog dig, vind ons dat UDP-pakkies teruggestuur word
  • Ons ry weg strace dig google.com en ons sien hoe grawe korrek roep sendmsg() и recvms(), maar die tweede een word onderbreek deur 'n uitteltyd

Ongelukkig kom die einde van die skof en ons word gedwing om die probleem na die volgende tydsone te eskaleer. Die versoek het egter belangstelling in ons span gewek, en 'n kollega stel voor om die aanvanklike DNS-pakket te skep deur die skrapse Python-module te gebruik.

from scapy.all import *

answer = sr1(IP(dst="169.254.169.254")/UDP(dport=53)/DNS(rd=1,qd=DNSQR(qname="google.com")),verbose=0)
print ("169.254.169.254", answer[DNS].summary())

Hierdie fragment skep 'n DNS-pakkie en stuur die versoek na die metadatabediener.

Die gebruiker loop die kode, die DNS-reaksie word teruggestuur en die toepassing ontvang dit, wat bevestig dat daar geen probleem op netwerkvlak is nie.

Na nog 'n "rond-die-wêreld-reis" keer die versoek terug na ons span, en ek dra dit heeltemal aan myself oor, en dink dat dit vir die gebruiker geriefliker sal wees as die versoek ophou om van plek tot plek te sirkel.

Intussen stem die gebruiker vriendelik in om 'n momentopname van die stelselbeeld te verskaf. Dit is baie goeie nuus: die vermoë om die stelsel self te toets, maak foutsporing baie vinniger, want ek hoef nie meer die gebruiker te vra om opdragte uit te voer, vir my die resultate te stuur en dit te ontleed nie, ek kan alles self doen!

My kollegas begin my bietjie beny. Oor middagete bespreek ons ​​die omskakeling, maar niemand het enige idee wat aangaan nie. Gelukkig het die gebruiker self reeds maatreëls getref om die gevolge te versag en is hy nie haastig nie, so ons het tyd om die probleem te dissekteer. En aangesien ons 'n beeld het, kan ons enige toetse uitvoer wat ons interesseer. Puik!

Om 'n tree terug te gee

Een van die gewildste onderhoudsvrae vir posisies van stelselingenieur is: “Wat gebeur as jy ping www.google.com? Die vraag is groot, aangesien die kandidaat alles van die dop tot gebruikersruimte, tot die stelselkern en dan na die netwerk moet beskryf. Ek glimlag: soms blyk onderhoudsvrae nuttig te wees in die werklike lewe ...

Ek besluit om hierdie MH-vraag op 'n huidige probleem toe te pas. Rofweg, wanneer jy probeer om 'n DNS-naam te bepaal, gebeur die volgende:

  1. Die toepassing roep 'n stelselbiblioteek soos libdns
  2. libdns kontroleer die stelselkonfigurasie met watter DNS-bediener dit moet kontak (in die diagram is dit 169.254.169.254, metadatabediener)
  3. libdns gebruik stelseloproepe om 'n UDP-sok (SOKET_DGRAM) te skep en UDP-pakkies met 'n DNS-navraag in beide rigtings te stuur
  4. Deur die sysctl-koppelvlak kan u die UDP-stapel op kernvlak instel
  5. Die kern is in wisselwerking met die hardeware om pakkies oor die netwerk te stuur via die netwerkkoppelvlak
  6. Die hiperviseerder vang en stuur die pakkie na die metadata-bediener by kontak daarmee
  7. Die metadata-bediener bepaal deur sy magie die DNS-naam en gee 'n antwoord met dieselfde metode terug

'n Storie oor ontbrekende DNS-pakkies van Google Wolk se tegniese ondersteuning
Laat ek jou herinner aan watter hipoteses ons reeds oorweeg het:

Hipotese: Gebroke biblioteke

  • Toets 1: hardloop strace in die stelsel, maak seker dat dig roep die korrekte stelsel roepe
  • Resultaat: Korrekte stelseloproepe word geroep
  • Toets 2: gebruik srapy om te kyk of ons name kan bepaal wat stelselbiblioteke omseil
  • Gevolg: ons kan
  • Toets 3: hardloop rpm –V op die libdns-pakket en md5sum-biblioteeklêers
  • Resultaat: die biblioteekkode is heeltemal identies aan die kode in die werkende bedryfstelsel
  • Toets 4: monteer die gebruiker se wortelstelselbeeld op 'n VM sonder hierdie gedrag, hardloop chroot, kyk of DNS werk
  • Resultaat: DNS werk korrek

Gevolgtrekking gebaseer op toetse: die probleem is nie in die biblioteke nie

Hipotese: Daar is 'n fout in die DNS-instellings

  • Toets 1: kyk na tcpdump en kyk of DNS-pakkies korrek gestuur en teruggestuur word nadat grawe uitgevoer is
  • Gevolg: pakkies word korrek versend
  • Toets 2: kyk na die bediener /etc/nsswitch.conf и /etc/resolv.conf
  • Gevolg: alles is korrek

Gevolgtrekking gebaseer op toetse: die probleem is nie met die DNS-konfigurasie nie

Hipotese: kern beskadig

  • Toets: installeer nuwe kern, kontroleer handtekening, herbegin
  • Gevolg: soortgelyke gedrag

Gevolgtrekking gebaseer op toetse: die kern is nie beskadig nie

Hipotese: verkeerde gedrag van die gebruikersnetwerk (of hypervisor-netwerkkoppelvlak)

  • Toets 1: Gaan jou firewall-instellings na
  • Gevolg: die brandmuur stuur DNS-pakkies op beide die gasheer en GCP deur
  • Toets 2: onderskep verkeer en monitor die korrektheid van die oordrag en terugkeer van DNS-versoeke
  • Resultaat: tcpdump bevestig dat die gasheer terugsendingpakkies ontvang het

Gevolgtrekking gebaseer op toetse: die probleem is nie in die netwerk nie

Hipotese: die metadatabediener werk nie

  • Toets 1: kyk na die metadata-bedienerlogboeke vir onreëlmatighede
  • Gevolg: daar is geen afwykings in die logs nie
  • Toets 2: Omseil die metadata-bediener via dig @8.8.8.8
  • Resultaat: Resolusie word gebreek selfs sonder om 'n metadatabediener te gebruik

Gevolgtrekking gebaseer op toetse: die probleem is nie by die metadata-bediener nie

Die bottom line: ons het alle substelsels getoets behalwe runtime instellings!

Duik in Kernel Runtime-instellings

Om die kernuitvoeromgewing op te stel, kan u opdragreëlopsies (grub) of die sysctl-koppelvlak gebruik. Ek het ingekyk /etc/sysctl.conf en dink net, ek het verskeie persoonlike instellings ontdek. Ek het gevoel asof ek aan iets vasgegryp het, en ek het alle nie-netwerk- of nie-tcp-instellings weggegooi, wat by die berginstellings gebly het net.core. Toe het ek gegaan na waar die gasheertoestemmings in die VM was en die instellings een vir een, een na die ander, met die stukkende VM begin toepas totdat ek die skuldige gevind het:

net.core.rmem_default = 2147483647

Hier is dit, 'n DNS-breek-konfigurasie! Ek het die moordwapen gevind. Maar hoekom gebeur dit? Ek het nog 'n motief nodig gehad.

Die basiese DNS-pakkiebuffergrootte word gekonfigureer via net.core.rmem_default. 'n Tipiese waarde is iewers rondom 200KiB, maar as jou bediener baie DNS-pakkies ontvang, wil jy dalk die buffergrootte vergroot. As die buffer vol is wanneer 'n nuwe pakkie aankom, byvoorbeeld omdat die toepassing dit nie vinnig genoeg verwerk nie, dan sal jy pakkies begin verloor. Ons kliënt het die buffergrootte korrek vergroot omdat hy bang was vir dataverlies, aangesien hy 'n toepassing gebruik het om statistieke deur DNS-pakkies in te samel. Die waarde wat hy gestel het, was die maksimum moontlike: 231-1 (indien dit op 231 gestel is, sal die kern "ONVALID ARGUMENT") terugstuur.

Skielik het ek besef hoekom nmap en scapy reg werk: hulle gebruik rou voetstukke! Rou voetstukke verskil van gewone voetstukke: hulle omseil iptables, en hulle word nie gebuffer nie!

Maar hoekom veroorsaak "buffer te groot" probleme? Dit werk duidelik nie soos bedoel nie.

Op hierdie stadium kon ek die probleem op veelvuldige pitte en veelvuldige verspreidings reproduseer. Die probleem het reeds op die 3.x-kern verskyn en nou het dit ook op die 5.x-kern verskyn.

Inderdaad, by opstart

sysctl -w net.core.rmem_default=$((2**31-1))

DNS het opgehou werk.

Ek het begin soek na werkwaardes deur 'n eenvoudige binêre soekalgoritme en gevind dat die stelsel met 2147481343 werk, maar hierdie nommer was vir my 'n betekenislose stel syfers. Ek het voorgestel dat die kliënt hierdie nommer probeer, en hy het geantwoord dat die stelsel met google.com werk, maar steeds 'n fout met ander domeine gegee het, so ek het my ondersoek voortgesit.

Ek het geïnstalleer dropwatch, 'n instrument wat vroeër gebruik moes gewees het: dit wys presies waar in die kern 'n pakkie beland. Die skuldige was die funksie udp_queue_rcv_skb. Ek het die kernbronne afgelaai en 'n paar bygevoeg funksie printk om op te spoor waar presies die pakkie beland. Ek het vinnig die regte toestand gevind if, en het bloot vir 'n geruime tyd daarna gestaar, want dit was toe dat alles uiteindelik saamgekom het in 'n geheelbeeld: 231-1, 'n betekenislose getal, 'n nie-werkende domein ... Dit was 'n stukkie kode in __udp_enqueue_schedule_skb:

if (rmem > (size + sk->sk_rcvbuf))
		goto uncharge_drop;

Aandag:

  • rmem is van tipe int
  • size is van tipe u16 (ongeteken sestien-bis int) en stoor die pakkiegrootte
  • sk->sk_rcybuf is van tipe int en stoor die buffergrootte wat per definisie gelyk is aan die waarde in net.core.rmem_default

Wanneer sk_rcvbuf 231 nader, wat die pakkiegrootte kan optel heelgetal oorloop. En aangesien dit 'n int is, word die waarde daarvan negatief, so die toestand word waar wanneer dit vals behoort te wees (jy kan meer hieroor lees by skakel).

Die fout kan op 'n onbenullige manier reggestel word: deur te gooi unsigned int. Ek het die regstelling toegepas en die stelsel herbegin en DNS het weer gewerk.

Smaak van oorwinning

Ek het my bevindinge aan die kliënt deurgestuur en gestuur LKML kern pleister. Ek is bly: elke stukkie van die legkaart pas in mekaar, ek kan presies verduidelik hoekom ons waargeneem het wat ons waargeneem het, en bowenal, ons kon 'n oplossing vir die probleem vind danksy ons spanwerk!

Dit is die moeite werd om te erken dat die saak skaars blyk te wees, en gelukkig ontvang ons selde sulke komplekse versoeke van gebruikers.

'n Storie oor ontbrekende DNS-pakkies van Google Wolk se tegniese ondersteuning


Bron: will.com

Voeg 'n opmerking