Hálózati problémák szimulálása Linux alatt

Üdvözlök mindenkit, a nevem Sasha, háttértesztelést vezetek a FunCorp-nál. Sok máshoz hasonlóan mi is szolgáltatás-orientált architektúrát valósítottunk meg. Ez egyrészt leegyszerűsíti a munkát, mert... Könnyebb az egyes szolgáltatásokat külön-külön tesztelni, másrészt azonban szükség van a szolgáltatások egymás közötti interakciójának tesztelésére, ami gyakran a hálózaton keresztül történik.

Ebben a cikkben két segédprogramról fogok beszélni, amelyek segítségével ellenőrizni lehet azokat az alapvető forgatókönyveket, amelyek leírják az alkalmazás működését hálózati problémák esetén.

Hálózati problémák szimulálása Linux alatt

Hálózati problémák szimulálása

A szoftvereket általában jó internetkapcsolattal rendelkező tesztszervereken tesztelik. Kíméletlen termelési környezetben a dolgok nem biztos, hogy olyan zökkenőmentesek, ezért néha rossz kapcsolati feltételek mellett kell tesztelni a programokat. Linuxon a segédprogram segít az ilyen feltételek szimulálásában tc.

tc(röv. a forgalomirányítástól) lehetővé teszi a hálózati csomagok átvitelének konfigurálását a rendszerben. Ez a segédprogram nagyszerű képességekkel rendelkezik, többet olvashat róluk itt. Itt csak néhányat fogok megfontolni közülük: minket a forgalom ütemezése érdekel, erre használjuk qdisc, és mivel instabil hálózatot kell emulálnunk, osztály nélküli qdisc-et fogunk használni netem.

Indítsunk el egy echo szervert a szerveren (én nmap-ncat):

ncat -l 127.0.0.1 12345 -k -c 'xargs -n1 -i echo "Response: {}"'

Annak érdekében, hogy az összes időbélyeget részletesen megjelenítsem az ügyfél és a szerver közötti interakció minden egyes lépésében, írtam egy egyszerű Python-szkriptet, amely kérést küld. Teszt visszhangszerverünkre.

Kliens forráskódja

#!/bin/python

import socket
import time

HOST = '127.0.0.1'
PORT = 12345
BUFFER_SIZE = 1024
MESSAGE = "Testn"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
t1 = time.time()
print "[time before connection: %.5f]" % t1
s.connect((HOST, PORT))
print "[time after connection, before sending: %.5f]" % time.time()
s.send(MESSAGE)
print "[time after sending, before receiving: %.5f]" % time.time()
data = s.recv(BUFFER_SIZE)
print "[time after receiving, before closing: %.5f]" % time.time()
s.close()
t2 = time.time()
print "[time after closing: %.5f]" % t2
print "[total duration: %.5f]" % (t2 - t1)

print data

Indítsuk el és nézzük meg a forgalmat a felületen lo és 12345-ös port:

[user@host ~]# python client.py
[time before connection: 1578652979.44837]
[time after connection, before sending: 1578652979.44889]
[time after sending, before receiving: 1578652979.44894]
[time after receiving, before closing: 1578652979.45922]
[time after closing: 1578652979.45928]
[total duration: 0.01091]
Response: Test

Forgalmi dump

