Netstat

A Unix/Linux szerverek üzemeltetése wikiből

A netstat egy minden Linux-rendszercsomagban megtalálható, parancssori, hálózati program arra, hogy megnézzük a hálózati konfigurációt és annak aktivitását. Képes mind a kimenő, mind a bejövő hálózati forgalom, a routing táblák és a hálózati interfészek statisztikájának megjelenítésére. Számos érdekes felhasználása lehet, csak néhány: képesek lehetünk vele például egy DoS támadás felderítésére, majd ezután letilthatjuk a támadó IP címét, vagy szkriptet írhatunk a napi, heti, havi forgalom kijelzésére esetleg annak kiderítésére, hogy épp kik kapcsolódnak hozzánk. Ha egy webszervert üzemeltetek fontos a terheléses támadás kivédése és az információ arról kik kapcsolódnak hozzám és milyen szolgáltatásokat használnak.

Tartalomjegyzék

1 Kapcsolók használata

-nr   routing táblák kiíratása,
–n    Az IP-címeket szimbolikus címekké alakítja. Ez egy kicsit gyorsítja a program futását,
      mert így nem hajt végre névfeloldást.
-i    a felkonfigurált hálózati interfészekről jelenít meg információt
-g    IPv4 és IPv6 multicast csoporttagságról jelenít meg információt,
-s    Minden egyes protokollról (IP, TCP, SNMP stb.)készít egy összefoglalót
-M    a maszkolt kapcsolatok kilistázása(Ip maszkolás például), az álcázott (masqueraded)
      kapcsolatok IP-táblái a Netstat számára nem láthatóak, ezek a/proc/net/ip_conntrack
      fájlban találhatóak meg.
-l    a „hallgatózó” szerver socketek kilistázása,
-ta,  Ezek a kapcsolók megmutatják az aktív TCP socket kapcsolatokat. 
      Ha „a”-t írunk utána akkor a kapcsolatra váró socketeket is megjeleníti.
-ua,  aktív UDP socketeket
-wa,  aktív RAW socketeket
-xa   aktív Unix socketeket

Néhány kapcsoló hatása

Nézzük meg mikre lehet felhasználni a netstat programot:

  • Írassuk ki a routing táblákat netstat -nr parancs felhasználásával:
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.4.0     0.0.0.0         255.255.255.0   U         0 0          0 eth1
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth1
0.0.0.0         192.168.4.199   0.0.0.0         UG        0 0          0 eth1

Az eredmény egyértelmű adott két routing bejegyzés a gépünkben és egy default route amely egy gateway-re küld minden olyan adatot aminek a cél címzettje nem ebben a hálózatban található. Minden csomagot az eth1 interfészen kell küldeni.

  • Most, hogy már láttuk a gépünk router tábláját és azt is milyen interfészen történik az adattovábbítás írassunk ki az interfészekről is információkat! Ehhez a netstat -i parancsot hívjuk segítségül:
Kernel Interface table
Iface   MTU Met   RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0       1500   0         0      0      0     0     0      0      0   0  BMRU
eth1       1500   0      5635      3      3     0     4725   0      5   0  BMRU
lo        16436   0        12      0      0     0     12     0      0   0  LRU

Így megtudtuk, hogy az eth0-án 1500byte az MTU például.

  • A netstat -g kiírja a szerverünk IPv4, IPv6 csoporttagságait:
IPv6/IPv4 Group Memberships
Interface       RefCnt Group
--------------- ------ ---------------------
lo              1      ALL-SYSTEMS.MCAST.NET
eth0            1      ALL-SYSTEMS.MCAST.NET
ppp0            1      ALL-SYSTEMS.MCAST.NET
lo              1      ipv6-allnodes
eth0            1      ipv6-allnodes
ppp0            1      ipv6-allnodes
  • Írassuk ki az TCP kapcsolatokat a netstat -ant parancs kiadásával:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN     
tcp        0      0 192.168.4.113:58559     209.85.148.120:443      TIME_WAIT  
tcp        0      0 192.168.4.113:46239     92.123.69.89:80         TIME_WAIT  
tcp        0      0 192.168.4.113:56160     209.85.148.113:80       TIME_WAIT  
tcp        0      0 192.168.4.113:37633     74.125.87.83:80         ESTABLISHED
tcp        0      0 192.168.4.113:37823     95.101.176.74:80        TIME_WAIT  
tcp        0      0 192.168.4.113:35738     74.125.87.104:80        TIME_WAIT  
tcp        0      0 192.168.4.113:33126     74.125.87.19:80         ESTABLISHED
tcp        0      0 192.168.4.113:36680     92.123.72.89:80         TIME_WAIT  
tcp        0      0 192.168.4.113:46241     92.123.69.89:80         TIME_WAIT  
tcp        0      0 192.168.4.113:36672     92.123.72.89:80         TIME_WAIT  
tcp        0      0 192.168.4.113:46240     92.123.69.89:80         TIME_WAIT  
tcp        0      0 192.168.4.113:60555     204.11.109.22:80        TIME_WAIT  
tcp        0      0 192.168.4.113:50016     66.220.153.11:80        TIME_WAIT  
tcp        0      0 192.168.4.113:54156     74.125.87.149:80        TIME_WAIT  
tcp        0      0 192.168.4.113:60556     204.11.109.22:80        TIME_WAIT  
tcp        0      0 192.168.4.113:39421     88.221.61.115:80        TIME_WAIT  
tcp6       0      0 ::1:631                 :::*                    LISTEN     
tcp6       0      0 :::445                  :::*                    LISTEN     
tcp6       0      0 :::139                  :::*                    LISTEN

