HexDEF6
24-11-2008, 15:14
Ciao,
siccome ho un po sistemato il firewall qui al lavoro, e l'ho reso piu' semplice da modificare, ho speso una mezzoretta a pulirlo dalle schifezze necessarie per alcune esigenze particolari e ho deciso di pubblicare lo script.
Questo perche' il firewall puo' essere modificato via file di CONFIG senza "quasi" sapere un tubo di iptables...
un po di info:
questo script va fatto girare su un server che ha 3 interfaccie di rete (INT per quella internet, DMZ e LAN)
la LAN viene considereata TRUSTED, quindi se qualcuno vuole fare danni dalla LAN puo' farlo!... e quindi chi e' in LAN puo' fare connessioni verso la DMZ e internet su qualunque porta...
lo script genera un minimo di log... e quando li genera' e' meglio darci un'occhiata perche' quel traffico che logga non dovrebbe esserci! (non loggo le connessioni fatte da internet verso il server... altrimenti avrei chilometri di log inutili... ma logga il traffico che la dmz fa verso la LAN, il server verso la DMZ, la DMZ verso internet)
lo scirpt e' fatto in modo che possa essere "facilmente" modificato (facilmente per me che l'ho scritto..... forse :D diciamo che spero che fra 3 mesi quando lo modifico di non perdermi!! :D ), ovviamente potrebbe aver delle rogne grossissime di cui non mi sono accorto... (e anche per questo lo pubblico, in modo che qualcuno ci dia una seconda occhiata)...
per esempio se uno scrive una regola "male" (tipo al posto di un ip scrive "cicciobello"..) lo script puo' andare al becco... quindi per i primi test meglio se avete accesso fisico sulla macchina dove lo lanciate!
Lo script potrebbe essere usato anche senza avere una dmz... e c'e' una parte fatta in modo che si possano redirigere delle porte verso le macchine della LAN... ovviamente sconsiglio questo utilizzo, visto che la DMZ e' fatta apposta per ospitare i servizi (ma lo so che qualcuno anche con una DMZ ha il mulo nella LAN!)
ecco i 2 file:
CONFIG
IPT=/sbin/iptables
NET="eth0"
LAN="eth1"
DMZ="eth2"
LO="lo"
#lista di ip (separati da spazio) che usano le macchine in dmz per fare update... tutte le connessioni dalla DMZ verso questi ip alle porte ftp e http verranno accettate
IP_UPDATE="XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY"
#inserire il proprio ip pubblico (quello dell'interfaccia eth0)
IP_NET="WWW.WWW.WWW.WWW"
IP_LAN="192.168.10.1"
IP_DMZ="192.168.20.1"
IP_LO="127.0.0.1"
RANGE_IP_LAN="192.168.10.0/24"
RANGE_IP_DMZ="192.168.20.0/24"
#lista di porte di cui viene generato automaticamente il postrouting
#e' impostata solo per la porta 25 e 53 (smtp e dns) in modo che se ho un server DNS/SMTP nella DMZ, questo posssa fare connessioni verso l'esterno
POSTROUTING_PORTS="25 53"
#una regola va scritta in questa maniera:
#RULE="IP_ESTERNO PORTA_ESTERNA IP_INTERNO PORTA_INTERNA PROTOCOLLO IP_ESTERNO_DA_CUI_VENGONO_ACCETTATE_LE_CONNESSIONI"
#se la porta esterna e' messa a 0, verranno redirette tutte le porte, se l'ip esterno da cui vengono accettate tutte le connessioni e' 0 verranno accettati tutti gli ip
#inserire le regole che si vogliono attivare in PASS_TO_LAN o PASS_TO_DMZ
#verranno attivate solo le regole in PASS_TO_LAN... se non si vuole niente di attivo, impostare PASS_TO_LAN a 0
#quando avro' bisogno di vnc (e' solo un test non utilizzate vnc in chiaro su internet!) bastera' modificare PASS_TO_LAN="VNC"
PASS_TO_LAN="0"
VNC="WWW.WWW.WWW.WWW 5903 192.168.10.10 5900 tcp 0"
#in questo caso ho attivato tutte le regole scritte, tranne HTTP2...
#e redirigo le connessioni fatte su WWW.WWW.WWW.WWW porta 10022 sulla porta ssh di 192.168.20.40 solo se la connessione proviene dall'ip 123.45.67.89
PASS_TO_DMZ="HTTP HTTPS SMTP DNS_TCP DNS_UDP SSH"
#regola per redirigere sull'ip della dmz 192.168.20.10 tutte le connessioni ricevute sull'ip WWW.WWW.WWW.WWW
HTTP="WWW.WWW.WWW.WWW 80 192.168.20.10 80 tcp 0"
HTTPS="WWW.WWW.WWW.WWW 443 192.168.20.10 443 tcp 0"
DNS_TCP="WWW.WWW.WWW.WWZ 53 192.168.20.30 53 tcp 0"
DNS_UDP="WWW.WWW.WWW.WWZ 53 192.168.20.30 53 udp 0"
SMTP="WWW.WWW.WWW.WWX 25 192.168.20.20 25 tcp 0"
HTTP2="WWW.WWW.WWW.WWX 80 192.168.20.40 80 tcp 0"
SSH="WWW.WWW.WWW.WWW 10022 192.168.20.40 22 tcp 123.45.67.89"
SERVER_OUT="OUT_FTP OUT_HTTP OUT_HTTPS OUT_SSH OUT_DNS OUT_NTP"
OUT_FTP="0.0.0.0/0.0.0.0 80 tcp"
OUT_HTTP="0.0.0.0/0.0.0.0 80 tcp"
OUT_HTTPS="0.0.0.0/0.0.0.0 443 tcp"
OUT_SSH="0.0.0.0/0.0.0.0 22 tcp"
OUT_DNS="0.0.0.0/0.0.0.0 53 udp"
OUT_NTP="0.0.0.0/0.0.0.0 123 udp"
firewall.sh
#!/bin/bash
WORKDIR="./"
#faccio un source del file di configurazione (con le dichiarazioni delle reti ecc.)
. $WORKDIR/CONFIG
#pulisco tutto
$IPT -F
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD
$IPT -F -t mangle
$IPT -F -t nat
$IPT -X
#imposto il comportamento di default
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
#abilito l'ip forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward
#creo dei chan nuovi per "ogni" tipo di connessione (vedi sotto)
$IPT -N dmz_to_lan
$IPT -N dmz_to_net
$IPT -N dmz_to_server
$IPT -N lan_to_dmz
$IPT -N lan_to_net
$IPT -N lan_to_server
$IPT -N net_to_dmz
$IPT -N net_to_lan
$IPT -N net_to_server
$IPT -N server_to_dmz
$IPT -N server_to_lan
$IPT -N server_to_net
#accetto in input sull'interfaccia LO tutto quello che viene dagli ip locali
$IPT -A INPUT -p ALL -i $LO -s $IP_LO -j ACCEPT
$IPT -A INPUT -p ALL -i $LO -s $IP_LAN -j ACCEPT
$IPT -A INPUT -p ALL -i $LO -s $IP_NET -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LO -d $IP_LO -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LO -d $IP_LAN -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LO -d $IP_NET -j ACCEPT
#rispondo ai ping e permetto al server di usare gli icmp
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A OUTPUT -p icmp -j ACCEPT
#natto la dmz
if [ "$PASS_TO_DMZ" != "0" ]
then
for RULES in $PASS_TO_DMZ
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
IP_DMZ=$(eval echo \$$RULES | cut -d " " -f 3)
PORT_DMZ=$(eval echo \$$RULES | cut -d " " -f 4)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 5)
IP_EXT=$(eval echo \$$RULES | cut -d " " -f 6)
if [ "$IP_EXT" != "0" ]
then
IP_SRC=" -s $IP_EXT "
IP_SRC_TXT=" solo se la connessione proviene da $IP_EXT"
else
IP_SRC=""
IP_SRC_TXT=""
fi
if [ "$PORT" -eq "0" ]
then
echo -e "\nREGOLA $RULES: ip esterno $IP rediretto in DMZ su $IP_DMZ $IP_SRC_TXT"
$IPT -t nat -A PREROUTING $IP_SRC -d $IP -j DNAT --to $IP_DMZ
else
echo -e "\nREGOLA $RULES: ip esterno $IP porta $PORT rediretto in DMZ su $IP_DMZ sulla porta $PORT_DMZ $IP_SRC_TXT protocollo $PROTOCOL"
$IPT -t nat -A PREROUTING $IP_SRC -d $IP -p $PROTOCOL --dport $PORT -j DNAT --to $IP_DMZ:$PORT_DMZ
for post_port in $POSTROUTING_PORTS
do
if [ $post_port -eq $PORT ]
then
echo "attivo il postrouting per l'ip $IP_DMZ porta $PORT_DMZ sull'ip $IP porta $PORT protocollo $PROTOCOL"
$IPT -t nat -A POSTROUTING -o $NET -s $IP_DMZ -p $PROTOCOL --dport $PORT -j SNAT --to-source $IP
fi
done
fi
done
fi
if [ "$PASS_TO_LAN" != "0" ]
then
for RULES in $PASS_TO_LAN
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
IP_LAN=$(eval echo \$$RULES | cut -d " " -f 3)
PORT_LAN=$(eval echo \$$RULES | cut -d " " -f 4)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 5)
IP_EXT=$(eval echo \$$RULES | cut -d " " -f 6)
if [ "$IP_EXT" != "0" ]
then
IP_SRC=" -s $IP_EXT "
IP_SRC_TXT=" solo se la connessione proviene da $IP_EXT"
else
IP_SRC=""
IP_SRC_TXT=""
fi
if [ "$PORT" -eq "0" ]
then
echo -e "\nREGOLA $RULES: ip esterno $IP rediretto in LAN su $IP_LAN $IP_SRC_TXT compreso di postrouting"
$IPT -t nat -A PREROUTING -i $NET $IP_SRC -d $IP -j DNAT --to $IP_LAN
$IPT -t nat -I POSTROUTING -o $NET -s $IP_LAN -j SNAT --to-source $IP
else
echo -e "\nREGOLA $RULES: ip esterno $IP porta $PORT rediretto in LAN su $IP_LAN sulla porta $PORT_LAN $IP_SRC_TXT protocollo $PROTOCOL"
$IPT -t nat -A PREROUTING -i $NET $IP_SRC -d $IP -p $PROTOCOL --dport $PORT -j DNAT --to $IP_LAN:$PORT_LAN
fi
done
fi
#e snatto gli update
for IP in $IP_UPDATE
do
$IPT -t nat -A POSTROUTING -o $NET -s $RANGE_IP_DMZ -d $IP -p tcp --dport 21 -j SNAT --to-source $IP_NET
$IPT -t nat -A POSTROUTING -o $NET -s $RANGE_IP_DMZ -d $IP -p tcp --dport 80 -j SNAT --to-source $IP_NET
done
#source nat se esco su internet cambio l'ip del sorgente con l'ip pubblico di eth0
$IPT -t nat -A POSTROUTING -o $NET -s $RANGE_IP_LAN -j SNAT --to-source $IP_NET
#divido le connessioni (FORWARD) in base alla provenienza/destinazione
$IPT -A FORWARD -i $DMZ -o $LAN -j dmz_to_lan
$IPT -A FORWARD -i $DMZ -o $NET -j dmz_to_net
$IPT -A FORWARD -i $LAN -o $DMZ -j lan_to_dmz
$IPT -A FORWARD -i $LAN -o $NET -j lan_to_net
$IPT -A FORWARD -i $NET -o $DMZ -j net_to_dmz
$IPT -A FORWARD -i $NET -o $LAN -j net_to_lan
#divido le connessioni in input
$IPT -A INPUT -i $DMZ -j dmz_to_server
$IPT -A INPUT -i $LAN -j lan_to_server
$IPT -A INPUT -i $NET -j net_to_server
#divido le connessioni in output
$IPT -A OUTPUT -o $DMZ -j server_to_dmz
$IPT -A OUTPUT -o $LAN -j server_to_lan
$IPT -A OUTPUT -o $NET -j server_to_net
### SERVER INPUT
#il server di frontiera non dovrebbe ricevere nulla dalla DMZ tranne le rsiposte ai propri pacchetti,
#quindi loggo e droppo
$IPT -A dmz_to_server -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A dmz_to_server -j LOG --log-prefix input_dmz:
#considero trusted le macchine registrate nella LAN, e quindi accetto tutte le connessioni provenienti da essa
$IPT -A lan_to_server -j ACCEPT
#il server non accetta nulla in ingresso (dall'interfaccia internet), tranne le related
$IPT -A net_to_server -m state --state RELATED,ESTABLISHED -j ACCEPT
### SERVER OUTPUT
#il server non puo' fare connessioni verso la DMZ... quindi loggo
$IPT -A server_to_dmz -j LOG --log-prefix output_dmz:
#il server puo' "uscire" verso la LAN trusted
$IPT -A server_to_lan -j ACCEPT
#genero in automatico le connessioni che puo' fare il server verso internet (oltre alle related)
$IPT -A server_to_net -m state --state RELATED,ESTABLISHED -j ACCEPT
#regola speciale per la vpn
if [ "$SERVER_OUT" != "0" ]
then
for RULES in $SERVER_OUT
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 3)
if [ "$PORT" -eq "0" ]
then
echo -e "\nREGOLA $RULES: il server esce verso ip $IP su tutte le porte"
$IPT -A server_to_net -d $IP -j ACCEPT
else
echo -e "\nREGOLA $RULES: il server esce verso ip $IP porta $PORT protocollo $PROTOCOL"
$IPT -A server_to_net -d $IP -p $PROTOCOL --dport $PORT -j ACCEPT
fi
done
fi
#loggo le altre connessioni che fa il server verso internet
$IPT -A server_to_net -j LOG --log-prefix server_to_net:
### DMZ
#dalla dmz verso la lan accetto solamente le connessioni related ed estabilished... e il resto lo loggo
$IPT -A dmz_to_lan -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A dmz_to_lan -j LOG --log-prefix dmz_to_lan:
#dalla DMZ verso internet accetto solo le connesioni related o estabilished
#o per fare l'update della macchina verso gli ip predefiniti e solo verso le porte di http e ftp
$IPT -A dmz_to_net -m state --state RELATED,ESTABLISHED -j ACCEPT
for IP in $IP_UPDATE
do
$IPT -A dmz_to_net -s $RANGE_IP_DMZ -d $IP -p tcp --dport 21 -j ACCEPT
$IPT -A dmz_to_net -s $RANGE_IP_DMZ -d $IP -p tcp --dport 80 -j ACCEPT
done
#vengono generate in automatico quelle per DNS e SMTP (vedi sotto)
$IPT -A dmz_to_net -j LOG --log-prefix dmz_to_net:
### LAN
#accetto tutte le connessioni fatte dalla LAN verso la DMZ....
$IPT -A lan_to_dmz -j ACCEPT
#dalla LAN permetto di uscire su tutte le porte
$IPT -A lan_to_net -j ACCEPT
### INTERNET
#accetto le connessioni da internet verso la dmz, quando sono related o established
#per via del prerouting probabilmente queste regole sono superflue... si potrebbe mettere un ACCEPT e basta
$IPT -A net_to_dmz -m state --state RELATED,ESTABLISHED -j ACCEPT
if [ "$PASS_TO_DMZ" != "0" ]
then
for RULES in $PASS_TO_DMZ
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
IP_DMZ=$(eval echo \$$RULES | cut -d " " -f 3)
PORT_DMZ=$(eval echo \$$RULES | cut -d " " -f 4)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 5)
IP_EXT=$(eval echo \$$RULES | cut -d " " -f 6)
if [ "$IP_EXT" != "0" ]
then
IP_SRC=" -s $IP_EXT "
else
IP_SRC=""
fi
if [ "$PORT" -eq "0" ]
then
$IPT -A net_to_dmz $IP_SRC -d $IP_DMZ -j ACCEPT
else
$IPT -A net_to_dmz $IP_SRC -d $IP_DMZ -p $PROTOCOL --dport $PORT_DMZ -j ACCEPT
for post_port in $POSTROUTING_PORTS
do
if [ $post_port -eq $PORT ]
then
# questa regola vale solo per i servizi di tipo smtp e dns (vedi POSTROUTING_PORTS nel file di CONFIG)
#notare il -I, cosi che la regola venga inserita prima di quella di log
$IPT -I dmz_to_net -s $IP_DMZ -p $PROTOCOL --dport $PORT -j ACCEPT
fi
done
fi
done
fi
#da internet verso la LAN accetto solo le connessioni related,estabilished
$IPT -A net_to_lan -m state --state RELATED,ESTABLISHED -j ACCEPT
#e leconnessioni che rigiro in LAN (da usare con cautela! c'e' la DMZ apposta!)
if [ "$PASS_TO_LAN" != "0" ]
then
for RULES in $PASS_TO_LAN
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
IP_LAN=$(eval echo \$$RULES | cut -d " " -f 3)
PORT_LAN=$(eval echo \$$RULES | cut -d " " -f 4)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 5)
IP_EXT=$(eval echo \$$RULES | cut -d " " -f 6)
if [ "$IP_EXT" != "0" ]
then
IP_SRC=" -s $IP_EXT "
else
IP_SRC=""
fi
if [ "$PORT" -eq "0" ]
then
$IPT -A net_to_lan $IP_SRC -d $IP_LAN -j ACCEPT
else
$IPT -A net_to_lan $IP_SRC -d $IP_LAN -p $PROTOCOL --dport $PORT_LAN -j ACCEPT
fi
done
fi
buon divertimento... e se avete suggerimenti sono i benvenuti
siccome ho un po sistemato il firewall qui al lavoro, e l'ho reso piu' semplice da modificare, ho speso una mezzoretta a pulirlo dalle schifezze necessarie per alcune esigenze particolari e ho deciso di pubblicare lo script.
Questo perche' il firewall puo' essere modificato via file di CONFIG senza "quasi" sapere un tubo di iptables...
un po di info:
questo script va fatto girare su un server che ha 3 interfaccie di rete (INT per quella internet, DMZ e LAN)
la LAN viene considereata TRUSTED, quindi se qualcuno vuole fare danni dalla LAN puo' farlo!... e quindi chi e' in LAN puo' fare connessioni verso la DMZ e internet su qualunque porta...
lo script genera un minimo di log... e quando li genera' e' meglio darci un'occhiata perche' quel traffico che logga non dovrebbe esserci! (non loggo le connessioni fatte da internet verso il server... altrimenti avrei chilometri di log inutili... ma logga il traffico che la dmz fa verso la LAN, il server verso la DMZ, la DMZ verso internet)
lo scirpt e' fatto in modo che possa essere "facilmente" modificato (facilmente per me che l'ho scritto..... forse :D diciamo che spero che fra 3 mesi quando lo modifico di non perdermi!! :D ), ovviamente potrebbe aver delle rogne grossissime di cui non mi sono accorto... (e anche per questo lo pubblico, in modo che qualcuno ci dia una seconda occhiata)...
per esempio se uno scrive una regola "male" (tipo al posto di un ip scrive "cicciobello"..) lo script puo' andare al becco... quindi per i primi test meglio se avete accesso fisico sulla macchina dove lo lanciate!
Lo script potrebbe essere usato anche senza avere una dmz... e c'e' una parte fatta in modo che si possano redirigere delle porte verso le macchine della LAN... ovviamente sconsiglio questo utilizzo, visto che la DMZ e' fatta apposta per ospitare i servizi (ma lo so che qualcuno anche con una DMZ ha il mulo nella LAN!)
ecco i 2 file:
CONFIG
IPT=/sbin/iptables
NET="eth0"
LAN="eth1"
DMZ="eth2"
LO="lo"
#lista di ip (separati da spazio) che usano le macchine in dmz per fare update... tutte le connessioni dalla DMZ verso questi ip alle porte ftp e http verranno accettate
IP_UPDATE="XXX.XXX.XXX.XXX YYY.YYY.YYY.YYY"
#inserire il proprio ip pubblico (quello dell'interfaccia eth0)
IP_NET="WWW.WWW.WWW.WWW"
IP_LAN="192.168.10.1"
IP_DMZ="192.168.20.1"
IP_LO="127.0.0.1"
RANGE_IP_LAN="192.168.10.0/24"
RANGE_IP_DMZ="192.168.20.0/24"
#lista di porte di cui viene generato automaticamente il postrouting
#e' impostata solo per la porta 25 e 53 (smtp e dns) in modo che se ho un server DNS/SMTP nella DMZ, questo posssa fare connessioni verso l'esterno
POSTROUTING_PORTS="25 53"
#una regola va scritta in questa maniera:
#RULE="IP_ESTERNO PORTA_ESTERNA IP_INTERNO PORTA_INTERNA PROTOCOLLO IP_ESTERNO_DA_CUI_VENGONO_ACCETTATE_LE_CONNESSIONI"
#se la porta esterna e' messa a 0, verranno redirette tutte le porte, se l'ip esterno da cui vengono accettate tutte le connessioni e' 0 verranno accettati tutti gli ip
#inserire le regole che si vogliono attivare in PASS_TO_LAN o PASS_TO_DMZ
#verranno attivate solo le regole in PASS_TO_LAN... se non si vuole niente di attivo, impostare PASS_TO_LAN a 0
#quando avro' bisogno di vnc (e' solo un test non utilizzate vnc in chiaro su internet!) bastera' modificare PASS_TO_LAN="VNC"
PASS_TO_LAN="0"
VNC="WWW.WWW.WWW.WWW 5903 192.168.10.10 5900 tcp 0"
#in questo caso ho attivato tutte le regole scritte, tranne HTTP2...
#e redirigo le connessioni fatte su WWW.WWW.WWW.WWW porta 10022 sulla porta ssh di 192.168.20.40 solo se la connessione proviene dall'ip 123.45.67.89
PASS_TO_DMZ="HTTP HTTPS SMTP DNS_TCP DNS_UDP SSH"
#regola per redirigere sull'ip della dmz 192.168.20.10 tutte le connessioni ricevute sull'ip WWW.WWW.WWW.WWW
HTTP="WWW.WWW.WWW.WWW 80 192.168.20.10 80 tcp 0"
HTTPS="WWW.WWW.WWW.WWW 443 192.168.20.10 443 tcp 0"
DNS_TCP="WWW.WWW.WWW.WWZ 53 192.168.20.30 53 tcp 0"
DNS_UDP="WWW.WWW.WWW.WWZ 53 192.168.20.30 53 udp 0"
SMTP="WWW.WWW.WWW.WWX 25 192.168.20.20 25 tcp 0"
HTTP2="WWW.WWW.WWW.WWX 80 192.168.20.40 80 tcp 0"
SSH="WWW.WWW.WWW.WWW 10022 192.168.20.40 22 tcp 123.45.67.89"
SERVER_OUT="OUT_FTP OUT_HTTP OUT_HTTPS OUT_SSH OUT_DNS OUT_NTP"
OUT_FTP="0.0.0.0/0.0.0.0 80 tcp"
OUT_HTTP="0.0.0.0/0.0.0.0 80 tcp"
OUT_HTTPS="0.0.0.0/0.0.0.0 443 tcp"
OUT_SSH="0.0.0.0/0.0.0.0 22 tcp"
OUT_DNS="0.0.0.0/0.0.0.0 53 udp"
OUT_NTP="0.0.0.0/0.0.0.0 123 udp"
firewall.sh
#!/bin/bash
WORKDIR="./"
#faccio un source del file di configurazione (con le dichiarazioni delle reti ecc.)
. $WORKDIR/CONFIG
#pulisco tutto
$IPT -F
$IPT -F INPUT
$IPT -F OUTPUT
$IPT -F FORWARD
$IPT -F -t mangle
$IPT -F -t nat
$IPT -X
#imposto il comportamento di default
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
#abilito l'ip forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward
#creo dei chan nuovi per "ogni" tipo di connessione (vedi sotto)
$IPT -N dmz_to_lan
$IPT -N dmz_to_net
$IPT -N dmz_to_server
$IPT -N lan_to_dmz
$IPT -N lan_to_net
$IPT -N lan_to_server
$IPT -N net_to_dmz
$IPT -N net_to_lan
$IPT -N net_to_server
$IPT -N server_to_dmz
$IPT -N server_to_lan
$IPT -N server_to_net
#accetto in input sull'interfaccia LO tutto quello che viene dagli ip locali
$IPT -A INPUT -p ALL -i $LO -s $IP_LO -j ACCEPT
$IPT -A INPUT -p ALL -i $LO -s $IP_LAN -j ACCEPT
$IPT -A INPUT -p ALL -i $LO -s $IP_NET -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LO -d $IP_LO -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LO -d $IP_LAN -j ACCEPT
$IPT -A OUTPUT -p ALL -o $LO -d $IP_NET -j ACCEPT
#rispondo ai ping e permetto al server di usare gli icmp
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A OUTPUT -p icmp -j ACCEPT
#natto la dmz
if [ "$PASS_TO_DMZ" != "0" ]
then
for RULES in $PASS_TO_DMZ
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
IP_DMZ=$(eval echo \$$RULES | cut -d " " -f 3)
PORT_DMZ=$(eval echo \$$RULES | cut -d " " -f 4)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 5)
IP_EXT=$(eval echo \$$RULES | cut -d " " -f 6)
if [ "$IP_EXT" != "0" ]
then
IP_SRC=" -s $IP_EXT "
IP_SRC_TXT=" solo se la connessione proviene da $IP_EXT"
else
IP_SRC=""
IP_SRC_TXT=""
fi
if [ "$PORT" -eq "0" ]
then
echo -e "\nREGOLA $RULES: ip esterno $IP rediretto in DMZ su $IP_DMZ $IP_SRC_TXT"
$IPT -t nat -A PREROUTING $IP_SRC -d $IP -j DNAT --to $IP_DMZ
else
echo -e "\nREGOLA $RULES: ip esterno $IP porta $PORT rediretto in DMZ su $IP_DMZ sulla porta $PORT_DMZ $IP_SRC_TXT protocollo $PROTOCOL"
$IPT -t nat -A PREROUTING $IP_SRC -d $IP -p $PROTOCOL --dport $PORT -j DNAT --to $IP_DMZ:$PORT_DMZ
for post_port in $POSTROUTING_PORTS
do
if [ $post_port -eq $PORT ]
then
echo "attivo il postrouting per l'ip $IP_DMZ porta $PORT_DMZ sull'ip $IP porta $PORT protocollo $PROTOCOL"
$IPT -t nat -A POSTROUTING -o $NET -s $IP_DMZ -p $PROTOCOL --dport $PORT -j SNAT --to-source $IP
fi
done
fi
done
fi
if [ "$PASS_TO_LAN" != "0" ]
then
for RULES in $PASS_TO_LAN
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
IP_LAN=$(eval echo \$$RULES | cut -d " " -f 3)
PORT_LAN=$(eval echo \$$RULES | cut -d " " -f 4)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 5)
IP_EXT=$(eval echo \$$RULES | cut -d " " -f 6)
if [ "$IP_EXT" != "0" ]
then
IP_SRC=" -s $IP_EXT "
IP_SRC_TXT=" solo se la connessione proviene da $IP_EXT"
else
IP_SRC=""
IP_SRC_TXT=""
fi
if [ "$PORT" -eq "0" ]
then
echo -e "\nREGOLA $RULES: ip esterno $IP rediretto in LAN su $IP_LAN $IP_SRC_TXT compreso di postrouting"
$IPT -t nat -A PREROUTING -i $NET $IP_SRC -d $IP -j DNAT --to $IP_LAN
$IPT -t nat -I POSTROUTING -o $NET -s $IP_LAN -j SNAT --to-source $IP
else
echo -e "\nREGOLA $RULES: ip esterno $IP porta $PORT rediretto in LAN su $IP_LAN sulla porta $PORT_LAN $IP_SRC_TXT protocollo $PROTOCOL"
$IPT -t nat -A PREROUTING -i $NET $IP_SRC -d $IP -p $PROTOCOL --dport $PORT -j DNAT --to $IP_LAN:$PORT_LAN
fi
done
fi
#e snatto gli update
for IP in $IP_UPDATE
do
$IPT -t nat -A POSTROUTING -o $NET -s $RANGE_IP_DMZ -d $IP -p tcp --dport 21 -j SNAT --to-source $IP_NET
$IPT -t nat -A POSTROUTING -o $NET -s $RANGE_IP_DMZ -d $IP -p tcp --dport 80 -j SNAT --to-source $IP_NET
done
#source nat se esco su internet cambio l'ip del sorgente con l'ip pubblico di eth0
$IPT -t nat -A POSTROUTING -o $NET -s $RANGE_IP_LAN -j SNAT --to-source $IP_NET
#divido le connessioni (FORWARD) in base alla provenienza/destinazione
$IPT -A FORWARD -i $DMZ -o $LAN -j dmz_to_lan
$IPT -A FORWARD -i $DMZ -o $NET -j dmz_to_net
$IPT -A FORWARD -i $LAN -o $DMZ -j lan_to_dmz
$IPT -A FORWARD -i $LAN -o $NET -j lan_to_net
$IPT -A FORWARD -i $NET -o $DMZ -j net_to_dmz
$IPT -A FORWARD -i $NET -o $LAN -j net_to_lan
#divido le connessioni in input
$IPT -A INPUT -i $DMZ -j dmz_to_server
$IPT -A INPUT -i $LAN -j lan_to_server
$IPT -A INPUT -i $NET -j net_to_server
#divido le connessioni in output
$IPT -A OUTPUT -o $DMZ -j server_to_dmz
$IPT -A OUTPUT -o $LAN -j server_to_lan
$IPT -A OUTPUT -o $NET -j server_to_net
### SERVER INPUT
#il server di frontiera non dovrebbe ricevere nulla dalla DMZ tranne le rsiposte ai propri pacchetti,
#quindi loggo e droppo
$IPT -A dmz_to_server -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A dmz_to_server -j LOG --log-prefix input_dmz:
#considero trusted le macchine registrate nella LAN, e quindi accetto tutte le connessioni provenienti da essa
$IPT -A lan_to_server -j ACCEPT
#il server non accetta nulla in ingresso (dall'interfaccia internet), tranne le related
$IPT -A net_to_server -m state --state RELATED,ESTABLISHED -j ACCEPT
### SERVER OUTPUT
#il server non puo' fare connessioni verso la DMZ... quindi loggo
$IPT -A server_to_dmz -j LOG --log-prefix output_dmz:
#il server puo' "uscire" verso la LAN trusted
$IPT -A server_to_lan -j ACCEPT
#genero in automatico le connessioni che puo' fare il server verso internet (oltre alle related)
$IPT -A server_to_net -m state --state RELATED,ESTABLISHED -j ACCEPT
#regola speciale per la vpn
if [ "$SERVER_OUT" != "0" ]
then
for RULES in $SERVER_OUT
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 3)
if [ "$PORT" -eq "0" ]
then
echo -e "\nREGOLA $RULES: il server esce verso ip $IP su tutte le porte"
$IPT -A server_to_net -d $IP -j ACCEPT
else
echo -e "\nREGOLA $RULES: il server esce verso ip $IP porta $PORT protocollo $PROTOCOL"
$IPT -A server_to_net -d $IP -p $PROTOCOL --dport $PORT -j ACCEPT
fi
done
fi
#loggo le altre connessioni che fa il server verso internet
$IPT -A server_to_net -j LOG --log-prefix server_to_net:
### DMZ
#dalla dmz verso la lan accetto solamente le connessioni related ed estabilished... e il resto lo loggo
$IPT -A dmz_to_lan -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A dmz_to_lan -j LOG --log-prefix dmz_to_lan:
#dalla DMZ verso internet accetto solo le connesioni related o estabilished
#o per fare l'update della macchina verso gli ip predefiniti e solo verso le porte di http e ftp
$IPT -A dmz_to_net -m state --state RELATED,ESTABLISHED -j ACCEPT
for IP in $IP_UPDATE
do
$IPT -A dmz_to_net -s $RANGE_IP_DMZ -d $IP -p tcp --dport 21 -j ACCEPT
$IPT -A dmz_to_net -s $RANGE_IP_DMZ -d $IP -p tcp --dport 80 -j ACCEPT
done
#vengono generate in automatico quelle per DNS e SMTP (vedi sotto)
$IPT -A dmz_to_net -j LOG --log-prefix dmz_to_net:
### LAN
#accetto tutte le connessioni fatte dalla LAN verso la DMZ....
$IPT -A lan_to_dmz -j ACCEPT
#dalla LAN permetto di uscire su tutte le porte
$IPT -A lan_to_net -j ACCEPT
### INTERNET
#accetto le connessioni da internet verso la dmz, quando sono related o established
#per via del prerouting probabilmente queste regole sono superflue... si potrebbe mettere un ACCEPT e basta
$IPT -A net_to_dmz -m state --state RELATED,ESTABLISHED -j ACCEPT
if [ "$PASS_TO_DMZ" != "0" ]
then
for RULES in $PASS_TO_DMZ
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
IP_DMZ=$(eval echo \$$RULES | cut -d " " -f 3)
PORT_DMZ=$(eval echo \$$RULES | cut -d " " -f 4)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 5)
IP_EXT=$(eval echo \$$RULES | cut -d " " -f 6)
if [ "$IP_EXT" != "0" ]
then
IP_SRC=" -s $IP_EXT "
else
IP_SRC=""
fi
if [ "$PORT" -eq "0" ]
then
$IPT -A net_to_dmz $IP_SRC -d $IP_DMZ -j ACCEPT
else
$IPT -A net_to_dmz $IP_SRC -d $IP_DMZ -p $PROTOCOL --dport $PORT_DMZ -j ACCEPT
for post_port in $POSTROUTING_PORTS
do
if [ $post_port -eq $PORT ]
then
# questa regola vale solo per i servizi di tipo smtp e dns (vedi POSTROUTING_PORTS nel file di CONFIG)
#notare il -I, cosi che la regola venga inserita prima di quella di log
$IPT -I dmz_to_net -s $IP_DMZ -p $PROTOCOL --dport $PORT -j ACCEPT
fi
done
fi
done
fi
#da internet verso la LAN accetto solo le connessioni related,estabilished
$IPT -A net_to_lan -m state --state RELATED,ESTABLISHED -j ACCEPT
#e leconnessioni che rigiro in LAN (da usare con cautela! c'e' la DMZ apposta!)
if [ "$PASS_TO_LAN" != "0" ]
then
for RULES in $PASS_TO_LAN
do
IP=$(eval echo \$$RULES | cut -d " " -f 1)
PORT=$(eval echo \$$RULES | cut -d " " -f 2)
IP_LAN=$(eval echo \$$RULES | cut -d " " -f 3)
PORT_LAN=$(eval echo \$$RULES | cut -d " " -f 4)
PROTOCOL=$(eval echo \$$RULES | cut -d " " -f 5)
IP_EXT=$(eval echo \$$RULES | cut -d " " -f 6)
if [ "$IP_EXT" != "0" ]
then
IP_SRC=" -s $IP_EXT "
else
IP_SRC=""
fi
if [ "$PORT" -eq "0" ]
then
$IPT -A net_to_lan $IP_SRC -d $IP_LAN -j ACCEPT
else
$IPT -A net_to_lan $IP_SRC -d $IP_LAN -p $PROTOCOL --dport $PORT_LAN -j ACCEPT
fi
done
fi
buon divertimento... e se avete suggerimenti sono i benvenuti