[user@host ~]# tcpdump -i lo -nn port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
10:42:59.448601 IP 127.0.0.1.54054 > 127.0.0.1.12345: Flags [S], seq 3383332866, win 43690, options [mss 65495,sackOK,TS val 606325685 ecr 0,nop,wscale 7], length 0
10:42:59.448612 IP 127.0.0.1.12345 > 127.0.0.1.54054: Flags [S.], seq 2584700178, ack 3383332867, win 43690, options [mss 65495,sackOK,TS val 606325685 ecr 606325685,nop,wscale 7], length 0
10:42:59.448622 IP 127.0.0.1.54054 > 127.0.0.1.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 606325685 ecr 606325685], length 0
10:42:59.448923 IP 127.0.0.1.54054 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 606325685 ecr 606325685], length 5
10:42:59.448930 IP 127.0.0.1.12345 > 127.0.0.1.54054: Flags [.], ack 6, win 342, options [nop,nop,TS val 606325685 ecr 606325685], length 0
10:42:59.459118 IP 127.0.0.1.12345 > 127.0.0.1.54054: Flags [P.], seq 1:15, ack 6, win 342, options [nop,nop,TS val 606325696 ecr 606325685], length 14
10:42:59.459213 IP 127.0.0.1.54054 > 127.0.0.1.12345: Flags [.], ack 15, win 342, options [nop,nop,TS val 606325696 ecr 606325696], length 0
10:42:59.459268 IP 127.0.0.1.54054 > 127.0.0.1.12345: Flags [F.], seq 6, ack 15, win 342, options [nop,nop,TS val 606325696 ecr 606325696], length 0
10:42:59.460184 IP 127.0.0.1.12345 > 127.0.0.1.54054: Flags [F.], seq 15, ack 7, win 342, options [nop,nop,TS val 606325697 ecr 606325696], length 0
10:42:59.460196 IP 127.0.0.1.54054 > 127.0.0.1.12345: Flags [.], ack 16, win 342, options [nop,nop,TS val 606325697 ecr 606325697], length 0

Minden szabványos: háromirányú kézfogás, PSH/ACK és ACK válaszként kétszer - ez a kérés és válasz cseréje a kliens és a szerver között, valamint kétszer FIN/ACK és ACK - a kapcsolat befejezése.

Csomag késleltetés

Most állítsuk be a késleltetést 500 ezredmásodpercre:

tc qdisc add dev lo root netem delay 500ms

Elindítjuk a klienst, és látjuk, hogy a szkript most 2 másodpercig fut:

[user@host ~]# ./client.py
[time before connection: 1578662612.71044]
[time after connection, before sending: 1578662613.71059]
[time after sending, before receiving: 1578662613.71065]
[time after receiving, before closing: 1578662614.72011]
[time after closing: 1578662614.72019]
[total duration: 2.00974]
Response: Test

Mi van a forgalomban? Nézzük:

Forgalmi dump

13:23:33.210520 IP 127.0.0.1.58694 > 127.0.0.1.12345: Flags [S], seq 1720950927, win 43690, options [mss 65495,sackOK,TS val 615958947 ecr 0,nop,wscale 7], length 0
13:23:33.710554 IP 127.0.0.1.12345 > 127.0.0.1.58694: Flags [S.], seq 1801168125, ack 1720950928, win 43690, options [mss 65495,sackOK,TS val 615959447 ecr 615958947,nop,wscale 7], length 0
13:23:34.210590 IP 127.0.0.1.58694 > 127.0.0.1.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 615959947 ecr 615959447], length 0
13:23:34.210657 IP 127.0.0.1.58694 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 615959947 ecr 615959447], length 5
13:23:34.710680 IP 127.0.0.1.12345 > 127.0.0.1.58694: Flags [.], ack 6, win 342, options [nop,nop,TS val 615960447 ecr 615959947], length 0
13:23:34.719371 IP 127.0.0.1.12345 > 127.0.0.1.58694: Flags [P.], seq 1:15, ack 6, win 342, options [nop,nop,TS val 615960456 ecr 615959947], length 14
13:23:35.220106 IP 127.0.0.1.58694 > 127.0.0.1.12345: Flags [.], ack 15, win 342, options [nop,nop,TS val 615960957 ecr 615960456], length 0
13:23:35.220188 IP 127.0.0.1.58694 > 127.0.0.1.12345: Flags [F.], seq 6, ack 15, win 342, options [nop,nop,TS val 615960957 ecr 615960456], length 0
13:23:35.720994 IP 127.0.0.1.12345 > 127.0.0.1.58694: Flags [F.], seq 15, ack 7, win 342, options [nop,nop,TS val 615961457 ecr 615960957], length 0
13:23:36.221025 IP 127.0.0.1.58694 > 127.0.0.1.12345: Flags [.], ack 16, win 342, options [nop,nop,TS val 615961957 ecr 615961457], length 0