Most szűrjük le azokat amiknek 80-as a portszáma, mert csak a HTTP kapcsolatokra vagyunk kíváncsiak:

netstat -ant | grep 80

Az eredmény:

tcp        0      0 192.168.4.113:37633     74.125.87.83:80         ESTABLISHED
tcp        0      0 192.168.4.113:33126     74.125.87.19:80         TIME_WAIT  
tcp        0      0 192.168.4.113:49028     74.125.87.83:80         ESTABLISHED
  • netstat -l a „hallgatózó” szerver socketek listázza ki:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 *:sunrpc                *:*                     LISTEN      
tcp        0      0 localhost:ipp           *:*                     LISTEN      
tcp        0      0 *:smtp                  *:*                     LISTEN      
tcp        0      0 *:sunrpc                *:*                     LISTEN      
tcp        0      0 localhost:ipp           *:*                     LISTEN      
tcp        0      0 *:smtp                  *:*                     LISTEN      
udp        0      0 *:820                   *:*                                 
udp        0      0 *:53437                 *:*                                 
udp        0      0 *:bootpc                *:*                                 
udp        0      0 *:mdns                  *:*                                 
udp        0      0 *:sunrpc                *:*                                 
udp        0      0 *:ipp                   *:*                                 
udp        0      0 *:820                   *:*                                 
udp        0      0 *:sunrpc                *:*      
                          
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node Path
unix  2      [ ACC ]     STREAM     LISTENING     6474   @/var/run/hald/dbus-5xGa2LPKv8
unix  2      [ ACC ]     STREAM     LISTENING     11508  private/bounce
unix  2      [ ACC ]     STREAM     LISTENING     11512  private/defer
unix  2      [ ACC ]     STREAM     LISTENING     11516  private/trace
unix  2      [ ACC ]     STREAM     LISTENING     7598   @/tmp/dbus-tp88b9tqUu

netstat -ta aktív TCP socketek kilistázása:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 *:sunrpc                *:*                     LISTEN      
tcp        0      0 localhost:ipp           *:*                     LISTEN      
tcp        0      0 *:smtp                  *:*                     LISTEN      
tcp        0      0 91.83.125.55.pool:39195 OCSP.IAD3.VERI:www-http TIME_WAIT   
tcp        0      0 91.83.125.55.pool:55886 hb-in-f83.1e100.n:https ESTABLISHED 
tcp        0      0 91.83.125.55.pool:46471 hb-in-f104.1e100.:https ESTABLISHED 
tcp        1      0 91.83.125.55.pool:40777 184-106-213-18:www-http CLOSE_WAIT  
tcp       38      0 91.83.125.55.pool:51176 elan.rulez.org:https    CLOSE_WAIT  
tcp        0      0 *:sunrpc                *:*                     LISTEN      
tcp        0      0 localhost:ipp           *:*                     LISTEN      
tcp        0      0 *:smtp                  *:*                     LISTEN      

Ha teljes képet szeretnénk kapni mi folyik a szerverünkön a következő paranccsal tehetjük meg, az awk program pedig segít az eredményeket csoportosítani:

netstat -ant | awk ‘{print $6}’ | sort | uniq -c | sort -n

print $6 balról jobbra haladva a 6.oszlopot emeli ki. Ez a State oszlop. Most pedig megszámoljuk az oszlopban lévő elemeket és kiírjuk hány fajta elem van és azokból mennyi van összesen.

jelenleg a kapcsolatok közül:

6 LISTEN
2 CLOSE_WAIT
2 ESTABLISHED
1 TIME_WAIT

2 DoS támadás kivédése Netstat-tal

2.1 Egyszerű megoldás

A módszer egyszerű: keressük meg a legtöbb TCP kapcsolatot nyitott IP-t és módosítsuk az iptables-t úgy, hogy dobja az erről az IP-ről jövő kéréseket. Sajnos ez egy félautomatikus megoldás, hiszen az eredményt nekem kézzel kell felvinnem az iptables-be.

Először is írassuk ki az aktív TCP kapcsolatokat, majd szűrjük le a 80-as portra (hiszen csak a http érdekel minket):

netstat -an | grep :80

Most, hogy megvannak az aktív 80-as porton lévő kapcsolatok, ismét az awk nevű szövegfeldolgozót hívjuk segítségül, hogy kinyerjük a távoli IP címeket és rakjuk is ki őket a kijelzőre.

