Tallafoc/Firewall: iptables

De wikijoan
Salta a la navegació Salta a la cerca

Referències

Manual IpTables

iptables

Iptables és un tallafoc/firewall, instal.lat per defecte en les distribucions Linux. Quan instal.les Ubuntu, iptables ja hi és, però està configurat per defecte per permetre tot el tràfic. A més, Ubuntu ve amb ufw, ja vist en la pràctica anterior, que treballa amb iptables d'una manera més fàcil.

Igual que en la pràctica anterior, treballaràs amb dos ordinadors: el que farà de firewall i on corren diferents serveis, i el que fa de màquina que es vol connectar. En aquest tutorial l'ordinador servidor-firewall del professor és el 192.168.1.130, i ho hauràs de substituir per la teva IP. Treballareu per parelles i s'aniran fent les proves que es comenten en aquest tutorial.

Comandes bàsiques

Per llistar les regles que hi ha definides a iptables:

$ sudo iptables -L

Si acabes d'instal.lar un servidor no tindràs regles, i senzillament veuràs:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

En realitat el professor (i l'alumne) obtindrà un llistat d'informació molt més gran, relacionat amb ufw. Com que nosaltres venim de la pràctica anterior, on hem estat treballant amb el firewall ufw, seria bo resetejar i deshabilitar aquest firewall.

$ sudo ufw reset

$ sudo ufw disable
Firewall stopped and disabled on system startup
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ufw-before-logging-input  all  --  anywhere             anywhere            
ufw-before-input  all  --  anywhere             anywhere            
ufw-after-input  all  --  anywhere             anywhere            
ufw-after-logging-input  all  --  anywhere             anywhere            
ufw-reject-input  all  --  anywhere             anywhere            
ufw-track-input  all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
ufw-before-logging-forward  all  --  anywhere             anywhere            
ufw-before-forward  all  --  anywhere             anywhere            
ufw-after-forward  all  --  anywhere             anywhere            
ufw-after-logging-forward  all  --  anywhere             anywhere            
ufw-reject-forward  all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ufw-before-logging-output  all  --  anywhere             anywhere            
ufw-before-output  all  --  anywhere             anywhere            
ufw-after-output  all  --  anywhere             anywhere            
ufw-after-logging-output  all  --  anywhere             anywhere            
ufw-reject-output  all  --  anywhere             anywhere            
ufw-track-output  all  --  anywhere             anywhere            

Chain ufw-after-forward (1 references)
target     prot opt source               destination         

Chain ufw-after-input (1 references)
target     prot opt source               destination         

Chain ufw-after-logging-forward (1 references)
target     prot opt source               destination         

Chain ufw-after-logging-input (1 references)
target     prot opt source               destination         

Chain ufw-after-logging-output (1 references)
target     prot opt source               destination         

Chain ufw-after-output (1 references)
target     prot opt source               destination         

Chain ufw-before-forward (1 references)
target     prot opt source               destination         

Chain ufw-before-input (1 references)
target     prot opt source               destination         

Chain ufw-before-logging-forward (1 references)
target     prot opt source               destination         

Chain ufw-before-logging-input (1 references)
target     prot opt source               destination         

Chain ufw-before-logging-output (1 references)
target     prot opt source               destination         

Chain ufw-before-output (1 references)
target     prot opt source               destination         

Chain ufw-reject-forward (1 references)
target     prot opt source               destination         

Chain ufw-reject-input (1 references)
target     prot opt source               destination         

Chain ufw-reject-output (1 references)
target     prot opt source               destination         

Chain ufw-track-input (1 references)
target     prot opt source               destination         

Chain ufw-track-output (1 references)
target     prot opt source               destination

Veiem que continuem tenint informació relacionada amb la pràctica de la setmana passada (encara que totes les regles relacionades amb ufw són permissives). Si realment volem deixar les taules iptables netes del tot i resetejades, hem d'utilitzar l'opció -F (flush):

$ sudo iptables -F

o millor -X (--delete-chain):

$ sudo iptables -X

Opcions d'Iptables bàsiques

A continuació es mostren les comandes bàsiques que s'utilitzen amb iptables. No et preocupis si no ho entens tot ara mateix, però repassa aquesta llista d'opcions a mesura que te les vagis trobant.

  • -A - Append this rule to a rule chain. Valid chains for what we're doing are INPUT, FORWARD and OUTPUT, but we mostly deal with INPUT in this tutorial, which affects only incoming traffic.
  • -L - List the current filter rules.
  • -m conntrack - Allow filter rules to match based on connection state. Permits the use of the --ctstate option.
  • --ctstate - Define the list of states for the rule to match on. Valid states are:
    • NEW - The connection has not yet been seen.
    • RELATED - The connection is new, but is related to another connection already permitted.
    • ESTABLISHED - The connection is already established.
    • INVALID - The traffic couldn't be identified for some reason.
  • -m limit - Require the rule to match only a limited number of times. Allows the use of the --limit option. Useful for limiting logging rules.
    • --limit - The maximum matching rate, given as a number followed by "/second", "/minute", "/hour", or "/day" depending on how often you want the rule to match. If this option is not used and -m limit is used, the default is "3/hour".
  • -p - The connection protocol used.
  • --dport - The destination port(s) required for this rule. A single port may be given, or a range may be given as start:end, which will match all ports from start to end, inclusive.
  • -j - Jump to the specified target. By default, iptables allows four targets:
    • ACCEPT - Accept the packet and stop processing rules in this chain.
    • REJECT - Reject the packet and notify the sender that we did so, and stop processing rules in this chain.
    • DROP - Silently ignore the packet, and stop processing rules in this chain.
    • LOG - Log the packet, and continue processing more rules in this chain. Allows the use of the --log-prefix and --log-level options.
  • --log-prefix - When logging, put this text before the log message. Use double quotes around the text to use.
  • --log-level - Log using the specified syslog level. 7 is a good choice unless you specifically need something else.
  • -i - Only match if the packet is coming in on the specified interface.
  • -I - Inserts a rule. Takes two options, the chain to insert the rule into, and the rule number it should be.
    • -I INPUT 5 would insert the rule into the INPUT chain and make it the 5th rule in the list.
  • -D elimina una regla

-R reemplaça una regla

  • -v - Display more information in the output. Useful for if you have rules that look similar without using -v.
  • -s --source - address[/mask] source specification
  • -d --destination - address[/mask] destination specification
  • -o --out-interface - output name[+] network interface name ([+] for wildcard)
  • -F, --flush [chain]. Flush the selected chain (all the chains in the table if none is given). This is equivalent to deleting all the rules one by one.

Permetre Sessions Establertes (Established)

Podem permetre sessions establertes per tal de permetre la rebuda de tràfic:

$ sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

(Important no ficar espais als dos costats de la coma a ESTABLISHED,RELATED)

Si la línia de dalt no funciona, podries estar en una VPS castrada el proveïdor de la qual no ha habilitat l'extensió, i aleshores et podria funcionar:

$ sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Permetre Tràfic d'Entrada en Ports Específics

Podríem començar blocant tot el tràfic, però és una pràctica habitual connectar-se als servidors via SSH, i així doncs haurem de permetre SSH abans de bloquejar tots els altres serveis.

Per permetre el tràfic d'entrada en el port per defecte de SSH (22), podem escriure a les iptables de permetre el tràfic TCP en aquest port:

$ sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT

Referint-los a la llista d'opcions de més amunt, podem veure que li estem dient a les iptables:

  • afegir aquesta regla a la cadena d'entrada (-A INPUT), i així mirarem el tràfic d'entrada.
  • mirem si és el protocol TCP (-p tcp).
  • si és el cas, mirem si l'entrada va la port SSH (--dport ssh).
  • si és el cas, acceptem l'entrada (-j ACCEPT).

Anem a mirar com han quedat les regles: (només es mostren les primeres)

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh

Ara anem a habilitar tot el tràfic web:

$ sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www

Hem permès explícitament el tràfic TCP en els ports SSH i WEB, però com que no hem blocat res, de fet tot el tràfic d'entrada encara pot entrar.

Bloquejar tot el tràfic

Un cop s'ha pres la decisió d'acceptar un paquet, no hi ha altres regles que l'afectin. Les regles d'acceptar SSH i WEB són les primeres de totes, i la regla per bloquejar tot la resta de tràfic ha de venir després. El que hem de fer és posar la regla de bloquejar-ho tot al final de tot:

$ sudo iptables -A INPUT -j DROP
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
DROP       all  --  anywhere             anywhere

No hem especificat cap interfície ni protocol, i així doncs es bloqueja tot el tràfic per qualsevol port i interfície (excepte per web i ssh).

Resumint, estic acceptant SSH i WEB (que de fet ja estaven permesos), i estic blocant la resta. Per exemple, un dels serveis que tenim en el servidor i que ara es veurà afectat per aquesta política restrictiva és telnet:

$ telnet 192.168.1.130

No ens podem connectar. Com que la regla és un DROP, el missatge que obtenim és un timed out (no hi ha resposta del servidor). Si haguéssim fet un REJECT en comptes d'un DROP el missatge hagués sigut diferent.

De fet, ens hem quedat sense connexió a Internet (per la wireless, eth1). Llegir l'apartat següent per tornar a recuperar la connexió a Internet.

Editing iptables

The only problem with our setup so far is that even the loopback port is blocked. We could have written the drop rule for just eth0 by specifying -i eth0, but we could also add a rule for the loopback. If we append this rule, it will come too late - after all the traffic has been dropped. We need to insert this rule before that. Since this is a lot of traffic, we'll insert it as the first rule so it's processed first.

$  sudo iptables -I INPUT 1 -i lo -j ACCEPT

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
DROP       all  --  anywhere             anywhere

La primera línia és la que acabem d'afegir, però de fet no veiem massa la diferència amb la línia última, així que utilitzarem l'opció -v per veure més detall i veure com la primera línia fa referència a loopback.

$ sudo iptables -L -v

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere
    0     0 ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:ssh
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:www
    0     0 DROP       all  --  any    any     anywhere             anywhere

You can now see a lot more information. This rule is actually very important, since many programs use the loopback interface to communicate with each other. If you don't allow them to talk, you could break those programs!

Després d'això que acabem de llegir, si volem recuperar la connexió a Internet per la interfície wireless farem:

$ sudo iptables -I INPUT 2 -i eth1 -j ACCEPT

(serà la regla número 2). Nota important. De fet, aquesta regla està malament doncs torna a habilitar tot per la interfície eth1, i concretament ara podem tornar a fer telnet.

Logging

In the above examples none of the traffic will be logged. If you would like to log dropped packets to syslog, this would be the quickest way:

$  sudo iptables -I INPUT 5 -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

See Tips section for more ideas on logging.

Veurem en el syslog una sortida similar a:

$ dmesg
...
[ 6645.831770] iptables denied: IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:10:bf:48:0d:2c:61:08:00 SRC=192.168.7.22 DST=255.255.255.255 LEN=140 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=UDP SPT=17500 DPT=17500 LEN=120 
...

Saving iptables

If you were to reboot your machine right now, your iptables configuration would disappear. Rather than type this each time you reboot, however, you can save the configuration, and have it start up automatically. To save the configuration, you can use iptables-save and iptables-restore.

$ man iptables-save
NAME
       iptables-save - dump iptables rules to stdout

SYNOPSIS
       iptables-save [-M modprobe] [-c] [-t table]
...
$ sudo iptables-save -c > /etc/iptables-rules.txt

# Generated by iptables-save v1.4.4 on Mon Feb  6 14:26:08 2012
*filter
:INPUT ACCEPT [10620:8396175]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [11735:2283398]
...
[0:0] -A INPUT -i lo -j ACCEPT
[735:530653] -A INPUT -i eth1 -j ACCEPT
...
$ man iptables-restore
IPTABLES-RESTORE(8)                                      IPTABLES-RESTORE(8)

NAME
       iptables-restore - Restore IP Tables

SYNOPSIS
       iptables-restore [-c] [-n]
$ sudo iptables-restore -c < /etc/iptables-rules.txt

Configuració en l'inici del sistema

L'enllaç de referència que estem seguint es va escriure per a la versió 8.04 d'Ubuntu, que ara ja queda lluny en el temps. Hi ha una sèrie de warnings sobre la incompatibilitat d'iptables (que es restrictiu per defecte), i el Network Manager de Gnome (que és permissiu per defecte). Ha passat el temps i s'ha de veure si aquests warnings encara són aplicables.

Es comenten tres mètodes per fer que les regles que hem guardat en un fitxer estiguin disponibles en l'inici del sistema. La més senzilla és la primera, es tracta d'editar el fitxer /etc/network/interfaces.

...
iface eth1 inet dhcp
  pre-up iptables-restore < /etc/iptables.rules
  post-down iptables-restore < /etc/iptables.downrules

En aquest cas tenim un fitxer amb regles que s'han d'executar just abans que la interfíce eth1 arrenqui, i un altre fitxer amb regles que s'han d'executar just després de què la interfície s'aturi.

Recordatori: Per aturar i arrencar (reconfigurar) totes les targetes de xarxa farem:

$ /etc/init.d/networking restart

o bé també ho puc fer manualment per a la interfície eth1:

$ sudo ifdown eth1
There is already a pid file /var/run/dhclient.eth1.pid with pid 5630
killed old client process, removed PID file
Internet Systems Consortium DHCP Client V3.1.3
Copyright 2004-2009 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth1/00:13:ce:82:8b:b0
Sending on   LPF/eth1/00:13:ce:82:8b:b0
Sending on   Socket/fallback
DHCPRELEASE on eth1 to 192.168.1.1 port 67
$ sudo ifup eth1
Internet Systems Consortium DHCP Client V3.1.3
Copyright 2004-2009 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth1/00:13:ce:82:8b:b0
Sending on   LPF/eth1/00:13:ce:82:8b:b0
Sending on   Socket/fallback
DHCPDISCOVER on eth1 to 255.255.255.255 port 67 interval 6
DHCPDISCOVER on eth1 to 255.255.255.255 port 67 interval 15
DHCPOFFER of 192.168.1.130 from 192.168.1.1
DHCPREQUEST of 192.168.1.130 on eth1 to 255.255.255.255 port 67
DHCPACK of 192.168.1.130 from 192.168.1.1
bound to 192.168.1.130 -- renewal in 113365 seconds.
ssh stop/waiting
ssh start/running, process 5673

Deshabilitar el firewall

If you need to disable the firewall temporarily, you can flush all the rules using

$ sudo iptables -F

or create a script:

$ sudo joe -w /root/fw.stop

echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Fem el script executable:

$ sudo chmod +x /root/fw.stop

i ja el podem executar:

$ sudo /root/fw.stop

Entrega

Recorda la normativa per entregar les pràctiques al Moodle: ASIX-M11-SAD#Normativa_d.27entrega_de_les_pr.C3.A0ctiques_al_Moodle.

Entregaràs al Moodle les captures de pantalla necessàries i suficients per demostrar la realització de la pràctica, així com el fitxer LLEGEIX-ME.txt amb les teves notes.


creat per Joan Quintana Compte, febrer 2012