Պատմություն Google Cloud տեխնիկական աջակցությունից բացակայող DNS փաթեթների մասին

Google Բլոգի խմբագրիչից. Երբևէ մտածե՞լ եք, թե ինչպես են Google Cloud Technical Solutions (TSE) ինժեներները լուծում ձեր աջակցության հարցումները: TSE-ի տեխնիկական աջակցության ինժեներները պատասխանատու են օգտատերերի կողմից հաղորդված խնդիրների աղբյուրները հայտնաբերելու և ուղղելու համար: Այս խնդիրներից մի քանիսը բավականին պարզ են, բայց երբեմն հանդիպում եք տոմսի, որը պահանջում է միանգամից մի քանի ինժեների ուշադրությունը: Այս հոդվածում TSE-ի աշխատակիցներից մեկը մեզ կպատմի իր վերջին պրակտիկայից մի շատ բարդ խնդրի մասին. DNS փաթեթների բացակայման դեպք. Այս պատմության մեջ մենք կտեսնենք, թե ինչպես են ինժեներներին հաջողվել կարգավորել իրավիճակը, և ինչ նոր բաներ են նրանք սովորել սխալն ուղղելիս: Հուսով ենք, որ այս պատմությունը ոչ միայն կսովորեցնի ձեզ խորը արմատացած սխալի մասին, այլև հնարավորություն կտա ձեզ պատկերացում կազմել այն գործընթացների մասին, որոնք գնում են Google Cloud-ում աջակցության տոմս ներկայացնելու մեջ:

Պատմություն Google Cloud տեխնիկական աջակցությունից բացակայող DNS փաթեթների մասին

Անսարքությունների վերացումը և՛ գիտություն է, և՛ արվեստ: Ամեն ինչ սկսվում է համակարգի ոչ ստանդարտ վարքագծի պատճառի մասին վարկած ստեղծելուց, որից հետո այն ստուգվում է ամրության համար։ Այնուամենայնիվ, նախքան վարկածը ձևակերպելը, մենք պետք է հստակ սահմանենք և հստակ ձևակերպենք խնդիրը: Եթե ​​հարցը չափազանց անորոշ է թվում, ապա ստիպված կլինեք ուշադիր վերլուծել ամեն ինչ. Սա խնդիրների լուծման «արվեստն» է:

Google Cloud-ի ներքո նման գործընթացները դառնում են էքսպոնենցիալ ավելի բարդ, քանի որ Google Cloud-ը փորձում է առավելագույնը երաշխավորել իր օգտատերերի գաղտնիությունը: Այդ պատճառով, TSE-ի ինժեներները հնարավորություն չունեն խմբագրելու ձեր համակարգերը, ինչպես նաև հնարավորություն չունեն կոնֆիգուրացիաները դիտելու այնքան լայն, որքան օգտվողները: Հետևաբար, մեր վարկածներից որևէ մեկը ստուգելու համար մենք (ինժեներները) չենք կարող արագ փոփոխել համակարգը:

Որոշ օգտատերեր կարծում են, որ մենք կուղղենք ամեն ինչ, ինչպես մեխանիկը մեքենայի ծառայության մեջ, և պարզապես մեզ կուղարկենք վիրտուալ մեքենայի id-ն, մինչդեռ իրականում գործընթացը տեղի է ունենում խոսակցական ձևաչափով՝ տեղեկատվության հավաքում, վարկածների ձևավորում և հաստատում (կամ հերքում), և, ի վերջո, որոշման խնդիրները հիմնված են հաճախորդի հետ շփման վրա:

Խնդիրը հարցականի տակ է

