Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

Kamusta kayong lahat! Ang pangalan ko ay Dmitry Samsonov, nagtatrabaho ako bilang isang nangungunang tagapangasiwa ng system sa Odnoklassniki. Mayroon kaming higit sa 7 libong pisikal na server, 11 libong container sa aming cloud at 200 application, na sa iba't ibang configuration ay bumubuo ng 700 iba't ibang cluster. Ang karamihan sa mga server ay nagpapatakbo ng CentOS 7.
Noong Agosto 14, 2018, na-publish ang impormasyon tungkol sa kahinaan ng FragmentSmack
(CVE-2018-5391) at SegmentSmack (CVE-2018-5390). Ang mga ito ay mga kahinaan na may vector attack sa network at medyo mataas na marka (7.5), na nagbabanta sa denial of service (DoS) dahil sa resource exhaustion (CPU). Ang pag-aayos ng kernel para sa FragmentSmack ay hindi iminungkahi sa oras na iyon; higit pa rito, lumabas ito nang mas huli kaysa sa paglalathala ng impormasyon tungkol sa kahinaan. Upang alisin ang SegmentSmack, iminungkahi na i-update ang kernel. Ang pakete ng pag-update mismo ay inilabas sa parehong araw, ang natitira lamang ay i-install ito.
Hindi, hindi kami tutol sa pag-update ng kernel! Gayunpaman, may mga nuances ...

Paano namin ina-update ang kernel sa produksyon

Sa pangkalahatan, walang kumplikado:

  1. Mag-download ng mga pakete;
  2. I-install ang mga ito sa isang bilang ng mga server (kabilang ang mga server na nagho-host sa aming cloud);
  3. Siguraduhing walang sira;
  4. Siguraduhin na ang lahat ng karaniwang mga setting ng kernel ay inilapat nang walang mga error;
  5. Maghintay ng ilang araw;
  6. Suriin ang pagganap ng server;
  7. Ilipat ang deployment ng mga bagong server sa bagong kernel;
  8. I-update ang lahat ng server sa pamamagitan ng data center (isang data center sa isang pagkakataon upang mabawasan ang epekto sa mga user kung sakaling magkaroon ng mga problema);
  9. I-reboot ang lahat ng mga server.

Ulitin para sa lahat ng sangay ng mga butil na mayroon tayo. Sa sandaling ito ay:

  • Stock CentOS 7 3.10 - para sa karamihan ng mga regular na server;
  • Vanilla 4.19 - para sa atin isang ulap na ulap, dahil kailangan natin ng BFQ, BBR, atbp.;
  • Elrepo kernel-ml 5.2 - para sa mga distributor na may mataas na load, dahil ang 4.19 ay dating hindi matatag, ngunit ang parehong mga tampok ay kinakailangan.

Tulad ng maaaring nahulaan mo, ang pag-reboot ng libu-libong mga server ay tumatagal ng pinakamahabang oras. Dahil hindi lahat ng mga kahinaan ay kritikal para sa lahat ng mga server, nire-reboot lang namin ang mga direktang naa-access mula sa Internet. Sa cloud, upang hindi limitahan ang flexibility, hindi namin itinatali ang mga external na naa-access na container sa mga indibidwal na server gamit ang isang bagong kernel, ngunit i-reboot ang lahat ng host nang walang pagbubukod. Sa kabutihang palad, ang pamamaraan doon ay mas simple kaysa sa mga regular na server. Halimbawa, ang mga stateless na lalagyan ay maaaring lumipat lamang sa isa pang server habang nagre-reboot.

Gayunpaman, marami pa ring trabaho, at maaaring tumagal ng ilang linggo, at kung may anumang mga problema sa bagong bersyon, hanggang sa ilang buwan. Naiintindihan ito ng mga umaatake, kaya kailangan nila ng plan B.

FragmentSmack/SegmentSmack. Workaround

Sa kabutihang palad, para sa ilang mga kahinaan ay umiiral ang isang plano B, at ito ay tinatawag na Workaround. Kadalasan, ito ay isang pagbabago sa mga setting ng kernel/application na maaaring mabawasan ang posibleng epekto o ganap na maalis ang pagsasamantala sa mga kahinaan.

Sa kaso ng FragmentSmack/SegmentSmack ay iminungkahi ito Workaround:

Β«Maaari mong baguhin ang mga default na halaga ng 4MB at 3MB sa net.ipv4.ipfrag_high_thresh at net.ipv4.ipfrag_low_thresh (at ang kanilang mga katapat para sa ipv6 net.ipv6.ipfrag_high_thresh at net.ipv6.ipfrag_low_thresh) sa 256 kB at 192 kB ayon sa pagkakabanggit. mas mababa. Ang mga pagsubok ay nagpapakita ng maliit hanggang sa makabuluhang pagbaba sa paggamit ng CPU sa panahon ng pag-atake depende sa hardware, mga setting, at kundisyon. Gayunpaman, maaaring may ilang epekto sa performance dahil sa ipfrag_high_thresh=262144 bytes, dahil dalawang 64K fragment lang ang maaaring magkasya sa reassembly queue sa isang pagkakataon. Halimbawa, may panganib na masira ang mga application na gumagana sa malalaking UDP packet'.

Ang mga parameter mismo sa dokumentasyon ng kernel inilarawan bilang sumusunod:

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.

Wala kaming malalaking UDP sa mga serbisyo sa produksyon. Walang pira-pirasong trapiko sa LAN; mayroong pira-pirasong trapiko sa WAN, ngunit hindi makabuluhan. Walang mga palatandaan - maaari mong ilunsad ang Workaround!

FragmentSmack/SegmentSmack. Unang dugo

Ang unang problemang naranasan namin ay ang mga cloud container kung minsan ay inilapat ang mga bagong setting ng bahagyang (tanging ipfrag_low_thresh), at kung minsan ay hindi nalalapat ang mga ito - nag-crash lang sila sa simula. Hindi posible na muling kopyahin ang problema nang matatag (lahat ng mga setting ay inilapat nang manu-mano nang walang anumang mga paghihirap). Ang pag-unawa kung bakit nag-crash ang container sa simula ay hindi rin napakadali: walang nakitang mga error. Isang bagay ang tiyak: ang pagbabalik ng mga setting ay malulutas ang problema sa mga pag-crash ng container.

Bakit hindi sapat na ilapat ang Sysctl sa host? Ang lalagyan ay nakatira sa sarili nitong nakalaang network Namespace, kaya kahit papaano bahagi ng mga parameter ng network Sysctl sa lalagyan ay maaaring iba sa host.

Paano eksaktong inilapat ang mga setting ng Sysctl sa lalagyan? Dahil walang pribilehiyo ang aming mga container, hindi mo mababago ang anumang setting ng Sysctl sa pamamagitan ng pagpunta sa mismong container - wala kang sapat na karapatan. Upang magpatakbo ng mga lalagyan, ginamit ng aming cloud noong panahong iyon ang Docker (ngayon podman). Ang mga parameter ng bagong container ay ipinasa sa Docker sa pamamagitan ng API, kasama ang mga kinakailangang setting ng Sysctl.
Habang naghahanap sa mga bersyon, lumabas na hindi ibinalik ng Docker API ang lahat ng mga error (kahit sa bersyon 1.10). Nang sinubukan naming simulan ang lalagyan sa pamamagitan ng "docker run", sa wakas ay nakakita kami ng kahit isang bagay:

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.

Ang halaga ng parameter ay hindi wasto. Pero bakit? At bakit ito ay hindi wasto kung minsan lamang? Lumalabas na hindi ginagarantiyahan ng Docker ang pagkakasunud-sunod kung saan inilapat ang mga parameter ng Sysctl (ang pinakabagong nasubok na bersyon ay 1.13.1), kaya minsan sinubukan ng ipfrag_high_thresh na itakda sa 256K kapag ang ipfrag_low_thresh ay 3M pa rin, iyon ay, mas mababa ang pinakamataas na limitasyon. kaysa sa mas mababang limitasyon, na humantong sa error.

Sa oras na iyon, ginamit na namin ang sarili naming mekanismo para sa muling pag-configure ng lalagyan pagkatapos magsimula (nagyeyelong lalagyan pagkatapos grupong freezer at pagpapatupad ng mga utos sa namespace ng container sa pamamagitan ng ip netns), at nagdagdag din kami ng pagsusulat ng mga parameter ng Sysctl sa bahaging ito. Nalutas ang problema.

FragmentSmack/SegmentSmack. Unang Dugo 2