netstat -an | grep :80 | awk ‘{print $5}’

print $5 a szöveges állomány (balról jobbra haladva) 5. oszlopát írja ki nekünk, ami épp a kapcsolatot létesítő gépek IP címei.

netstat -an | grep :80 | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort | uniq

Most kiszedjük az első sort, hiszen az a 0.0.0.0 cím (default gateway), ez nem érdekel minket és sorrendbe rakjuk, hogy a legtöbb TCP kapcsolatot nyitott IP címet lássuk.

Ha megvan a DoS támadást indító gép IP címe (jelen példában ez legyen: 154.162.32.15) az iptables-ben beállítjuk, hogy az erről a címről érkező TCP SYN kéréseket dobja a tűzfal:

iptables -I INPUT -s 154.162.32.15 -j DROP

2.2 Összetettebb megoldás

#!/bin/sh
#
# This script runs netstat, and looks for single IP addresses with more connections
# than is reasonable. This works well for finding and blocking SYN floods etc.
# BSD PEOPLE ETC: IF YOU RUN SOMETHING OTHER THAN LINUX: you need to modify it to
# use whatever method your OS needs to add a block to your local firewall 
# (linux uses iptables)
#
# How many connections from a single host is too many?
# If you run a webserver, I suggest 50 or more. If not, you may be able to lower 
# this to 25, thus making it way more effective. (Some browsers make up to 50 
# requests at a time to a webserver)
MAX_CONS=60
# I suggest adding iptables -I INPUT -s yourip -j ACCEPT at system boot time
# so that this script can never lock you out if it goes haywire.
#
# 'iptables -L INPUT' will show you which IPs are DROP'd, 
# you can remove them with iptables -F INPUT, or iptables -D INPUT # where # is
# the line number from -L you want to delete. man iptables.
# Function to block the IP
function block_ip
{
       if /sbin/iptables -L -n | grep $1 > /dev/null
       then
               echo " Blocked!"
       else
               echo " Blocking!"
               echo "---- netstat of $1: ----"
               # This puts output of netstat into the cron email
               # so you can see whats going on
               /bin/netstat -an 
               # BSD PEOPLE: change this..
               /sbin/iptables -I INPUT 1 -s $1 -j DROP
               echo " "
       fi
}
# Function to count distinct hosts
function counter
{
       declare -a hosts
       IFS=$' :\t\n'
       LASTADDR=
       COUNT=0
       while read ADDR PORT
       do
               if [ "${LASTADDR}" != "${ADDR}" ]
               then
                       if [ "${LASTADDR}" != "" ]
                       then
                               if expr $COUNT \>= $MAX_CONS > /dev/null
                               then
                                       echo -n $LASTADDR
$COUNT                                        
					block_ip $LASTADDR              
                               fi
                       fi
                       COUNT=1
               else
                       COUNT=$(($COUNT + 1))              
               fi
               LASTADDR=${ADDR}              
       done
       if [ "${LASTADDR}" != "" ]              
       then
               if expr $COUNT \>= $MAX_CONS > /dev/null              
               then
                       echo -n $LASTADDR $COUNT              
                       block_ip ${LASTADDR}              
               fi
       fi
}
# Do the work!
/bin/netstat -t -n | /bin/grep -e SYN_RECV | /usr/bin/cut -b 45-68 | /usr/bin/sort | counter

3 Forgalom statisztika

A netstat felhasználásával forgalom mérő szkriptet is alkothatunk.

#!/usr/local/bin/bash
#
#
SECS=`uptime | awk '{ if ($3 ~ /:/) { split($3,a,":"); print (a[1]*60+a[2])*60} else { split($3,b,":"); split($5,a,":"); print b[1]*86400+ (a[1]*60+a[2])*60} }'`
EXT_IN=`netstat -n -i eth0 | grep eth0 | tail -1 | awk '{print $5}'`
EXT_OUT=`netstat -n -I eth0 | grep eth0 | tail -1 | awk '{print $6}'`
echo " "
echo "External interface bandwidth usage:"
echo " uptime             " $(($SECS/86400)) "days"
echo " ExtIf in total     " $(($EXT_IN/1000000000)) "GBytes"
echo " ExtIf out total    " $(($EXT_OUT/1000000000)) "GBytes"
echo " ExtIf in/day       " $(($EXT_IN*86400/$SECS/1000000)) "MBytes/day"
echo " ExtIf out/day      " $(($EXT_OUT*86400/$SECS/1000000)) "MBytes/day"
echo " ExtIf in/30day     " $(($EXT_IN*86400*30/$SECS/1000000000)) "GBytes/month"
echo " ExtIf out/30day    " $(($EXT_OUT*86400*30/$SECS/1000000000)) "GBytes/month"
echo " ExtIf in+out/30day " $((($EXT_OUT+$EXT_IN)*86400*30/$SECS/1000000000)) "GBytes/month"
Személyes eszközök