ProHoster > blog > Utawala > Hadithi kuhusu kukosa pakiti za DNS kutoka kwa usaidizi wa kiufundi wa Wingu la Google
Hadithi kuhusu kukosa pakiti za DNS kutoka kwa usaidizi wa kiufundi wa Wingu la Google
Kutoka kwa Mhariri wa Blogu ya Google: Je, umewahi kujiuliza jinsi wahandisi wa Google Cloud Technical Solutions (TSE) hushughulikia maombi yako ya usaidizi? Wahandisi wa Usaidizi wa Kiufundi wa TSE wana jukumu la kutambua na kurekebisha vyanzo vya matatizo vilivyoripotiwa na mtumiaji. Baadhi ya shida hizi ni rahisi sana, lakini wakati mwingine unakutana na tikiti ambayo inahitaji umakini wa wahandisi kadhaa mara moja. Katika nakala hii, mmoja wa wafanyikazi wa TSE atatuambia juu ya shida moja gumu kutoka kwa mazoezi yake ya hivi majuzi - kesi ya kukosa pakiti za DNS. Katika hadithi hii, tutaona jinsi wahandisi waliweza kutatua hali hiyo, na ni mambo gani mapya waliyojifunza wakati wa kurekebisha kosa. Tunatumahi kuwa hadithi hii haitakuelimisha tu kuhusu hitilafu iliyo ndani kabisa, lakini pia inakupa maarifa kuhusu michakato inayoingia katika kuwasilisha tikiti ya usaidizi kwa Wingu la Google.
Utatuzi wa shida ni sayansi na sanaa. Yote huanza na kujenga hypothesis kuhusu sababu ya tabia isiyo ya kawaida ya mfumo, baada ya hapo inajaribiwa kwa nguvu. Hata hivyo, kabla ya kuunda dhana, ni lazima tufafanue kwa uwazi na kuunda tatizo kwa usahihi. Ikiwa swali linasikika kuwa wazi sana, basi itabidi kuchambua kila kitu kwa uangalifu; Hii ni "sanaa" ya kutatua matatizo.
Chini ya Wingu la Google, michakato kama hii huwa ngumu zaidi, kwani Wingu la Google hujaribu iwezavyo kuhakikisha ufaragha wa watumiaji wake. Kwa sababu hii, wahandisi wa TSE hawana ufikiaji wa kuhariri mifumo yako, wala uwezo wa kuona usanidi kwa upana kama watumiaji wanavyofanya. Kwa hivyo, ili kujaribu nadharia zetu zozote, sisi (wahandisi) hatuwezi kurekebisha mfumo haraka.
Watumiaji wengine wanaamini kuwa tutarekebisha kila kitu kama mechanics katika huduma ya gari, na tutumie tu kitambulisho cha mashine pepe, ilhali kwa uhalisia mchakato unafanyika katika muundo wa mazungumzo: kukusanya habari, kuunda na kuthibitisha (au kukanusha) nadharia, na, mwishowe, shida za uamuzi zinatokana na mawasiliano na mteja.
Tatizo katika swali
Leo tuna hadithi yenye mwisho mzuri. Moja ya sababu za ufumbuzi wa mafanikio wa kesi iliyopendekezwa ni maelezo ya kina na sahihi ya tatizo. Hapo chini unaweza kuona nakala ya tikiti ya kwanza (iliyohaririwa ili kuficha taarifa za siri):
Ujumbe huu una habari nyingi muhimu kwetu:
VM maalum imebainishwa
Shida yenyewe imeonyeshwa - DNS haifanyi kazi
Inaonyeshwa ambapo shida inajidhihirisha - VM na chombo
Hatua ambazo mtumiaji alichukua kutambua tatizo zimeonyeshwa.
Ombi lilisajiliwa kama "P1: Athari Muhimu - Huduma Isiyotumika katika uzalishaji", ambayo inamaanisha ufuatiliaji wa mara kwa mara wa hali 24/7 kulingana na mpango wa "Fuata Jua" (unaweza kusoma zaidi kuhusu vipaumbele vya maombi ya watumiaji), pamoja na uhamisho wake kutoka kwa timu moja ya usaidizi wa kiufundi hadi nyingine kwa kila mabadiliko ya saa za eneo. Kwa hakika, wakati tatizo lilipofikia timu yetu huko Zurich, tayari ilikuwa imezunguka dunia. Kufikia wakati huu, mtumiaji alikuwa amechukua hatua za kupunguza, lakini aliogopa kurudia hali hiyo katika uzalishaji, kwani sababu ya mizizi ilikuwa bado haijagunduliwa.
Kufikia wakati tikiti ilifika Zurich, tayari tulikuwa na habari ifuatayo mkononi:
Yaliyomo /etc/hosts
Yaliyomo /etc/resolv.conf
Pato iptables-save
Imekusanywa na timu ngrep pcap faili
Kwa data hii, tulikuwa tayari kuanza "uchunguzi" na awamu ya utatuzi.
Hatua zetu za kwanza
Kwanza kabisa, tuliangalia kumbukumbu na hali ya seva ya metadata na tukahakikisha kuwa inafanya kazi kwa usahihi. Seva ya metadata inajibu kwa anwani ya IP 169.254.169.254 na, kati ya mambo mengine, inawajibika kwa kudhibiti majina ya kikoa. Pia tulikagua mara mbili kuwa ngome inafanya kazi kwa usahihi na VM na haizuii pakiti.
Ilikuwa ni aina fulani ya shida ya kushangaza: ukaguzi wa nmap ulikanusha nadharia yetu kuu juu ya upotezaji wa pakiti za UDP, kwa hivyo kiakili tulikuja na chaguzi kadhaa zaidi na njia za kuziangalia:
Je, pakiti hudondoshwa kwa kuchagua? => Angalia sheria za iptables
Je, si ni ndogo sana? MTU? => Angalia pato ip a show
Je, tatizo linaathiri pakiti za UDP pekee au TCP pia? => Endesha mbali dig +tcp
Je, pakiti zinazozalishwa na kuchimba zinarejeshwa? => Endesha mbali tcpdump
Je, libdns inafanya kazi kwa usahihi? => Endesha mbali strace kuangalia upitishaji wa pakiti katika pande zote mbili
Hapa tunaamua kumwita mtumiaji ili kutatua matatizo moja kwa moja.
Wakati wa simu tunaweza kuangalia mambo kadhaa:
Baada ya ukaguzi kadhaa tunatenga sheria za iptables kutoka kwa orodha ya sababu
Tunaangalia miingiliano ya mtandao na meza za kuelekeza, na angalia mara mbili kuwa MTU ni sahihi
Tunagundua hilo dig +tcp google.com (TCP) inafanya kazi kama inavyopaswa, lakini dig google.com (UDP) haifanyi kazi
Baada ya kufukuzwa tcpdump bado inafanya kazi dig, tunapata kwamba pakiti za UDP zinarejeshwa
Tunaendesha gari strace dig google.com na tunaona jinsi kuchimba kwa usahihi wito sendmsg() ΠΈ recvms(), hata hivyo ya pili inakatizwa na kuisha kwa muda
Kwa bahati mbaya, mwisho wa zamu hufika na tunalazimika kuongeza tatizo hadi eneo la wakati ujao. Ombi hilo, hata hivyo, liliamsha shauku kwa timu yetu, na mfanyakazi mwenzetu anapendekeza kuunda kifurushi cha awali cha DNS kwa kutumia moduli ya Python chakavu.
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())
Kipande hiki huunda pakiti ya DNS na kutuma ombi kwa seva ya metadata.
Mtumiaji anaendesha msimbo, majibu ya DNS yanarejeshwa, na programu inapokea, kuthibitisha kuwa hakuna tatizo katika ngazi ya mtandao.
Baada ya "safari nyingine ya kuzunguka ulimwengu," ombi linarudi kwa timu yetu, na ninaihamisha kwangu kabisa, nikifikiria kuwa itakuwa rahisi zaidi kwa mtumiaji ikiwa ombi litaacha kuzunguka kutoka mahali hadi mahali.
Wakati huo huo, mtumiaji anakubali kwa fadhili kutoa picha ya picha ya mfumo. Hii ni habari njema sana: uwezo wa kupima mfumo mwenyewe hufanya utatuzi wa shida haraka sana, kwa sababu sihitaji tena kuuliza mtumiaji kutekeleza amri, nitumie matokeo na kuyachambua, naweza kufanya kila kitu mwenyewe!
Wenzangu wanaanza kunionea wivu kidogo. Wakati wa chakula cha mchana tunajadili uongofu, lakini hakuna anayejua kinachoendelea. Kwa bahati nzuri, mtumiaji mwenyewe tayari amechukua hatua za kupunguza matokeo na hana haraka, kwa hivyo tuna wakati wa kugawanya shida. Na kwa kuwa tunayo picha, tunaweza kuendesha majaribio yoyote yanayotuvutia. Kubwa!
Kuchukua hatua nyuma
Mojawapo ya maswali maarufu ya mahojiano kwa nafasi za wahandisi wa mifumo ni: "Ni nini hufanyika unapopiga www.google.com? Swali ni nzuri, kwani mgombea anahitaji kuelezea kila kitu kutoka kwa ganda hadi nafasi ya mtumiaji, hadi kwenye kernel ya mfumo na kisha kwa mtandao. Ninatabasamu: wakati mwingine maswali ya mahojiano yanageuka kuwa muhimu katika maisha halisi ...
Ninaamua kutumia swali hili la HR kwa shida ya sasa. Kwa kusema, unapojaribu kuamua jina la DNS, yafuatayo hufanyika:
Programu huita maktaba ya mfumo kama vile libdns
libdns hukagua usanidi wa mfumo ambao seva ya DNS inapaswa kuwasiliana nayo (kwenye mchoro hii ni 169.254.169.254, seva ya metadata)
libdns hutumia simu za mfumo kuunda soketi ya UDP (SOKET_DGRAM) na kutuma pakiti za UDP zilizo na swali la DNS katika pande zote mbili.
Kupitia kiolesura cha sysctl unaweza kusanidi mkusanyiko wa UDP kwenye kiwango cha kernel
Keneli huingiliana na maunzi ili kusambaza pakiti kwenye mtandao kupitia kiolesura cha mtandao
Hypervisor inashika na kusambaza pakiti kwa seva ya metadata inapogusana nayo
Seva ya metadata, kwa uchawi wake, huamua jina la DNS na kurudisha jibu kwa kutumia njia sawa
Acha nikukumbushe ni nadharia gani ambazo tayari tumezingatia:
Dhana: Maktaba zilizovunjwa
Jaribio la 1: endesha safu kwenye mfumo, angalia kuwa kuchimba huita simu sahihi za mfumo
Matokeo: Simu sahihi za mfumo zinaitwa
Jaribio la 2: kutumia srapy kuangalia kama tunaweza kubainisha majina kwa kupita maktaba za mfumo
Matokeo: tunaweza
Jaribio la 3: endesha rpm -V kwenye kifurushi cha libdns na faili za maktaba za md5sum
Matokeo: msimbo wa maktaba ni sawa kabisa na kanuni katika mfumo wa uendeshaji wa kazi
Jaribio la 4: weka picha ya mfumo wa mizizi ya mtumiaji kwenye VM bila tabia hii, endesha chroot, angalia ikiwa DNS inafanya kazi
Matokeo: DNS inafanya kazi kwa usahihi
Hitimisho kulingana na vipimo: tatizo halipo kwenye maktaba
Dhana: Kuna hitilafu katika mipangilio ya DNS
Jaribio la 1: angalia tcpdump na uone ikiwa pakiti za DNS zimetumwa na kurudishwa kwa usahihi baada ya kuchimba.
Matokeo: pakiti hupitishwa kwa usahihi
Jaribio la 2: angalia mara mbili kwenye seva /etc/nsswitch.conf ΠΈ /etc/resolv.conf
Matokeo: kila kitu ni sawa
Hitimisho kulingana na vipimo: shida sio na usanidi wa DNS
Hypothesis: msingi umeharibiwa
Mtihani: sasisha kernel mpya, angalia saini, anzisha tena
Matokeo: tabia sawa
Hitimisho kulingana na vipimo: punje haijaharibiwa
Hypothesis: tabia isiyo sahihi ya mtandao wa mtumiaji (au kiolesura cha mtandao cha hypervisor)
Jaribio la 1: Angalia mipangilio yako ya ngome
Matokeo: ngome hupitisha pakiti za DNS kwenye seva pangishi na GCP
Jaribio la 2: zuia trafiki na ufuatilie usahihi wa utumaji na urejeshaji wa maombi ya DNS
Matokeo: tcpdump inathibitisha kuwa mwenyeji amepokea pakiti za kurejesha
Hitimisho kulingana na vipimo: tatizo halipo kwenye mtandao
Hypothesis: seva ya metadata haifanyi kazi
Jaribio la 1: angalia kumbukumbu za seva ya metadata kwa hitilafu
Matokeo: hakuna hitilafu kwenye kumbukumbu
Jaribio la 2: Pitisha seva ya metadata kupitia dig @8.8.8.8
Matokeo: Azimio limevunjwa hata bila kutumia seva ya metadata
Hitimisho kulingana na vipimo: tatizo haliko kwenye seva ya metadata
line ya chini: tulijaribu mifumo yote ndogo isipokuwa mipangilio ya wakati wa kukimbia!
Kuingia kwenye Mipangilio ya Kernel Runtime
Ili kusanidi mazingira ya utekelezaji wa kernel, unaweza kutumia chaguzi za mstari wa amri (grub) au kiolesura cha sysctl. Nikatazama ndani /etc/sysctl.conf na fikiria tu, niligundua mipangilio kadhaa maalum. Nilihisi kana kwamba nilikuwa nimeshika kitu, nilitupa mipangilio yote isiyo ya mtandao au isiyo ya tcp, nikibaki na mipangilio ya mlima. net.core. Kisha nikaenda ambapo ruhusa za mwenyeji zilikuwa kwenye VM na nikaanza kutumia mipangilio moja baada ya nyingine, moja baada ya nyingine, na VM iliyovunjika, hadi nikapata mhalifu:
net.core.rmem_default = 2147483647
Hii hapa, usanidi wa kuvunja DNS! Nilipata silaha ya mauaji. Lakini kwa nini hii inatokea? Bado nilihitaji nia.
Saizi ya msingi ya bafa ya pakiti ya DNS imesanidiwa kupitia net.core.rmem_default. Thamani ya kawaida ni mahali fulani karibu 200KiB, lakini seva yako ikipokea pakiti nyingi za DNS, unaweza kutaka kuongeza saizi ya bafa. Ikiwa buffer imejaa wakati pakiti mpya inapowasili, kwa mfano kwa sababu programu haijaichakata haraka vya kutosha, basi utaanza kupoteza pakiti. Mteja wetu aliongeza kwa usahihi ukubwa wa bafa kwa sababu aliogopa kupoteza data, kwa kuwa alikuwa akitumia programu ya kukusanya vipimo kupitia pakiti za DNS. Thamani aliyoweka ilikuwa ya juu iwezekanavyo: 231-1 (ikiwa imewekwa 231, kernel itarudi "HOJA BATILI").
Ghafla niligundua ni kwanini nmap na scapy zilifanya kazi kwa usahihi: walikuwa wakitumia soketi mbichi! Soketi mbichi ni tofauti na soketi za kawaida: hupita iptables, na hazijapigwa buffer!
Lakini kwa nini "bafa kubwa sana" husababisha shida? Ni wazi haifanyi kazi kama ilivyokusudiwa.
Kwa wakati huu ningeweza kuzaliana tena shida kwenye kokwa nyingi na usambazaji mwingi. Tatizo tayari limeonekana kwenye 3.x kernel na sasa lilionekana pia kwenye 5.x kernel.
Kwa kweli, wakati wa kuanza
sysctl -w net.core.rmem_default=$((2**31-1))
DNS iliacha kufanya kazi.
Nilianza kutafuta maadili ya kufanya kazi kupitia algorithm rahisi ya utaftaji wa binary na nikagundua kuwa mfumo ulifanya kazi na 2147481343, lakini nambari hii ilikuwa seti isiyo na maana ya nambari kwangu. Nilipendekeza mteja ajaribu nambari hii, na akajibu kuwa mfumo ulifanya kazi na google.com, lakini bado ulitoa hitilafu na vikoa vingine, kwa hivyo niliendelea na uchunguzi wangu.
Nimeweka dropwatch, chombo ambacho kilipaswa kutumika mapema: inaonyesha ni wapi kwenye kernel pakiti inaishia. Mkosaji alikuwa kazi udp_queue_rcv_skb. Nilipakua vyanzo vya kernel na kuongeza chache kaziprintk kufuatilia ni wapi pakiti inaishia. Nilipata hali sahihi haraka if, na kuiangalia tu kwa muda, kwa sababu ilikuwa wakati huo kwamba kila kitu hatimaye kilikusanyika katika picha nzima: 231-1, nambari isiyo na maana, kikoa kisichofanya kazi ... Ilikuwa kipande cha kanuni katika __udp_enqueue_schedule_skb:
if (rmem > (size + sk->sk_rcvbuf))
goto uncharge_drop;
Tafadhali kumbuka:
rmem ni ya aina int
size ni ya aina ya u16 (isiyo na saini ya biti kumi na sita) na huhifadhi saizi ya pakiti
sk->sk_rcybuf ni ya aina int na huhifadhi saizi ya bafa ambayo, kwa ufafanuzi, ni sawa na thamani ndani net.core.rmem_default
Wakati sk_rcvbuf inakaribia 231, kwa muhtasari wa saizi ya pakiti inaweza kusababisha kufurika kamili. Na kwa kuwa ni int, thamani yake inakuwa hasi, kwa hivyo hali inakuwa kweli wakati inapaswa kuwa ya uwongo (unaweza kusoma zaidi juu ya hii kwa kiungo).
Hitilafu inaweza kusahihishwa kwa njia isiyo na maana: kwa kutupa unsigned int. Nilitumia urekebishaji na kuanza tena mfumo na DNS ilifanya kazi tena.
Ladha ya ushindi
Nilituma matokeo yangu kwa mteja na kutuma LKML kiraka cha kernel. Nimefurahiya: kila kipande cha fumbo kinalingana, ninaweza kueleza haswa kwa nini tuliona kile tulichoona, na muhimu zaidi, tuliweza kupata suluhu la tatizo kutokana na kazi yetu ya pamoja!
Inafaa kutambua kuwa kesi hiyo iligeuka kuwa nadra, na kwa bahati nzuri sisi hupokea maombi magumu kama haya kutoka kwa watumiaji.