Látható, hogy a várt fél másodperces késés megjelent a kliens és a szerver interakciójában. A rendszer sokkal érdekesebben viselkedik, ha nagyobb a késés: a kernel elkezdi újraküldeni néhány TCP-csomagot. Módosítsuk a késleltetést 1 másodpercre, és nézzük a forgalmat (a kliens kimenetét nem mutatom, ott van a várt 4 másodperc a teljes időtartamban):

tc qdisc change dev lo root netem delay 1s

Forgalmi dump

13:29:07.709981 IP 127.0.0.1.39306 > 127.0.0.1.12345: Flags [S], seq 283338334, win 43690, options [mss 65495,sackOK,TS val 616292946 ecr 0,nop,wscale 7], length 0
13:29:08.710018 IP 127.0.0.1.12345 > 127.0.0.1.39306: Flags [S.], seq 3514208179, ack 283338335, win 43690, options [mss 65495,sackOK,TS val 616293946 ecr 616292946,nop,wscale 7], length 0
13:29:08.711094 IP 127.0.0.1.39306 > 127.0.0.1.12345: Flags [S], seq 283338334, win 43690, options [mss 65495,sackOK,TS val 616293948 ecr 0,nop,wscale 7], length 0
13:29:09.710048 IP 127.0.0.1.39306 > 127.0.0.1.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 616294946 ecr 616293946], length 0
13:29:09.710152 IP 127.0.0.1.39306 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 616294947 ecr 616293946], length 5
13:29:09.711120 IP 127.0.0.1.12345 > 127.0.0.1.39306: Flags [S.], seq 3514208179, ack 283338335, win 43690, options [mss 65495,sackOK,TS val 616294948 ecr 616292946,nop,wscale 7], length 0
13:29:10.710173 IP 127.0.0.1.12345 > 127.0.0.1.39306: Flags [.], ack 6, win 342, options [nop,nop,TS val 616295947 ecr 616294947], length 0
13:29:10.711140 IP 127.0.0.1.39306 > 127.0.0.1.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 616295948 ecr 616293946], length 0
13:29:10.714782 IP 127.0.0.1.12345 > 127.0.0.1.39306: Flags [P.], seq 1:15, ack 6, win 342, options [nop,nop,TS val 616295951 ecr 616294947], length 14
13:29:11.714819 IP 127.0.0.1.39306 > 127.0.0.1.12345: Flags [.], ack 15, win 342, options [nop,nop,TS val 616296951 ecr 616295951], length 0
13:29:11.714893 IP 127.0.0.1.39306 > 127.0.0.1.12345: Flags [F.], seq 6, ack 15, win 342, options [nop,nop,TS val 616296951 ecr 616295951], length 0
13:29:12.715562 IP 127.0.0.1.12345 > 127.0.0.1.39306: Flags [F.], seq 15, ack 7, win 342, options [nop,nop,TS val 616297952 ecr 616296951], length 0
13:29:13.715596 IP 127.0.0.1.39306 > 127.0.0.1.12345: Flags [.], ack 16, win 342, options [nop,nop,TS val 616298952 ecr 616297952], length 0

Látható, hogy a kliens kétszer, a szerver pedig kétszer küldött SYN/ACK-t.

Az állandó érték mellett a késleltetés beállítható eltérésre, eloszlási függvényre és korrelációra (az előző csomag értékével). Ez a következőképpen történik:

tc qdisc change dev lo root netem delay 500ms 400ms 50 distribution normal

Itt 100 és 900 milliszekundum közé állítottuk a késleltetést, az értékek normál eloszlás szerint lesznek kiválasztva, és 50%-os korreláció lesz az előző csomag késleltetési értékével.

Talán észrevetted, hogy az első parancsban, amit használtam hozzá, és akkor változik. Ezeknek a parancsoknak a jelentése nyilvánvaló, ezért csak annyit teszek hozzá, hogy van még több del, amellyel eltávolítható a konfiguráció.