Այսօր մենք ունենք լավ ավարտ ունեցող պատմություն։ Առաջարկվող գործի հաջող հանգուցալուծման պատճառներից մեկը խնդրի շատ մանրամասն և ճշգրիտ նկարագրությունն է։ Ստորև կարող եք տեսնել առաջին տոմսի պատճենը (խմբագրված՝ գաղտնի տեղեկատվությունը թաքցնելու համար).
Պատմություն Google Cloud տեխնիկական աջակցությունից բացակայող DNS փաթեթների մասին
Այս հաղորդագրությունը պարունակում է մեզ համար շատ օգտակար տեղեկություններ.

  • Նշված է հատուկ VM
  • Խնդիրն ինքնին նշված է՝ DNS-ը չի աշխատում
  • Նշվում է, թե որտեղ է դրսևորվում խնդիրը՝ VM և կոնտեյներ
  • Նշված են այն քայլերը, որոնք օգտագործողը ձեռնարկել է խնդիրը բացահայտելու համար:

Հարցումը գրանցվել է որպես «P1. Կրիտիկական ազդեցություն - Ծառայություն, որն անօգտագործելի է արտադրության մեջ», ինչը նշանակում է իրավիճակի մշտական ​​մոնիտորինգ 24/7՝ համաձայն «Հետևիր արևին» սխեմայի (կարող եք կարդալ ավելին օգտագործողների հարցումների առաջնահերթությունները), յուրաքանչյուր ժամային գոտու հերթափոխով տեխնիկական աջակցության մեկ թիմից մյուսը տեղափոխելով: Փաստորեն, երբ խնդիրը հասավ Ցյուրիխի մեր թիմին, այն արդեն պտտվել էր աշխարհով մեկ: Այս պահին օգտատերը մեղմացնող միջոցներ էր ձեռնարկել, բայց վախենում էր արտադրության մեջ իրավիճակի կրկնությունից, քանի որ հիմնական պատճառը դեռևս բացահայտված չէր:

Երբ տոմսը հասավ Ցյուրիխ, մենք արդեն ձեռքի տակ ունեինք հետևյալ տեղեկությունը.

  • Բովանդակություն /etc/hosts
  • Բովանդակություն /etc/resolv.conf
  • Արտադրողականություն iptables-save
  • Թիմի կողմից հավաքված ngrep pcap ֆայլ

Այս տվյալներով մենք պատրաստ էինք սկսել «հետաքննության» և անսարքությունների վերացման փուլը:

Մեր առաջին քայլերը

Առաջին հերթին մենք ստուգեցինք մետատվյալների սերվերի տեղեկամատյաններն ու կարգավիճակը և համոզվեցինք, որ այն ճիշտ է աշխատում։ Մետատվյալների սերվերը պատասխանում է 169.254.169.254 IP հասցեին և, ի թիվս այլ բաների, պատասխանատու է տիրույթի անունները վերահսկելու համար: Մենք նաև կրկնակի ստուգեցինք, որ firewall-ը ճիշտ է աշխատում VM-ի հետ և չի արգելափակում փաթեթները:

Դա ինչ-որ տարօրինակ խնդիր էր. nmap-ի ստուգումը հերքեց UDP փաթեթների կորստի մասին մեր հիմնական վարկածը, ուստի մենք մտովի հայտնեցինք դրանք ստուգելու ևս մի քանի տարբերակներ և եղանակներ.

  • Արդյո՞ք փաթեթները ընտրովի են ընկնում: => Ստուգեք iptables կանոնները
  • Շատ փոքր չէ՞։ MTU? => Ստուգեք ելքը ip a show
  • Արդյո՞ք խնդիրը ազդում է միայն UDP փաթեթների կամ TCP-ի վրա: => Քշել հեռու dig +tcp
  • Արդյո՞ք փորման արդյունքում ստեղծված փաթեթները վերադարձվում են: => Քշել հեռու tcpdump
  • Արդյո՞ք libdns-ը ճիշտ է աշխատում: => Քշել հեռու strace ստուգել փաթեթների փոխանցումը երկու ուղղություններով

Այստեղ մենք որոշում ենք զանգահարել օգտատիրոջը՝ խնդիրներն ուղիղ եթերում լուծելու համար:

Զանգի ընթացքում մենք կարող ենք ստուգել մի քանի բան.

  • Մի քանի ստուգումներից հետո մենք բացառում ենք iptables կանոնները պատճառների ցանկից
  • Մենք ստուգում ենք ցանցի միջերեսները և երթուղիների աղյուսակները և կրկնակի ստուգում, որ MTU-ն ճիշտ է
  • Մենք դա բացահայտում ենք dig +tcp google.com (TCP) աշխատում է այնպես, ինչպես պետք է, բայց dig google.com (UDP) չի աշխատում
  • Քշվելով tcpdump այն դեռ աշխատում է dig, մենք գտնում ենք, որ UDP փաթեթները վերադարձվում են
  • Մենք քշում ենք strace dig google.com և մենք տեսնում ենք, թե ինչպես է փորում ճիշտ կանչում sendmsg() и recvms(), սակայն երկրորդն ընդհատվում է թայմաութով

Ցավոք, հերթափոխի ավարտը հասնում է, և մենք ստիպված ենք խնդիրը սրել հաջորդ ժամային գոտի: Հարցումը, սակայն, հետաքրքրություն առաջացրեց մեր թիմի մոտ, և գործընկերներից մեկն առաջարկում է ստեղծել նախնական DNS փաթեթը՝ օգտագործելով scrapy Python մոդուլը։

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

Այս հատվածը ստեղծում է DNS փաթեթ և հարցումն ուղարկում մետատվյալների սերվերին:

Օգտագործողը գործարկում է կոդը, DNS-ի պատասխանը վերադարձվում է, և հավելվածը ստանում է այն՝ հաստատելով, որ ցանցի մակարդակում խնդիր չկա։

Հերթական «շուրջաշխարհի ճանապարհորդությունից» հետո հարցումը վերադառնում է մեր թիմին, և ես այն ամբողջությամբ փոխանցում եմ ինձ՝ մտածելով, որ օգտագործողի համար ավելի հարմար կլինի, եթե հարցումը դադարի տեղից տեղ պտտվել:

Միևնույն ժամանակ, օգտվողը սիրով համաձայնում է տրամադրել համակարգի պատկերի պատկերը: Սա շատ լավ նորություն է. ինքս համակարգը փորձարկելու ունակությունը շատ ավելի արագ է դարձնում անսարքությունների վերացումը, քանի որ ես այլևս կարիք չունեմ օգտվողին խնդրելու հրամաններ գործարկել, ուղարկել ինձ արդյունքները և վերլուծել դրանք, ես ինքս կարող եմ ամեն ինչ անել:

Գործընկերներս սկսում են մի փոքր նախանձել ինձ։ Ճաշի ընթացքում մենք քննարկում ենք փոխակերպումը, բայց ոչ ոք պատկերացում չունի, թե ինչ է կատարվում: Բարեբախտաբար, օգտատերն ինքը արդեն միջոցներ է ձեռնարկել հետևանքները մեղմելու համար և չի շտապում, այնպես որ մենք ժամանակ ունենք խնդիրը վերացնելու համար։ Եվ քանի որ մենք ունենք պատկեր, կարող ենք մեզ հետաքրքրող ցանկացած թեստ անցկացնել։ Հիանալի

Մի քայլ հետ գնալով

Համակարգի ինժեների պաշտոնների համար ամենահայտնի հարցազրույցի հարցերից մեկը հետևյալն է www.google.com? Հարցը հիանալի է, քանի որ թեկնածուն պետք է նկարագրի ամեն ինչ՝ shell-ից մինչև օգտագործողի տարածք, համակարգի միջուկ և այնուհետև ցանց: Ժպտում եմ. երբեմն հարցազրույցի հարցերն օգտակար են դառնում իրական կյանքում...