Bago kami magkaroon ng oras upang maunawaan ang paggamit ng Workaround sa cloud, nagsimulang dumating ang mga unang bihirang reklamo mula sa mga user. Sa oras na iyon, ilang linggo na ang lumipas mula noong simula ng paggamit ng Workaround sa mga unang server. Ang paunang pagsisiyasat ay nagpakita na ang mga reklamo ay natanggap laban sa mga indibidwal na serbisyo, at hindi lahat ng mga server ng mga serbisyong ito. Ang problema ay muling naging lubhang hindi tiyak.

Una sa lahat, siyempre, sinubukan naming ibalik ang mga setting ng Sysctl, ngunit wala itong epekto. Ang iba't ibang mga manipulasyon sa mga setting ng server at application ay hindi rin nakatulong. Nakatulong ang pag-reboot. Ang pag-reboot ng Linux ay hindi natural tulad ng karaniwan para sa Windows noong unang panahon. Gayunpaman, nakatulong ito, at inilagay namin ito sa isang "kernel glitch" kapag inilapat ang mga bagong setting sa Sysctl. Gaano ito kawalang kwenta...

Pagkalipas ng tatlong linggo, naulit ang problema. Ang pagsasaayos ng mga server na ito ay medyo simple: Nginx sa proxy/balancer mode. Hindi gaanong traffic. Bagong panimulang tala: ang bilang ng 504 na mga error sa mga kliyente ay tumataas araw-araw (Pag-timeout ng Gateway). Ipinapakita ng graph ang bilang ng 504 na mga error bawat araw para sa serbisyong ito:

Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

Ang lahat ng mga error ay tungkol sa parehong backend - tungkol sa isa na nasa cloud. Ang memory consumption graph para sa mga fragment ng package sa backend na ito ay ganito ang hitsura:

Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

Ito ay isa sa mga pinaka-halatang pagpapakita ng problema sa mga graph ng operating system. Sa cloud, sa parehong oras, isa pang problema sa network sa mga setting ng QoS (Traffic Control) ay naayos. Sa graph ng pagkonsumo ng memorya para sa mga fragment ng packet, eksaktong pareho ang hitsura nito:

Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

Ang palagay ay simple: kung pareho ang hitsura nila sa mga graph, kung gayon mayroon silang parehong dahilan. Bukod dito, ang anumang mga problema sa ganitong uri ng memorya ay napakabihirang.

Ang kakanyahan ng nakapirming problema ay ginamit namin ang fq packet scheduler na may mga default na setting sa QoS. Bilang default, para sa isang koneksyon, pinapayagan ka nitong magdagdag ng 100 packet sa pila, at ang ilang mga koneksyon, sa mga sitwasyon ng kakulangan ng channel, ay nagsimulang humarang sa pila sa kapasidad. Sa kasong ito, ang mga packet ay bumaba. Sa tc statistics (tc -s qdisc) makikita itong ganito:

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

Ang "464545 flows_plimit" ay ang mga packet na na-drop dahil sa paglampas sa queue limit ng isang koneksyon, at ang "drop 464545" ay ang kabuuan ng lahat ng mga dropped na packet ng scheduler na ito. Matapos taasan ang haba ng pila sa 1 libo at i-restart ang mga lalagyan, huminto ang problema sa nangyari. Maaari kang umupo at uminom ng smoothie.

FragmentSmack/SegmentSmack. Huling Dugo

Una, ilang buwan pagkatapos ng anunsyo ng mga kahinaan sa kernel, sa wakas ay lumitaw ang isang pag-aayos para sa FragmentSmack (paalalahanan ko kayo na kasama ang anunsyo noong Agosto, isang pag-aayos lamang para sa SegmentSmack ang inilabas), na nagbigay sa amin ng pagkakataong iwanan ang Workaround, na nagdulot sa amin ng maraming problema. Sa panahong ito, nagawa na naming ilipat ang ilan sa mga server sa bagong kernel, at ngayon kailangan naming magsimula sa simula. Bakit namin na-update ang kernel nang hindi naghihintay para sa pag-aayos ng FragmentSmack? Ang katotohanan ay ang proseso ng pagprotekta laban sa mga kahinaan na ito ay kasabay (at pinagsama) sa proseso ng pag-update mismo ng CentOS (na tumatagal ng mas maraming oras kaysa sa pag-update lamang ng kernel). Bilang karagdagan, ang SegmentSmack ay isang mas mapanganib na kahinaan, at isang pag-aayos para dito ay agad na lumitaw, kaya naging makabuluhan pa rin ito. Gayunpaman, hindi lang namin mai-update ang kernel sa CentOS dahil ang kahinaan ng FragmentSmack, na lumitaw noong CentOS 7.5, ay naayos lamang sa bersyon 7.6, kaya kinailangan naming ihinto ang pag-update sa 7.5 at magsimulang muli sa pag-update sa 7.6. At nangyayari rin ito.

