ProHoster > Блог > Administrasi > Waspada karo kerentanan sing nggawa babak kerja. Bagean 1: FragmentSmack/SegmentSmack
Waspada karo kerentanan sing nggawa babak kerja. Bagean 1: FragmentSmack/SegmentSmack
Halo kabeh! Jenengku Dmitry Samsonov, aku kerja minangka administrator sistem terkemuka ing Odnoklassniki. Kita duwe luwih saka 7 ewu server fisik, 11 ewu kontaner ing awan lan 200 aplikasi, sing ing macem-macem konfigurasi mbentuk 700 kluster sing beda. Umume server mbukak CentOS 7.
Tanggal 14 Agustus 2018, informasi babagan kerentanan FragmentSmack diterbitake
(CVE-2018-5391) lan SegmentSmack (CVE-2018-5390). Iki minangka kerentanan karo vektor serangan jaringan lan skor sing cukup dhuwur (7.5), sing ngancam penolakan layanan (DoS) amarga kekeselen sumber daya (CPU). Perbaikan kernel kanggo FragmentSmack ora diusulake nalika iku; luwih-luwih, metu luwih cepet tinimbang publikasi informasi babagan kerentanan kasebut. Kanggo ngilangi SegmentSmack, disaranake nganyari kernel. Paket nganyari dhewe dirilis ing dina sing padha, sing isih ana yaiku nginstal.
Ora, kita ora nglawan nganyari kernel! Nanging, ana nuansa ...
Carane kita nganyari kernel ing produksi
Umumé, ora ana sing rumit:
Download paket;
Instal ing sawetara server (kalebu server hosting awan kita);
Priksa manawa ora ana sing rusak;
Priksa manawa kabeh setelan kernel standar ditrapake tanpa kasalahan;
Enteni sawetara dina;
Priksa kinerja server;
Ngalih penyebaran server anyar menyang kernel anyar;
Nganyari kabeh server kanthi pusat data (siji pusat data sekaligus kanggo nyilikake efek ing pangguna yen ana masalah);
Urip maneh kabeh server.
Baleni kanggo kabeh cabang saka kernels kita duwe. Ing wayahe iku:
Simpenan CentOS 7 3.10 - kanggo umume server biasa;
Vanilla 4.19 - kanggo kita mendhung siji, amarga kita butuh BFQ, BBR, lsp;
Elrepo kernel-ml 5.2 - kanggo distributor banget dimuat, amarga 4.19 digunakake ora stabil, nanging fitur sing padha dibutuhake.
Kaya sing wis sampeyan duga, urip maneh ewonan server mbutuhake wektu paling suwe. Amarga ora kabeh kerentanan kritis kanggo kabeh server, kita mung urip maneh sing bisa diakses langsung saka Internet. Ing méga, supaya ora kanggo matesi keluwesan, kita ora dasi kontaner externally diakses kanggo server individu karo kernel anyar, nanging urip maneh kabeh sarwa dumadi tanpa istiméwa. Untunge, prosedur kasebut luwih gampang tinimbang karo server biasa. Contone, wadhah stateless mung bisa pindhah menyang server liyane nalika urip maneh.
Nanging, isih ana akeh karya, lan bisa njupuk sawetara minggu, lan yen ana masalah karo versi anyar, nganti sawetara sasi. Para penyerang ngerti banget babagan iki, mula butuh rencana B.
FragmentSmack/SegmentSmack. Solusi
Untunge, kanggo sawetara kerentanan, rencana B kasebut ana, lan diarani Workaround. Paling asring, iki minangka owah-owahan ing setelan kernel/aplikasi sing bisa nyilikake efek sing bisa ditindakake utawa ngilangi eksploitasi kerentanan.
Ing kasus FragmentSmack/SegmentSmack diusulake Solusi iki:
«Sampeyan bisa ngganti nilai standar 4MB lan 3MB ing net.ipv4.ipfrag_high_thresh lan net.ipv4.ipfrag_low_thresh (lan mitra kanggo ipv6 net.ipv6.ipfrag_high_thresh lan net.ipv6.ipfrag_low_thresh) dadi 256 kB utawa 192 kB. ngisor. Tes nuduhake tetes cilik nganti signifikan ing panggunaan CPU sajrone serangan gumantung saka hardware, setelan, lan kahanan. Nanging, bisa uga ana pengaruh kinerja amarga ipfrag_high_thresh=262144 bait, amarga mung rong fragmen 64K sing bisa pas karo antrian reassembly sekaligus. Contone, ana risiko yen aplikasi sing nggarap paket UDP gedhe bakal rusak".
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.
Kita ora duwe UDP gedhe ing layanan produksi. Ora ana lalu lintas fragmentasi ing LAN; ana lalu lintas fragmentasi ing WAN, nanging ora signifikan. Ora ana pratandha - sampeyan bisa muter Workaround!
FragmentSmack/SegmentSmack. getih pisanan
Masalah pisanan sing kita temokake yaiku kontaner awan kadhangkala mung ngetrapake setelan anyar mung sebagian (mung ipfrag_low_thresh), lan kadhangkala ora ditrapake - mung nabrak ing wiwitan. Ora bisa ngasilake masalah kanthi stabil (kabeh setelan diterapake kanthi manual tanpa ana kangelan). Ngerteni kenapa wadhah nabrak ing wiwitan uga ora gampang: ora ana kesalahan sing ditemokake. Siji bab tartamtu: muter maneh setelan solves masalah karo kacilakan wadhah.
Napa ora cukup kanggo ngetrapake Sysctl ing host? Wadhah kasebut manggon ing Namespace jaringan khusus dhewe, paling ora bagean saka paramèter Sysctl jaringan ing wadhah bisa beda-beda saka inang.
Kepiye carane setelan Sysctl ditrapake ing wadhah kasebut? Amarga wadhah kita ora duwe hak istimewa, sampeyan ora bakal bisa ngganti setelan Sysctl kanthi mlebu ing wadhah kasebut - sampeyan mung ora duwe hak sing cukup. Kanggo mbukak kontaner, awan kita ing wektu kasebut nggunakake Docker (saiki podho). Parameter wadhah anyar diterusake menyang Docker liwat API, kalebu setelan Sysctl sing dibutuhake.
Nalika nggoleki versi kasebut, ternyata API Docker ora ngasilake kabeh kesalahan (paling ora ing versi 1.10). Nalika nyoba miwiti wadhah kasebut liwat "docker run", pungkasane kita bisa ndeleng:
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.
Nilai parameter ora valid. Nanging kenapa? Lan kenapa ora sah mung kadhangkala? Pranyata Docker ora njamin supaya paramèter Sysctl ditrapake (versi paling anyar sing diuji yaiku 1.13.1), mula kadhangkala ipfrag_high_thresh nyoba disetel menyang 256K nalika ipfrag_low_thresh isih 3M, yaiku watesan ndhuwur luwih murah. saka watesan ngisor, kang mimpin kanggo kesalahan.
Ing wektu iku, kita wis nggunakake mekanisme dhewe kanggo reconfiguring wadhah sawise wiwitan (beku wadhah sawise freezer klompok lan nglakokaké printah ing namespace saka wadhah liwat ip net), lan kita uga nambahake paramèter Sysctl nulis ing bagean iki. Masalah iki ditanggulangi.
FragmentSmack/SegmentSmack. Darah Pertama 2
Sadurunge kita duwe wektu kanggo ngerti panggunaan Workaround ing méga, keluhan langka pisanan saka pangguna wiwit teka. Ing wektu iku, sawetara minggu wis liwati wiwit wiwitan nggunakake Workaround ing server pisanan. Penyelidikan awal nuduhake yen keluhan ditampa marang layanan individu, lan ora kabeh server layanan kasebut. Masalah wis maneh dadi arang banget ora mesthi.
Kaping pisanan, kita, mesthi, nyoba nggulung maneh setelan Sysctl, nanging iki ora ana pengaruhe. Macem-macem manipulasi karo setelan server lan aplikasi uga ora mbantu. Reboot mbantu. Urip maneh Linux ora wajar kaya biasane kanggo Windows ing jaman biyen. Nanging, iku mbantu, lan kita chalked munggah menyang "kernel glitch" nalika nglamar setelan anyar ing Sysctl. Carane sembrono iku ...
Telung minggu sabanjure masalah kasebut bola-bali. Konfigurasi server kasebut cukup prasaja: Nginx ing mode proxy/balancer. Ora akeh lalu lintas. Cathetan pambuko anyar: jumlah 504 kesalahan ing klien saya tambah saben dina (Wektu Mati Gateway). Grafik kasebut nuduhake jumlah kesalahan 504 saben dina kanggo layanan iki:
Kabeh kesalahan ana babagan backend sing padha - babagan sing ana ing méga. Grafik konsumsi memori kanggo fragmen paket ing backend iki katon kaya iki:
Iki minangka salah sawijining manifestasi sing paling jelas saka masalah ing grafik sistem operasi. Ing méga, mung ing wektu sing padha, masalah jaringan liyane karo setelan QoS (Traffic Control) wis diatasi. Ing grafik konsumsi memori kanggo fragmen paket, katon padha:
Asumsi kasebut prasaja: yen padha katon ing grafik, mula duwe alasan sing padha. Kajaba iku, masalah karo jinis memori iki arang banget.
Inti masalah tetep yaiku nggunakake panjadwal paket fq kanthi setelan gawan ing QoS. Kanthi gawan, kanggo siji sambungan, sampeyan bisa nambah 100 paket menyang antrian, lan sawetara sambungan, ing kahanan kekurangan saluran, wiwit clog antrian kanggo kapasitas. Ing kasus iki, paket dibuwang. Ing tc statistics (tc -s qdisc) bisa dideleng kaya mangkene:
"464545 flows_plimit" iku paket dropped amarga ngluwihi watesan antrian siji sambungan, lan "dropped 464545" iku jumlah kabeh paket dropped saka panjadwal iki. Sawise nambah dawa antrian nganti 1 ewu lan miwiti maneh kontaner, masalah kasebut mandheg. Sampeyan bisa lungguhan lan ngombe smoothie.
FragmentSmack/SegmentSmack. Darah Pungkasan
Pisanan, sawetara sasi sawise woro-woro kerentanan ing kernel, fix kanggo FragmentSmack pungkasane katon (ayo kula ngelingake sampeyan yen bebarengan karo woro-woro ing Agustus, fix mung kanggo SegmentSmack dirilis), sing menehi kita kesempatan kanggo ninggalake Workaround, kang nyebabake kita cukup akèh alangan. Sajrone wektu iki, kita wis bisa nransfer sawetara server menyang kernel anyar, lan saiki kita kudu miwiti saka wiwitan. Napa kita nganyari kernel tanpa ngenteni fix FragmentSmack? Kasunyatane yaiku proses nglindhungi kerentanan kasebut pas (lan digabung) karo proses nganyari CentOS dhewe (sing mbutuhake wektu luwih akeh tinimbang nganyari kernel). Kajaba iku, SegmentSmack minangka kerentanan sing luwih mbebayani, lan solusi kasebut katon langsung, mula bisa uga. Nanging, kita ora bisa mung nganyari kernel ing CentOS amarga kerentanan FragmentSmack, sing muncul sajrone CentOS 7.5, mung didandani ing versi 7.6, mula kita kudu mungkasi nganyari menyang 7.5 lan miwiti maneh kanthi nganyari 7.6. Lan iki uga kedadeyan.
Kapindho, keluhan pangguna langka babagan masalah wis bali menyang kita. Saiki kita wis ngerti manawa kabeh ana hubungane karo unggahan file saka klien menyang sawetara server kita. Kajaba iku, jumlah unggahan sing sithik banget saka total massa ngliwati server kasebut.
Nalika kita ngelingi saka crita ing ndhuwur, muter maneh Sysctl ora mbantu. Urip maneh mbantu, nanging sementara.
Dugaan babagan Sysctl ora dibusak, nanging wektu iki perlu kanggo ngumpulake informasi sabisa. Ana uga kekurangan kemampuan kanggo ngasilake masalah unggahan ing klien supaya bisa sinau kanthi luwih tepat apa sing kedadeyan.
Analisis kabeh statistik lan log sing kasedhiya ora nggawa kita luwih cedhak kanggo ngerteni apa sing kedadeyan. Ana kekurangan akut kemampuan kanggo ngasilake masalah kasebut supaya "ngrasakake" sambungan tartamtu. Pungkasan, para pangembang, nggunakake versi aplikasi khusus, bisa ngrampungake masalah reproduksi stabil ing piranti uji nalika disambungake liwat Wi-Fi. Iki minangka terobosan ing penyelidikan. Klien disambungake menyang Nginx, sing diproksi menyang backend, yaiku aplikasi Java kita.
Dialog kanggo masalah kaya iki (didandani ing sisih proxy Nginx):
Klien: njaluk nampa informasi babagan ngundhuh file.
server Jawa: respon.
Klien: POST karo file.
Server Jawa: kesalahan.
Ing wektu sing padha, server Java nulis menyang log yen 0 bita data ditampa saka klien, lan proxy Nginx nulis yen panjaluk kasebut njupuk luwih saka 30 detik (30 detik minangka wektu entek aplikasi klien). Napa wektu entek lan kenapa 0 bita? Saka perspektif HTTP, kabeh bisa digunakake, nanging POST karo file katon ilang saka jaringan. Kajaba iku, ilang ing antarane klien lan Nginx. Iku wektu kanggo lengen dhewe karo Tcpdump! Nanging pisanan sampeyan kudu ngerti konfigurasi jaringan. Proksi Nginx ana ing mburi keseimbangan L3 NFware. Tunneling digunakake kanggo ngirim paket saka balancer L3 menyang server, sing nambah header menyang paket:
Ing kasus iki, jaringan teka ing server iki ing wangun lalu lintas sing diwenehi tag Vlan, sing uga nambah kolom dhewe menyang paket:
Lan lalu lintas iki uga bisa dipérang (persentase cilik saka lalu lintas pecahan sing padha sing diomongake nalika ngevaluasi risiko saka Workaround), sing uga ngganti isi header:
Sawise maneh: paket dibungkus nganggo tag Vlan, dibungkus karo trowongan, dipérang. Kanggo luwih ngerti kepiye kedadeyan kasebut, ayo nglacak rute paket saka klien menyang proxy Nginx.
Paket kasebut tekan keseimbangan L3. Kanggo nuntun sing bener ing pusat data, paket kasebut dibungkus ing trowongan lan dikirim menyang kertu jaringan.
Amarga header paket + trowongan ora cocog karo MTU, paket kasebut dipotong dadi pecahan lan dikirim menyang jaringan.
Ngalih sawise balancer L3, nalika nampa paket, nambah tag Vlan lan dikirim ing.
Ngalih ing ngarep proxy Nginx sumerep (adhedhasar setelan port) sing server wis dikarepake paket Vlan-encapsulated, supaya ngirim minangka, tanpa mbusak tag Vlan.
Linux njupuk fragmen paket individu lan nggabungake dadi siji paket gedhe.
Sabanjure, paket tekan antarmuka Vlan, ing ngendi lapisan pisanan dibusak saka iku - enkapsulasi Vlan.
Linux banjur dikirim menyang antarmuka Tunnel, ing ngendi lapisan liyane dibusak saka iku - enkapsulasi Tunnel.
Kangelan iku kanggo pass kabeh iki minangka paramèter kanggo tcpdump.
Ayo dadi miwiti saka mburi: ana resik (tanpa header rasah) paket IP saka klien, karo vlan lan trowongan enkapsulasi dibusak?
tcpdump host <ip клиента>
Ora, ora ana paket kasebut ing server. Dadi masalah kudu ana sadurunge. Apa ana paket sing mung enkapsulasi Vlan sing dibusak?
tcpdump ip[32:4]=0xx390x2xx
0xx390x2xx minangka alamat IP klien ing format hex.
32:4 — alamat lan dawa lapangan kang SCR IP ditulis ing paket Tunnel.
Alamat lapangan kudu dipilih kanthi brute force, amarga ing Internet nulis babagan 40, 44, 50, 54, nanging ora ana alamat IP ing kana. Sampeyan uga bisa ndeleng salah siji saka paket ing hex (parameter -xx utawa -XX ing tcpdump) lan ngetung alamat IP sampeyan ngerti.
Apa ana fragmen paket tanpa enkapsulasi Vlan lan Tunnel dibusak?
tcpdump ((ip[6:2] > 0) and (not ip[6] = 64))
Piandel iki bakal nuduhake kabeh fragmen, kalebu sing pungkasan. Mbokmenawa, bab sing padha bisa disaring dening IP, nanging aku ora nyoba, amarga ora akeh banget paket kasebut, lan sing dibutuhake gampang ditemokake ing aliran umum. Punika:
Iki minangka rong fragmen saka siji paket (ID padha 53652) kanthi foto (tembung Exif katon ing paket pisanan). Amarga kasunyatan sing ana paket ing tingkat iki, nanging ora ing wangun gabungan ing dumps, masalah cetha karo Déwan. Akhire ana bukti dokumenter iki!
Dekoder paket ora mbukak masalah sing bakal nyegah pambangunan kasebut. Nyoba ing kene: hpd.gasmi.net. Kaping pisanan, nalika sampeyan nyoba ngisi barang ing kana, dekoder ora seneng karo format paket. Ternyata ana sawetara ekstra rong oktet antarane Srcmac lan Ethertype (ora ana hubungane karo informasi fragmen). Sawise nyopot, decoder wiwit digunakake. Nanging, ora nuduhake masalah.
Apa wae sing bisa dikandhakake, ora ana sing ditemokake kajaba Sysctl. Kabeh sing isih ana yaiku golek cara kanggo ngenali server masalah supaya bisa ngerti skala lan mutusake tumindak luwih lanjut. Counter sing dibutuhake ditemokake kanthi cepet:
"Jumlah kegagalan sing dideteksi dening algoritma perakitan ulang IP (kanggo alesan apa wae: wektu entek, kesalahan, lsp.)."
Antarane klompok server sing masalah sinau, ing loro counter iki tambah luwih cepet, ing loro luwih alon, lan loro liyane ora nambah ing kabeh. Mbandhingake dinamika counter iki karo dinamika kesalahan HTTP ing server Jawa dicethakaké korélasi. Tegese, meter bisa dipantau.
Nduwe indikator masalah sing bisa dipercaya iku penting banget supaya sampeyan bisa nemtokake kanthi akurat apa Sysctl bisa mbantu, amarga saka crita sadurunge kita ngerti manawa iki ora bisa langsung dingerteni saka aplikasi kasebut. Indikator iki bakal ngidini kita ngenali kabeh area masalah ing produksi sadurunge pangguna nemokake.
Sawise mbatalake Sysctl, kesalahan ngawasi mandheg, mula sababe masalah kasebut kabukten, uga kasunyatan manawa rollback mbantu.
We mbalek maneh setelan fragmentasi ing server liyane, ngendi ngawasi anyar teka menyang muter, lan nang endi wae kita diparengake malah luwih memori kanggo pecahan saka sadurunge standar (iki statistik UDP, mundhut sebagean kang ora katon ing latar mburi umum). .
Pitakonan sing paling penting
Napa paket-paket dipecah-pecah ing penyeimbang L3 kita? Umume paket sing teka saka pangguna menyang penyeimbang yaiku SYN lan ACK. Ukuran paket kasebut cilik. Nanging amarga bagean saka paket kasebut akeh banget, ing latar mburi kita ora weruh anane paket gedhe sing wiwit pecah.
Alesane yaiku skrip konfigurasi sing rusak advmss ing server karo antarmuka Vlan (ana sawetara banget server karo lalu lintas diwenehi tag ing produksi nalika iku). Advmss ngidini kita ngirimake menyang klien informasi sing paket menyang arah kita kudu ukurane luwih cilik supaya sawise masang header trowongan kanggo wong-wong mau, padha ora kudu fragmented.
Napa Sysctl rollback ora mbantu, nanging urip maneh? Muter maneh Sysctl ngganti jumlah memori sing kasedhiya kanggo nggabungake paket. Ing wektu sing padha, ketoke kasunyatan banget kebanjiran memori kanggo pecahan mimpin kanggo slowdown saka sambungan, kang mimpin kanggo pecahan kang telat kanggo dangu ing antrian. Sing, proses tindak ing siklus.
Urip maneh ngresiki memori lan kabeh bali menyang urutan.
Apa bisa ditindakake tanpa Workaround? Ya, nanging ana risiko dhuwur ninggalake pangguna tanpa layanan yen ana serangan. Mesthine, panggunaan Workaround nyebabake macem-macem masalah, kalebu kalem salah sawijining layanan kanggo pangguna, nanging kita percaya yen tumindak kasebut dibenerake.
Many thanks kanggo Andrey Timofeev (atimofeyev) kanggo bantuan kanggo nindakake penyelidikan, uga Alexey Krenev (pirantix) - kanggo karya titanic nganyari Centos lan kernels ing server. Proses sing ing kasus iki kudu diwiwiti saka wiwitan kaping pirang-pirang, mulane nyeret nganti pirang-pirang wulan.