====== Iptables ====== ===== Connection tracking ===== Il numero massimo di connessioni che il kernel riesce a gestire è stabilito da ''**/proc/sys/net/ipv4/ip_conntrack_max**'', lo stato attuale delle connessioni riconosciute è invece in ''**/proc/net/ip_conntrack**''. Vedere questo articolo sul **{{.iptables:conntrack.html|Connection tracking}}** prelevato {{http://kalamazoolinux.org/presentations/20010417/conntrack.html|qui}}. Con il tool **''conntrack''** (installato dall'omonimo pacchetto) è possibile vedere le connessioni in essere e manipolarle. Tanto per iniziare si possono vedere e rimuoverle tutte: conntrack -L conntrack -F ===== Accessing a DNAT sever from the local LAN using the public IP address ===== Scenario: an **iptables firewall** forwards connections from the internet to a **local server** through a **DNAT rule**. Hosts on the **local LAN** want to connect to the local server through its **public IP address**. * The public IP address is **82.189.151.152** * The private IP of the server is **192.168.1.32** * The service is TCP port **80** (www) * The local netword is **192.168.1.0/24** * The firewall interface on the LAN is **eth0** # This is the DNAT rule for internet requests: iptables -t nat -I PREROUTING -d 82.189.151.152 -p tcp --dport 80 -j DNAT --to-dest 192.168.1.32 # This is for the firewall itself: iptables -t nat -I OUTPUT -d 82.189.151.152 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.32:80 # This is for the hosts on the local LAN: iptables -t nat -I PREROUTING -d 82.189.151.152 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.32:80 iptables -t nat -I POSTROUTING -o eth0 -s 192.168.1.0/24 -d 192.168.1.32 -j MASQUERADE iptables -I FORWARD -i eth0 -o eth0 -d 192.168.1.32 -j ACCEPT iptables -I FORWARD -i eth0 -o eth0 -s 192.168.1.32 -j ACCEPT ===== Shorewall and DNAT onto a local host ===== A web server is reachable from the internet onto a local host (**192.168.1.5**) via a DNAT rule, local hosts want to use the public address (**130.151.100.69**) to reach the d-natted server. Traffic will be masqueraded by the firewall with its address (**192.168.1.254**) on the local LAN (**eth0**, **192.168.1.0/24**): In **/etc/shorewall/interfaces**: #ZONE INTERFACE OPTIONS loc eth0 routeback For Shorewall 5 we nedd a line in **/etc/shorewall/snat**: #ACTION SOURCE DEST PROTO PORT SNAT(192.168.1.254) 192.168.1.0/24 eth0:192.168.1.5 tcp www Shorewall 4 instead requires a line in **/etc/shorewall/masq**: #INTERFACE SUBNET ADDRESS PROTO PORT(S) eth0:192.168.1.5 192.168.1.0/24 192.168.1.254 tcp www In **/etc/shorewall/rules**: #ACTION SOURCE DEST PROTO DEST PORT SOURCE ORIGINAL # PORT DEST. DNAT loc loc:192.168.1.5 tcp www - 130.151.100.69 DNAT net loc:192.168.1.5 tcp www - 130.151.100.69 Mapping different port from outside to inside is handled only in **/etc/shorewall/rules**, as usual. ===== Shorewall with router in local LAN ===== Hosts in LAN#1 may access hosts in LAN#2 by just adding a static route to the **192.168.2.0/24 network** via the **192.168.1.10 gateway**, but it is very annoying to modify the routing table into several hosts. {{shorewall-router-in-lan.png?400|Shorewall with router in LAN}} You can instead make **two configurations** on the Shorewall firewall. First of all you add the static route into **/etc/network/interfaces**: auto eth1 iface eth1 inet static address 192.168.1.1 netmask 255.255.255.0 up /sbin/route add -net 192.168.2.0/24 gw 192.168.1.10 || true down /sbin/route del -net 192.168.2.0/24 gw 192.168.1.10 || true then you have to add the **routeback** option for the **eth1** interfaces in the **/etc/shorewall/interfaces** file: loc eth1 routeback ===== Iptables schema ===== How the various tables are traversed? This is an handy schema found [[http://jonatan.spse.pilsedu.cz/iptables.png|here]]: {{.:iptables:iptables.png?240|iptables schema}} ===== Shorewall on a diskless host ===== There is a problem starting Shorewall on a diskless host which mounts its root filesystem via NFS; the standard behaviour of Shorewall on start, is to set a **DROP default policy** for **INPUT** and **OUTPUT** chains before enforcing other rules. In this way the NFS mount gets blocked while Shorewall tries to acquire a lockfile on the disk and the entire host is screwed. The error message is: lockfile: Sorry, giving up on "/var/lock/shorewall" There is a non-documented feature called **CRITICALHOSTS**, this is a list of hosts that requires to never be blocked. Just put into **''/etc/shorewall/shorewall.conf''** someting like: CRITICALHOSTS="eth0:172.21.10.1 eth0:172.21.10.254" **WARNING** the interface name is required, otherwise the iptable rules are syntactically correct, but ineffective. May be this is a bug of Shorewall 4.0.8. ===== Usare iptables per mitigare o bloccare un DNS Amplification Attack ===== Vedere la definizione del [[wpit>DNS Amplification Attack]]. Con un tool tipo **iptraf** si verifica il traffico DNS cioè **UDP porta 53**, utilizzando la funzione //Statistical breakdowns...//, //By TCP/UDP port//. Se siamo in presenza di un attacco è facile vedere il flood di pacchetti con **tcpdump**, l'host di destinazione è il nostro server DNS: tcpdump -i eth0 -n 'port 53 and dst host 148.67.69.17' 16:51:31.065257 IP 185.28.23.10.56539 > 148.67.69.17.53: 9359+ [1au] ANY? zing.zong.co.ua. (44) 16:51:31.067428 IP 185.28.23.10.47247 > 148.67.69.17.53: 2560+ [1au] ANY? zing.zong.co.ua. (44) 16:51:31.067806 IP 198.176.28.48.24916 > 148.67.69.17.53: 59757+ [1au] ANY? zing.zong.co.ua. (44) 16:51:31.068372 IP 198.176.28.48.17633 > 148.67.69.17.53: 30287+ [1au] ANY? zing.zong.co.ua. (44) 16:51:31.080435 IP 79.178.169.108.14210 > 148.67.69.17.53: 56049+ [1au] ANY? zing.zong.co.ua. (44) 16:51:31.084766 IP 217.79.182.87.18963 > 148.67.69.17.53: 31993+ [1au] ANY? zing.zong.co.ua. (44) 16:51:31.086912 IP 217.79.182.87.47510 > 148.67.69.17.53: 28265+ [1au] ANY? zing.zong.co.ua. (44) l'IP sorgente può essere più di uno, si tratta ovviamente di un IP spooffato e si tratta della reale vittima dell'attacco DDOS. In questo caso l'amplificazione consiste nel fatto che una semplice query di tipo ANY su zing.zong.co.ua restituisce una risposta di circa 10k: host -t ANY zing.zong.co.ua | wc -c 10254 Se la query è identificabile in modo univoco si può rapidamente aggiungere una regola iptables e bloccare tutte le richieste malevole, le relative risposte (che sono il reale peso) non ci saranno. Anzitutto identifichiamo una stringa del payload: tcpdump -X -i eth0 -n 'port 53 and dst host 148.67.69.17 and src host 217.79.182.87' 16:59:04.205759 IP 217.79.182.87.14717 > 148.67.69.17.53: 28265+ [1au] ANY? zing.zong.co.ua. (44) 0x0000: 4500 0048 1db6 0000 f211 47ec d94f b657 E..H......G..O.W 0x0010: 904c 430f 397d 0035 0034 0000 6e69 0100 .LC.9}.5.4..ni.. 0x0020: 0001 0000 0000 0001 047a 696e 6704 7a6f .........zing.zo 0x0030: 6e67 0263 6f02 7561 0000 ff00 0100 0029 ng.co.ua.......) 0x0040: 2328 0000 0000 0000 #(...... 16:59:04.211641 IP 217.79.182.87.50901 > 148.67.69.17.53: 42235+ [1au] ANY? zing.zong.co.ua. (44) 0x0000: 4500 0048 1db7 0000 f211 47eb d94f b657 E..H......G..O.W 0x0010: 904c 430f c6d5 0035 0034 0000 a4fb 0100 .LC....5.4...... 0x0020: 0001 0000 0000 0001 047a 696e 6704 7a6f .........zing.zo 0x0030: 6e67 0263 6f02 7561 0000 ff00 0100 0029 ng.co.ua.......) 0x0040: 2328 0000 0000 0000 #(...... **Attenzione** che il punto non è il carattere **0x2e** come ci si aspetta: ^ Hex ^ ASCII ^ | 047a 696e 6704 7a6f 6e67 0263 6f02 7561 | zing.zong.co.ua | Quindi aggiungiamo la regola **iptables**: /sbin/iptables -I INPUT -p udp -m string --hex-string '|047A696E67047A6F6E6702636F027561|' \ --algo bm --from 40 --to 56 -j DROP -m comment --comment "DROP DNS Q zing.zong.co.ua" Discorso diverso se si vuole **limitare il rate delle richieste DNS**, in questo modo si prevengono futuri attacchi, indipendentemente dal payload del pacchetto. Ecco uno script che imposta un limite di 4 richieste al secondo per ogni IP sorgente. Un singolo IP viene considerato whitelisted e non sottoposto al rate: #!/bin/sh limit="4/second" # Trigger rule above this packet rate. burst="20" # Accept a burst of packets from good sources. expire="60000" # Keep the rule for msec. options="! -s 144.76.223.44 -p udp --dport 53 -m hashlimit --hashlimit-name DNS \ --hashlimit-above $limit --hashlimit-burst $burst --hashlimit-htable-expire $expire \ --hashlimit-mode srcip --hashlimit-srcmask 32" case "$1" in start) iptables -I INPUT $options -j DROP #iptables -I INPUT $options -j LOG --log-level debug ;; stop) iptables -D INPUT $options -j DROP #iptables -D INPUT $options -j LOG --log-level debug ;; *) echo "Usage: $(basename $0) {start|stop}" ;; esac Nella tabella **''/proc/net/ipt_hashlimit/DNS''** troviamo: - Conto alla rovescia per rimuovere la entry dalla tabella - Inirizzo_IP:porta sorgente - Inirizzo_IP:porta destinazione - Credito attuale - Credito massimo: es. (burst 20) * (costo 6400) = 128000 - Costo: es. 6400 per 5/s, 8000 per 4/s, cioè 32000 / (n/s)