Google Cloud техникалык колдоосунан DNS пакеттеринин жетишсиздиги жөнүндө окуя

Google Блог Редакторунан: Google Cloud Technical Solutions (TSE) инженерлери сиздин колдоо сурамдарыңызды кантип аткарары жөнүндө ойлонуп көрдүңүз беле? TSE Техникалык колдоо инженерлери көйгөйлөрдүн колдонуучу билдирген булактарын аныктоо жана оңдоо үчүн жооптуу. Бул көйгөйлөрдүн айрымдары абдан жөнөкөй, бирок кээде сиз бир эле учурда бир нече инженердин көңүлүн талап кылган билетке туш болосуз. Бул макалада TSE кызматкерлеринин бири өзүнүн акыркы тажрыйбасынан бир өтө татаал маселе жөнүндө айтып берет - DNS пакеттери жок болгон учурда. Бул окуяда инженерлер кырдаалды кантип чечкенин жана катаны оңдоодо алар кандай жаңы нерселерди үйрөнүшкөнүн көрөбүз. Бул окуя сизге терең орун алган мүчүлүштүктөрдү гана эмес, Google Cloud менен колдоо билетин тапшыруу процесстерин да түшүнүүгө жардам берет деп үмүттөнөбүз.

Google Cloud техникалык колдоосунан DNS пакеттеринин жетишсиздиги жөнүндө окуя

Кыйынчылыктарды жоюу – бул илим жана искусство. Мунун баары системанын стандарттуу эмес жүрүм-турумунун себеби жөнүндө гипотеза түзүү менен башталат, андан кийин ал күчкө сыналат. Бирок, гипотезаны түзүүдөн мурун, маселени так аныктап, так формулировкалашыбыз керек. Эгерде суроо өтө бүдөмүк болсо, анда баарын кылдат талдап чыгууга туура келет; Бул көйгөйлөрдү чечүүнүн "искусствосу".

Google Булуттун шартында, мындай процесстер экспоненциалдуу түрдө татаалдашат, анткени Google Cloud өз колдонуучуларынын купуялуулугун кепилдөө үчүн колунан келгендин баарын жасайт. Ушундан улам, TSE инженерлери тутумдарыңызды оңдоого же конфигурацияларды колдонуучулардай кеңири көрүү мүмкүнчүлүгүнө ээ эмес. Ошондуктан, гипотезаларыбызды текшерүү үчүн, биз (инженерлер) системаны тез өзгөртө албайбыз.

Кээ бир колдонуучулар биз автосервистеги механика сыяктуу баарын оңдоп, бизге виртуалдык машинанын идентификаторун жөнөтөбүз деп ишенишет, ал эми иш жүзүндө процесс сүйлөшүү форматында жүрөт: маалымат чогултуу, гипотезаларды түзүү жана тастыктоо (же жокко чыгаруу), жана, акыры, бир чечим көйгөйлөр кардар менен байланышка негизделген.

Каралып жаткан маселе

Бүгүн бизде аягы жакшы болгон окуя бар. Сунуш кылынган иштин ийги-ликтуу чечилишинин себептеринин бири — маселенин ете так жана так баяндалышы. Төмөндө биринчи билеттин көчүрмөсүн көрө аласыз (жашыруун маалыматты жашыруу үчүн редакцияланган):
Google Cloud техникалык колдоосунан DNS пакеттеринин жетишсиздиги жөнүндө окуя
Бул билдирүү биз үчүн көптөгөн пайдалуу маалыматтарды камтыйт:

  • Атайын VM көрсөтүлгөн
  • Көйгөйдүн өзү көрсөтүлгөн - DNS иштебейт
  • Көйгөй кайда көрүнүп турганы көрсөтүлөт - VM жана контейнер
  • Колдонуучу көйгөйдү аныктоо үчүн жасаган кадамдары көрсөтүлгөн.

Сурам "P1: Критикалык таасир - өндүрүштө колдонууга жараксыз кызмат" катары катталган, бул "Күндү ээрчүү" схемасы боюнча 24/7 кырдаалга туруктуу мониторинг жүргүзүүнү билдирет (сиз жөнүндө көбүрөөк окуй аласыз колдонуучулардын суроо-талаптарынын артыкчылыктары), ар бир убакыт алкагынын жылышы менен бир техникалык колдоо тобунан экинчисине өтүү менен. Чынында, бул маселе Цюрихтеги биздин командага жеткенде, ал жер шарын айланып өткөн. Бул убакытка чейин, колдонуучу жумшартуу чараларды көргөн, бирок түпкү себеби али ачыла элек болгондуктан, өндүрүштөгү кырдаалдын кайталанышынан корккон.