Pangalawa, ang mga bihirang reklamo ng user tungkol sa mga problema ay bumalik sa amin. Ngayon ay alam na natin na ang lahat ay nauugnay sa pag-upload ng mga file mula sa mga kliyente sa ilan sa aming mga server. Bukod dito, napakaliit na bilang ng mga pag-upload mula sa kabuuang masa ang dumaan sa mga server na ito.

Tulad ng naaalala natin mula sa kuwento sa itaas, ang pagbabalik ng Sysctl ay hindi nakatulong. Nakatulong ang pag-reboot, ngunit pansamantala.
Ang mga hinala tungkol sa Sysctl ay hindi inalis, ngunit sa pagkakataong ito ay kinakailangan upang mangolekta ng maraming impormasyon hangga't maaari. Nagkaroon din ng malaking kakulangan ng kakayahang muling gawin ang problema sa pag-upload sa kliyente upang mapag-aralan nang mas tumpak kung ano ang nangyayari.

Ang pagsusuri sa lahat ng magagamit na istatistika at mga tala ay hindi nagdala sa amin ng mas malapit sa pag-unawa sa kung ano ang nangyayari. Nagkaroon ng matinding kakulangan ng kakayahang muling gawin ang problema upang "maramdaman" ang isang partikular na koneksyon. Sa wakas, ang mga developer, gamit ang isang espesyal na bersyon ng application, ay nakamit ang matatag na pagpaparami ng mga problema sa isang pagsubok na aparato kapag nakakonekta sa pamamagitan ng Wi-Fi. Ito ay isang pambihirang tagumpay sa imbestigasyon. Nakakonekta ang kliyente sa Nginx, na nag-proxy sa backend, na aming Java application.

Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

Ang dialogue para sa mga problema ay ganito (naayos sa Nginx proxy side):

  1. Client: humiling na makatanggap ng impormasyon tungkol sa pag-download ng file.
  2. Java server: tugon.
  3. Kliyente: POST na may file.
  4. Java server: error.

Kasabay nito, nagsusulat ang Java server sa log na 0 byte ng data ang natanggap mula sa kliyente, at isinusulat ng Nginx proxy na ang kahilingan ay tumagal ng higit sa 30 segundo (30 segundo ang timeout ng application ng kliyente). Bakit ang timeout at bakit 0 bytes? Mula sa pananaw ng HTTP, gumagana ang lahat ayon sa nararapat, ngunit ang POST na may file ay tila nawawala sa network. Bukod dito, nawawala ito sa pagitan ng kliyente at Nginx. Oras na para armasan ang iyong sarili ng Tcpdump! Ngunit kailangan mo munang maunawaan ang pagsasaayos ng network. Ang Nginx proxy ay nasa likod ng L3 balancer NFware. Ang tunneling ay ginagamit upang maghatid ng mga packet mula sa L3 balancer sa server, na nagdaragdag ng mga header nito sa mga packet:

Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

Sa kasong ito, ang network ay pumupunta sa server na ito sa anyo ng trapikong na-tag ng Vlan, na nagdaragdag din ng sarili nitong mga field sa mga packet:

Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

At ang trapikong ito ay maaari ding hatiin (ang maliit na porsyento ng papasok na pira-pirasong trapiko na napag-usapan namin noong tinatasa ang mga panganib mula sa Workaround), na nagbabago rin sa nilalaman ng mga header:

Mag-ingat sa mga kahinaan na nagdudulot ng mga pag-ikot sa trabaho. Bahagi 1: FragmentSmack/SegmentSmack

