[OpenBSD]

[Precedente: Firewall Redundancy con CARP e pfsync] [Indice]

PF: Esempio: Firewall domestico o per un piccolo ufficio


Indice


Lo scenario

In questo esempio, PF funziona su una macchina OpenBSD come firewall e gateway NAT per una piccola rete domestica o per un ufficio. L'obiettivo principale e' di fornire alla rete locale accesso ad Internet e limitare l'accesso da Internet al firewall. Tutto questo si puo' ottenere con il seguente esempio di regole di configurazione.

La rete

La rete e' cosi' schematizzata:
    
  [ COMP1 ]    [ COMP3 ]
      |            |                               
   ---+------+-----+------- xl0 [ OpenBSD ] fxp0 -------- ( Internet )
             |
         [ COMP2 ]

La rete locale e' costituita da un certo numero di computer, lo schema ne mostra tre, ma il numero e' irrilevante. Questi computer sono workstation utilizzate per navigare su web, email, chat, ecc., con l'eccezione di COMP3 sul quale e' in funzione un piccolo web server. La rete interna utilizza la subnet 192.168.0.0 / 255.255.255.0.

Il router OpenBSD e' un Celeron 300 con due interfaccie di rete : una 3com 3c509B (xl0) e una Intel EtherExpress Pro/100 (fxp0). Il router ha una connessione con cavo a Internet e utilizza la NAT per condividere questa connessione con la rete interna. L'indirizzo IP sull'interfaccia esterna viens assegnato dinamicamente dal Server Provider Internet.

L'Obiettivo

Gli obiettivi sono:

Preparazione

Si presuppone che l'host OpenBSD sia stato configurato in modo appropriato per agire da router, siano stati verificati il setup di rete, la connettivita' con Internet, e il settaggio delle variabili sysctl(3) net.inet.ip.forwarding e/o net.inet6.ip6.forwarding to "1". Inotre dovrà anche essere abilitato PF usando pfctl(8) o impostando la rispettiva variabile in /etc/rc.conf.local.

Regole di configurazione

Di seguito, passo dopo passo, vi sono le regole di configurazione che soddisfano tutti gli obiettivi.

Macro

Le seguenti macro sono definite per una semplice lettura e un facile aggiornamento delle regole:
ext_if="fxp0"
int_if="xl0"

tcp_services="{ 22, 113 }"
icmp_types="echoreq"

comp3="192.168.0.3"

Le prime due righe definiscono le interfaccie di rete sulle quali avviene il filtraggio. Con queste definizioni se si dovesse spostare il sistema su un altro hardware, basterebbe cambiare solo queste due righe. La terza e la quarta linea elencano i numeri di porte TCP dei servizi che saranno resi accessibili da Internet (SSH e ident/auth) e i pacchetti ICMP ai quali e' concesso di raggiungere il firewall. Infine, l'ultima linea definisce l'indirizzo IP di COMP3.

Nota: Se la connessione Internet richiede PPPoE, il filtraggio e la NAT devono aver luogo sull'intersaccia tun0 e non sulla fxp0.

Opzione

Le seguenti due opzioni configurano la risposta di default per le regole di filtraggio block e attivano le statistiche di logging per l'interfaccia esterna:
set block-policy return
set loginterface $ext_if

Ogni sistema unix ha un'interfaccia di "loopback". E' un'interfaccia di rete virtuale usata da ogni applicazione per comunicare con le altre all'interno del sistema. Su OpenBSD, l'interfaccia di loopback è lo(4). E' considerata una buona abitudine disabilitare tutti i filtraggi sulle interfaccie di loopback. Questo si ottiene con set skip.

set skip on lo
Da notare che in questo modo disabilitiamo l'intero gruppo di interfaccie lo, in questo modo, potremoin seguito aggiungere ulteriori interfaccie di loopback, non ci dovremo preoccupare di alterare questa porzione esistente delle regole di configurazione.

Scrub

Non c'e' ragione per non usare lo scrubbing di tutto il traffico in arrivo, questo si ottiene con una semplice linea:
scrub in

Network Address Translation

Per ottenere la NAT per tutta la rete locale si usa la seguente regola nat:
nat on $ext_if from !($ext_if) to any -> ($ext_if)

Il "!($ext_if)" potrebbe essere facilmente sostituito in questo caso da "$int_if", ma se si dovessero aggiungere più interfaccie interne, occorrerebbero più regole di NAT di questo tipo.

Dato che l'indirizzo IP sull'interfaccia esterna viene assegnata dinamicamente, le parentesi tra l'interfaccia traslata consentono a PF di adattarsi al cambiamento.

Desiderando anche il proxy FTP, metteremo anche la seguente ancora NAT:

