Simuleer netwerkprobleme in Linux

Hallo almal, my naam is Sasha, ek lei backend-toetse by FunCorp. Ons het, soos baie ander, 'n diensgerigte argitektuur geïmplementeer. Aan die een kant vergemaklik dit die werk, want... Dit is makliker om elke diens afsonderlik te toets, maar aan die ander kant is daar 'n behoefte om die interaksie van dienste met mekaar te toets, wat dikwels oor die netwerk plaasvind.

In hierdie artikel sal ek praat oor twee nutsprogramme wat gebruik kan word om basiese scenario's na te gaan wat die werking van 'n toepassing beskryf in die teenwoordigheid van netwerkprobleme.

Simuleer netwerkprobleme in Linux

Simuleer netwerkprobleme

Tipies word sagteware op toetsbedieners met 'n goeie internetverbinding getoets. In moeilike produksie-omgewings is dinge dalk nie so glad nie, so soms moet jy programme in swak verbindingstoestande toets. Op Linux sal die hulpprogram help met die taak om sulke toestande te simuleer tc.

tc(abbr. van Verkeersbeheer) laat jou toe om die oordrag van netwerkpakkies in die stelsel op te stel. Hierdie program het uitstekende vermoëns, jy kan meer daaroor lees hier. Hier sal ek slegs 'n paar van hulle oorweeg: ons stel belang in verkeerskedulering, waarvoor ons gebruik qskyf, en aangesien ons 'n onstabiele netwerk moet naboots, sal ons klaslose qdisc gebruik netem.

Kom ons begin 'n eggo-bediener op die bediener (ek het nmap-ncat):

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

Om al die tydstempels by elke stap van interaksie tussen die kliënt en die bediener in detail te vertoon, het ek 'n eenvoudige Python-skrip geskryf wat 'n versoek stuur Toets na ons eggo-bediener.

Kliënt bronkode

#!/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

Kom ons begin dit en kyk na die verkeer op die koppelvlak lo en poort 12345:

[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

Verkeershoop

[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

Alles is standaard: 'n drierigting-handdruk, PSH/ACK en ACK in reaksie twee keer - dit is die uitruil van versoek en reaksie tussen die kliënt en bediener, en FIN/ACK en ACK twee keer - voltooi die verbinding.

Pakkie vertraging

Kom ons stel nou die vertraging op 500 millisekondes:

tc qdisc add dev lo root netem delay 500ms

Ons begin die kliënt en sien dat die skrip nou vir 2 sekondes loop:

[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

Wat is in die verkeer? Kom ons kyk:

Verkeershoop

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

U kan sien dat die verwagte vertraging van 'n halwe sekonde in die interaksie tussen die kliënt en die bediener verskyn het. Die stelsel tree baie interessanter op as die vertraging groter is: die kern begin om sommige TCP-pakkies weer te stuur. Kom ons verander die vertraging na 1 sekonde en kyk na die verkeer (ek sal nie die kliënt se uitset wys nie, daar is die verwagte 4 sekondes in totale duur):

tc qdisc change dev lo root netem delay 1s

Verkeershoop

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

Dit kan gesien word dat die kliënt 'n SYN-pakkie twee keer gestuur het, en die bediener het twee keer 'n SYN/ACK gestuur.

Benewens 'n konstante waarde, kan die vertraging ingestel word op 'n afwyking, 'n verspreidingsfunksie en 'n korrelasie (met die waarde vir die vorige pakkie). Dit word soos volg gedoen:

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

Hier het ons die vertraging tussen 100 en 900 millisekondes gestel, die waardes sal gekies word volgens 'n normale verspreiding en daar sal 'n 50% korrelasie wees met die vertragingswaarde vir die vorige pakkie.

Jy het dalk opgemerk dat in die eerste opdrag wat ek gebruik het voeg, en dan verander. Die betekenis van hierdie opdragte is voor die hand liggend, so ek sal net byvoeg dat daar meer is del, wat gebruik kan word om die konfigurasie te verwyder.

Pakkie verlies

Kom ons probeer nou om pakkieverlies te doen. Soos uit die dokumentasie gesien kan word, kan dit op drie maniere gedoen word: pakkies willekeurig met 'n mate van waarskynlikheid verloor, 'n Markov-ketting van 2, 3 of 4 state gebruik om pakkieverlies te bereken, of die Elliott-Gilbert-model te gebruik. In die artikel sal ek die eerste (eenvoudigste en mees voor die hand liggende) metode oorweeg, en jy kan oor ander lees hier.

Kom ons maak die verlies van 50% van pakkies met 'n korrelasie van 25%:

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

Ongelukkig, tcpdump sal nie vir ons die verlies van pakkies duidelik kan wys nie, ons sal net aanvaar dat dit regtig werk. En die verhoogde en onstabiele looptyd van die skrif sal ons help om dit te verifieer. client.py (kan onmiddellik voltooi word, of miskien binne 20 sekondes), sowel as 'n groter aantal herversend pakkies:

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

Voeg geraas by pakkies

Benewens pakkieverlies, kan jy pakkieskade simuleer: geraas sal op 'n ewekansige pakkieposisie verskyn. Kom ons maak pakkieskade met 'n 50% waarskynlikheid en sonder korrelasie:

tc qdisc change dev lo root netem corrupt 50%

Ons loop die kliënt script (niks interessant daar nie, maar dit het 2 sekondes geneem om te voltooi), kyk na die verkeer:

Verkeershoop

[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

Dit kan gesien word dat sommige pakkies herhaaldelik gestuur is en daar is een pakkie met gebroke metadata: opsies [nop,onbekend-65 0x0a3dcf62eb3d,[slegte opsie]>. Maar die belangrikste ding is dat alles op die ou end reg gewerk het - TCP het sy taak hanteer.

Pakkie duplisering

Waarmee anders kan jy doen netem? Simuleer byvoorbeeld die omgekeerde situasie van pakkieverlies—pakkie duplisering. Hierdie opdrag neem ook 2 argumente: waarskynlikheid en korrelasie.

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

Verander die volgorde van pakkette

Jy kan die sakke op twee maniere meng.

In die eerste word sommige pakkies onmiddellik gestuur, die res met 'n bepaalde vertraging. Voorbeeld uit die dokumentasie:

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

Met 'n waarskynlikheid van 25% (en 'n korrelasie van 50%) sal die pakkie onmiddellik gestuur word, die res sal met 'n vertraging van 10 millisekondes gestuur word.

Die tweede metode is wanneer elke Nde pakkie onmiddellik gestuur word met 'n gegewe waarskynlikheid (en korrelasie), en die res met 'n gegewe vertraging. Voorbeeld uit die dokumentasie:

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

Elke vyfde pakket het 'n 25%-kans om sonder versuim gestuur te word.

Verandering van bandwydte

Gewoonlik oral waarna hulle verwys TBF, maar met die hulp netem U kan ook die koppelvlakbandwydte verander:

tc qdisc change dev lo root netem rate 56kbit

Hierdie span sal rondtrekke maak localhost so pynlik soos om op die internet te surf via 'n inbelmodem. Benewens die stel van die bitsnelheid, kan jy ook die skakellaagprotokolmodel naboots: stel die bokoste vir die pakkie, die selgrootte en die bokoste vir die sel in. Dit kan byvoorbeeld nageboots word ATM en bitsnelheid 56 kbit/sek:

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

Simuleer verbinding-time-out

Nog 'n belangrike punt in die toetsplan wanneer sagteware aanvaar word, is time-outs. Dit is belangrik omdat in verspreide stelsels, wanneer een van die dienste gedeaktiveer is, die ander betyds na die ander moet terugval of 'n fout aan die kliënt moet terugstuur, en in geen geval moet hulle bloot hang, wag vir 'n antwoord of 'n verbinding nie. gestig te word.

Daar is verskeie maniere om dit te doen: gebruik byvoorbeeld 'n bespotting wat nie reageer nie, of koppel aan die proses deur 'n ontfouter te gebruik, plaas 'n breekpunt op die regte plek en stop die proses (dit is waarskynlik die mees perverse manier). Maar een van die mees voor die hand liggende is vir firewall-poorte of -gashere. Dit sal ons hiermee help iptables.

Vir demonstrasie sal ons firewall-poort 12345 en ons kliëntskrip laat loop. Jy kan uitgaande pakkies na hierdie poort firewall by die sender of inkomende pakkies by die ontvanger. In my voorbeelde sal inkomende pakkies firewalled wees (ons gebruik ketting INPUT en die opsie --dport). Sulke pakkies kan DROP, REJECT of REJECT wees met die TCP-vlag RST, of met ICMP-gasheer onbereikbaar (in werklikheid is die verstekgedrag icmp-poort-onbereikbaar, en daar is ook die geleentheid om 'n antwoord te stuur icmp-net-onbereikbaar, icmp-proto-onbereikbaar, icmp-net-verbied и icmp-gasheer-verbied).

DROP

As daar 'n reël met DROP is, sal pakkies eenvoudig "verdwyn".

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

Ons begin die kliënt en sien dat dit vries op die stadium van koppeling aan die bediener. Kom ons kyk na die verkeer:
Verkeershoop

[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

Dit kan gesien word dat die kliënt SYN-pakkies stuur met 'n eksponensieel toenemende time-out. So ons het 'n klein fout in die kliënt gevind: jy moet die metode gebruik settime-out()om die tyd te beperk waartydens die kliënt sal probeer om aan die bediener te koppel.

Ons verwyder onmiddellik die reël:

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

Jy kan alle reëls gelyktydig uitvee:

iptables -F

As jy Docker gebruik en jy moet alle verkeer wat na die houer gaan firewall, dan kan jy dit soos volg doen:

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

VERWERP

Kom ons voeg nou 'n soortgelyke reël by, maar met VERWERP:

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

Die kliënt gaan na 'n sekonde uit met 'n fout [Errno 111] Verbinding geweier. Kom ons kyk na die ICMP-verkeer:

[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

Dit kan gesien word dat die kliënt twee keer ontvang het hawe onbereikbaar en toe geëindig met 'n fout.

VERWERP met tcp-reset

Kom ons probeer om die opsie by te voeg --verwerp-met tcp-terugstel:

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

In hierdie geval gaan die kliënt onmiddellik uit met 'n fout, want die eerste versoek het 'n RST-pakkie ontvang:

[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

VERWERP met icmp-gasheer-onbereikbaar

Kom ons probeer 'n ander opsie om REJECT te gebruik:

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

Die kliënt gaan na 'n sekonde uit met 'n fout [Errno 113] Geen roete na gasheer nie, sien ons in ICMP-verkeer ICMP-gasheer 127.0.0.1 onbereikbaar.

Jy kan ook die ander REJECT-parameters probeer, en ek sal daarop fokus :)

Simuleer versoek-uitteltyd

'n Ander situasie is wanneer die kliënt aan die bediener kon koppel, maar nie 'n versoek daarna kan stuur nie. Hoe om pakkies te filter sodat die filter nie dadelik begin nie? As jy na die verkeer van enige kommunikasie tussen die kliënt en die bediener kyk, sal jy opmerk dat wanneer 'n verbinding tot stand gebring word, slegs die SYN- en ACK-vlae gebruik word, maar wanneer data uitgeruil word, sal die laaste versoekpakket die PSH-vlag bevat. Dit word outomaties geïnstalleer om buffering te vermy. Jy kan hierdie inligting gebruik om 'n filter te skep: dit sal alle pakkies toelaat behalwe dié wat die PSH-vlag bevat. Die verbinding sal dus tot stand gebring word, maar die kliënt sal nie data na die bediener kan stuur nie.

DROP

Vir DROP sal die opdrag soos volg lyk:

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

Begin die kliënt en kyk na die verkeer:

Verkeershoop

[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

Ons sien dat die verbinding tot stand is en die kliënt kan nie data na die bediener stuur nie.

VERWERP

In hierdie geval sal die gedrag dieselfde wees: die kliënt sal nie die versoek kan stuur nie, maar sal ontvang ICMP 127.0.0.1 tcp-poort 12345 onbereikbaar en verhoog die tyd tussen versoekherindienings eksponensieel. Die opdrag lyk soos volg:

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

VERWERP met tcp-reset

Die opdrag lyk soos volg:

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

Ons weet dit reeds wanneer ons dit gebruik --verwerp-met tcp-terugstel die kliënt sal 'n RST-pakkie in reaksie ontvang, so die gedrag kan voorspel word: ontvangs van 'n RST-pakkie terwyl die verbinding tot stand is, beteken dat die sok aan die ander kant onverwags gesluit is, wat beteken dat die kliënt moet ontvang Verbinding teruggestel deur eweknie. Kom ons voer ons skrif uit en maak seker hiervan. En so sal die verkeer lyk:

Verkeershoop

[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

VERWERP met icmp-gasheer-onbereikbaar

Ek dink dit is reeds vir almal duidelik hoe die opdrag sal lyk :) Die kliënt se gedrag in hierdie geval sal effens anders wees as dié met 'n eenvoudige VERWERP: die kliënt sal nie die tydsduur tussen pogings om die pakkie weer te stuur, verhoog nie.

[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

Output

Dit is nie nodig om 'n spot te skryf om die interaksie van 'n diens met 'n gehang kliënt of bediener te toets nie; soms is dit genoeg om standaard nutsprogramme wat in Linux gevind word, te gebruik.

Die nutsprogramme wat in die artikel bespreek word, het selfs meer vermoëns as wat beskryf is, so jy kan met 'n paar van jou eie opsies vorendag kom om dit te gebruik. Persoonlik het ek altyd genoeg van waaroor ek geskryf het (trouens nog minder). As jy hierdie of soortgelyke nutsprogramme gebruik om in jou maatskappy te toets, skryf asseblief presies hoe. Indien nie, dan hoop ek dat u sagteware beter sal word as u besluit om dit te toets in toestande van netwerkprobleme deur die voorgestelde metodes te gebruik.

Bron: will.com

Voeg 'n opmerking