Csomagvesztés

Most próbáljuk meg a csomagvesztést. A dokumentációból látható, hogy ezt háromféleképpen lehet megtenni: csomagokat véletlenszerűen, bizonyos valószínűséggel elveszítve, 2, 3 vagy 4 állapotú Markov-láncot használva a csomagvesztés kiszámításához, vagy az Elliott-Gilbert modell segítségével. A cikkben az első (legegyszerűbb és legkézenfekvőbb) módszert fogom megvizsgálni, és olvashatsz másokról is itt.

Tegyük a csomagok 50%-ának elvesztését 25%-os korrelációval:

tc qdisc add dev lo root netem loss 50% 25%

Sajnos, tcpdump nem tudja egyértelműen megmutatni nekünk a csomagok elvesztését, csak feltételezzük, hogy valóban működik. A szkript megnövekedett és instabil futási ideje pedig segíteni fog ennek ellenőrzésében. client.py (azonnal, de akár 20 másodperc alatt is teljesíthető), valamint megnövekedett számú újraküldhető csomag:

[user@host ~]# netstat -s | grep retransmited; sleep 10; netstat -s | grep retransmited
    17147 segments retransmited
    17185 segments retransmited

Zaj hozzáadása a csomagokhoz

A csomagvesztésen kívül lehetőség van csomagkárosodás szimulálására is: a zaj egy véletlenszerű csomaghelyen jelenik meg. Tegyünk csomagsebzést 50%-os valószínűséggel és korreláció nélkül:

tc qdisc change dev lo root netem corrupt 50%

Lefuttatjuk a kliens szkriptet (nincs semmi érdekes, de 2 másodpercig tartott a befejezés), nézd meg a forgalmat:

Forgalmi dump