Muli: ang mga packet ay naka-encapsulated na may Vlan tag, na naka-encapsulated ng tunnel, pira-piraso. Upang mas maunawaan kung paano ito nangyayari, subaybayan natin ang ruta ng packet mula sa kliyente hanggang sa Nginx proxy.

  1. Ang packet ay umabot sa L3 balancer. Para sa tamang pagruruta sa loob ng data center, ang packet ay naka-encapsulated sa isang tunnel at ipinadala sa network card.
  2. Dahil ang mga packet + tunnel header ay hindi magkasya sa MTU, ang packet ay pinutol sa mga fragment at ipinadala sa network.
  3. Ang switch pagkatapos ng L3 balancer, kapag tumatanggap ng isang packet, ay nagdaragdag ng Vlan tag dito at ipinapadala ito.
  4. Ang switch sa harap ng Nginx proxy ay nakikita (batay sa mga setting ng port) na ang server ay umaasa ng isang Vlan-encapsulated packet, kaya ito ay nagpapadala nito kung ano man, nang hindi inaalis ang Vlan tag.
  5. Kinukuha ng Linux ang mga fragment ng mga indibidwal na pakete at pinagsasama ang mga ito sa isang malaking pakete.
  6. Susunod, ang packet ay umabot sa Vlan interface, kung saan ang unang layer ay tinanggal mula dito - Vlan encapsulation.
  7. Pagkatapos ay ipinapadala ito ng Linux sa interface ng Tunnel, kung saan ang isa pang layer ay tinanggal mula dito - Tunnel encapsulation.

Ang kahirapan ay ipasa ang lahat ng ito bilang mga parameter sa tcpdump.
Magsimula tayo sa dulo: mayroon bang malinis (nang walang mga hindi kinakailangang header) na mga IP packet mula sa mga kliyente, na inalis ang vlan at tunnel encapsulation?

tcpdump host <ip ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°>

Hindi, walang ganoong mga pakete sa server. Kaya dapat mas maaga ang problema. Mayroon bang anumang mga packet na ang Vlan encapsulation lamang ang tinanggal?

tcpdump ip[32:4]=0xx390x2xx

Ang 0xx390x2xx ay ang client IP address sa hex na format.
32:4 β€” address at haba ng field kung saan nakasulat ang SCR IP sa Tunnel packet.

Ang address ng field ay kailangang mapili sa pamamagitan ng malupit na puwersa, dahil sa Internet ay sumulat sila tungkol sa 40, 44, 50, 54, ngunit walang IP address doon. Maaari mo ring tingnan ang isa sa mga packet sa hex (ang -xx o -XX na parameter sa tcpdump) at kalkulahin ang IP address na alam mo.

Mayroon bang mga packet fragment na walang Vlan at Tunnel encapsulation na inalis?

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

Ipapakita sa atin ng mahika na ito ang lahat ng mga fragment, kabilang ang huli. Marahil, ang parehong bagay ay maaaring i-filter ng IP, ngunit hindi ko sinubukan, dahil walang masyadong maraming mga packet, at ang mga kailangan ko ay madaling mahanap sa pangkalahatang daloy. Nandito na sila:

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 ..............

Ito ay dalawang fragment ng isang pakete (parehong ID 53652) na may litrato (ang salitang Exif ay makikita sa unang pakete). Dahil sa ang katunayan na may mga pakete sa antas na ito, ngunit hindi sa pinagsamang anyo sa mga dump, ang problema ay malinaw sa pagpupulong. Sa wakas may dokumentaryong ebidensya nito!

Ang packet decoder ay hindi nagpahayag ng anumang mga problema na pumipigil sa pagbuo. Sinubukan ito dito: hpd.gasmi.net. Sa una, kapag sinubukan mong ilagay ang isang bagay doon, hindi gusto ng decoder ang format ng packet. Ito ay lumabas na mayroong ilang dagdag na dalawang octet sa pagitan ng Srcmac at Ethertype (hindi nauugnay sa impormasyon ng fragment). Matapos tanggalin ang mga ito, nagsimulang gumana ang decoder. Gayunpaman, hindi ito nagpakita ng mga problema.
Anuman ang maaaring sabihin ng isa, walang ibang natagpuan maliban sa mga Sysctl na iyon. Ang natitira na lang ay maghanap ng paraan upang matukoy ang mga server ng problema upang maunawaan ang sukat at magpasya sa mga karagdagang aksyon. Mabilis na natagpuan ang kinakailangang counter:

netstat -s | grep "packet reassembles failed”

