====== 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)