[user@host ~]# tcpdump -i lo -nn port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
10:20:54.812434 IP 127.0.0.1.43666 > 127.0.0.1.12345: Flags [S], seq 2023663770, win 43690, options [mss 65495,sackOK,TS val 1037001049 ecr 0,nop,wscale 7], length 0
10:20:54.812449 IP 127.0.0.1.12345 > 127.0.0.1.43666: Flags [S.], seq 2104268044, ack 2023663771, win 43690, options [mss 65495,sackOK,TS val 1037001049 ecr 1037001049,nop,wscale 7], length 0
10:20:54.812458 IP 127.0.0.1.43666 > 127.0.0.1.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 1037001049 ecr 1037001049], length 0
10:20:54.812509 IP 127.0.0.1.43666 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1037001049 ecr 1037001049], length 5
10:20:55.013093 IP 127.0.0.1.43666 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1037001250 ecr 1037001049], length 5
10:20:55.013122 IP 127.0.0.1.12345 > 127.0.0.1.43666: Flags [.], ack 6, win 342, options [nop,nop,TS val 1037001250 ecr 1037001250], length 0
10:20:55.014681 IP 127.0.0.1.12345 > 127.0.0.1.43666: Flags [P.], seq 1:15, ack 6, win 342, options [nop,nop,TS val 1037001251 ecr 1037001250], length 14
10:20:55.014745 IP 127.0.0.1.43666 > 127.0.0.1.12345: Flags [.], ack 15, win 340, options [nop,nop,TS val 1037001251 ecr 1037001251], length 0
10:20:55.014823 IP 127.0.0.1.43666 > 127.0.0.5.12345: Flags [F.], seq 2023663776, ack 2104268059, win 342, options [nop,nop,TS val 1037001251 ecr 1037001251], length 0
10:20:55.214088 IP 127.0.0.1.12345 > 127.0.0.1.43666: Flags [P.], seq 1:15, ack 6, win 342, options [nop,unknown-65 0x0a3dcf62eb3d,[bad opt]>
10:20:55.416087 IP 127.0.0.1.43666 > 127.0.0.1.12345: Flags [F.], seq 6, ack 15, win 342, options [nop,nop,TS val 1037001653 ecr 1037001251], length 0
10:20:55.416804 IP 127.0.0.1.12345 > 127.0.0.1.43666: Flags [F.], seq 15, ack 7, win 342, options [nop,nop,TS val 1037001653 ecr 1037001653], length 0
10:20:55.416818 IP 127.0.0.1.43666 > 127.0.0.1.12345: Flags [.], ack 16, win 343, options [nop,nop,TS val 1037001653 ecr 1037001653], length 0
10:20:56.147086 IP 127.0.0.1.12345 > 127.0.0.1.43666: Flags [F.], seq 15, ack 7, win 342, options [nop,nop,TS val 1037002384 ecr 1037001653], length 0
10:20:56.147101 IP 127.0.0.1.43666 > 127.0.0.1.12345: Flags [.], ack 16, win 342, options [nop,nop,TS val 1037002384 ecr 1037001653], length 0

Látható, hogy néhány csomagot többször is elküldtek, és van egy csomag hibás metaadatokkal: opciók [nop,unknown-65 0x0a3dcf62eb3d,[bad opt]>. De a lényeg az, hogy végül minden megfelelően működött - a TCP megbirkózott a feladatával.

Csomagmásolás

Mi mást lehet vele csinálni netem? Például szimulálja a csomagvesztés fordított helyzetét – a csomagduplikációt. Ez a parancs két argumentumot is használ: valószínűség és korreláció.

tc qdisc change dev lo root netem duplicate 50% 25%

A csomagok sorrendjének megváltoztatása

A zacskókat kétféleképpen keverheti össze.

Az elsőben néhány csomag azonnal, a többi meghatározott késleltetéssel kerül elküldésre. Példa a dokumentációból:

tc qdisc change dev lo root netem delay 10ms reorder 25% 50%

25%-os valószínűséggel (és 50%-os korrelációval) a csomag azonnal, a többi 10 ezredmásodperces késéssel kerül elküldésre.

A második módszer, amikor minden N-edik csomagot azonnal elküldjük adott valószínűséggel (és korrelációval), a többit pedig adott késleltetéssel. Példa a dokumentációból:

tc qdisc change dev lo root netem delay 10ms reorder 25% 50% gap 5

Minden ötödik csomag 25%-os eséllyel késedelem nélkül elküldésre kerül.

Sávszélesség módosítása

Általában mindenhol, ahová hivatkoznak TBF, de a segítséggel netem Az interfész sávszélességét is módosíthatja:

tc qdisc change dev lo root netem rate 56kbit

Ez a csapat körbe fog túrázni localhost olyan fájdalmas, mint a betárcsázós modemen keresztül való internetezés. A bitsebesség beállítása mellett emulálhatja a kapcsolati réteg protokoll modelljét is: állítsa be a csomag többletköltségét, a cella méretét és a cella többletköltségét. Például ez szimulálható ATM és bitráta 56 kbit/sec:

tc qdisc change dev lo root netem rate 56kbit 0 48 5

A kapcsolat időtúllépésének szimulálása

A tesztterv másik fontos pontja a szoftverek elfogadásakor az időtúllépések. Ez azért fontos, mert az elosztott rendszerekben az egyik szolgáltatás letiltásakor a többinek időben vissza kell esnie a többihez, vagy hibát kell visszaadnia a kliensnek, és semmi esetre sem szabad egyszerűen lefagyni, válaszra vagy csatlakozásra várva. létre kell hozni.

Ennek többféle módja is van: például használj egy ál-módot, amely nem válaszol, vagy csatlakozz a folyamathoz egy hibakereső segítségével, tegyél egy töréspontot a megfelelő helyre, és állítsd le a folyamatot (valószínűleg ez a legperverzebb módszer). De az egyik legnyilvánvalóbb a tűzfal portjai vagy gazdagépei. Ebben segíteni fog nekünk iptables.

A demonstrációhoz a tűzfal 12345-ös portját használjuk, és lefuttatjuk az ügyfélszkriptünket. A kimenő csomagokat erre a portra a feladónál, a bejövő csomagokat pedig a fogadónál tűzfalazhatja. Példáimban a bejövő csomagok tűzfallal lesznek védettek (a lánc INPUT-ot és az opciót használjuk --dport). Az ilyen csomagok lehetnek DROP, REJECT vagy REJECT RST TCP jelzővel, vagy elérhetetlen ICMP gazdagépekkel (valójában az alapértelmezett viselkedés icmp-port-unreachable, és lehetőség van válasz küldésére is icmp-net-unreachable, icmp-proto-unreachable, icmp-net tiltva и icmp-host-inhibited).

DROP

Ha van szabály a DROP-pal, a csomagok egyszerűen „eltűnnek”.

iptables -A INPUT -p tcp --dport 12345 -j DROP

Elindítjuk a klienst, és látjuk, hogy lefagy a szerverhez való csatlakozás szakaszában. Nézzük a forgalmat:
Forgalmi dump

[user@host ~]# tcpdump -i lo -nn port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
08:28:20.213506 IP 127.0.0.1.32856 > 127.0.0.1.12345: Flags [S], seq 3019694933, win 43690, options [mss 65495,sackOK,TS val 1203046450 ecr 0,nop,wscale 7], length 0
08:28:21.215086 IP 127.0.0.1.32856 > 127.0.0.1.12345: Flags [S], seq 3019694933, win 43690, options [mss 65495,sackOK,TS val 1203047452 ecr 0,nop,wscale 7], length 0
08:28:23.219092 IP 127.0.0.1.32856 > 127.0.0.1.12345: Flags [S], seq 3019694933, win 43690, options [mss 65495,sackOK,TS val 1203049456 ecr 0,nop,wscale 7], length 0
08:28:27.227087 IP 127.0.0.1.32856 > 127.0.0.1.12345: Flags [S], seq 3019694933, win 43690, options [mss 65495,sackOK,TS val 1203053464 ecr 0,nop,wscale 7], length 0
08:28:35.235102 IP 127.0.0.1.32856 > 127.0.0.1.12345: Flags [S], seq 3019694933, win 43690, options [mss 65495,sackOK,TS val 1203061472 ecr 0,nop,wscale 7], length 0

Látható, hogy a kliens exponenciálisan növekvő időtúllépéssel küld SYN csomagokat. Tehát találtunk egy kis hibát a kliensben: használni kell a módszert settimeout()korlátozza azt az időt, ameddig a kliens megpróbál csatlakozni a szerverhez.

Azonnal eltávolítjuk a szabályt:

iptables -D INPUT -p tcp --dport 12345 -j DROP

Az összes szabályt egyszerre törölheti:

iptables -F

Ha Dockert használ, és tűzfalra kell állítania a tárolóba érkező összes forgalmat, akkor ezt a következőképpen teheti meg:

iptables -I DOCKER-USER -p tcp -d CONTAINER_IP -j DROP

ELUTASÍT

Most adjunk hozzá egy hasonló szabályt, de REJECT-el:

iptables -A INPUT -p tcp --dport 12345 -j REJECT

A kliens egy másodperc múlva hibával kilép [Errno 111] A csatlakozás megtagadva. Nézzük az ICMP forgalmat:

[user@host ~]# tcpdump -i lo -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
08:45:32.871414 IP 127.0.0.1 > 127.0.0.1: ICMP 127.0.0.1 tcp port 12345 unreachable, length 68
08:45:33.873097 IP 127.0.0.1 > 127.0.0.1: ICMP 127.0.0.1 tcp port 12345 unreachable, length 68

Látható, hogy az ügyfél kétszer kapott a port elérhetetlen majd hibával ért véget.

ELUTASÍTÁS a tcp-reset segítségével

Próbáljuk meg hozzáadni a lehetőséget --reject-with tcp-reset:

iptables -A INPUT -p tcp --dport 12345 -j REJECT --reject-with tcp-reset

Ebben az esetben a kliens azonnal kilép hibával, mert az első kérés RST-csomagot kapott:

[user@host ~]# tcpdump -i lo -nn port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
09:02:52.766175 IP 127.0.0.1.60658 > 127.0.0.1.12345: Flags [S], seq 1889460883, win 43690, options [mss 65495,sackOK,TS val 1205119003 ecr 0,nop,wscale 7], length 0
09:02:52.766184 IP 127.0.0.1.12345 > 127.0.0.1.60658: Flags [R.], seq 0, ack 1889460884, win 0, length 0

ELUTASÍTÁS az icmp-host-unreachable segítségével

Próbáljunk ki egy másik lehetőséget a REJECT használatához:

iptables -A INPUT -p tcp --dport 12345 -j REJECT --reject-with icmp-host-unreachable

A kliens egy másodperc múlva hibával kilép [Errno 113] Nincs útvonal a gazdagéphez, látjuk az ICMP-forgalomban Az ICMP gazdagép 127.0.0.1 nem érhető el.

Kipróbálhatod a többi REJECT paramétert is, én ezekre fogok koncentrálni :)

A kérés időtúllépésének szimulálása

Egy másik helyzet az, amikor a kliens tudott csatlakozni a szerverhez, de nem tud kérést küldeni neki. Hogyan lehet a csomagokat szűrni, hogy a szűrés ne induljon el azonnal? Ha megnézzük a kliens és a szerver közötti bármilyen kommunikáció forgalmát, akkor észrevehetjük, hogy kapcsolat létesítésekor csak a SYN és ACK jelzőket használjuk, de adatcserénél az utolsó kéréscsomag tartalmazza a PSH jelzőt. A pufferelés elkerülése érdekében automatikusan települ. Ezt az információt felhasználhatja egy szűrő létrehozásához: az összes csomagot engedélyezi, kivéve azokat, amelyek a PSH jelzőt tartalmazzák. Így a kapcsolat létrejön, de a kliens nem tud adatokat küldeni a szervernek.

DROP

DROP esetén a parancs így néz ki:

iptables -A INPUT -p tcp --tcp-flags PSH PSH --dport 12345 -j DROP

Indítsa el a klienst, és figyelje a forgalmat:

Forgalmi dump

[user@host ~]# tcpdump -i lo -nn port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
10:02:47.549498 IP 127.0.0.1.49594 > 127.0.0.1.12345: Flags [S], seq 2166014137, win 43690, options [mss 65495,sackOK,TS val 1208713786 ecr 0,nop,wscale 7], length 0
10:02:47.549510 IP 127.0.0.1.12345 > 127.0.0.1.49594: Flags [S.], seq 2341799088, ack 2166014138, win 43690, options [mss 65495,sackOK,TS val 1208713786 ecr 1208713786,nop,wscale 7], length 0
10:02:47.549520 IP 127.0.0.1.49594 > 127.0.0.1.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 1208713786 ecr 1208713786], length 0
10:02:47.549568 IP 127.0.0.1.49594 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1208713786 ecr 1208713786], length 5
10:02:47.750084 IP 127.0.0.1.49594 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1208713987 ecr 1208713786], length 5
10:02:47.951088 IP 127.0.0.1.49594 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1208714188 ecr 1208713786], length 5
10:02:48.354089 IP 127.0.0.1.49594 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1208714591 ecr 1208713786], length 5

