Linux Transparent Firewall

In questo infobox verra' illustrato come configurare una linux box come transparent firewall.
Rispetto ad una configurazione in cui il firewall ruoti anche i pacchetti, in questa situazione il sistema si comporta come un bridge: esso si limita a passare i pacchetti da un'interfaccia all'altra secondo le regole di filtraggio definita, senza occuparsi del routing.
Una simile configurazione presenta il grande vantaggio di una maggiore semplicita' nel deploy. Posizionando il firewall inline, infatti, non sara' necessario apportare alcuna modifica alla configurazione della rete esistente o delle macchine. Il funzionamento del firewall sara' completamente trasparente. Inoltre non dovendosi occupare del routing dei pacchetti, le prestazioni del sistema dovrebbero essere superiori rispetto ad un firewall in "routing mode".  

Nell'esempio illustrato e' presente una lan con indirizzo 192.168.1.0/24. Il router, avente indirizzo IP 192.168.1.1 e' collegato all'interfaccia esterna del firewall, mentre l'inside di quest'ultimo sara' connessa allo switch dove sono attestati i pc client.

Per potere utilizzare il sistema come firewall trasparente e' innanzitutto necessario configurare la macchina linux in modo che possa svolgere la funzione di bridge ethernet. Il tool utilizzato per la configurazione di questo aspetto e' brctl e puo' essere installato con il seguente comando:

apt-get install bridge-utils

Nell'esempio verra' configurato un bridge di nome br0 costituito dalle interfacce eth0 ed eth1. La creazione del bridge e l'aggiunta delle interfacce puo' venire effettuata con i seguenti comandi:

brctl addbr br0
brctl addif br0 eth0
brctl addif br0 eth1

Il supporto per il bridging ethernet dovrebbe essere gia' incluso all'interno del kernel, ed il relativo modulo venire caricato automaticamente all'esecuzione del comando brctl addbr br0.

Per verificare l'aggiunta delle interfacce al bridge eseguire brctl show:

bridge name     bridge id               STP enabled     interfaces
br0             8000.00219b02b0d6       no              eth0
                                                        eth1

Dall'output del comando si puo' notare come la configurazione dello spanning tree sia disabilitata. Avendo l'esempio di rete illustrata una struttura estremamente semplice e priva di loop non e' stato abilitato il protocollo in questione.

Una volta creato il bridge assicurarsi che le interfacce eth0 ed eth1 appartenenti allo stesso non abbiano alcun indirizzp ip assegnato:

ifconfig eth0 down
ifconfig eth0 0.0.0.0 up
ifconfing eth1 down
ifconfig eth1 0.0.0.0 up

Inoltre, per consentira un accesso remoto al firewall potrebbe essere opportuno configurare un indirizzo ip su una terza interfaccia (se disponibile) oppure assegnarlo direttamente al bridge. Si ipotizza di assegnare al bridge br0 l'indirizzo 192.168.1.3:

ifconfig br0 192.168.1.50 netmask 255.255.255.0 up

A questo punto la configurazione delle schede di rete e del bridge visualizzabili con il comando ifconfig dovrebbero risultare simile alla seguente:

br0       Link encap:Ethernet  HWaddr 00:21:9b:02:b0:d6  
          inet addr:192.168.1.50  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::221:9bff:fe02:b0d6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:65 errors:0 dropped:0 overruns:0 frame:0
          TX packets:78 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:9800 (9.5 KiB)  TX bytes:10319 (10.0 KiB)

eth0      Link encap:Ethernet  HWaddr 00:21:9b:02:b0:d6  
          inet6 addr: fe80::221:9bff:fe02:b0d6/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2748 errors:0 dropped:3728821171 overruns:0 frame:0
          TX packets:2925 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:319216 (311.7 KiB)  TX bytes:3064216 (2.9 MiB)
          Interrupt:219

eth1      Link encap:Ethernet  HWaddr 00:48:54:60:c1:6b  
          inet6 addr: fe80::248:54ff:fe60:c16b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14365 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9394 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:19225516 (18.3 MiB)  TX bytes:799834 (781.0 KiB)
          Interrupt:21 Base address:0xae00

Per completare la configurazione del bridge e' infine necessario abilitare il forward dei pacchetti ip (echo 1 > /proc/sys/net/ipv4/ip_forward) ed eventualmente impostare un default gateway in caso si voglia rendere raggiungibile l'ip di gestione anche al di fuori della rete 192.168.1.0/24.
La funzionalita' del firewall e' comunque indipendente dall'impostazione di un default gateway, ma potrebbe essere opportuno aggiungerlo, anche per consentire eventuali download degli update dai repository debian:

route add default gw 192.168.1.1


A questo punto dai client connessi allo switch dovrebbe essere possibile pingare il router ed altre reti poste oltre di esso. A fini di test e' possibile disabilitare una delle interfacce (ifconfig ethX down per verificare come il traffico non attraversi piu' il bridge e di conseguenza non raggiunga il router e le reti da esso ruotate.
L'esempio di configurazione illustrato, non e' pero' permanente ed andrebbe perso al primo riavvio del sistema. Per rendere la configurazione permanente e' possibile editare il file /etc/network/interfaces in modo da eseguire automaticamente i comandi necessari:

#loopback
auto lo
iface lo inet loopback

