Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

Բարեւ բոլորին! Ես Դմիտրի Սամսոնովն եմ, աշխատում եմ որպես առաջատար համակարգի ադմինիստրատոր Odnoklassniki-ում: Մենք ունենք ավելի քան 7 հազար ֆիզիկական սերվեր, 11 հազար կոնտեյներ մեր ամպում և 200 հավելվածներ, որոնք տարբեր կոնֆիգուրացիաներով կազմում են 700 տարբեր կլաստերներ։ Սերվերների ճնշող մեծամասնությունը աշխատում է CentOS 7-ով:
14 թվականի օգոստոսի 2018-ին հրապարակվել է FragmentSmack խոցելիության մասին տեղեկություն
(CVE-2018-5391- ը) և SegmentSmack (CVE-2018-5390- ը) Սրանք խոցելիություններ են ցանցային հարձակման վեկտորով և բավականին բարձր միավորով (7.5), որը սպառնում է ծառայության մերժմանը (DoS) ռեսուրսների սպառման (CPU) պատճառով: FragmentSmack-ի համար միջուկի ուղղում այն ​​ժամանակ չէր առաջարկվել, ավելին, այն հայտնվեց շատ ավելի ուշ, քան խոցելիության մասին տեղեկատվության հրապարակումը։ SegmentSmack-ը վերացնելու համար առաջարկվեց թարմացնել միջուկը։ Թարմացման փաթեթն ինքնին թողարկվեց նույն օրը, մնում էր միայն տեղադրել այն։
Ոչ, մենք ընդհանրապես դեմ չենք միջուկի թարմացմանը։ Այնուամենայնիվ, կան նրբերանգներ...

Ինչպես ենք մենք թարմացնում միջուկը արտադրության վրա

Ընդհանուր առմամբ, ոչ մի բարդ բան.

  1. Ներբեռնեք փաթեթներ;
  2. Տեղադրեք դրանք մի շարք սերվերների վրա (ներառյալ սերվերները, որոնք հյուրընկալում են մեր ամպը);
  3. Համոզվեք, որ ոչինչ կոտրված չէ;
  4. Համոզվեք, որ միջուկի բոլոր ստանդարտ կարգավորումները կիրառվում են առանց սխալների.
  5. Սպասեք մի քանի օր;
  6. Ստուգեք սերվերի կատարումը;
  7. Փոխարկել նոր սերվերների տեղակայումը նոր միջուկին;
  8. Թարմացրեք բոլոր սերվերները ըստ տվյալների կենտրոնի (միաժամանակ մեկ տվյալների կենտրոն՝ խնդիրների դեպքում օգտագործողների վրա ազդեցությունը նվազագույնի հասցնելու համար);
  9. Վերագործարկեք բոլոր սերվերները:

Կրկնեք մեր ունեցած միջուկների բոլոր ճյուղերի համար: Այս պահին այն է.

  • Stock CentOS 7 3.10 - սովորական սերվերների մեծամասնության համար;
  • Վանիլ 4.19 - մեր համար մեկ ամպամած ամպեր, քանի որ մեզ անհրաժեշտ են BFQ, BBR և այլն;
  • Elrepo kernel-ml 5.2 - համար բարձր բեռնված դիստրիբյուտորներ, քանի որ 4.19-ը նախկինում իրեն անկայուն էր պահում, բայց անհրաժեշտ են նույն հատկանիշները։

Ինչպես կարող էիք կռահել, հազարավոր սերվերների վերագործարկումն ամենաերկարն է պահանջում: Քանի որ ոչ բոլոր խոցելիությունները կարևոր են բոլոր սերվերների համար, մենք միայն վերագործարկում ենք դրանք, որոնք ուղղակիորեն հասանելի են ինտերնետից: Ամպում, ճկունությունը չսահմանափակելու համար, մենք չենք կապում արտաքին հասանելի կոնտեյներները առանձին սերվերների հետ նոր միջուկով, այլ վերաբեռնում ենք բոլոր հոսթերն առանց բացառության: Բարեբախտաբար, այնտեղ ընթացակարգն ավելի պարզ է, քան սովորական սերվերների դեպքում: Օրինակ, քաղաքացիություն չունեցող բեռնարկղերը պարզապես կարող են տեղափոխվել մեկ այլ սերվեր վերաբեռնման ժամանակ:

Այնուամենայնիվ, դեռ շատ աշխատանք կա, և դա կարող է տևել մի քանի շաբաթ, իսկ եթե նոր տարբերակի հետ կապված խնդիրներ լինեն՝ մինչև մի քանի ամիս։ Հարձակվողները դա շատ լավ հասկանում են, ուստի նրանց պետք է պլան Բ:

FragmentSmack/SegmentSmack. Լուծում

Բարեբախտաբար, որոշ խոցելիությունների համար գոյություն ունի նման պլան B, և այն կոչվում է «Աշխատանք»: Ամենից հաճախ սա միջուկի/հավելվածի կարգավորումների փոփոխություն է, որը կարող է նվազագույնի հասցնել հնարավոր ազդեցությունը կամ ամբողջությամբ վերացնել խոցելիության օգտագործումը:

FragmentSmack/SegmentSmack-ի դեպքում առաջարկվել է այս լուծումը.

«Դուք կարող եք փոխել 4 ՄԲ-ի և 3 ՄԲ-ի լռելյայն արժեքները net.ipv4.ipfrag_high_thresh և net.ipv4.ipfrag_low_thresh (և դրանց նմանակները ipv6 net.ipv6.ipfrag_high_thresh և net.ipv6.ipfrag_low_thresh-ի համար) և համապատասխանաբար 256 կամ B k192-ի: ավելի ցածր. Թեստերը ցույց են տալիս հարձակման ժամանակ պրոցեսորի օգտագործման փոքր կամ զգալի անկումներ՝ կախված սարքաշարից, կարգավորումներից և պայմաններից: Այնուամենայնիվ, կարող է լինել որոշակի ազդեցություն ipfrag_high_thresh=262144 բայթի պատճառով, քանի որ միայն երկու 64K բեկորներ կարող են միաժամանակ տեղավորվել վերահավաքման հերթում: Օրինակ, վտանգ կա, որ մեծ UDP փաթեթներով աշխատող հավելվածները կփչանան.

Պարամետրերն իրենք են միջուկի փաստաթղթերում նկարագրված է հետևյալ կերպ.

ipfrag_high_thresh - LONG INTEGER
    Maximum memory used to reassemble IP fragments.

ipfrag_low_thresh - LONG INTEGER
    Maximum memory used to reassemble IP fragments before the kernel
    begins to remove incomplete fragment queues to free up resources.
    The kernel still accepts new fragments for defragmentation.

Մենք չունենք մեծ UDP արտադրական ծառայությունների համար: LAN-ում չկա մասնատված երթևեկություն, WAN-ում կա մասնատված տրաֆիկ, բայց ոչ էական: Նշաններ չկան. դուք կարող եք գործարկել Workaround-ը:

FragmentSmack/SegmentSmack. Առաջին արյուն

Առաջին խնդիրը, որին մենք հանդիպեցինք, այն էր, որ ամպային կոնտեյներները երբեմն միայն մասնակիորեն կիրառում էին նոր կարգավորումները (միայն ipfrag_low_thresh), իսկ երբեմն ընդհանրապես չէին կիրառում դրանք, դրանք պարզապես խափանվում էին սկզբում: Հնարավոր չէր կայուն վերարտադրել խնդիրը (բոլոր կարգավորումները կիրառվել են ձեռքով, առանց որևէ դժվարության): Հասկանալը, թե ինչու է բեռնարկղը սկզբում վթարի ենթարկվում, նույնպես այնքան էլ հեշտ չէ. սխալներ չեն հայտնաբերվել: Մի բան հաստատ էր. կարգավորումները հետ գլորելը լուծում է կոնտեյների խափանումների խնդիրը:

Ինչու՞ բավարար չէ Sysctl-ը հոսթի վրա կիրառելը: Կոնտեյները ապրում է իր հատուկ ցանցի Անունների տարածության մեջ, գոնե այդպես ցանցի Sysctl պարամետրերի մի մասը կոնտեյներով կարող է տարբերվել հյուրընկալողից:

Ինչպե՞ս են կոնկրետ Sysctl կարգավորումները կիրառվում բեռնարկղում: Քանի որ մեր բեռնարկղերը արտոնված չեն, դուք չեք կարողանա փոխել Sysctl-ի որևէ կարգավորում՝ մտնելով հենց կոնտեյներ. դուք պարզապես չունեք բավարար իրավունքներ: Կոնտեյներներ գործարկելու համար մեր ամպն այն ժամանակ օգտագործում էր Docker (այժմ Պոդման) Նոր կոնտեյների պարամետրերը փոխանցվել են Docker-ին API-ի միջոցով՝ ներառյալ Sysctl-ի անհրաժեշտ կարգավորումները։
Տարբերակները փնտրելիս պարզվեց, որ Docker API-ն չի վերադարձրել բոլոր սխալները (համենայն դեպս 1.10 տարբերակում)։ Երբ մենք փորձեցինք բեռնարկղը գործարկել «docker run» միջոցով, մենք վերջապես տեսանք գոնե մի բան.

write /proc/sys/net/ipv4/ipfrag_high_thresh: invalid argument docker: Error response from daemon: Cannot start container <...>: [9] System error: could not synchronise with container process.

Պարամետրի արժեքը վավեր չէ: Բայց ինչու? Իսկ ինչո՞ւ դա միայն երբեմն վավեր չէ։ Պարզվեց, որ Docker-ը չի երաշխավորում Sysctl պարամետրերի կիրառման հերթականությունը (վերջին փորձարկված տարբերակը 1.13.1-ն է), այնպես որ երբեմն ipfrag_high_thresh-ը փորձում էր սահմանել 256K, երբ ipfrag_low_thresh դեռ 3M էր, այսինքն՝ վերին սահմանն ավելի ցածր էր։ քան ստորին սահմանը, ինչը հանգեցրել է սխալի։

Այն ժամանակ մենք արդեն օգտագործում էինք մեր սեփական մեխանիզմը կոնտեյները սկսելուց հետո վերակազմավորելու համար (տարան սառեցնելուց հետո խմբային սառնարան և հրամանների կատարում կոնտեյների անվանատարածքում միջոցով ip ցանցեր), և այս մասում ավելացրեցինք նաև Sysctl պարամետրեր գրելը։ Խնդիրը լուծվեց.

FragmentSmack/SegmentSmack. Առաջին արյուն 2

Մինչ մենք ժամանակ կունենայինք հասկանալու Workaround-ի օգտագործումը ամպում, օգտատերերի առաջին հազվագյուտ բողոքները սկսեցին հայտնվել: Այդ ժամանակ մի քանի շաբաթ էր անցել առաջին սերվերների վրա Workaround-ի օգտագործման մեկնարկից։ Նախնական հետաքննությունը ցույց է տվել, որ բողոքներ են ստացվել առանձին ծառայությունների, և ոչ բոլոր սերվերների դեմ։ Խնդիրը կրկին ծայրաստիճան անորոշ է դարձել։

Նախ, իհարկե, մենք փորձեցինք հետ գլորել Sysctl կարգավորումները, բայց դա ոչ մի ազդեցություն չունեցավ։ Սերվերի և հավելվածի կարգավորումների հետ կապված տարբեր մանիպուլյացիաները նույնպես չօգնեցին: Վերագործարկումն օգնեց: Linux-ի վերագործարկումը նույնքան անբնական է, որքան հին ժամանակներում Windows-ի համար: Այնուամենայնիվ, դա օգնեց, և մենք այն վերածեցինք «միջուկի անսարքության»՝ Sysctl-ում նոր կարգավորումները կիրառելիս: Ինչքան անլուրջ էր...

Երեք շաբաթ անց խնդիրը կրկնվեց։ Այս սերվերների կոնֆիգուրացիան բավականին պարզ էր՝ Nginx պրոքսի/հավասարակշռող ռեժիմում։ Ոչ շատ երթևեկություն: Նոր ներածական նշում. հաճախորդների 504 սխալների թիվը օրեցօր ավելանում է (Gateway Timeout-ը) Գրաֆիկը ցույց է տալիս այս ծառայության համար օրական 504 սխալների թիվը.

Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

