Saga um DNS-pakka sem vantar frá tækniaðstoð Google Cloud

Frá Google Blog Editor: Hefur þú einhvern tíma velt því fyrir þér hvernig verkfræðingar Google Cloud Technical Solutions (TSE) höndla stuðningsbeiðnir þínar? TSE tækniaðstoðarverkfræðingar eru ábyrgir fyrir því að bera kennsl á og leiðrétta uppsprettur vandamála sem notendur hafa tilkynnt um. Sum þessara vandamála eru frekar einföld, en stundum rekst þú á miða sem krefst athygli nokkurra verkfræðinga í einu. Í þessari grein mun einn starfsmanna TSE segja okkur frá einu mjög erfiðu vandamáli frá nýlegri æfingu hans - ef DNS-pakka vantar. Í þessari sögu munum við sjá hvernig verkfræðingum tókst að leysa ástandið og hvaða nýja hluti þeir lærðu á meðan þeir lagfærðu villuna. Við vonum að þessi saga fræði þig ekki aðeins um djúpstæða villu, heldur gefi þér einnig innsýn í ferlana sem fylgja því að senda inn stuðningsmiða hjá Google Cloud.

Saga um DNS-pakka sem vantar frá tækniaðstoð Google Cloud

Úrræðaleit er bæði vísindi og list. Það byrjar allt á því að byggja upp tilgátu um ástæðuna fyrir óstöðluðu hegðun kerfisins, eftir það er það prófað með tilliti til styrkleika. Hins vegar, áður en við setjum fram tilgátu, verðum við að skilgreina og móta vandamálið nákvæmlega. Ef spurningin hljómar of óljós, þá verður þú að greina allt vandlega; Þetta er „listin“ við bilanaleit.

Undir Google Cloud verða slík ferli veldisvísis flóknari þar sem Google Cloud reynir sitt besta til að tryggja friðhelgi notenda sinna. Vegna þessa hafa TSE verkfræðingar hvorki aðgang til að breyta kerfum þínum né getu til að skoða stillingar eins víða og notendur gera. Þess vegna, til að prófa einhverjar tilgátur okkar, getum við (verkfræðingar) ekki breytt kerfinu fljótt.

Sumir notendur trúa því að við munum laga allt eins og vélfræði í bílaþjónustu og einfaldlega senda okkur auðkenni sýndarvélar, en í raun fer ferlið fram á samtalsformi: safna upplýsingum, móta og staðfesta (eða hrekja) tilgátur, og á endanum byggist ákvörðunarvandamál á samskiptum við viðskiptavininn.

Vandamál sem um ræðir

Í dag höfum við sögu með góðum endi. Ein af ástæðunum fyrir farsælli úrlausn fyrirhugaðs máls er mjög nákvæm og nákvæm lýsing á vandanum. Hér að neðan má sjá afrit af fyrsta miðanum (breytt til að fela trúnaðarupplýsingar):
Saga um DNS-pakka sem vantar frá tækniaðstoð Google Cloud
Þessi skilaboð innihalda mikið af gagnlegum upplýsingum fyrir okkur:

  • Sérstakur VM tilgreindur
  • Vandamálið sjálft er gefið til kynna - DNS virkar ekki
  • Tilgreint er hvar vandamálið lýsir sér - VM og ílát
  • Tilgreind eru skrefin sem notandinn tók til að bera kennsl á vandamálið.

Beiðnin var skráð sem „P1: Critical Impact - Service Unusable in production“, sem þýðir stöðugt eftirlit með aðstæðum 24/7 samkvæmt „Follow the Sun“ kerfinu (þú getur lesið meira um forgangsröðun notendabeiðna), með flutningi þess frá einu tækniaðstoðarteymi til annars með hverri tímabeltisbreytingu. Reyndar, þegar vandamálið barst teymi okkar í Zürich, hafði það þegar farið hringinn um heiminn. Á þessum tíma hafði notandinn gripið til mótvægisaðgerða, en óttaðist að ástandið í framleiðslunni endurtaki sig, þar sem undirrótin hafði ekki enn fundist.

Þegar miðinn barst til Zürich höfðum við þegar eftirfarandi upplýsingar við höndina:

  • Innihald /etc/hosts
  • Innihald /etc/resolv.conf
  • Output iptables-save
  • Samsett af liðinu ngrep pcap skrá