Azt látjuk, hogy a kapcsolat létrejött, és a kliens nem tud adatokat küldeni a szervernek.

ELUTASÍT

Ebben az esetben a viselkedés ugyanaz lesz: az ügyfél nem tudja elküldeni a kérést, de megkapja Az ICMP 127.0.0.1 tcp 12345-ös portja nem érhető el és exponenciálisan növeli a kérelmek újraküldése közötti időt. A parancs így néz ki:

iptables -A INPUT -p tcp --tcp-flags PSH PSH --dport 12345 -j REJECT

ELUTASÍTÁS a tcp-reset segítségével

A parancs így néz ki:

iptables -A INPUT -p tcp --tcp-flags PSH PSH --dport 12345 -j REJECT --reject-with tcp-reset

Ezt már használat közben is tudjuk --reject-with tcp-reset a kliens válaszul RST csomagot kap, így a viselkedés előre jelezhető: RST csomag fogadása a kapcsolat létrejötte közben azt jelenti, hogy a socket váratlanul bezárul a másik oldalon, ami azt jelenti, hogy a kliensnek meg kell kapnia A kapcsolat alaphelyzetbe állítása partner által. Futtassuk a forgatókönyvünket, és győződjünk meg erről. A forgalom pedig így fog kinézni:

Forgalmi dump