Բոլոր սխալները մոտավորապես նույնն են՝ ամպի մեջ գտնվողի մասին: Փաթեթի բեկորների համար հիշողության սպառման գրաֆիկը այս հետնամասում այսպիսի տեսք ուներ.

Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

Սա օպերացիոն համակարգի գրաֆիկներում խնդրի ամենաակնառու դրսեւորումներից մեկն է։ Ամպում, հենց նույն պահին, շտկվեց մեկ այլ ցանցային խնդիր QoS (Traffic Control) կարգավորումների հետ: Փաթեթների բեկորների համար հիշողության սպառման գրաֆիկում այն ​​ճիշտ նույնն էր.

Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

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

Ուղղված խնդրի էությունը կայանում էր նրանում, որ մենք օգտագործում էինք fq փաթեթների ժամանակացույցը՝ QoS-ում լռելյայն կարգավորումներով: Լռելյայնորեն, մեկ կապի համար այն թույլ է տալիս հերթին ավելացնել 100 փաթեթ, իսկ որոշ կապեր, ալիքի պակասի իրավիճակներում, սկսեցին խցանել հերթը մինչև հզորությունը: Այս դեպքում փաթեթները թափվում են: tc վիճակագրության մեջ (tc -s qdisc) այն կարելի է տեսնել այսպես.