Með þessum gögnum vorum við tilbúin að hefja „rannsókn“ og bilanaleit.

Fyrstu skrefin okkar

Í fyrsta lagi skoðuðum við annála og stöðu lýsigagnaþjónsins og tryggðum að hann virkaði rétt. Lýsigagnaþjónninn svarar IP tölunni 169.254.169.254 og sér meðal annars um að stjórna lénsheitum. Við tékkuðum líka að eldveggurinn virki rétt með VM og lokar ekki pökkum.

Þetta var einhvers konar undarlegt vandamál: nmap athugunin vísaði á bug helstu tilgátu okkar um tap á UDP pakka, svo við fundum andlega upp nokkra fleiri valkosti og leiðir til að athuga þá:

  • Eru pakkar sleppt vali? => Athugaðu iptables reglur
  • Er það ekki of lítið? MTU? => Athugaðu úttak ip a show
  • Hefur vandamálið aðeins áhrif á UDP pakka eða TCP líka? => Ekið í burtu dig +tcp
  • Er pökkum sem myndast við grafa skilað? => Ekið í burtu tcpdump
  • Er libdns að virka rétt? => Ekið í burtu strace til að athuga sendingu pakka í báðar áttir

Hér ákveðum við að hringja í notandann til að leysa vandamál í beinni.

Meðan á símtalinu stendur getum við athugað ýmislegt:

  • Eftir nokkrar athuganir útilokum við iptables reglur frá listanum yfir ástæður
  • Við athugum netviðmót og leiðartöflur og tvisvar hvort MTU sé rétt
  • Við uppgötvum það dig +tcp google.com (TCP) virkar eins og það á að gera, en dig google.com (UDP) virkar ekki
  • Búinn að keyra í burtu tcpdump það er enn að virka dig, komumst við að því að verið er að skila UDP pökkum
  • Við keyrum í burtu strace dig google.com og við sjáum hvernig grafa kallar rétt sendmsg() и recvms(), hins vegar er sú seinni rofin af tímamörkum

Því miður er lok vaktarinnar komið og við neyðumst til að auka vandamálið á næsta tímabelti. Beiðnin vakti hins vegar áhuga hjá teyminu okkar og samstarfsmaður stingur upp á því að búa til upphaflega DNS pakkann með því að nota skraufléttu Python eininguna.

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())

Þetta brot býr til DNS pakka og sendir beiðnina til lýsigagnaþjónsins.

Notandinn keyrir kóðann, DNS svarinu er skilað og forritið fær það sem staðfestir að ekkert vandamál sé á netkerfisstigi.

Eftir aðra „heimsferð“ kemur beiðnin aftur til teymisins okkar og ég yfirfæri hana algjörlega á sjálfan mig og held að það sé þægilegra fyrir notandann ef beiðnin hættir að hringsnúast á milli staða.

Í millitíðinni samþykkir notandinn vinsamlega að leggja fram skyndimynd af kerfismyndinni. Þetta eru mjög góðar fréttir: hæfileikinn til að prófa kerfið sjálfur gerir bilanaleit mun hraðari, því ég þarf ekki lengur að biðja notandann um að keyra skipanir, senda mér niðurstöðurnar og greina þær, ég get gert allt sjálfur!

Samstarfsmenn mínir eru farnir að öfunda mig svolítið. Í hádeginu ræðum við umskiptin en enginn hefur hugmynd um hvað er í gangi. Sem betur fer hefur notandinn sjálfur þegar gert ráðstafanir til að draga úr afleiðingunum og er ekkert að flýta okkur, svo við höfum tíma til að kryfja vandamálið. Og þar sem við höfum mynd, getum við keyrt hvaða próf sem vekur áhuga okkar. Frábært!

Að taka skref til baka

Ein vinsælasta viðtalsspurningin fyrir stöður kerfisfræðinga er: „Hvað gerist þegar þú smellir www.google.com? Spurningin er frábær, þar sem umsækjandinn þarf að lýsa öllu frá skelinni til notendarýmis, til kerfiskjarnans og síðan til netsins. Ég brosi: stundum reynast viðtalsspurningar gagnlegar í raunveruleikanum...

