Linux: creare una rete Bastion Host con DMZ

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.

 

Linux: creare una rete Bastion Host con DMZultima modifica: 2009-04-28T19:57:00+02:00da nazarenolatella
Reposta per primo quest’articolo

12 pensieri su “Linux: creare una rete Bastion Host con DMZ

  1. 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…

  2. 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.

  3. 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..

  4. 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?

  5. 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.

  6. 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

  7. 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 😀

  8. 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.

  9. 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

  10. 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?

  11. 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.

I commenti sono chiusi.