Бойцеся ўразлівасцяў, воркэраунды якія прыносяць. Частка 1: FragmentSmack/SegmentSmack

Бойцеся ўразлівасцяў, воркэраунды якія прыносяць. Частка 1: FragmentSmack/SegmentSmack

Ўсім прывітанне! Мяне клічуць Зміцер Самсонаў, я працую кіроўным сістэмным адміністратарам у «Аднакласніках». У нас больш за 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. Перазагрузіць усе серверы.

Паўтарыць для ўсіх галінак наяўных у нас ядраў. На дадзены момант гэта:

  • Стоковае CentOS 7 3.10 – для большасці звычайных сервераў;
  • Ванільнае 4.19 - для нашага аблокі one-cloud, таму што нам патрэбен BFQ, BBR і г.д.;
  • Elrepo kernel-ml 5.2 - для высоканагружаных раздатчыкаў, таму што 4.19 раней паводзіў сябе нестабільна, а фічы патрэбныя тыя ж.

Як вы маглі здагадацца, больш за ўсё часу займае перазагрузка тысяч сервераў. Паколькі не ўсе ўразлівасці крытычныя для ўсіх сервераў, то мы перазагружаем толькі тыя, якія наўпрост даступныя з інтэрнэту. У воблаку, каб не абмяжоўваць гнуткасць, мы не прывязваем даступныя звонку кантэйнеры да асобных сервераў з новым ядром, а перазагружаем усе хасты без выключэння. На шчасце, там працэдура прасцей, чым са звычайнымі серверамі. Напрыклад, stateless-кантэйнеры могуць проста пераехаць на іншы сервер падчас рэбута.

Тым не менш працы ўсё роўна шмат, і яна можа займаць некалькі тыдняў, а пры ўзнікненні якіх-небудзь праблем з новай версіяй - да некалькіх месяцаў. Зламыснікі гэта выдатна разумеюць, таму патрэбны план "Б".

FragmentSmack/SegmentSmack. Workaround

На шчасце, для некаторых уразлівасцяў такі план "Бы" існуе, і называецца ён Workaround. Часцей за ўсё гэта змена налад ядра/прыкладанняў, якія дазваляюць мінімізаваць магчымы эфект ці цалкам выключыць эксплуатацыю ўразлівасцяў.

У выпадку з FragmentSmack/SegmentSmack прапаноўваўся такі Workaround:

«Можна змяніць дэфолтныя значэнні 4MB і 3MB у net.ipv4.ipfrag_high_thresh і net.ipv4.ipfrag_low_thresh (і іх аналагі для ipv6 net.ipv6.ipfrag_high_thresh і net.ipv6.ipfrag_low_thresh) і на . Тэсты паказваюць ад невялікага да значнага падзення выкарыстання CPU падчас нападу ў залежнасці ад абсталявання, налад і ўмоў. Аднак можа быць некаторы ўплыў на прадукцыйнасць з-за ipfrag_high_thresh=256 bytes, бо толькі два 192K-фрагмента могуць адначасова змясціцца ў чарзе на перазборку. Напрыклад, ёсць рызыка, што прыкладанні, якія працуюць з вялікімі 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 на хасце? Кантэйнер жыве ў сваім вылучаным сеткавым Namespace, таму прынамсі частка сеткавых Sysctl-параметраў у кантэйнеры можа адрознівацца ад хаста.