Ég ákveð að beita þessari HR spurningu á núverandi vandamál. Í grófum dráttum, þegar þú reynir að ákvarða DNS nafn, gerist eftirfarandi:

  1. Forritið kallar á kerfissafn eins og libdns
  2. libdns athugar kerfisstillinguna við hvaða DNS-þjón það ætti að hafa samband (á skýringarmyndinni er þetta 169.254.169.254, lýsigagnaþjónn)
  3. libdns notar kerfissímtöl til að búa til UDP fals (SOKET_DGRAM) og senda UDP pakka með DNS fyrirspurn í báðar áttir
  4. Í gegnum sysctl viðmótið geturðu stillt UDP stafla á kjarnastigi
  5. Kjarninn hefur samskipti við vélbúnaðinn til að senda pakka yfir netið í gegnum netviðmótið
  6. Yfirvísirinn grípur og sendir pakkann til lýsigagnaþjónsins þegar hann hefur samband við hann
  7. Lýsigagnaþjónninn, af töfrum sínum, ákvarðar DNS nafnið og skilar svari með sömu aðferð

Saga um DNS-pakka sem vantar frá tækniaðstoð Google Cloud
Leyfðu mér að minna þig á hvaða tilgátur við höfum þegar íhugað:

Tilgáta: Brotin bókasöfn

  • Próf 1: keyrðu strace í kerfinu, athugaðu að dig kallar rétt kerfiskall
  • Niðurstaða: Hringt er í rétt kerfissímtöl
  • Próf 2: nota srapy til að athuga hvort við getum ákvarðað nöfn sem fara framhjá kerfissöfnum
  • Niðurstaða: við getum
  • Próf 3: keyrðu rpm –V á libdns pakkanum og md5sum bókasafnsskrám
  • Niðurstaða: bókasafnskóðinn er alveg eins og kóðinn í virka stýrikerfinu
  • Próf 4: festu rótarkerfismynd notandans á VM án þessarar hegðunar, keyrðu chroot, athugaðu hvort DNS virkar
  • Niðurstaða: DNS virkar rétt

Niðurstaða byggð á prófum: vandamálið er ekki á bókasöfnunum

Tilgáta: Það er villa í DNS stillingunum

  • Próf 1: athugaðu tcpdump og athugaðu hvort DNS pakkar séu sendir og skilaðir rétt eftir að grafa er keyrt
  • Niðurstaða: pakkar eru sendir á réttan hátt
  • Próf 2: tékkaðu á þjóninum /etc/nsswitch.conf и /etc/resolv.conf
  • Niðurstaða: allt er rétt

Niðurstaða byggð á prófum: vandamálið er ekki með DNS uppsetninguna

Tilgáta: kjarni skemmdur

  • Próf: settu upp nýjan kjarna, athugaðu undirskrift, endurræstu
  • Niðurstaða: svipuð hegðun

Niðurstaða byggð á prófum: kjarninn er ekki skemmdur

Tilgáta: röng hegðun notandanetsins (eða netviðmóts netkerfisins)

  • Próf 1: Athugaðu eldveggstillingarnar þínar
  • Niðurstaða: eldveggurinn sendir DNS pakka á bæði hýsilinn og GCP
  • Próf 2: stöðva umferð og fylgjast með réttmæti sendingar og skila DNS beiðna
  • Niðurstaða: tcpdump staðfestir að gestgjafinn hafi fengið skilapakka

Niðurstaða byggð á prófum: vandamálið er ekki í netkerfinu

Tilgáta: lýsigagnaþjónninn virkar ekki

  • Próf 1: athugaðu lýsigagnaþjónsskrárnar fyrir frávik
  • Niðurstaða: Engin frávik eru í skránni
  • Próf 2: Framhjá lýsigagnaþjóninum í gegnum dig @8.8.8.8
  • Niðurstaða: Upplausn er rofin jafnvel án þess að nota lýsigagnaþjón

Niðurstaða byggð á prófum: vandamálið er ekki með lýsigagnaþjóninum

The botn lína: við prófuðum öll undirkerfi nema runtime stillingar!

Að kafa í Kernel Runtime Settings

Til að stilla keyrsluumhverfi kjarna geturðu notað skipanalínuvalkosti (grub) eða sysctl viðmótið. Ég leit inn /etc/sysctl.conf og hugsaðu bara, ég uppgötvaði nokkrar sérsniðnar stillingar. Mér leið eins og ég hefði gripið í eitthvað, ég fleygði öllum stillingum sem ekki voru netkerfi eða ekki tcp, eftir með fjallastillingunum net.core. Síðan fór ég þangað sem hýsingarheimildirnar voru í VM og byrjaði að beita stillingunum eina í einu, hverja eftir aðra, með bilaða VM, þar til ég fann sökudólginn:

