Często przed wdrożeniem produkcyjnym aplikacji potrzebujemy upewnić się, że mamy wytrasowane wszystkie połączenia sieciowe zgodnie z wymaganiami.
W większych firmach polityki na firewallu aplikowane są przez inne zespoły i aby uniknąć niepotrzebnego stresu, opóźnień czy nawet awarii lepiej upewnić się przed finalnym deploymentem czy aby na pewno ruch jest przepuszczony tak jak powinien.
Nie ma w tym raczej nic trudnego gdy mamy już działającą usługę z wystawionymi portami do której chcemy się połączyć…
co natomiast jeśli potrzebujemy sprawdzić reguły na firewallu jeszcze przed wdrożeniem? np. gdy przygotowujemy się kilka tygodni na jedną konkretną noc?
Pokażę dzisiaj kilka ciekawych praktyk, które z pewnością przydadzą Wam się w przyszłości 🙂
Gdy jest już wystawiony port który chcemy sprawdzić zwykle wykorzystujemy do tego starego, poczciwego telneta:
[root@client~]# telnet server.local 443
ale to tylko jeden ze sposobów, jako alternatywę możemy użyć netcata:
[root@client~]# nc -zv -w3 server.local 443
wytłumaczenie parametrów i więcej możliwości możecie znaleźć tutaj – https://linux.die.net/man/1/nc
szczerze mówiąc jest to opcja do której najczęściej sięgam, największa przewaga jest taka, że w parametrze „-w” możemy podać ilość sekund po których dostaniemy timeout.
Również w przypadku pomyślnego skanu od razu dostajemy odpowiedź (bez czekania na input do przesłania). Dzięki temu możemy łatwo i przyjemnie wykorzystywać nc w swoich skryptach.
zajawka:
[root@client~]# for port in {80..82}; do nc -zv -w3 wp.pl ${port} &> /dev/null && echo "${port}/tcp - sukces" || echo "${port}/tcp - timeout"; done
80/tcp - sukces
81/tcp - timeout
82/tcp - timeout
[root@client~]# for node in {01..10}; do nc -zv -w3 azure-www-${node}.local 443 &> /dev/null && echo "--443/tcp--> azure-www-${node}.local - sukces" || echo "--443/tcp--> azure-www-${node}.local - timeout"; done
--443/tcp--> azure-www-01.local - sukces
--443/tcp--> azure-www-02.local - timeout
--443/tcp--> azure-www-03.local - sukces
--443/tcp--> azure-www-04.local - timeout
--443/tcp--> azure-www-05.local - sukces
--443/tcp--> azure-www-06.local - timeout
--443/tcp--> azure-www-07.local - sukces
--443/tcp--> azure-www-08.local - timeout
--443/tcp--> azure-www-09.local - sukces
--443/tcp--> azure-www-10.local - timeout
mało kto wie, ale w przypadku gdy debugujemy np. kontenery i nie mamy dostępu do pobrania pakietów możemy do przetestowania połączenia wykorzystać CURLa, który często jest preinstalowany w obrazie 🙂 (ping to bardzo słaby sposób na testowanie połączenia)
jeżeli zależy nam na połączeniu HTTP/HTTPS możemy po prostu sprawdzić:
[root@client~]# curl server.local:443
lub jeżeli chcemy sprawdzić dowolny port TCP możemy użyć:
[root@client~]# curl -v telnet://server.local:9200
co natomiast gdy nie mamy jeszcze otwartego portu a chcemy sprawdzić czy firewall wewnętrzny/zewnętrzny przepuści nas na drugi serwer 🤔? możemy tymczasowo otworzyć taki port 😎 używając wcześniej wspomnianego netcata – służy do tego polecenie:
[root@server~]# nc -l -p 8080
w ten sposób otwieramy port i rozpoczynamy na nim nasłuchiwanie
(pamiętaj, że porty < 1024 są uprzywilejowane i nie otworzymy ich bez podniesienia uprawnień)
na drugim serwerze możemy spróbować nawiązać połączenie, a nawet przesłać dane
[root@client~]# telnet 127.0.0.1 8080
Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is '^]'.
testor inwestor :)
co tak jest widoczne na serwerze z otwartym portem
[root@server~]# nc -l -p 8080
testor inwestor :)
(tym sposobem możemy zrobić reverse shell ;))

DNS – w przypadku problemów sieciowych nauczony doświadczeniem polecam sprawdzić na jakie adresy rozwiązuje się dany endpoint do którego próbujemy się połączyć.
przeszkodą może być zostawienie starego adresu IP w rekordzie A, przez co losowy „strzał” do endpointu kończy się timeoutem 😫
gdy korzystamy z load balancerów schowanych na przykład za GTM od F5 (więcej info tutaj) musimy pamiętać o wytrasowaniu się do wszystkich adresów IP loadbalancerów, które GTM może nam zaserwować, w przeciwnym wypadku wykorzystując balansowanie round-robin co drugi request będzie się timeoutował (a w przypadku global availability przestanie nam działać połączenie po przepięciu się do drugiej serwerowni 🙂)
na sam koniec zostawiłem narzędzia które często pomogły mi znaleźć przyczynę gdy nie miałem już żadnych pomysłów
mam na myśli lsof, strace i tcpdump
polecenie lsof standardowo pokazuje otwarte pliki (co też jest przydatne, ale nie w tym wpisie)
natomiast z przełącznikiem -i wyświetla listę nawiązanych w danym momencie połączeń sieciowych na serwerze
[root@server~]# lsof -i
...
dnf 26754 root 24u IPv4 181335 0t0 TCP serwer.local:59472->proxy14.fedoraproject.org:https (ESTABLISHED)
...
w ten sposób możemy zobaczyć kto aktualnie jest podłączony do serwera np. po http/https/ssh/…
do jakich adresów serwer nawiązuje połączenie (np. przy pobieraniu pakietów)
narzędzie strace – pozwala na wyświetlenie wywołań systemowych (baardzo przydatne polecenie, natomiast jego wynik należy traktować bardziej jako źródło do grepowania, niż do czytania w całości)
dodając do niego parametr „-e” możemy podpiąć się pod konkretne wywołanie systemowe (w tym przypadku będziemy korzystać z connect)
flaga „-f” oznacza natomiast, że chcemy podpinać się pod forki procesu
[root@client~]# strace -e connect mysql -h serwer.local
...
connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("8.8.8.8")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("192.168.0.11")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("10.11.0.1")}, 16) = 0
REFUSED (Connection refused)
connect(3, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("192.168.0.11")}, 16) = 0
ERROR 1045 (28000): Access denied for user 'root'@'192.168.0.11' (using password: NO)
możemy podpiąć się stracem pod komende lub wywołać binarkę i prześwietlić do jakich konkretnie adresów IP „uderza” aplikacja.
komanda o szerokim zastosowaniu, jednym z nich może być określenie do jakiego adresu IP klastra bazy danych łączy się binarka (gdy przykładowo wykorzystujemy MSSQL i MultiSubnetFailover=True).
ostatnie narzędzie w tym wpisie o którym chciałbym powiedzieć/przypomnieć to tcpdump.
choć pewnie większości bardzo dobrze znane, nie mogło go tutaj zabraknąć.
służy do odpalenia nasłuchiwania na karcie sieciowej i pozwala zrzucać pakiety do pliku w celu ich późniejszej analizy.
Największą zaletą tego narzędzia jest surowy wynik, który możemy odpalić w WireSharku i w czytelniejszej formie filtrować, analizować niskopoziomowe pakiety. „Surówka” daje nam też możliwość przesłania zebranej komunikacji sieciowej do sieciowców w celu głębszej analizy.