qdisc fq 2c6c: parent 1:2c6c limit 10000p flow_limit 100p buckets 1024 orphan_mask 1023 quantum 3028 initial_quantum 15140 refill_delay 40.0ms
 Sent 454701676345 bytes 491683359 pkt (dropped 464545, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  1024 flows (1021 inactive, 0 throttled)
  0 gc, 0 highprio, 0 throttled, 464545 flows_plimit

«464545 flows_plimit»-ը մեկ կապի հերթի սահմանաչափը գերազանցելու պատճառով բաց թողնված փաթեթներն են, իսկ «թողված 464545»-ը այս ժամանակացույցի բոլոր բաց թողնված փաթեթների գումարն է: Հերթի երկարությունը 1 հազարի հասցնելուց և բեռնարկղերը վերագործարկելուց հետո խնդիրը դադարեց։ Դուք կարող եք հանգիստ նստել և խմել սմուզի:

FragmentSmack/SegmentSmack. Վերջին արյուն

Նախ, միջուկում խոցելիության մասին հայտարարությունից մի քանի ամիս անց վերջապես հայտնվեց FragmentSmack-ի ուղղումը (հիշեցնեմ, որ օգոստոսին հայտարարության հետ մեկտեղ թողարկվեց միայն SegmentSmack-ի շտկում), ինչը մեզ հնարավորություն տվեց հրաժարվել Workaround-ից, ինչը մեզ բավականին մեծ դժբախտություն պատճառեց։ Այս ընթացքում մենք արդեն հասցրել էինք սերվերների մի մասը տեղափոխել նոր միջուկ, և հիմա պետք է սկսեինք սկզբից։ Ինչո՞ւ թարմացրինք միջուկը՝ չսպասելով FragmentSmack-ի ուղղմանը: Փաստն այն է, որ այս խոցելիություններից պաշտպանվելու գործընթացը համընկավ (և միաձուլվեց) հենց CentOS-ի թարմացման գործընթացի հետ (որը նույնիսկ ավելի շատ ժամանակ է պահանջում, քան միայն միջուկը թարմացնելը): Բացի այդ, SegmentSmack-ն ավելի վտանգավոր խոցելիություն է, և դրա շտկումը անմիջապես հայտնվեց, այնպես որ, այնուամենայնիվ, այն իմաստալից էր: Այնուամենայնիվ, մենք չկարողացանք պարզապես թարմացնել միջուկը CentOS-ում, քանի որ FragmentSmack խոցելիությունը, որը հայտնվեց CentOS 7.5-ի ժամանակ, շտկվել էր միայն 7.6 տարբերակում, ուստի մենք ստիպված էինք դադարեցնել թարմացումը մինչև 7.5-ը և նորից սկսել 7.6-ի թարմացումով: Եվ սա նույնպես տեղի է ունենում.

Երկրորդ, օգտատերերի հազվադեպ բողոքները խնդիրների վերաբերյալ վերադարձել են մեզ: Այժմ մենք արդեն հաստատ գիտենք, որ դրանք բոլորը կապված են հաճախորդներից մեր որոշ սերվերներ ֆայլերի վերբեռնման հետ: Ավելին, այս սերվերների միջով անցել են ընդհանուր զանգվածից բեռնումների շատ փոքր քանակություն։

Ինչպես հիշում ենք վերը նշված պատմությունից, Sysctl-ը հետ գլորելը չօգնեց: Վերագործարկումն օգնեց, բայց ժամանակավոր:
Sysctl-ի հետ կապված կասկածները չհեռացվեցին, սակայն այս անգամ անհրաժեշտ էր հնարավորինս շատ տեղեկատվություն հավաքել։ Կար նաև հաճախորդի վրա վերբեռնման խնդիրը վերարտադրելու ունակության հսկայական բացակայություն՝ ավելի ճշգրիտ ուսումնասիրելու համար, թե ինչ է կատարվում:

Բոլոր առկա վիճակագրության և տեղեկամատյանների վերլուծությունը մեզ ավելի մոտ չբերեց հասկանալու, թե ինչ է կատարվում: Կոնկրետ կապը «զգալու» համար խնդիրը վերարտադրելու ունակության սուր բացակայություն կար: Ի վերջո, ծրագրավորողներին, օգտագործելով հավելվածի հատուկ տարբերակը, հաջողվել է հասնել խնդիրների կայուն վերարտադրության փորձնական սարքի վրա՝ Wi-Fi-ի միջոցով միանալու դեպքում: Սա բեկում էր հետաքննության մեջ։ Հաճախորդը միացել է Nginx-ին, որը պրոքսի է անցել backend-ին, որը մեր Java հավելվածն էր:

Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

Խնդիրների համար երկխոսությունն այսպիսին էր (ֆիքսված է Nginx վստահված անձի կողմից).

  1. Հաճախորդ. խնդրեք ստանալ տեղեկատվություն ֆայլի ներբեռնման մասին:
  2. Java սերվեր. պատասխան:
  3. Հաճախորդ՝ POST ֆայլով:
  4. Java սերվեր. սխալ:

Միևնույն ժամանակ, Java սերվերը գրում է գրանցամատյանում, որ հաճախորդից ստացվել է 0 բայթ տվյալ, իսկ Nginx վստահված անձը գրում է, որ հարցումը տևել է ավելի քան 30 վայրկյան (30 վայրկյանը հաճախորդի հավելվածի ժամկետն է): Ինչու՞ ժամանակի ավարտը և ինչու՞ 0 բայթ: HTTP-ի տեսանկյունից ամեն ինչ աշխատում է այնպես, ինչպես պետք է, բայց ֆայլով POST-ը կարծես անհետանում է ցանցից: Ավելին, այն անհետանում է հաճախորդի և Nginx-ի միջև: Ժամանակն է զինվել Tcpdump-ով: Բայց նախ դուք պետք է հասկանաք ցանցի կոնֆիգուրացիան: Nginx վստահված անձը գտնվում է L3 հավասարակշռողի հետևում NFware. Թունելավորումն օգտագործվում է L3 հավասարակշռողից փաթեթները սերվեր առաքելու համար, որն իր վերնագրերն ավելացնում է փաթեթներին.

Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

Այս դեպքում ցանցը գալիս է այս սերվերին Vlan պիտակավորված տրաֆիկի տեսքով, որը նաև փաթեթներին ավելացնում է իր սեփական դաշտերը.

Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

Եվ այս տրաֆիկը կարող է նաև մասնատված լինել (մուտքային մասնատված տրաֆիկի այդ նույն փոքր տոկոսը, որի մասին մենք խոսեցինք Workaround-ի ռիսկերը գնահատելիս), ինչը նաև փոխում է վերնագրերի բովանդակությունը.

Զգուշացեք խոցելիությունից, որոնք բերում են աշխատանքի փուլ: Մաս 1. FragmentSmack/SegmentSmack

Եվս մեկ անգամ. փաթեթները պարուրված են Vlan պիտակով, պարուրված են թունելով, մասնատված: Ավելի լավ հասկանալու համար, թե ինչպես է դա տեղի ունենում, եկեք հետևենք փաթեթի երթուղին հաճախորդից մինչև Nginx վստահված անձ:

  1. Փաթեթը հասնում է L3 հավասարակշռողին: Տվյալների կենտրոնի ներսում ճիշտ երթուղղման համար փաթեթը պարփակվում է թունելում և ուղարկվում ցանցային քարտ:
  2. Քանի որ փաթեթ + թունելների վերնագրերը չեն տեղավորվում MTU-ի մեջ, փաթեթը կտրվում է բեկորների և ուղարկվում ցանց:
  3. L3 բալանսավորիչից հետո անջատիչը փաթեթ ստանալիս դրան ավելացնում է Vlan թեգ և ուղարկում այն։
  4. Nginx վստահված անձի դիմաց գտնվող անջատիչը տեսնում է (պորտի կարգավորումների հիման վրա), որ սերվերը սպասում է Vlan-ով ծածկված փաթեթ, ուստի այն ուղարկում է այնպես, ինչպես կա, առանց Vlan պիտակը հեռացնելու:
  5. Linux-ը վերցնում է առանձին փաթեթների բեկորներ և դրանք միավորում մեկ մեծ փաթեթի մեջ:
  6. Այնուհետև փաթեթը հասնում է Vlan ինտերֆեյսին, որտեղից հանվում է առաջին շերտը՝ Vlan encapsulation։
  7. Այնուհետև Linux-ն այն ուղարկում է Թունելի միջերես, որտեղից հեռացվում է մեկ այլ շերտ՝ Թունելի ինկապսուլյացիան։

Դժվարությունն այն է, որ այս ամենը որպես պարամետրեր փոխանցվի tcpdump-ին։
Սկսենք վերջից. կա՞ն արդյոք մաքուր (առանց ավելորդ վերնագրերի) IP-փաթեթներ հաճախորդներից՝ հանված vlan-ով և թունելային ինկապսուլյացիայով:

tcpdump host <ip клиента>

Ոչ, սերվերում նման փաթեթներ չեն եղել։ Այսպիսով, խնդիրը պետք է լինի ավելի վաղ: Կա՞ն արդյոք փաթեթներ, որոնց միայն Vlan պարկուճը հանված է:

tcpdump ip[32:4]=0xx390x2xx

0xx390x2xx-ը հաճախորդի IP հասցեն է hex ձևաչափով:
32:4 — այն դաշտի հասցեն և երկարությունը, որում գրված է SCR IP-ն Թունելի փաթեթում:

Դաշտի հասցեն պետք է ընտրվեր բիրտ ուժով, քանի որ ինտերնետում գրում են 40, 44, 50, 54, բայց IP հասցե չկար այնտեղ։ Կարող եք նաև դիտել վեցանկյուն փաթեթներից մեկը (-xx կամ -XX պարամետրը tcpdump-ում) և հաշվարկել ձեր իմացած IP հասցեն:

Կա՞ն արդյոք փաթեթների բեկորներ, առանց Vlan-ի և Tunnel-ի պարուրման:

tcpdump ((ip[6:2] > 0) and (not ip[6] = 64))

Այս կախարդանքը մեզ ցույց կտա բոլոր բեկորները, ներառյալ վերջինը: Հավանաբար, նույն բանը կարող է զտվել IP-ով, բայց ես չփորձեցի, քանի որ այդպիսի փաթեթներ այնքան էլ շատ չեն, և ինձ անհրաժեշտները հեշտությամբ գտնվեցին ընդհանուր հոսքում: Այստեղ են:

14:02:58.471063 In 00:de:ff:1a:94:11 ethertype IPv4 (0x0800), length 1516: (tos 0x0, ttl 63, id 53652, offset 0, flags [+], proto IPIP (4), length 1500)
    11.11.11.11 > 22.22.22.22: truncated-ip - 20 bytes missing! (tos 0x0, ttl 50, id 57750, offset 0, flags [DF], proto TCP (6), length 1500)
    33.33.33.33.33333 > 44.44.44.44.80: Flags [.], seq 0:1448, ack 1, win 343, options [nop,nop,TS val 11660691 ecr 2998165860], length 1448
        0x0000: 0000 0001 0006 00de fb1a 9441 0000 0800 ...........A....
        0x0010: 4500 05dc d194 2000 3f09 d5fb 0a66 387d E.......?....f8}
        0x0020: 1x67 7899 4500 06xx e198 4000 3206 6xx4 [email protected].
        0x0030: b291 x9xx x345 2541 83b9 0050 9740 0x04 .......A...P.@..
        0x0040: 6444 4939 8010 0257 8c3c 0000 0101 080x dDI9...W.......
        0x0050: 00b1 ed93 b2b4 6964 xxd8 ffe1 006a 4578 ......ad.....jEx
        0x0060: 6966 0000 4x4d 002a 0500 0008 0004 0100 if..MM.*........