[user@host ~]# tcpdump -i lo -nn port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
10:22:14.186269 IP 127.0.0.1.52536 > 127.0.0.1.12345: Flags [S], seq 2615137531, win 43690, options [mss 65495,sackOK,TS val 1209880423 ecr 0,nop,wscale 7], length 0
10:22:14.186284 IP 127.0.0.1.12345 > 127.0.0.1.52536: Flags [S.], seq 3999904809, ack 2615137532, win 43690, options [mss 65495,sackOK,TS val 1209880423 ecr 1209880423,nop,wscale 7], length 0
10:22:14.186293 IP 127.0.0.1.52536 > 127.0.0.1.12345: Flags [.], ack 1, win 342, options [nop,nop,TS val 1209880423 ecr 1209880423], length 0
10:22:14.186338 IP 127.0.0.1.52536 > 127.0.0.1.12345: Flags [P.], seq 1:6, ack 1, win 342, options [nop,nop,TS val 1209880423 ecr 1209880423], length 5
10:22:14.186344 IP 127.0.0.1.12345 > 127.0.0.1.52536: Flags [R], seq 3999904810, win 0, length 0

ELUTASÍTÁS az icmp-host-unreachable segítségével

Azt hiszem, már mindenki számára nyilvánvaló, hogy fog kinézni a parancs :) A kliens viselkedése ebben az esetben kissé eltér egy egyszerű REJECT-től: a kliens nem fogja megnövelni az időtúllépést a csomag újraküldési kísérletei között.

