Dopo aver parlato di alcune tra le possibili topologie di una rete facente uso dei cosiddetti Bastion Host, vediamo come configurare una DMZ posta dietro uno screened router e collegata all’altra estremità con un dual homed firewall, il quale svolge anche operazioni di routing e di port forwarding.
In particolare, ecco come si sviluppa la nostra piccola rete:
Screened router -> DMZ -> Bastion Host -> LAN
dove alla DMZ non andremo a collegare nessun host che deve fornire servizi (HTTP, FTP ecc.) contattabili dal network esterno (Internet), ma serve solo come link point-to-point tra lo screened router ed il Bastion Host.
Passiamo ora alla configurazione vera e propria del Bastion Host (basato su Debian). Come già detto in precedenza, esso è un dual-homed firewall, cioè è dotato di due schede di rete: eth0, alla quale è connessa la nostra LAN ed eth1, alla quale è collegata la DMZ.
Poichè trattasi di un collegamento point-to-point, può essere utilizzata la seguente subnet mask: 255.255.255.252, che in termini di CIDR viene rappresentata come una /30 (4 indirizzi in tutto di cui solo 2 utilizzabili). Assegniamo quindi all’interfaccia eth1 l’indirizzo IP 192.168.1.2, come subnet quella sopra citata e come gateway l’indirizzo del router, cioè 192.168.1.1. Possiamo eseguire tale operazione mediante il comando ifconfig oppure modificando il file /etc/network/interfaces:
root@nightbox:~$ nano /etc/network/interfaces
ed inseriamo le seguenti stringhe:
#Interfaccia esterna auto eth1 iface auto inet static address 192.168.1.2 netmask 255.255.255.252 network 192.168.1.0 broadcast 192.168.1.3 gateway 192.168.1.1
Andiamo ad impostare i DNS per la risoluzione dei nomi (altrimenti non potremmo navigare):
root@nightbox:~$ nano /etc/resolv.conf
ed inseriamo i seguenti parametri:
nameserver 151.99.125.2 nameserver 151.99.125.3
oppure i DNS forniti dal vostro ISP (potete utilizzare anche OpenDNS).
Proviamo adesso a pingare prima il router e successivamente google. Se ai ping seguono delle reply (in gergo “pong”), vuol dire che la configurazione è corretta.
Passiamo adesso alla scheda collegata alla LAN, cioè eth0. Associamola all’indirizzo 10.0.0.1 con subnet 255.255.255.0 (/24) e non definiamo alcun gateway.
root@nightbox:~$ nano /etc/network/interfaces #Interfaccia Interna auto eth0 iface auto inet static address 10.0.0.1 netmask 255.255.255.0 network 10.0.0.0 broadcast 10.0.0.255
Proviamo a pingare un qualsiasi host della LAN e se risponde vuol dire che anche tale configurazione risulta valida.
Bene, ora è necessario abilitare la comunicazione tra la scheda interna e quella esterna (disabilitata di default per motivi di sicurezza). Per fare ciò basta modificare il contenuto del file /proc/sysnet/ipv4/ip_forward inserendo al suo interno il valore 1 anzichè 0.
Poichè tale operazione deve essere eseguita in automatico ad ogni avvio del sistema, possiamo posizionare la seguente stringa all’interno del file /etc/rc.local e, per la precisione, tra i commenti ed exit 0.
#!/bin/sh -e # # rc.local # # This scrip is executed at the end of each multiuser runlevel. # Make sure that the scrip will "exit 0" on success or any other # value on error. # # In order to enable or disable this scrip just change the execution # bits. # # By default this scrip does nothing. #Attivo la comunicazione tra le due NIC echo 1 > /proc/sys/net/ipv4/ip_forward exit 0
Affinchè però un qualsiasi host della nostra LAN possa “uscire” su internet (cioè venga messa in sharing la connessione) è necessario attivare il masquerading, conosciuto anche come NAT (Network Address Translation). Possiamo farè ciò servendoci di iptables, cioè l’interfaccia testuale di NetFilter, il firewall installato di default in quasi tutte le distribuzioni linux:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
In questo modo, gli indirizzi della nostra LAN verranno tradotti in indirizzi della DMZ e successivamente in indirizzo IP pubblico grazie allo screened router.
Definiamo adesso le policy di default per il nostro firewall:
iptables -P INPUT DROP iptables -P OUTPUT ACCEPT iptables -P FORWARD DROP
Queste policy fanno in modo che qualunque pacchetto ricevuto in ingresso dal firewall venga scartato. Stesso discorso vale per un qualunque pacchetto che transita da una scheda di rete all’altra (forward).
Fatto ciò occorre che il firewall accetti in ingresso i pacchetti provenienti dalla nostra LAN, ovvero dall’interfaccia eth0:
iptables -P INPUT -i eth0 -j ACCEPT
Devono essere accettati in ingresso anche i pacchetti relativi ad una connessione già aperta, ad esempio una navigazione mediante browser:
iptables -A INPUT -m state --state ESTABLISHED, RELATED -j ACCEPT
Adesso settiamo le regole per lo scambio di pacchetti tra le due schede di rete. In particolare, possono transitare dalla scheda di rete esterna (eth1) alla scheda di rete interna (eth0) soltanto i pacchetti associati ad una qualsiasi connessione proveniente dalla nostra LAN:
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
Infine, permettiamo il transito di tutti i pacchetti provenienti dalla scheda interna verso quella esterna:
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
Ora non ci resta che settare il port forwarding per eventuali applicativi p2p:
iptables -t nat -A PREROUTING -p tcp --dport 4711 -i eth1 -j DNAT --to 10.0.0.3 iptables -t nat -A PREROUTING -p tcp --dport 4652 -i eth1 -j DNAT --to 10.0.0.4 iptables -t nat -A PREROUTING -p udp --dport 5889 -i eth1 -j DNAT --to 10.0.0.4 iptables -t nat -A PREROUTING -p tcp --dport 4662 -i eth1 -j DNAT --to 10.0.0.2 iptables -t nat -A PREROUTING -p udp --dport 4672 -i eth1 -j DNAT --to 10.0.0.2
Altre rules che potremo definire sono quelle contro l’IP Spoofing, il DoS ed eventuali trojan:
#IP Spoofing iptables -A INPUT -s 10.0.0.0/8 -i eth1 -j DROP iptables -A FORWARD -s 10.0.0.0/8 -i eth1 -j DROP iptables -A INPUT -s 172.16.0.0/12 -i eth1 -j DROP iptables -A FORWARD -s 172.16.0.0/12 -i eth1 -j DROP iptables -A INPUT -s 192.168.1.1 -i eth1 -j ACCEPT iptables -A FORWARD -s 192.168.1.1 -i eth1 -j ACCEPT iptables -A INPUT -s 192.168.0.0/16 -i eth1 -j DROP iptables -A FORWARD -s 192.168.0.0/16 -i eth1 -j DROP iptables -A INPUT -s 224.0.0.0/3 -j DROP iptables -A FORWARD -s 224.0.0.0/3 -j DROP iptables -A INPUT -s 127.0.0.1 -i eth1 -j DROP iptables -A FORWARD -s 127.0.0.1 -i eth1 -j DROP # Trojan (elite ports) iptables -A OUTPUT -o eth0 -p tcp --dport 31337 --sport 31337 -j DROP iptables -A FORWARD -o eth0 -p tcp --dport 31337 --sport 31337 -j DROP iptables -A OUTPUT -o eth0 -p tcp --dport 31338 --sport 31338 -j DROP iptables -A FORWARD -o eth0 -p tcp --dport 31338 --sport 31338 -j DROP iptables -A OUTPUT -o eth0 -p tcp --dport 31339 --sport 31339 -j DROP iptables -A FORWARD -o eth0 -p tcp --dport 31339 --sport 31339 -j DROP iptables -A OUTPUT -o eth0 -p tcp --dport 31340 --sport 31340 -j DROP iptables -A FORWARD -o eth0 -p tcp --dport 31340 --sport 31340 -j DROP #DoS iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 2/s -j ACCEPT iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
Possiamo anche definire qualche regola per il controllo delle sessioni (Stateful Inspection):
#Stateful Inspection iptables -A INPUT -m state --state INVALID -j DROP
NB: le regole vengono applicate in ordine sequenziale, ovvero seguendo l’ordine di inserimento. Nel caso in cui un dato pacchetto non rispetti nessuna delle regole precedentemente definite verranno applicate le policy di default.
Per evitare che questi comandi vengano inseriti manualmente dopo ogni riavvio del sistema, possiamo tranquillamente posizionarli all’interno del file rc.local, sempre prima della chiamata exit 0.
Abbiamo quasi completato la configurazione del nostro Bastion Host. Non ci resta che installare un IDS (Intrusion Detection System).
Quello che consiglio (perchè molto semplice ed affidabile) è snort (IDS net-based). Installiamolo sulla nostra macchina e successivamente configuriamolo tramite debconf (la rete interna deve essere identificata dagli indirizzi 10.0.0.0 e 192.168.1.0 mentre quella esterna con ANY):
root@nightbox:~$ apt-get install snort
visualizziamo il file di configurazione per vedere se è tutto a norma:
root@nightbox:~$nano /etc/snort/snort.conf
l’output dovrà essere il seguente (per le sezioni che abbiamo precedentemente configurato):
var HOME_NET [10.0.0.0/24,192.168.1.0/29] var EXTERNAL_NET any
possiamo anche scegliere il grado di accuratezza del file di log impostandolo da 0 (molto basso – minor spreco di risorse) a 1, 2 ecc..
Vediamo adesso se dopo l’installazione snort è attivo. Per fare ciò digitiamo:
root@nightbox:~$ ps aux | grep snort
nel caso in cui non risulti avviato, facciamolo noi tramite il comando:
root@nightbox:~$ /etc/init.d/snort start
Infine, per visualizzare gli alert basta leggere il file /var/log/snort/alert
root@nightbox:~$ cat /var/log/snort/alert
Ora la nostra LAN può ritenersi “sicura”. A presto.
credo ormai sia inutile commentare questo articolo in quanto ormai datato.. ma ci provo:
Ho settato il mio Bastion come descritto sopra, e fila abbastanza tutto liscio tranne nelle policies di default, le quali se settate come descritto sopra non riesco a navigare.. solo se modifico la voce iptables -P FORWARD DROP in
iptables -P FORWARD ACCEPT riprendo a navigare, ma negondomi comunque l’accesso ssh al Bastion, che comunque dovendo essere un host praticamente blindato, non mi dispiace affatto questa mutilazione.. ma comunque non segue la logica che settiamo dopo co le altre iptables, specialmente quella dove si accetta tutte le richieste dalla LAN (eth0)..
Premetto che la mia situazione è un po diversa da quella sopra perche usa la distro Ubuntu server 11.04, ma comunque i programmi installati sono i soliti e i file di configurazione sono settati nella solita maniera…
Probabilmente si tratta nella nomenclatura delle schede di rete. Nella policy che ho inserito in questo post, ovvero:
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
la scheda interna è l’eth0, mentre quella esterna è l’eth1. Controlla che anche da te sia effettivamente così.
E’ molto importante anche la seguente regola:
iptables -A FORWARD -i eth1 -o eth0 -m state –state ESTABLISHED,RELATED -j ACCEPT
che consente il traffico dei pacchetti dalla schede esterna a quella interna SOLO per i pacchetti la cui sessione ha come origine la scheda interna. Fammi sapere, ciao.
che piacere vedere che non è morto questo articolo… al nome delle interfaccie ho dato molta attenzione in quanto le mie interfaccie sono deverse perche uso per la rete esterna wlan0 e per quella interna è eth0.. sono certo che anche la regola da te citata l’ho inserita.. nel mio caso quindi diventa:
iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -m state –state ESTABLISHED,RELATED -j ACCEPT;
c’è un’altro file che potrebbe interferire con iptables?
inizialmente il moio bastion era configurato con firehol, il quale faceva da solo il routing tra le interfeccie ma non era settato in nessuna maniera, quindi non filtrava nessun tipo di pacchetti, cioè direzionava tutto il traffico di wlan0 su eth0..
l’ho rimosso con un apt-get remove–purge firehol, estirpando anche i relativi file di configurazione..
ecco dov’è il nostro errore probabilmente.. avviando il PC con uno schermo connesso, è apparso un’errore che non riuscivo a vedere tramite ssh:
rc-sysinit start/running, process 1974
iptables v1.4.10: -x requires a chain and a policy
try ‘iptables -h’ or ‘iptables –help’ for more informations..
che succede secondo te?
Non saprei, molto probabilmente c’è qualche servizio in autorun che prova ad avviare iptables con la flag -X. Questo servizio cozza con il tuo file rc.local in cui hai inserito le regole di firewalling. La rogna è che quando iptables non digerisce qualche rule blocca TUTTO il traffico…
Ti riporto dall’output del –help il significato della flag -X:
–delete-chain
-X [chain] Delete a user-defined chain
Fai un’analisi del file del syslog ed individua qual è il servizio che prova ad avviare iptables.
stavo giusto per guardare.. leggendo nella documentazione di ubuntu leggo che networkmanager potrebbe avere dei conflitti con iptables… uffff, guardiamo un po cosa dicono i log, a presto
Queste sono le impostazioni che mi fanno navigare e connettere tramite ssh, ma temo che non faccia il suo lavoro, mi spiego meglio, vorrei che il pc accettasse solo le connessioni ssh e internet da eth0..
*nat
:PREROUTING ACCEPT [22:1679]
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o wlan0 -j MASQUERADE
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [83:5149]
:OUTPUT ACCEPT [49:6788]
-A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp –dport 22 -j ACCEPT
-A INPUT -j DROP
COMMIT
le regole che mi danno errori con -X sono :
iptables -P INPUT -i eth0 -j ACCEPT
iptables -A INPUT -m state –state ESTABLISHED, RELATED -j ACCEPT
visto che sono con ubuntu server non credo che sia networkmanager a gestirmi la connessione, nei processi difatti non c’e 😀
Ma da dove hai ricavato questo output? Perchè definisci il comportamento di alcune chains sia qui
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
che qui
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [83:5149]
:OUTPUT ACCEPT [49:6788]
Ricontrolla il tutto, è possibile uno shadowing delle regole. Ricorda che è estremamente importante l’ordine delle rules, al primo match IPTABLES smette di scorrere la lista.
le prie 5 voci sono le regole che impartisce il nat attivato con
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
difatti c’e scritto *nat
quelle righe a tua insaputa le aggiungi anche te tra le regole di iptables..
poi quelle sotto sono i filtri che aggiungiamo noi al nat
Il file sopra lo ricavi digitando iptables-save > nomechevuoi
dopo di che con l’editor, io uso nano
nano nomechevuoi
ed avrai un file con le regole da te impartite, puoi modificarle a tuo piacimento per poi testarle con
iptables-apply nomechevuoi
cosi se tutto funziona puoi registrarle con
iptables-restore < nomechevuoi
Sinceramente non ho mai utilizzato questo approccio, preferisco lavorare direttamente sul file rc.local. In questo modo ho un set di regole molto più pulito. Se fai semplicemente un iptables -L cosa ricevi in output?
non riesco ad inserire il mio iptables -L, mi manda ad ul tuo ultimo post…
Non so che dirti, forse dipende dalle impostazioni di myblog. Prova ad inviarmi l’output in pvt. Il mio indirizzo email lo trovi sul CV.