nat-anchor "ftp-proxy/*"

Reindirizzamento

La prima regola di reindirizzamento necessaria e' per l' ftp-proxy(8) per consentire ai client FTP sulla rete locale di connettersi ai server FTP su Internet.
rdr-anchor "ftp-proxy/*"
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021

Da notare che questa regola riguarda solo la connessione FTP con la porta 21. Se gli utenti si collegano ai server FTP su altre porte sara' necessaria una lista per specificare la porta di destinazione, per esempio: from any to any port { 21, 2121 }.

La seconda regola di reindirizzamento si occupa delle connessioni da Internet alla porta 80 TCP del firewall. Si tratta di utenti che provano ad accedere al web server della rete. Questi tentativi di connessione vengono reindirizzati a COMP3:

rdr on $ext_if proto tcp from any to any port 80 -> $comp3

Regole di filtraggio

Ora le regole di filtraggio. Partiamo con la regola di default deny:
block in

A questo punto nulla passera' attraverso il firewall, persino dalla rete interna. Le regole seguenti apriranno le porte del firewall solo al traffico desiderato e alle eventuali interfaccie virtuali.

Da tenere a mente, PF può bloccare il traffico che arriva o parte dalle interfaccie. Per semplificare il tutto si può scegliere di filtrare il traffico in una direzione piuttosto che farlo per entrambe. Nel nostro caso scegliamo di filtrare il traffico entrante, ma quando il traffico è permesso in una interfaccia noi non cercheremo di ostacolarlo:

pass out keep state

Avremo bisogno di un'ancora per l'ftp-proxy(8):

anchor "ftp-proxy/*"
E' bene usare la protezione antispoof:
antispoof quick for { lo $int_if }

Ora apriamo le porte utilizzate dai servizi resi disponibili per Internet. Per prima cosa, il traffico destinato al firewall stesso:

pass in on $ext_if inet proto tcp from any to ($ext_if) \
   port $tcp_services flags S/SA keep state

Specificare le porte nella macro $tcp_services semplifica l'apertura di ulteriori, eventuali, servizi a Internet semplicemente aggiornando la macro e ricaricando le regole di configurazione. Per i servizi UDP si puo' creare una macro $udp_services e aggiungere una regola di filtraggio, simile a quella precedente, specificando proto udp.

Inoltre il traffico che attraverso una regola rdr viene trasferito al web server COMP3 deve passare attraverso il firewall:

pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
    flags S/SA synproxy state

Per essere un po' piu' sicuri, faremo uso del TCP SYN Proxy per proteggere ulteriormente il web server.

Per far passare il traffico ICMP:

pass in inet proto icmp all icmp-type $icmp_types keep state

Come per la macro $tcp_services ,anche la macro $icmp_types puo' essere modificata per scegliere i pacchetti ICMP ai quali viene permesso il passaggio attraverso il firewall. Da notare che questa regola si applica a tutte le interfaccie di rete.

Con queste regole il traffico consentito raggiungera' la rete interna. Si presume che gli utenti sulla rete locale sappiano cosa stanno facendo e non siano fonte di guai. Questa non e' una certezza assoluta e per questi sistemi sarebbero desiderabili delle regole di configurazione piu' restrittive.

pass in quick on $int_if

Al traffico TCP, UDP, e ICMP e' permesso di uscire dal firewall verso Internet a causa del precedente "pass out keep state". Le informazioni di stato sono conservate cosi' da consentire ai pacchetti di ritorno di passare attraverso il firewall.

Le regole di configurazione complete

# macro
ext_if="fxp0"
int_if="xl0"

tcp_services="{ 22, 113 }"
icmp_types="echoreq"

comp3="192.168.0.3"

# opzioni
set block-policy return
set loginterface $ext_if

set skip on lo

# scrub
scrub in

# nat/rdr
nat on $ext_if from !($ext_if) -> ($ext_if:0)
nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"

rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
rdr on $ext_if proto tcp from any to any port 80 -> $comp3

# regole di filtraggio
block in

pass out keep state

anchor "ftp-proxy/*"
antispoof quick for { lo $int_if }

pass in on $ext_if inet proto tcp from any to ($ext_if) \
   port $tcp_services flags S/SA keep state

pass in on $ext_if inet proto tcp from any to $comp3 port 80 \
    flags S/SA synproxy state

pass in inet proto icmp all icmp-type $icmp_types keep state

pass in quick on $int_if

[Precedente: Firewall Redundancy con CARP e pfsync] [Indice]


[back] www@openbsd.org
$OpenBSD: example1.html,v 1.2 2008/04/28 08:25:41 tobias Exp $