net.core.rmem_default = 2147483647

Hér er það, DNS-brjótandi stillingar! Ég fann morðvopnið. En hvers vegna er þetta að gerast? Mig vantaði samt hvata.

Grunnstærð DNS pakka biðminni er stillt í gegnum net.core.rmem_default. Dæmigert gildi er einhvers staðar í kringum 200KiB, en ef þjónninn þinn fær mikið af DNS-pökkum gætirðu viljað auka biðminni. Ef biðminni er fullur þegar nýr pakki kemur, til dæmis vegna þess að forritið er ekki að vinna úr honum nógu hratt, þá muntu byrja að tapa pökkum. Viðskiptavinur okkar jók biðminni rétt vegna þess að hann var hræddur við gagnatap, þar sem hann var að nota forrit til að safna mælingum í gegnum DNS pakka. Gildið sem hann setti var hæsta mögulega: 231-1 (ef það er stillt á 231 mun kjarninn skila „ÓVALD RÖK“).

Allt í einu áttaði ég mig á því hvers vegna nmap og scapy virkuðu rétt: þeir voru að nota hráar fals! Raw innstungur eru frábrugðnar venjulegum innstungum: þær fara framhjá iptables og þær eru ekki í biðminni!

En hvers vegna veldur „of stór buffer“ vandamál? Það virkar greinilega ekki eins og ætlað er.

Á þessum tímapunkti gæti ég endurskapað vandamálið á mörgum kjarna og mörgum dreifingum. Vandamálið birtist þegar á 3.x kjarnanum og nú birtist það líka á 5.x kjarnanum.

Reyndar við ræsingu

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

DNS hætti að virka.

Ég byrjaði að leita að vinnugildum með einföldu tvíundarleitaralgrími og komst að því að kerfið virkaði með 2147481343, en þessi tala var tilgangslaust talnasett fyrir mér. Ég stakk upp á því að viðskiptavinurinn prófaði þetta númer og hann svaraði því til að kerfið virkaði með google.com, en gaf samt villu með öðrum lénum, ​​svo ég hélt áfram rannsókn minni.

Ég er búinn að setja upp dropaúr, tól sem hefði átt að vera notað fyrr: það sýnir nákvæmlega hvar í kjarnanum pakki endar. Sökudólgurinn var hlutverkið udp_queue_rcv_skb. Ég sótti kjarnaheimildirnar og bætti við nokkrum aðgerðir printk til að fylgjast með hvar nákvæmlega pakkinn endar. Ég fann fljótt rétta ástandið if, og starði einfaldlega á það í nokkurn tíma, því það var þá sem allt kom loksins saman í heila mynd: 231-1, merkingarlaus tala, óvirkt lén... Þetta var stykki af kóða í __udp_enqueue_schedule_skb:

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

Vinsamlegast athugið:

  • rmem er af gerðinni int
  • size er af gerðinni u16 (ómerkt sextán bita int) og geymir pakkastærðina
  • sk->sk_rcybuf er af gerðinni int og geymir biðminni stærð sem samkvæmt skilgreiningu er jöfn gildinu í net.core.rmem_default

Þegar sk_rcvbuf nálgast 231, samantekt pakkastærðar getur leitt til heiltölu yfirfall. Og þar sem það er int verður gildi þess neikvætt, þannig að skilyrðið verður satt þegar það ætti að vera rangt (þú getur lesið meira um þetta á tengill).

Hægt er að leiðrétta villuna á léttvægan hátt: með steypu unsigned int. Ég beitti lagfæringunni og endurræsti kerfið og DNS virkaði aftur.

Bragð af sigur

Ég sendi niðurstöður mínar til viðskiptavinarins og sendi LKML kjarnaplástur. Ég er ánægður: hvert púsl passar saman, ég get útskýrt nákvæmlega hvers vegna við fylgdumst með því sem við sáum og síðast en ekki síst, okkur tókst að finna lausn á vandamálinu þökk sé teymisvinnu okkar!

Rétt er að viðurkenna að málið reyndist sjaldgæft og sem betur fer fáum við sjaldan jafn flóknar beiðnir frá notendum.

Saga um DNS-pakka sem vantar frá tækniaðstoð Google Cloud


Heimild: www.habr.com

Bæta við athugasemd