Билет Цюрихке жеткенде, бизде төмөнкү маалыматтар бар болчу:

  • көрүү /etc/hosts
  • көрүү /etc/resolv.conf
  • жыйынтыктоо iptables-save
  • Команда тарабынан чогултулган ngrep pcap файлы

Бул маалыматтар менен биз "иликтөө" жана көйгөйлөрдү чечүү баскычын баштоого даяр болчубуз.

Биздин алгачкы кадамдарыбыз

Биринчиден, биз метаберилиштер серверинин журналдарын жана абалын текшерип, анын туура иштеп жаткандыгына ынандык. Метаберилиш сервери 169.254.169.254 IP дарегине жооп берет жана башка нерселер менен катар домендик аталыштарды көзөмөлдөө үчүн жооп берет. Биз ошондой эле брандмауэр VM менен туура иштешин жана пакеттерди бөгөттөбөй турганын эки жолу текшердик.

Бул кандайдыр бир кызыктай көйгөй болду: nmap текшерүүсү UDP пакеттеринин жоголушу жөнүндөгү негизги гипотезабызды жокко чыгарды, ошондуктан биз акыл эсибизде дагы бир нече варианттарды жана аларды текшерүүнүн жолдорун ойлоп таптык:

  • Пакеттер тандалып түшүрүлөбү? => iptables эрежелерин текшерүү
  • Өтө кичинекей эмеспи? АДАМ? => Чыгууну текшерүү 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(), бирок экинчиси тайм-аут менен үзгүлтүккө учурайт

Тилекке каршы, нөөмөттүн аягы келип, маселени кийинки убакыт алкагына өткөрүүгө аргасыз болуп жатабыз. Бирок бул өтүнүч биздин команданын кызыгуусун жаратты жана кесиптешибиз Scrapy Python модулунун жардамы менен баштапкы DNS пакетин түзүүнү сунуштайт.

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? Суроо абдан жакшы, анткени талапкер кабыктан колдонуучу мейкиндигине, системанын өзөгүнө жана андан кийин тармакка чейин баарын сүрөттөп бериши керек. Жылмайам: кээде интервью суроолору чыныгы жашоодо пайдалуу болуп калат...

Мен бул 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 иштетиңиз, казуунун туура тутум чалууларын чакырганын текшериңиз
  • Натыйжа: Туура система чалуулары чакырылат
  • Сыноо 2: srapy аркылуу система китепканаларын кыйгап өтүп аттарды аныктоого болобу же жокпу текшерүү
  • Натыйжа: биз алабыз
  • Тест 3: libdns пакетинде жана md5sum китепканасынын файлдарында rpm –V иштетиңиз
  • Натыйжа: китепкана коду иштеп жаткан операциялык системадагы код менен толугу менен окшош
  • Тест 4: колдонуучунун тамыр тутумунун сүрөтүн VMге мындай жүрүм-туруму жок орнотуңуз, chrootту иштетиңиз, DNS иштейби же жокпу, көрүңүз
  • Натыйжа: DNS туура иштейт

Тесттердин негизинде корутунду: маселе китепканаларда эмес

Гипотеза: DNS орнотууларында ката бар

  • Тест 1: tcpdump текшерип, DNS пакеттери казылгандан кийин туура жөнөтүлгөнүн жана кайтарылганын көрүңүз
  • Натыйжа: пакеттер туура өткөрүлдү
  • Тест 2: серверде эки жолу текшерүү /etc/nsswitch.conf и /etc/resolv.conf
  • Жыйынтык: баары туура

Тесттердин негизинде корутунду: көйгөй DNS конфигурациясында эмес

Гипотеза: өзөк бузулган

  • Сыноо: жаңы ядрону орнотуу, кол тамганы текшерүү, кайра иштетүү
  • Натыйжа: окшош жүрүм-турум

Тесттердин негизинде корутунду: ядро бузулган эмес

Гипотеза: колдонуучу тармагынын туура эмес жүрүм-туруму (же гипервизордук тармак интерфейси)

  • Тест 1: Firewall жөндөөлөрүңүздү текшериңиз
  • Натыйжа: брандмауэр DNS пакеттерин хостко жана GCPге өткөрөт
  • Тест 2: трафикти кармап, DNS суроо-талаптарын берүүнүн жана кайтаруунун тууралыгын көзөмөлдөө
  • Натыйжа: tcpdump хост кайтаруу пакеттерин алганын тастыктайт

Тесттердин негизинде корутунду: маселе тармакта эмес