#bridge br0
auto br0
iface br0 inet  static
    address 192.168.1.50
    netmask 255.255.255.0
    broadcast 192.168.1.255
    network 192.168.1.0
    gateway 192.168.1.1
    pre-up ifconfig eth0 down
    pre-up ifconfig eth1 down
    pre-up brctl addbr br0
    pre-up brctl addif br0 eth0
    pre-up brctl addif br0 eth1
    pre-up ifconfig eth0 up
    pre-up ifconfig eth1 up
    post-down ifconfig eth0 down
    post-down ifconfig eth1 down

Con la configurazione illustrata sino a questo punto il sistema ha funzionalita' di bridge ethernet, ma non effettua ancora alcun tipo di filtraggio, lasciando passare tutto il traffico che riceve. A tal fine e' necessario configurare iptables specificando le opportune regole.
In questo caso, le regole piu' importanti riguarderanno probabilmente la catena FORWARD, ovvero quella relativa ai pacchetti che attraversino il firewall.
Inserendo le regole nella catena INPUT si andrannoo invece a discriminare solamente i pacchetti diretti al sistema stesso, ovvero all'indirizzo 192.168.1.50.

Un esempio di set di regole minimale e' il seguente che blocca tutti i pacchetti in transito ad eccezione delle richieste dns dalla subnet 192.168.1.0/24 verso l'indirizzo 172.16.105.3, le request dhcp e le risposte dal dhcp server 172.16.105.5 eil traffico diretto alle porte 80 e 8080 di un proxy http con ip 172.16.105.12.
Per il traffico in senso contrario non e' stato necessario inserire regole puntuali, in quanto verra' matchato dalla statefull inspection grazie alle regole con l'opzione -m state --state ESTABLISHED, RELATED.
Sono state inoltre previste alcune regole sulle catene di input ed output per consentire l'accesso via ssh al firewall e la possibilita' di scaricare aggiornamenti tramite il protocollo http.

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -s 192.168.1.50 -p tcp -dport 80 -j ACCEPT
iptables -A OUTPUT -s 192.168.1.50 -p udp -dport 53 -d 172.16.105.3 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -p udp --dport 67 -j ACCEPT
iptables -A FORWARD -p udp --dport 68 -s 172.16.105.5 -j ACCEPT
iptables -A FORWARD -p udp --dport 53 -s 192.168.1.0/24 -d 172.16.105.3 -j ACCEPT
iptables -A FORWARD -p tcp --dport 80 -s 192.168.1.0/24 -d 172.16.105.12 -j ACCEPT
iptables -A FORWARD -p tcp --dport 8080 -s 192.168.1.0/24 -d 172.16.105.12 -j ACCEPT

Anche in questo caso con il reboot del sistema si perderebbe la a configurazione delle regole di filtraggio. A tal fine e' possibile creare uno shellscript come il seguente da inserire nella struttura di init del sistema

#!/bin/sh

IPTABLES="/sbin/$IPTABLES"

######################
# start  firewall
######################
start()
{

# caricamento moduli necessari
/sbin/insmod ip_tables > /dev/null 2> /dev/null
/sbin/insmod iptable_NAT > /dev/null 2> /dev/null
/sbin/insmod ip_conntrack > /dev/null 2> /dev/null
/sbin/insmod ipt_MASQUERADE > /dev/null 2> /dev/null

# flush regole
$IPTABLES -F INPUT > /dev/null
$IPTABLES -F OUTPUT > /dev/null
$IPTABLES -F FORWARD > /dev/null
$IPTABLES -t nat -F > /dev/null

# attivazione ip_forward  
echo 1 > /proc/sys/net/ipv4/ip_forward

# regole filtraggio
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
$IPTABLES -A INPUT -p tcp --dport 22 -j ACCEPT
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -s 192.168.1.50 -p tcp -dport 80 -j ACCEPT
$IPTABLES -A OUTPUT -s 192.168.1.50 -p udp -dport 53 -d 172.16.105.3 -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -p udp --dport 67 -j ACCEPT
$IPTABLES -A FORWARD -p udp --dport 68 -s 172.16.105.5 -j ACCEPT
$IPTABLES -A FORWARD -p udp --dport 53 -s 192.168.1.0/24 -d 172.16.105.3 -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 80 -s 192.168.1.0/24 -d 172.16.105.12 -j ACCEPT
$IPTABLES -A FORWARD -p tcp --dport 8080 -s 192.168.1.0/24 -d 172.16.105.12 -j ACCEPT
}

#################
# stop firewall
#################
stop()
{

#Flush regole e policy in accept
$IPTABLES -F
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -t nat -F
$IPTABLES -t mangle -F

# Rimozione dei moduli necessari
/sbin/rmmod ip_conntrack > /dev/null 2> /dev/null
/sbin/rmmod ipt_MASQUERADE > /dev/null 2> /dev/null
/sbin/rmmod iptable_nat > /dev/null 2> /dev/null
  
#Disattivazione IP forwarding
echo 0 > /proc/sys/net/ipv4/ip_forward
}


case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
      stop
    start
    ;;
  status)
        $IPTABLES -L -v
        ;;
  *)
        echo "Usage: $0 {start | stop | status}"
        exit 1
        ;;
esac
exit 0

Privacy Policy