14:02:58.471103 In 00:de:ff:1a:94:11 ethertype IPv4 (0x0800), length 62: (tos 0x0, ttl 63, id 53652, offset 1480, flags [none], proto IPIP (4), length 40)
    11.11.11.11 > 22.22.22.22: ip-proto-4
        0x0000: 0000 0001 0006 00de fb1a 9441 0000 0800 ...........A....
        0x0010: 4500 0028 d194 00b9 3f04 faf6 2x76 385x E..(....?....f8}
        0x0020: 1x76 6545 xxxx 1x11 2d2c 0c21 8016 8e43 .faE...D-,.!...C
        0x0030: x978 e91d x9b0 d608 0000 0000 0000 7c31 .x............|Q
        0x0040: 881d c4b6 0000 0000 0000 0000 0000 ..............

Սրանք մեկ փաթեթի երկու հատված են (նույն ID 53652) լուսանկարով (առաջին փաթեթում տեսանելի է Exif բառը): Շնորհիվ այն բանի, որ այս մակարդակի փաթեթներ կան, բայց ոչ միաձուլված տեսքով աղբավայրերում, խնդիրն ակնհայտորեն կապված է հավաքի հետ: Վերջապես կա դրա փաստագրական ապացույցը:

Փաթեթների ապակոդավորիչը չի հայտնաբերել որևէ խնդիր, որը կխանգարի կառուցմանը: Փորձել է այստեղ. hpd.gasmi.net. Սկզբում, երբ փորձում եք ինչ-որ բան լցնել այնտեղ, ապակոդավորողին դուր չի գալիս փաթեթի ձևաչափը: Պարզվեց, որ Srcmac-ի և Ethertype-ի միջև կան մի քանի լրացուցիչ երկու օկտետներ (կապված չէ հատված տեղեկատվության հետ): Դրանք հեռացնելուց հետո ապակոդավորիչը սկսել է աշխատել։ Այնուամենայնիվ, այն ոչ մի խնդիր չցուցաբերեց:
Ինչ էլ ասի, ուրիշ ոչինչ չգտնվեց, բացի այդ Sysctl-ից: Մնում էր միայն գտնել խնդրահարույց սերվերների նույնականացման միջոց՝ մասշտաբները հասկանալու և հետագա գործողությունները որոշելու համար: Պահանջվող հաշվիչը բավականին արագ է հայտնաբերվել.