Гипотеза: метаберилиштер сервери иштебей жатат

  • Тест 1: метаберилиштер серверинин журналдарында аномалияларды текшериңиз
  • Натыйжа: журналдарда аномалиялар жок
  • Тест 2: Метаберилиш серверин айланып өтүү dig @8.8.8.8
  • Натыйжа: Метаберилиш серверин колдонбостон да чечилет

Тесттердин негизинде корутунду: көйгөй метадата серверинде эмес

Жыйынтык: башка бардык подсистемаларды сынап көрдүк иштөө убактысынын жөндөөлөрү!

Ядронун Runtime Орнотууларына киришүү

Ядронун аткаруу чөйрөсүн конфигурациялоо үчүн, сиз буйрук сабынын параметрлерин (grub) же sysctl интерфейсин колдоно аласыз. Мен карадым /etc/sysctl.conf жана жөн эле ойлонуп көрүңүз, мен бир нече жеке жөндөөлөрдү таптым. Мен бир нерсени кармап алгандай сезип, тоо жөндөөлөрү менен калган тармактык эмес же tcp эмес бардык орнотууларды жокко чыгардым. net.core. Андан кийин мен VM'деги хост уруксаттары болгон жерге бардым жана күнөөлүүнү тапканга чейин, бузулган VM менен жөндөөлөрдү биринин артынан бири колдоно баштадым:

net.core.rmem_default = 2147483647

Мына, бул DNS-бузуучу конфигурация! Мен өлтүргөн куралды таптым. Бирок эмне үчүн бул болуп жатат? Мага дагы эле мотив керек болчу.

Негизги DNS пакет буфер өлчөмү аркылуу конфигурацияланат net.core.rmem_default. Кадимки маани 200KiB тегерегинде, бирок сервериңиз көп DNS пакеттерин алса, буфердин өлчөмүн чоңойтууну кааласаңыз болот. Жаңы пакет келгенде буфер толуп калса, мисалы, тиркеме аны жетиштүү ылдам иштетпей жаткандыктан, анда пакеттерди жоготуп баштайсыз. Биздин кардар буфердин өлчөмүн туура чоңойтту, анткени ал маалыматтарды жоготуудан корккон, анткени ал DNS пакеттери аркылуу метрикаларды чогултуу үчүн тиркемени колдонуп жаткан. Ал койгон маани максималдуу мүмкүн болгон: 231-1 (эгерде 231 деп коюлса, ядро ​​"ЖАРАКСЫЗ АРГУМЕНТ" кайтарат).

Күтүлбөгөн жерден мен nmap жана scapy эмне үчүн туура иштегенин түшүндүм: алар чийки розеткаларды колдонуп жатышкан! Чийки розеткалар кадимки розеткалардан айырмаланат: алар iptables'ти айланып өтүшөт жана буферленбейт!

Бирок эмне үчүн "буфер өтө чоң" көйгөйлөрдү жаратат? Ал ойдогудай иштебей жатканы анык.

Бул учурда мен көйгөйдү бир нече ядродо жана бир нече бөлүштүрүүдө чыгара алмакмын. Көйгөй мурунтан эле 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 int түрүнө кирет
  • size u16 тибинде (кол коюлбаган он алты биттик int) жана пакеттин өлчөмүн сактайт
  • sk->sk_rcybuf int түрүнө кирет жана аныктамасы боюнча in маанисине барабар болгон буфер өлчөмүн сактайт net.core.rmem_default

качан sk_rcvbuf 231ге жакындайт, пакеттин өлчөмүн жыйынтыктоо алып келиши мүмкүн бүтүн сан ашып кетүү. Жана бул int болгондуктан, анын мааниси терс болуп калат, андыктан шарт жалган болушу керек болгондо чындыкка айланат (бул тууралуу кененирээк бул жерден окуй аласыз байланыш).

Катаны тривиалдуу түрдө оңдоого болот: кастинг менен unsigned int. Мен оңдоону колдонуп, системаны кайра иштеттим жана DNS кайра иштеди.

үстөм даамы

Мен өзүмдүн тыянактарымды кардарга жөнөтүп, жөнөттүм LKML ядро патч. Мен ыраазымын: табышмактын ар бир бөлүгү бири-бирине дал келет, мен эмне үчүн байкаганыбызды так түшүндүрүп бере алам, эң негизгиси, биз командалык ишибиздин аркасында маселенин чечимин таба алдык!

Бул иш сейрек болуп чыкканын моюнга алуу керек, бактыга жараша, биз колдонуучулардан мындай татаал суроо-талаптарды сейрек алабыз.

Google Cloud техникалык колдоосунан DNS пакеттеринин жетишсиздиги жөнүндө окуя


Source: www.habr.com

Комментарий кошуу