Як менавіта прымяняюцца налады Sysctl у кантэйнеры? Бо кантэйнеры ў нас непрывілеяваныя, змяніць любую наладу Sysctl, зойдучы ў сам кантэйнер, не атрымаецца – проста не хопіць правоў. Для запуску кантэйнераў наша воблака на той момант выкарыстоўвала Docker (цяпер ужо Падман). Докер праз API перадаваліся параметры новага кантэйнера, у тым ліку патрэбныя налады Sysctl.
Падчас перабору версій высветлілася, што API Docker не аддавала ўсе памылкі (прынамсі, у версіі 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, гэта значыць верхняя мяжа была ніжэй, чым ніжняя, што і прыводзіла.

На той момант у нас ужо выкарыстоўваўся свой механізм даканфігурвання кантэйнера пасля старту (замарозка кантэйнера праз cgroup freezer і выкананне каманд у namespace кантэйнера праз ip netns), і мы дадалі ў гэтую частку таксама прапісванне Sysctl-параметраў. Праблема была вырашана.

FragmentSmack/SegmentSmack. Першая кроў 2

Не паспелі мы разабрацца з ужываннем Workaround у воблаку, як сталі паступаць першыя рэдкія скаргі ад карыстачоў. На той момант прайшло некалькі тыдняў з пачатку прымянення Workaround на першых серверах. Першаснае расследаванне паказала, што скаргі паступалі на асобныя сэрвісы і не на ўсе серверы дадзеных сэрвісаў. Праблема зноў набыла вельмі нявызначаны характар.

У першую чаргу мы, вядома, паспрабавалі адкаціць наладкі Sysctl, але гэта не дало ніякага эфекту. Розныя маніпуляцыі з наладамі сервера і прыкладанні таксама не дапамаглі. Дапамог reboot. Reboot для Linux гэтак жа процінатуральны, калі ён быў звычайнай умовай для працы з Windows у былыя дні. Тым не менш ён дапамог, і мы спісалі ўсё на глюк у ядры пры ўжыванні новых налад у Sysctl. Як жа гэта было легкадумна...

Праз тры тыдні праблема паўтарылася. Канфігурацыя гэтых сервераў была даволі простай: Nginx у рэжыме проксі/балансавальніка. Трафіку няшмат. Новая ўступная: на кліентах з кожным днём павялічваецца колькасць 504-х памылак (Тайм-аўт шлюзу). На графіцы паказана колькасць 504-х памылак у дзень па гэтым сэрвісе:

Бойцеся ўразлівасцяў, воркэраунды якія прыносяць. Частка 1: FragmentSmack/SegmentSmack

Усе памылкі пра адзін і той жа бэкенд - пра той, які знаходзіцца ў воблаку. Графік спажывання памяці пад фрагменты пакетаў на гэтым бэкендзе выглядаў наступным чынам:

Бойцеся ўразлівасцяў, воркэраунды якія прыносяць. Частка 1: FragmentSmack/SegmentSmack

Гэта адна з самых яркіх праяў праблемы на графіках аперацыйнай сістэмы. У воблаку як раз у гэты ж час была пафікшана іншая сеткавая праблема з наладамі QoS (Traffic Control). На графіцы спажывання памяці пад фрагменты пакетаў яна выглядала сапраўды гэтак жа:

Бойцеся ўразлівасцяў, воркэраунды якія прыносяць. Частка 1: FragmentSmack/SegmentSmack

Здагадка была простай: калі на графіках яны выглядаюць аднолькава, то і прычына ў іх аднолькавая. Тым больш, што якія-небудзь праблемы з гэтым тыпам памяці здараюцца надзвычай рэдка.

Сутнасць пафіксанай праблемы складалася ў тым, што мы выкарыстоўвалі ў QoS пакетны шэдулер fq з дэфолтнымі наладамі. Па змаўчанні для аднаго злучэння ён дазваляе дадаваць у чаргу 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" - гэта і ёсць пакеты, драпнутыя з-за перавышэнні ліміту чаргі аднаго злучэння, а "dropped 464545" - гэта сума ўсіх драпнутых пакетаў гэтага шэдулера. Пасля павелічэння даўжыні чаргі да 1 тыс. і рэстарту кантэйнераў праблема перастала праяўляцца. Можна адкінуцца ў крэсле і выпіць смузи.

FragmentSmack/SegmentSmack. Апошняя кроў

Па-першае, праз некалькі месяцаў пасля анонсу ўразлівасцяў у ядры, нарэшце, з'явіўся фікс для FragmentSmack (нагадаю, што разам з анонсам у жніўні выйшаў фікс толькі для SegmentSmack), што дало шанец адмовіцца ад Workaround, які даставіў нам даволі шмат непрыемнасцяў. Частку сервераў за гэты час мы ўжо паспелі перавесці на новае ядро, і зараз трэба было пачынаць з пачатку. Навошта мы абнаўлялі ядро, не чакаючы фікса FragmentSmack? Справа ў тым, што працэс абароны ад гэтых уразлівасцяў супаў (і зліўся) з працэсам абнаўлення самога CentOS (што займае яшчэ больш часу, чым абнаўленне толькі ядры). Да таго ж SegmentSmack – больш небяспечная ўразлівасць, а фікс для яго з'явіўся адразу, так што сэнс быў у любым выпадку. Аднак, проста абнавіць ядро ​​на CentOS мы не маглі, таму што ўразлівасць FragmentSmack, якая з'явілася ў часы CentOS 7.5, была пафікшана толькі ў версіі 7.6, таму нам прыйшлося спыняць абнаўленне да 7.5 і пачынаць усё нанова з абнаўленнем да 7.6. І так таксама бывае.

Па-другое, да нас вярнуліся рэдкія скаргі карыстальнікаў на праблемы. Цяпер мы ўжо сапраўды ведаем, што ўсе яны злучаны з аплоадам файлаў ад кліентаў на некаторыя нашы серверы. Прычым праз гэтыя серверы ішло вельмі невялікая колькасць аплаадаў ад агульнай масы.

Як мы памятаем з аповяду вышэй, адкат Sysctl не дапамагаў. Дапамагаў Reboot, але часова.
Падазрэнні з Sysctl не былі зняты, але на гэты раз патрабавалася сабраць як мага больш інфармацыі. Таксама вельмі не хапала магчымасці прайграць праблему з аплаадам на кліенце, каб больш кропкава вывучыць, што адбываецца.

Аналіз усёй даступнай статыстыкі і логаў не наблізіў нас да разумення адбывалага. Востра не хапала магчымасці прайграць праблему, каб "памацаць" канкрэтнае злучэнне. Нарэшце, распрацоўнікам на спецверсіі прыкладання атрымалася дамагчыся стабільнага прайгравання праблем на тэставай прыладзе пры падлучэнні праз Wi-Fi. Гэта стала прарывам у расследаванні. Кліент падключаўся да Nginx, той праксіраваў на бэкенд, якім з'яўлялася наша дадатак на 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-інкапсуляванне.
  7. Затым Linux адпраўляе яго на Tunnel-інтэрфейс, дзе з яго здымаецца яшчэ адзін пласт - Tunnel-інкапсуляванне.

Складанасць у тым, каб перадаць гэта ўсё ў выглядзе параметраў у tcpdump.
Пачнём з канца: ці ёсць чыстыя (без лішніх загалоўкаў) IP-пакеты ад кліентаў, са знятым vlan-і tunnel-інкапсуляванне?

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

Не, такіх пакетаў на сэрвэры не было. Такім чынам, праблема павінна быць раней. Ці ёсць пакеты са знятым толькі Vlan-інкапсуляванне?

tcpdump ip[32:4]=0xx390x2xx

0xx390x2xx - гэта IP-адрас кліента ў hex-фармаце.
32:4 - адрас і даўжыня поля, у якім запісаны SCR IP у Tunnel-пакеце.

Адрас поля прыйшлося падбіраць пераборам, бо ў інтэрнэце пішуць пра 40, 44, 50, 54, але там IP-адрасы не было. Таксама можна паглядзець адзін з пакетаў у hex (параметр -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-адрасоўкай алгарытмаў (для якой reason: timed out, errors, etc.)".

Сярод групы сервераў, на якіх вывучалася праблема, на двух гэты лічыльнік павялічваўся хутчэй, на двух - павольней, а яшчэ на двух наогул не павялічваўся. Параўнанне дынамікі гэтага лічыльніка з дынамікай HTTP-памылак на Java-серверы выявіла карэляцыю. Гэта значыць лічыльнік можна было ставіць на маніторынг.

Наяўнасць надзейнага індыкатара праблем вельмі важна, каб можна было дакладна вызначыць, ці дапамагае адкат Sysctl, бо з папярэдняга апавядання мы ведаем, што па дадатку гэта адразу зразумець нельга. Дадзены індыкатар дазволіў бы выявіць усе праблемныя месцы ў прадакшэне да таго, як гэта выявяць карыстачы.
Пасля адкату Sysctl памылкі па маніторынгу спыніліся, такім чынам прычына праблем была даказана, як і тое, што адкат дапамагае.

Мы адкацілі налады фрагментацыі на іншых серверах, дзе загарэўся новы маніторынг, а дзесьці пад фрагменты вылучылі нават больш памяці, чым было да гэтага па змаўчанні (гэта была udp-статыстыка, частковая страта якой не была прыкметная на агульным фоне).

Самыя галоўныя пытанні

Чаму ў нас на L3-балансавальніку фрагментуюцца пакеты? Большасць пакетаў, якія прылятаюць ад карыстачоў на балансавальнікі, - гэта SYN і ACK. Памеры гэтых пакетаў невялікія. Але бо дзель такіх пакетаў вельмі вялікая, то на іх фоне мы не заўважылі наяўнасць вялікіх пакетаў, якія сталі фрагментавацца.

Прычынай стаў скрыпт канфігурацыі, які паламаўся. advmss на серверах з Vlan-інтэрфейсамі (сервераў з тэгаваным трафікам на той момант у прадакшэне было вельмі мала). Advmss дазваляе данесці да кліента інфармацыю аб тым, што пакеты ў наш бок павінны быць меншага памеру, каб пасля прыклейвання да іх загалоўкаў тунэля іх не прыйшлося фрагментаваць.

Чаму адкат Sysctl не дапамагаў, а рэбуты дапамагаў? Адкат Sysctl мяняў аб'ём памяці, даступнай для склейвання пакетаў. Пры гэтым, мяркуючы па ўсім, сам факт перапаўнення памяці пад фрагменты прыводзіў да тармажэння злучэнняў, што прыводзіла да таго, што фрагменты надоўга затрымліваліся ў чарзе. Гэта значыць, працэс зацыкліваўся.
Рэбут абнуляў памяць і ўсё прыходзіла ў парадак.

Ці можна было абысціся без Workaround? Так, але вялікая рызыка пакінуць карыстальнікаў без абслугоўвання ў выпадку нападу. Вядома, ужыванне Workaround у выніку прывяло да ўзнікнення розных праблем, уключаючы тармажэнне аднаго з сэрвісаў у карыстачоў, але тым не менш мы лічым, што дзеянні былі апраўданыя.

Вялікі дзякуй Андрэю Цімафееву (atimofeyev) за дапамогу ў правядзенні расследавання, а таксама Аляксею Кранёву (devicex) - за тытанічную працу па абнаўленні Centos і ядраў на серверах. Працэс, які ў дадзеным выпадку некалькі разоў прыйшлося пачынаць з пачатку, з-за чаго ён зацягнуўся на шмат месяцаў.

Крыніца: habr.com

Дадаць каментар