#!/bin/sh # FBoisson Mars 2009 # interfaces extérieure et Lan IF_EXT=eth1 IF_LAN=eth0 # # réseau local et IP public LAN=192.168.1 IP=82.66.248.156 MOI=1 IP_LAN=$LAN.$MOI # IPTABLES="iptables" # # restrictif # RESTRICT="-m state --state NEW,ESTABLISHED,RELATED " # ############################################################# # Utilitaires ############################################################# ############################################################# # # obtient le port port () { unset PRT PRT=`grep -E "^$1[^a-zA-Z]" /etc/services | sed -e '1,$s|^.*[\t| ]\([0-9]*\)/.*$|\1|' | head -n 1` if [ ! -z $PRT ] ; then RES=$PRT else RES=$1 fi } ############################################################# # Redirection ############################################################# ############################################################# # # service local sur port $1 protocole $2 redirigé sur $LAN.$3:$4 ou $LAN.$3:$1 sinon # redirigeserveur () { port $1 PORT=$RES if [ -z $4 ] ; then PDEST=$PORT else port $4 PDEST=$RES fi $IPTABLES -t nat -A PREROUTING $RESTRICT -p $2 --dport $PORT -j DNAT -i $IF_LAN -d $IP --to $LAN.$3:$PDEST $IPTABLES -t nat -A PREROUTING $RESTRICT -p $2 --dport $PORT -j DNAT -i $IF_EXT --to $LAN.$3:$PDEST $IPTABLES -t nat -A POSTROUTING -o $IF_LAN -p $2 --dport $PORT -s $LAN.0/24 -j MASQUERADE } ############################################################# # # redirection simple du port $1 protocole $2 redirigé sur $LAN.$3:$4 ou $LAN.$3:$1 sinon # en se limitant au paquet venant de $5 si $5 existe # redirige port protocole ou port origine # redirige () { port $1 PORT=$RES if [ -z $4 ] ; then PDEST=$PORT else port $4 PDEST=$RES fi unset ORIGINE if [ ! -z $5 ] ; then ORIGINE="-s $5" fi $IPTABLES -t nat -A PREROUTING $RESTRICT -p $2 --dport $PORT -j DNAT -i $IF_EXT $ORIGINE --to $LAN.$3:$PDEST } ############################################################# # # redirection de tout ce qui vient de $1 protocole $2 redirigé sur $LAN.$3 # fromto ou protocole vers # fromto () { $IPTABLES -t nat -A PREROUTING -p $2 -i $IF_EXT -s $1 -j DNAT --to $LAN.$3 } ############################################################# # Gestion des entrées ############################################################# ############################################################# # # limite les connexions tcp sur le port $1 pour $2 connexions par $3 secondes # limiteport () { port $1 PORT=$RES $IPTABLES -I INPUT -i $IF_EXT -p tcp --dport $PORT -m state --state NEW -m recent --set $IPTABLES -I INPUT -i $IF_EXT -p tcp --dport $PORT -m state --state NEW -m recent --update --seconds $3 --hitcount $2 -j DROP } ############################################################# # # interdit le port $1 protocole $2 à tous excepté la liste $3 $4 etc # interdit () { PROT=$2 port $1 PORT=$RES shift shift for m in $* ; do $IPTABLES -A INPUT -p $PROT $RESTRICT --dport $PORT -i $IF_EXT -s $m -j ACCEPT done $IPTABLES -A INPUT -p $PROT --dport $PORT -i $IF_EXT -j DROP } ############################################################# # # autorise le port $1 protocole $2 à tous excepté la liste $3 $4 etc # accepte () { PROT=$2 port $1 PORT=$RES shift shift for m in $* ; do $IPTABLES -A INPUT -p $PROT --dport $PORT -i $IF_EXT -s $m -j DROP done $IPTABLES -A INPUT -p $PROT $RESTRICT --dport $PORT -i $IF_EXT -j ACCEPT } ############################################################# # # Entrée OK en protocole $1 pour les ports suivants éventuellement limité # à une source donnée si suivi par s # exemple: inputok tcp smtp ssh telnet s 12.34.55.66 s 12.44.233.22 www # inputok () { PROT=$1 shift while [ ! -z $1 ] ; do port $1 PORT=$RES shift if [ ! -z $1 ] && [ $1 = "s" ] ; then while [ ! -z $1 ] && [ $1 = "s" ] ; do shift DEST="-s $1" shift $IPTABLES -A INPUT $RESTRICT -p $PROT $DEST --dport $PORT -j ACCEPT done else $IPTABLES -A INPUT $RESTRICT -p $PROT --dport $PORT -j ACCEPT fi done } ############################################################# # # Liste de machines de confiance, tout ce qui vient de ces machines # est acceptée # potes () { while [ ! -z $1 ] ; do $IPTABLES -A INPUT $RESTRICT -s $1 -j ACCEPT shift done } ############################################################# # Gestion des sorties ############################################################# ############################################################# # # SortieOK en protocole $1 pour les ports suivants éventuellement limité # à une destination donnée si suivi par d # exemple: outputok tcp smtp ssh telnet d 12.34.55.66 d 12.44.233.22 www # si forward est donné en premier argument, cela porte sur la chaine FORWARD # sinon sur la chaine OUTPUT # exemple: outputok forward tcp smtp ssh telnet d 12.34.55.66 d 12.44.233.22 www # outputok () { unset $TABLE if [ $1 = "forward" ] ; then TABLE=FORWARD shift else TABLE=OUTPUT fi PROT=$1 shift while [ ! -z $1 ] ; do port $1 PORT=$RES shift if [ ! -z $1 ] && [ $1 = "d" ] ; then while [ ! -z $1 ] && [ $1 = "d" ] ; do shift DEST="-d $1" shift $IPTABLES -A $TABLE $RESTRICT -p $PROT $DEST --dport $PORT -j ACCEPT done else $IPTABLES -A $TABLE $RESTRICT -p $PROT --dport $PORT -j ACCEPT fi done } ############################################################# # # Liste de machines de confiance, tout ce qui vient de ces machines # est acceptée, et tout ce qui est à destination de ces machines est accepté # machinesures () { while [ ! -z $1 ] ; do $IPTABLES -A FORWARD $RESTRICT -s $1 -j ACCEPT shift done } destinationsures () { while [ ! -z $1 ] ; do $IPTABLES -A OUTPUT $RESTRICT -d $1 -j ACCEPT shift done } ############################################################# # # Interdiction de sortie pour des machines données exceptés # des ports précis, attention la syntaxe est un peu différente # sortielimite 240 tcp www 443 110 d 195.154.98.97 25 8080 udp 53 # limite la machine au port 80, 443 et 110 en tcp, 53 en udp # et 25 et8080 en tcp vers 195.154.98.97 sortielimite () { MACHINE=$LAN.$1 DEST="" shift PROT=$1 shift PROT=tcp while [ ! -z $1 ] ; do if [ $1 = "tcp" ] || [ $1 = "udp" ] ; then PROT=$1 DEST="" shift elif [ $1 = "d" ] ; then shift DEST="-d $1" shift else port $1 PORT=$RES shift $IPTABLES -A FORWARD -s $MACHINE $DEST -p $PROT --dport $PORT -j ACCEPT fi done $IPTABLES -A FORWARD -s $MACHINE -m state --state RELATED,ESTABLISHED -j ACCEPT $IPTABLES -A FORWARD -s $MACHINE -p ! icmp -j DROP } ############################################################# # Gestion de passerelle ############################################################# ############################################################# # # passerelle # passerelle () { $IPTABLES -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE } ############################################################# # # sortie vers port $1 interdit sauf pour les indications après de la forme # fin_IP_source [d IP destination] # exemple: sortie tcp smtp 251 240 d 12.45.245.23 252 # OK pour $IP_LAN.251 et 252 et OK pour $LAN.240 -> 12.45.245.23 # sortie () { PROT=$1 shift port $1 PORT=$RES shift while [ ! -z $1 ] ; do SOURCE=$LAN.$1 shift if [ ! -z $1 ] && [ $1 = "d" ] ; then shift DEST="-d $1" shift else unset DEST fi $IPTABLES -t nat -A PREROUTING $RESTRICT -p $PROT -s $SOURCE $DEST -i $IF_LAN --dport $PORT -j ACCEPT done $IPTABLES -t nat -A PREROUTING -p $PROT --dport $PORT -i $IF_LAN -d $IP_LAN -j ACCEPT $IPTABLES -t nat -A PREROUTING -p $PROT --dport $PORT -i $IF_LAN -d $IP -j ACCEPT $IPTABLES -t nat -A PREROUTING -p $PROT --dport $PORT -i $IF_LAN -j DROP } ############################################################# # Initialisation ############################################################# ############################################################# # # initialisation restrictive par défaut mais cool sur les chaines données en argument # initialisation OUTPUT FORWARD # met ACCEPT sur OUTPUT et FORWARD # initialisation () { # raz echo "1" > /proc/sys/net/ipv4/ip_forward echo "16384" > /proc/sys/net/ipv4/ip_conntrack_max OUTPUT=DROP INPUT=DROP FORWARD=DROP while [ ! -z $1 ] ; do if [ $1 = OUTPUT ] ; then OUTPUT=ACCEPT fi if [ $1 = INTPUT ] ; then INTPUT=ACCEPT fi if [ $1 = FORWARD ] ; then FORWARD=ACCEPT fi shift done $IPTABLES -F INPUT $IPTABLES -F OUTPUT $IPTABLES -F FORWARD $IPTABLES -F INPUT $IPTABLES -t nat -F $IPTABLES -P INPUT $INPUT $IPTABLES -P OUTPUT $OUTPUT $IPTABLES -P FORWARD $FORWARD if [ $INPUT = DROP ] ; then # sur le LAN c'est des potes $IPTABLES -A INPUT -i $IF_LAN -j ACCEPT # les connexions liées ou ouvertes c'est OK. $IPTABLES -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # loopback: don't be schizo $IPTABLES -A INPUT -i lo -j ACCEPT # icmp: pas de parano tout de même sinon on ne fait rien $IPTABLES -A INPUT -p icmp -j ACCEPT fi if [ $OUTPUT = DROP ] ; then # sur le LAN c'est des potes $IPTABLES -A OUTPUT -o $IF_LAN -j ACCEPT # les connexions liées ou ouvertes c'est OK. $IPTABLES -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # loopback: don't be schizo $IPTABLES -A OUTPUT -o lo -j ACCEPT # icmp: pas de parano tout de même sinon on ne fait rien $IPTABLES -A OUTPUT -p icmp -j ACCEPT $IPTABLES -A FORWARD -p icmp -j ACCEPT fi if [ $FORWARD = DROP ] ; then # les connexions liées ou ouvertes c'est OK. $IPTABLES -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT # icmp: pas de parano tout de même sinon on ne fait rien $IPTABLES -A FORWARD -p icmp -j ACCEPT fi } ############################################################# # Règles ############################################################# # # Le parefeu se suppose en fait deux interfaces à régler dans le début du script # IF_EXT est l'interface vers l'extérieur (Internet), IF_LAN est celle # vers le LAN # LAN est le prefix du réseau (supposé /24, tout ça est a améliorer). # Le parefeu se fait par appel à plusieurs routines # * initialisation initialise le parefeu, les arguments sont INPUT OUTPUT FORWARD # ordre indifférent, qui sont les chaines où la politique par défaut est # ACCEPT. Si on veut tout paramétrer, on met # initialisation # L'utlisateur normal met # initialisation OUTPUT FORWARD ############################################################# # * passerelle est une fonction sans argument qui indique que la machine # est une passerelle # Suivent des fonctions gérant les entrées, les redirections et les sorties. # Les ports peuvent être indiqués par leur nom (ssh) ou leur numéro (23). # protocole définit le protocle (tcp ou udp essentiellement) # Pour gérer les entrées on a comme fonctions ############################################################# # * inputok qui prend comme argument # - le protocole # - une suite de ports qui seront autorisés en entrée avec éventuellement # une source imposée. Ainsi # inputok tcp pop3 smtp domain telnet s 122.23.23.1 s 144.22.3.0/24 www https # ouvre les ports pop3, smtp, www et https pour tous et le port telnet # pour la machine 122.23.23.1 et le réseau 144.22.3.0/24 ############################################################# # * accepte qui prend comme argument # - le protocole # - un numéro de port # - une liste de machine ou de réseau # ouvre le port à tous excepté les machines indiquées dans la liste. # accepte tcp www 66.249.93.104 # accepte tout le monde sur le port www excepté 66.249.93.104 ############################################################# # * interdit qui prend comme argument # - le protocole # - un numéro de port # - une liste de machine ou de réseau # interdit le port à tous excepté les machines indiquées dans la liste. # interdit tcp ssh 66.249.93.104 82.66.248.0/24 # accepte tout le monde sur le port ssh excepté 66.249.93.104 et # le réseau 82.66.248.0/24 ############################################################# # * potes prenant comme arguments une liste de machines/réseau définit # les machines de confiance. Tout est accepté venant d'eux. # potes 82.66.248.156 # me permet d'aller sur tous les ports chez vous. ############################################################# # * limiteport prenant comme argument # - un numéro de port # - un décompte # - un temps en secondes # bloque toute machine ayant effectuée trop de connexions durant le temps donné # sur le port indiqué. # limiteport ssh 3 90 # bloque toute personne ayant fait plus de 3 connexions ssh en 90s, cela pendant # 90 secondes. ############################################################# # * redirigeserveur # permet de rediriger les connexions vers un serveur, cela est vrai pour # l'extérieur comme pour le LAN. En clair # redirigeserveur www tcp 251 81 # redirige les connexions venant de l'internet sur 192.168.1.251:81 (en # admettant que LAN=192.168.1) et également celle venant du LAN (ce qui est # important et nécessite du MASQUERADING). ############################################################# # * redirige prenant comme argument # - un numéro de port # - un protocole # - le numéro définissant une machine dans le LAN (23 pour 192.168.1.23) # - un numéro de port (optionnel) # redirige le port donné en premier argument sur la machine donnée en 3ième # argument (port identique ou défini par le 4ième argument) # Si un 5ième argument est donné, cela limite la règle uniquement à la # machine donné en argument. # redirige 2222 tcp 123 22 82.66.248.156 # permet à la machine 82.66.248.156 et elle seulement (merci :)) d'aller sur le # port ssh de 192.168.1.123 (si LAN=192.168.1) ############################################################# # * fromto est une redirection basique # Il redirige le port donné en premier argument (protocole donné en 2ième # argument) sur la machine définie par le 3ième argument (éventuellement # port donné en 4ième argument). Pour jouer à Starcraft, sur la machine # 192.168.1.234, ce serait # fromto 6112 tcp 234 # fromto 6112 udp 234 # fromto 4000 tcp 234 # fromto 4000 udp 234 # (je ne sais plus si c'est UDP ou TCP à rediriger, je met les 2) ############################################################# # * outputok gère les sorties ou si forward est donné en premier argument, # le forwarding (on ne comptera cet éventuel premier argument dans # ce qui suit). L'argument suivant est le protocle (tcp ou udp) puis # suivent une liste de ports avec éventuellement une destination imposée. # outputok forward tcp telnet ssh smtp d 12.34.55.66 d 12.44.233.22 www # autorise le relais tcp vers les ports telnet, ssh, smtp uniquement vers # 12.34.55.66 et 12.44.233.22 et vers le port www. ############################################################# # * machinesures définit une liste de machines sûres autorisées à tout faire # échappant aux restrictions ci dessus (pour le relais). destinationsures # désigne les machines sur pour la sortie. ############################################################# # * sortie port protocole liste de machines # interdit les accès vers l'extérieur pour les machines venant du LAN excepté # pour les machines indiquées avec éventuellement des destinations limitées. # sortie smtp tcp 251 249 d 195.154.98.97 249 d 212.27.48.4 # interdit le port 25 sauf à la machine 192.168.1.251 et, pour les destinations # 195.154.98.97 et 212.27.48.4 à la machine 192.168.1.249 (remarquez que 249 # a été répété). ############################################################# # * sortielimite machine protocole liste_de_ports ... # Interdiction de sortie pour des machines donn es except s # des ports pr cis, attention la syntaxe est un peu diff rente # sortielimite 240 tcp www 443 110 d 195.154.98.97 25 8080 udp 53 # limite la machine au port 80, 443 et 110 en tcp, 53 en udp # et 25 et8080 en tcp vers 195.154.98.97 # # un parefeu typique serait initialisation OUTPUT FORWARD passerelle # on autorise les accès aux serveurs pop3, pop3ssl, ftp, smtp web et ssh. inputok tcp pop3s pop3 ftp smtp www ssh https # permet de renouveller le bail si on possède une box qui se configure en DHCP inputok udp bootpc bootps ntp domain # limiter les accès à ssh, ftp et pop3 limiteport ssh 5 90 limiteport ftp 10 90 limiteport pop3 5 90 # Tant pis pour HADOPI, un petit coup de Edonkey sur la machine 192.168.1.2 redirige tcp 4662 2 redirige udp 4672 2 redirige udp 4665 2 # on veut jouer à Starcraft sur cette machine 192.168.1.2 redirige 6112 tcp 2 redirige 6112 udp 2 redirige 4000 tcp 2 redirige 4000 udp 2 # et à CS redirigeserveur 27016 udp 2 # # je veux regarder la tele sur mon ordinateur en profitant de freeplayer # freeplayer (freeplayer.freebox.fr=212.27.38.253) # mais je ne connais pas les ports. Tant pis on fait confiance: potes 212.27.38.253 fromto 212.27.38.253 tcp 2 fromto 212.27.38.253 udp 2 # maintenant soyons sérieux, le serveur Web est sur 192.168.1.3 redirigeserveur www tcp 3 # # enfin il y a des gens qui sont sous Windows, eux je ne veux pas qu'ils # accèdent au port SMTP. Seul moi (192.168.1.2) je peux et aussi ma # femme qui peut accéder à son compte sur laposte.net (elle a 192.168.1.3) sortie tcp smtp 2 3 d 193.251.214.114 # on suppose qu'on a une FONERA avec 192.168.1.100 comme adresse IP, avec HADOPI # qui vient de sortir, on stresse. Une limitation raisonnable et liberale serait # de limiter la sortie vers les ports > 1204 sauf des essentiels # FONERA exige les ports 1937 (tcp) et 1812/1813 en UDP # ci dessous on autorise OpenVPN, CVS, MySQL, MSN, AOL, subversion, Battlenet sortielimite 100 tcp 1:24 26:1023 \ 8080 aol svn openvpn cvspserver mysql vnetd msnp 6891 4000 1937 \ udp 1:1023 aol svn openvpn cvspserver mysql msnp 6891 6112 1812 1813