[user@host ~]# tcpdump -i lo -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
10:29:56.149202 IP 127.0.0.1 > 127.0.0.1: ICMP host 127.0.0.1 unreachable, length 65
10:29:56.349107 IP 127.0.0.1 > 127.0.0.1: ICMP host 127.0.0.1 unreachable, length 65
10:29:56.549117 IP 127.0.0.1 > 127.0.0.1: ICMP host 127.0.0.1 unreachable, length 65
10:29:56.750125 IP 127.0.0.1 > 127.0.0.1: ICMP host 127.0.0.1 unreachable, length 65
10:29:56.951130 IP 127.0.0.1 > 127.0.0.1: ICMP host 127.0.0.1 unreachable, length 65
10:29:57.152107 IP 127.0.0.1 > 127.0.0.1: ICMP host 127.0.0.1 unreachable, length 65
10:29:57.353115 IP 127.0.0.1 > 127.0.0.1: ICMP host 127.0.0.1 unreachable, length 65

Teljesítmény

Nem szükséges egy gúnyt írni egy szolgáltatás interakciójának teszteléséhez egy leakasztott klienssel vagy szerverrel, néha elegendő a Linuxban található szabványos segédprogramok használata.

A cikkben tárgyalt segédprogramok még a leírtaknál is több képességgel rendelkeznek, így Ön saját maga is kitalálhatja ezeket a lehetőségeket. Nekem személy szerint mindig elegem van abból, amiről írtam (sőt, még kevésbé). Ha ilyen vagy hasonló segédprogramokat használ a tesztelés során a cégénél, kérjük, írja meg, hogyan pontosan. Ha nem, akkor remélem, hogy szoftvere jobb lesz, ha úgy dönt, hogy hálózati problémák esetén teszteli a javasolt módszerekkel.

Forrás: will.com

Hozzászólás