netstat -s | grep "packet reassembles failed”

Այն նաև snmpd-ում է OID=1.3.6.1.2.1.4.31.1.1.16.1 (ipSystemStatsReasmFails).

«IP-ի վերահավաքման ալգորիթմի կողմից հայտնաբերված խափանումների քանակը (ցանկացած պատճառով. ժամանակի ավարտ, սխալներ և այլն):

Սերվերների այն խմբից, որոնց վրա խնդիրն ուսումնասիրվել է, երկուսի վրա այս հաշվիչն ավելի արագ է աճել, երկուսի վրա՝ ավելի դանդաղ, ևս երկուսի վրա այն ընդհանրապես չի աճել։ Համեմատելով այս հաշվիչի դինամիկան Java սերվերի վրա HTTP սխալների դինամիկայի հետ բացահայտեց հարաբերակցությունը: Այսինքն՝ հաշվիչը կարող էր վերահսկվել։

Խնդիրների հուսալի ցուցիչ ունենալը շատ կարևոր է, որպեսզի կարողանաք ճշգրիտ որոշել, թե արդյոք Sysctl-ի հետ վերադարձնելն օգնում է, քանի որ նախորդ պատմությունից մենք գիտենք, որ դա հնարավոր չէ անմիջապես հասկանալ հավելվածից: Այս ցուցանիշը թույլ կտա մեզ բացահայտել արտադրության բոլոր խնդրահարույց ոլորտները, նախքան օգտագործողների կողմից այն հայտնաբերելը:
Sysctl-ը ետ գլորելուց հետո մոնիտորինգի սխալները դադարեցվեցին, այդպիսով ապացուցվեց խնդիրների պատճառը, ինչպես նաև այն, որ հետ վերադարձն օգնում է:

Մենք հետ դարձրեցինք ֆրագմենտացիայի կարգավորումները այլ սերվերների վրա, որտեղ նոր մոնիտորինգ սկսեց գործել, և ինչ-որ տեղ մենք հատկացրեցինք նույնիսկ ավելի շատ հիշողություն բեկորների համար, քան նախկինում լռելյայն էր (սա UDP վիճակագրություն էր, որի մասնակի կորուստը նկատելի չէր ընդհանուր ֆոնի վրա) .

Ամենակարևոր հարցերը

Ինչու՞ են փաթեթները մասնատված մեր L3 հաշվեկշռի վրա: Փաթեթների մեծ մասը, որոնք հասնում են օգտվողներից հավասարակշռողներին, SYN և ACK են: Այս փաթեթների չափերը փոքր են։ Բայց քանի որ նման փաթեթների տեսակարար կշիռը շատ մեծ է, դրանց ֆոնին մենք չնկատեցինք մեծ փաթեթների առկայությունը, որոնք սկսեցին մասնատվել։

Պատճառը կոնֆիգուրացիայի կոտրված սցենարն էր advmss Vlan ինտերֆեյսներով սերվերների վրա (այդ ժամանակ արտադրության մեջ պիտակավորված տրաֆիկով շատ քիչ սերվերներ կային): Advmss-ը մեզ թույլ է տալիս հաճախորդին փոխանցել այն տեղեկությունը, որ մեր ուղղությամբ փաթեթները պետք է լինեն ավելի փոքր չափերով, որպեսզի դրանց վրա թունելի վերնագրերը կցելուց հետո դրանք չպետք է մասնատվեն:

Ինչու՞ Sysctl-ի հետ վերադարձը չօգնեց, բայց վերաբեռնումը չօգնեց: Հետ վերադարձնելը Sysctl-ը փոխեց փաթեթների միաձուլման համար հասանելի հիշողության ծավալը: Միևնույն ժամանակ, ըստ երևույթին, բեկորների համար հիշողության հորդառատ փաստը հանգեցրեց կապերի դանդաղեցմանը, ինչը հանգեցրեց նրան, որ բեկորները երկար ժամանակ հետաձգվեցին հերթում: Այսինքն՝ գործընթացը շրջվել է ցիկլերով։
Վերագործարկումը մաքրեց հիշողությունը և ամեն ինչ վերադարձավ իր կարգին:

Հնարավո՞ր էր անել առանց Workaround-ի: Այո, բայց հարձակման դեպքում օգտատերերին առանց ծառայության թողնելու մեծ ռիսկ կա: Իհարկե, Workaround-ի օգտագործումը հանգեցրեց տարբեր խնդիրների, այդ թվում՝ օգտատերերի համար ծառայություններից մեկի դանդաղեցմանը, բայց, այնուամենայնիվ, մենք կարծում ենք, որ գործողություններն արդարացված էին:

Շատ շնորհակալություն Անդրեյ Տիմոֆեևին (ատիմոֆեև) հետաքննության անցկացմանն աջակցելու համար, ինչպես նաև Ալեքսեյ Կրենևին (սարքըx) - սերվերների վրա Centos-ի և միջուկների թարմացման տիտանական աշխատանքի համար: Գործընթաց, որը այս դեպքում մի քանի անգամ պետք էր սկզբից սկսել, ինչի պատճառով էլ այն ձգձգվեց երկար ամիսներ։

Source: www.habr.com

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