Ես որոշում եմ կիրառել այս HR հարցը ընթացիկ խնդրին: Կոպիտ ասած, երբ փորձում եք որոշել DNS անունը, տեղի է ունենում հետևյալը.

  1. Հավելվածը կանչում է համակարգային գրադարան, ինչպիսին է libdns-ը
  2. libdns-ը ստուգում է համակարգի կոնֆիգուրացիան, որին պետք է կապվի DNS սերվերի հետ (գծապատկերում սա 169.254.169.254 է, մետատվյալների սերվեր)
  3. libdns-ն օգտագործում է համակարգային զանգեր՝ ստեղծելու UDP վարդակ (SOKET_DGRAM) և ուղարկել UDP փաթեթներ՝ DNS հարցումով երկու ուղղություններով:
  4. sysctl ինտերֆեյսի միջոցով դուք կարող եք կարգավորել UDP ստեկը միջուկի մակարդակում
  5. Միջուկը փոխազդում է սարքաշարի հետ՝ ցանցային միջերեսի միջոցով փաթեթներ փոխանցելու համար
  6. Հիպերվիզորը որսում և փոխանցում է փաթեթը մետատվյալների սերվերին՝ դրա հետ շփվելուց հետո
  7. Մետատվյալների սերվերն իր հմայքով որոշում է DNS անվանումը և պատասխան է տալիս նույն մեթոդով

Պատմություն Google Cloud տեխնիկական աջակցությունից բացակայող DNS փաթեթների մասին
Հիշեցնեմ, թե ինչ վարկածներ ենք մենք արդեն դիտարկել.

Վարկած՝ կոտրված գրադարաններ

  • Թեստ 1. գործարկել strace համակարգում, ստուգել, ​​որ dig-ը կանչում է ճիշտ համակարգային զանգեր
  • Արդյունք. ճիշտ համակարգային զանգեր են կանչվում
  • Թեստ 2. օգտագործելով srapy՝ ստուգելու համար, թե արդյոք մենք կարող ենք անուններ որոշել՝ շրջանցելով համակարգի գրադարանները
  • Արդյունք՝ մենք կարող ենք
  • Թեստ 3. գործարկել rpm –V libdns փաթեթի և md5sum գրադարանի ֆայլերի վրա
  • Արդյունք. գրադարանի կոդը լիովին նույնական է գործող օպերացիոն համակարգի կոդի հետ
  • Թեստ 4. տեղադրեք օգտագործողի արմատային համակարգի պատկերը VM-ի վրա առանց այս պահվածքի, գործարկեք chroot-ը, տեսեք, թե արդյոք DNS-ն աշխատում է:
  • Արդյունք. DNS-ը ճիշտ է աշխատում

Եզրակացություն՝ հիմնված թեստերի վրա. խնդիրը գրադարաններում չէ

Վարկած. DNS-ի կարգավորումներում սխալ կա

  • Փորձարկում 1. ստուգեք tcpdump-ը և տեսեք, թե արդյոք DNS փաթեթները ճիշտ են ուղարկվում և վերադարձվում փորագրումը կատարելուց հետո
  • Արդյունք. փաթեթները ճիշտ են փոխանցվում
  • Թեստ 2. կրկնակի ստուգում սերվերի վրա /etc/nsswitch.conf и /etc/resolv.conf
  • Արդյունք. ամեն ինչ ճիշտ է

Եզրակացություն՝ հիմնված թեստերի վրա. խնդիրը DNS կոնֆիգուրացիայի մեջ չէ

Վարկած. միջուկը վնասված է

  • Թեստ. տեղադրել նոր միջուկ, ստուգել ստորագրությունը, վերագործարկել
  • Արդյունքը՝ նմանատիպ վարքագիծ

Եզրակացություն՝ հիմնված թեստերի վրա. միջուկը վնասված չէ

Վարկած. օգտագործողի ցանցի սխալ վարքագիծը (կամ հիպերվիզորի ցանցի ինտերֆեյսը)

  • Թեստ 1. Ստուգեք ձեր firewall-ի կարգավորումները
  • Արդյունք. firewall-ը փոխանցում է DNS փաթեթներ ինչպես հյուրընկալողի, այնպես էլ GCP-ի վրա
  • Թեստ 2. ընդհատել տրաֆիկը և վերահսկել DNS հարցումների փոխանցման և վերադարձի ճիշտությունը
  • Արդյունք. tcpdump-ը հաստատում է, որ հյուրընկալողը ստացել է վերադարձի փաթեթներ