Ito rin ay nasa snmpd sa ilalim ng OID=1.3.6.1.2.1.4.31.1.1.16.1 (ipSystemStatsReasmFails).

"Ang bilang ng mga pagkabigo na nakita ng IP re-assembly algorithm (para sa anumang kadahilanan: nag-time out, mga error, atbp.)."

Kabilang sa pangkat ng mga server kung saan pinag-aralan ang problema, sa dalawa ang counter na ito ay tumaas nang mas mabilis, sa dalawa pang mabagal, at sa dalawa pa ay hindi ito tumaas. Ang paghahambing ng dynamics ng counter na ito sa dynamics ng mga error sa HTTP sa Java server ay nagpakita ng isang ugnayan. Iyon ay, ang metro ay maaaring masubaybayan.

Ang pagkakaroon ng maaasahang tagapagpahiwatig ng mga problema ay napakahalaga upang tumpak mong matukoy kung nakakatulong ang pagbabalik ng Sysctl, dahil mula sa nakaraang kuwento alam namin na hindi ito agad na mauunawaan mula sa aplikasyon. Ang indicator na ito ay magbibigay-daan sa amin na tukuyin ang lahat ng mga lugar ng problema sa produksyon bago ito matuklasan ng mga user.
Matapos ibalik ang Sysctl, huminto ang mga error sa pagsubaybay, kaya napatunayan ang sanhi ng mga problema, pati na rin ang katotohanan na nakakatulong ang rollback.

Ibinalik namin ang mga setting ng fragmentation sa iba pang mga server, kung saan nagkaroon ng bagong pagsubaybay, at kung saan naglaan kami ng mas maraming memorya para sa mga fragment kaysa sa dati nang default (ito ay mga istatistika ng UDP, ang bahagyang pagkawala nito ay hindi napapansin laban sa pangkalahatang background) .

Ang pinakamahalagang tanong

Bakit pira-piraso ang mga packet sa aming L3 balancer? Karamihan sa mga packet na dumarating mula sa mga user hanggang sa mga balancer ay SYN at ACK. Maliit ang mga sukat ng mga paketeng ito. Ngunit dahil ang bahagi ng naturang mga packet ay napakalaki, laban sa kanilang background ay hindi namin napansin ang pagkakaroon ng malalaking packet na nagsimulang maghiwa-hiwalay.

Ang dahilan ay isang sirang configuration script advmss sa mga server na may mga interface ng Vlan (kaunti lang ang mga server na may naka-tag na trapiko sa produksyon noong panahong iyon). Ang Advmss ay nagpapahintulot sa amin na ihatid sa kliyente ang impormasyon na ang mga packet sa aming direksyon ay dapat na mas maliit sa laki upang pagkatapos na ilakip ang mga header ng tunnel sa kanila ay hindi na sila kailangang mahati-hati.

Bakit hindi nakatulong ang Sysctl rollback, ngunit nakatulong ang pag-reboot? Binago ng pagbabalik ng Sysctl ang dami ng memory na magagamit para sa pagsasama-sama ng mga pakete. Kasabay nito, tila ang mismong katotohanan ng overflow ng memorya para sa mga fragment ay humantong sa pagbagal ng mga koneksyon, na humantong sa mga fragment na naantala ng mahabang panahon sa pila. Ibig sabihin, umikot ang proseso.
Ang pag-reboot ay na-clear ang memorya at ang lahat ay bumalik sa pagkakasunud-sunod.

Posible bang gawin nang walang Workaround? Oo, ngunit may mataas na panganib na iwan ang mga user nang walang serbisyo kung sakaling magkaroon ng pag-atake. Siyempre, ang paggamit ng Workaround ay nagresulta sa iba't ibang mga problema, kabilang ang pagbagal ng isa sa mga serbisyo para sa mga user, ngunit gayunpaman, naniniwala kami na ang mga aksyon ay makatwiran.

Maraming salamat kay Andrey Timofeev (atimofeyev) para sa tulong sa pagsasagawa ng imbestigasyon, gayundin si Alexey Krenev (aparatox) - para sa titanic na gawain ng pag-update ng Centos at kernels sa mga server. Isang proseso na sa kasong ito ay kailangang simulan mula sa simula nang maraming beses, kaya naman nag-drag ito sa loob ng maraming buwan.

Pinagmulan: www.habr.com

Magdagdag ng komento