Եզրակացություն՝ հիմնված թեստերի վրա. խնդիրը ցանցում չէ

Վարկած. մետատվյալների սերվերը չի աշխատում

  • Թեստ 1. ստուգեք մետատվյալների սերվերի տեղեկամատյանները անոմալիաների համար
  • Արդյունք. տեղեկամատյաններում անոմալիաներ չկան
  • Թեստ 2. շրջանցել մետատվյալների սերվերը dig @8.8.8.8
  • Արդյունք. Բանաձևը խափանում է նույնիսկ առանց մետատվյալների սերվեր օգտագործելու

Եզրակացություն՝ հիմնված թեստերի վրա. խնդիրը մետատվյալների սերվերի մեջ չէ

Ներքեւի տողը: մենք փորձարկել ենք բոլոր ենթահամակարգերը, բացառությամբ գործարկման ժամանակի կարգավորումներ!

Սուզվել միջուկի գործարկման ժամանակի կարգավորումներում

Միջուկի կատարման միջավայրը կարգավորելու համար կարող եք օգտագործել հրամանի տողի ընտրանքները (grub) կամ sysctl ինտերֆեյսը: Ես ներս նայեցի /etc/sysctl.conf և պարզապես մտածեք, ես հայտնաբերեցի մի քանի մաքսային կարգավորումներ: Կարծես ինչ-որ բան բռնել եմ, ես հրաժարվեցի բոլոր ոչ ցանցային կամ ոչ tcp կարգավորումներից՝ մնալով լեռան կարգավորումներում։ net.core. Հետո ես գնացի այնտեղ, որտեղ հոսթի թույլտվությունները գտնվում էին VM-ում և սկսեցի հերթով, մեկը մյուսի հետևից, կոտրված VM-ով կիրառել կարգավորումները, մինչև գտա մեղավորին.

net.core.rmem_default = 2147483647

Ահա դա, DNS-խախտող կոնֆիգուրացիա: Ես գտա սպանության զենքը. Բայց ինչու է դա տեղի ունենում: Ինձ դեռ շարժառիթ էր պետք։

Հիմնական DNS փաթեթի բուֆերի չափը կազմաձևվում է միջոցով net.core.rmem_default. Տիպիկ արժեքը մոտ 200 ԿԲ է, բայց եթե ձեր սերվերը ստանում է շատ DNS փաթեթներ, կարող եք մեծացնել բուֆերի չափը: Եթե ​​բուֆերը լցված է, երբ նոր փաթեթ է գալիս, օրինակ, քանի որ հավելվածը բավականաչափ արագ չի մշակում այն, ապա դուք կսկսեք կորցնել փաթեթները: Մեր հաճախորդը ճիշտ մեծացրել է բուֆերի չափը, քանի որ վախենում էր տվյալների կորստից, քանի որ օգտագործում էր հավելված DNS փաթեթների միջոցով չափումներ հավաքելու համար։ Նրա սահմանած արժեքը առավելագույն հնարավորն էր՝ 231-1 (եթե սահմանվի 231, միջուկը կվերադարձնի «ԱՆՎԱՎԵՐ ԱՐԳՄԵՆՏ»):

Հանկարծ ես հասկացա, թե ինչու են nmap-ը և scapy-ը ճիշտ աշխատում. նրանք օգտագործում էին հում վարդակներ: Հում վարդակները տարբերվում են սովորական վարդակից. նրանք շրջանցում են iptable-ները և բուֆերացված չեն:

Բայց ինչո՞ւ է «շատ մեծ բուֆերը» խնդիրներ առաջացնում: Այն ակնհայտորեն չի աշխատում, ինչպես նախատեսված է:

Այս պահին ես կարող եմ վերարտադրել խնդիրը բազմաթիվ միջուկների և բազմաթիվ բաշխումների վրա: Խնդիրն արդեն հայտնվել է 3.x միջուկի վրա, իսկ այժմ այն ​​հայտնվել է նաև 5.x միջուկի վրա։

Իրոք, գործարկման ժամանակ

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

DNS-ը դադարեց աշխատել:

Ես սկսեցի աշխատանքային արժեքներ փնտրել պարզ երկուական որոնման ալգորիթմի միջոցով և պարզեցի, որ համակարգը աշխատում է 2147481343-ով, բայց այս թիվը ինձ համար թվերի անիմաստ հավաքածու էր: Ես առաջարկեցի հաճախորդին փորձել այս համարը, և նա պատասխանեց, որ համակարգը աշխատում է google.com-ի հետ, բայց այնուամենայնիվ սխալ է թույլ տվել այլ տիրույթների հետ, ուստի ես շարունակեցի իմ հետաքննությունը:

ես տեղադրել եմ dropwatch, գործիք, որը պետք է օգտագործվեր ավելի վաղ. այն ցույց է տալիս, թե միջուկի որտեղ է ավարտվում փաթեթը: Մեղավորը գործառույթն էր udp_queue_rcv_skb. Ես ներբեռնեցի միջուկի աղբյուրները և ավելացրի մի քանիսը գործառույթները printk հետևելու, թե կոնկրետ որտեղ է ավարտվում փաթեթը: Ես արագ գտա ճիշտ վիճակը if, և պարզապես որոշ ժամանակ նայեցի դրան, քանի որ հենց այդ ժամանակ էր, որ ամեն ինչ վերջապես հավաքվեց մի ամբողջ պատկերի մեջ՝ 231-1, անիմաստ թիվ, չաշխատող տիրույթ... Դա կոդի կտոր էր։ __udp_enqueue_schedule_skb:

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

Խնդրում ենք նկատի ունենալ:

  • rmem ինտ տիպի է
  • size ունի u16 տիպ (անստորագիր տասնվեց բիթանոց int) և պահպանում է փաթեթի չափը
  • sk->sk_rcybuf int տիպի է և պահպանում է բուֆերի չափը, որն ըստ սահմանման հավասար է արժեքին net.core.rmem_default

Երբ sk_rcvbuf մոտենում է 231-ին, փաթեթի չափն ամփոփելը կարող է հանգեցնել ամբողջ թվերի արտահոսք. Եվ քանի որ դա int է, դրա արժեքը դառնում է բացասական, ուստի պայմանը դառնում է ճշմարիտ, երբ այն պետք է լինի կեղծ (այս մասին ավելին կարող եք կարդալ այստեղ՝ ՈՒղեցույց).

Սխալը կարելի է ուղղել չնչին եղանակով՝ ձուլման միջոցով unsigned int. Ես կիրառեցի ուղղումը և վերագործարկեցի համակարգը և DNS-ը նորից աշխատեց:

Հաղթանակի համը

Ես փոխանցեցի իմ գտածոները հաճախորդին և ուղարկեցի LKML միջուկի կարկատել: Ես գոհ եմ. հանելուկի յուրաքանչյուր կտոր տեղավորվում է, ես կարող եմ հստակ բացատրել, թե ինչու ենք մենք դիտարկել այն, ինչ դիտել ենք, և ամենակարևորը, մենք կարողացանք խնդրի լուծում գտնել թիմային աշխատանքի միջոցով:

Արժե գիտակցել, որ դեպքը հազվադեպ է ստացվել, և, բարեբախտաբար, մենք հազվադեպ ենք նման բարդ հարցումներ ստանում օգտատերերից:

Պատմություն Google Cloud տեխնիկական աջակցությունից բացակայող DNS փաթեթների մասին


Source: www.habr.com

Добавить комментарий