[Actualité] Exemple d'automatisation d'un pare-feu via un service pour Linux Debian
par
, 02/06/2017 à 22h49 (2739 Affichages)
Exemple d'automatisation d'un pare-feu
via un service
pour Linux Debian
Résumé
La mise en place d'un pare-feu est un point clé incontournable de la configuration d'un serveur en ligne qu'il soit virtuel ou réel. Ici je vais donc aborder la mise en place sous forme d'un service pour en faciliter l'utilisation. Je parlerais plus particulièrement du cas de serveurs chez OVH pour la partie monitoring externe.
Prérequis
Les utilitaires suivants sont nécessaires :
- ifconfig, utilitaire pour la configuration réseau (matériel et logiciels) ;
- cat, utilitaire de lecture de fichier texte ;
- grep, utilitaire de recherche d'expressions dans des fichiers ou pipe ;
- awk, utilitaire de recherche et modification de texte dans des fichiers ou pipe ;
- iptables, utilitaire de filtrage réseau ;
- ssh, utilitaire d'administration et de communication.
Notions utilisées
Les notions suivantes seront préférables pour mieux comprendre ce qui est fait :
- comprendre diverses notions sur les réseaux (protocoles, NAT, IP, DNS, ports, etc.) ;
- comprendre la notion de pipelines et de redirection des sorties sous Linux ;
- comprendre la gestion de droit sous Linux ;
- comprendre les chaînes de caractères heredocs ;
- comprendre l'écriture de script exécutable dans une console sous Linux ;
- comprendre la notion de services sous Debian.
Nota
Il y a moult façons de faire des recherches, extractions ou remplacement de texte dans les différentes distributions de Linux et même au sein d'une seule... Celles que je présente ci-dessous ne sont pas forcément les plus optimisées, mais vu que pour leur utilisation dans ce cadre, la vitesse est moins importante que la maintenabilité et la compréhension, j'ai préféré enchaîner des utilitaires que parfois tout faire avec un seul avec une expression plus pénible à trouver ou comprendre...
1. Les services sous Debian
1.1. Un service c'est quoi ?
Un service (ou démon) est un programme qui est lancé de manière automatique au démarrage du système et s'arrête en même temps que l'arrêt de celui-ci. Il sert à gérer des actions en tâche de fond et peut agir seul, comme NTP, le service de recalage de l'heure, ou attendre des actions à traiter comme le service iptables qui traitera toutes les interactions réseau.
Un service est souvent composé de deux parties :
- un script qui va servir à interagir avec le service ;
- un exécutable persistant qui réalise les actions correspondant au service.
Le fait de placer un script dans /ect/init.d ne l'active pas.
Pour inscrire en tant que service un script nom_script dans ce répertoire, il faut utiliser :
Pour le désinscrire :
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part update-rc.d nom_script defaults
À partir de la version Jessie de Debian, le script d'interaction doit répondre aux principes de LSB (Linux Standard Base) qui l'obligent à :
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part update-rc.d -f nom_script remove
- permettre au moins les actions suivantes : start, stop, restart, force-reload et status ;
- retourner un code de fin d'exécution cohérent (0 ras sinon un problème s'est produit) ;
- contenir un bloc d'information (un bloc de commentaires spécialement formaté) donnant obligatoirement les dépendances de démarrage et d'arrêt du service.
Un warning est émis à chaque appel à update-rc.d si ces trois conditions ne sont pas remplies.
1.2. L'utilitaire iptables
C'est donc l'utilitaire qui permet de contrôler les flux réseau, il est une interface en ligne de commande à netfilter. Il permet de générer des filtres sur les paquets en agissant selon leur protocole (TCP, UDP ou ICMP) , leur source ou destination en termes de port et/ou d'URL ou d'IP, le nombre de connexions ou des règles de traduction d'adresse (NAT) par exemple. À chaque invocation de iptables avec une règle, celle-ci s'ajoute à la chaîne de règles qui seront testées dans l'ordre de leur ajout jusqu'à ce qu'une décision sur le flux soit prise (acceptation, rejet avec ou sans notification à l'émetteur). Des modules optionnels sont à installer voire à compiler selon les besoins. iptables tient son nom du fait que les règles sont organisées en tables. Une présentation succincte de iptables est faite ici.
On pourra lister les règles en place avec :
On notera qu'il existe un paquet Debian pour rendre persistantes les règles : iptables-persistent. Néanmoins il ne fait que sauvegarder ou restaurer les règles dans un fichier. C'est pour ça que je lui préfère le principe du programme que l'on transforme en service une fois la phase de test finie. En cas d'erreur, tant qu'on n’a pas testé les règles avec succès, un simple redémarrage du système suffit pour revenir à la configuration précédente.
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part iptables -L
2. Un service de pare-feu
2.1. Stratégie choisie
Dans le cas du pare-feu, il n'y aura que le script d'interaction. L'idée va être de faire un script de génération, dans le répertoire /root, pour le code du script d'interaction qui lui sera dans le répertoire /ect/init.d.
2.2. parefeu.sh
2.2.1. But
Le script sera placé dans le répertoire /root et pour le rendre exécutable, on utilisera :
Le but de ce script va être de :
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part chmod 700 /root/parefeu.sh
- récupérer la valeur du port SSH ;
- récupérer les 24 bits supérieurs de l'IP du serveur de monitoring d'OVH ;
- créer le script du pare-feu.
2.2.2. Récupérer la valeur du port SSH
On va utiliser grep sur /etc/ssh/sshd_config pour récupérer la ligne du port utilisé par le service SSH et awk pour extraire le nombre qui est la 2e valeur de celle-ci.
On peut se passer de cat:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part ssh_port=$(cat /etc/ssh/sshd_config | grep Port | awk '{print $2;}')
Ou même tout faire avec awk:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part ssh_port=$(grep Port /etc/ssh/sshd_config | awk '{print $2;}')
2.2.3. Récupérer les 24 bits supérieurs de l'IP du serveur de monitoring d'OVH
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part ssh_port=$(awk '/Port/ {print $2;}' /etc/ssh/sshd_config)
L'utilitaire ifconfig permet de mettre en place ou de récupérer tout ou partie des configurations réseau. Nous avons besoin de l'IP externe du serveur, donc nous allons lire la partie concernant l'interface réseau eth0. On fait un grep pour extraire la ligne qui contient l'IP et enfin on ne garde que l'IP grâce à un appel à awk. On obtient le code suivant :
On peut se passer de grep là aussi:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part serveur_ip=$(ifconfig eth0 | grep Bcast | awk '{sub(/[a-zA-Z]+\:/,"",$2); print $2;}')
Il peut être utile d'avoir l'IP complète pour certains cas ou réglages donc on extrait de celle-ci les codes des 3 premiers octets grâce à une commande awk:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part serveur_ip=$(ifconfig eth0 | awk '/Bcast/ {sub(/[a-zA-Z]+\:/,"",$2); print $2;}')
2.2.4. Désinscription du service du pare-feu si besoin
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part serveur_24=$(echo $serveur_ip | awk -F "." '{print $1"."$2"."$3;}')
Pour éviter d'avoir des warnings à propos de la modification du code du service, on teste la présence du fichier dans le répertoire /ect/init.d et, si le fichier /ect/init.d/parefeu, on désinscrit le service parefeu. On utilise pour cela le code suivant :
2.2.5. Créer le script du pare-feu
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 if [ -f "/etc/init.d/$parefeu" ]; then echo -e "Suppression du referencement du service du service" update-rc.d -f $parefeu remove else touch /etc/init.d/$parefeu chmod 755 /etc/init.d/$parefeu fi
Pour ce faire, on utilise cat à qui on passe un here doc dont le délimiteur est la chaîne de caractères EOF, et on redirige sa sortie vers un fichier en faisant un remplacement complet du contenu. Comme le délimiteur n'a pas de quotes, simples ou doubles, autour de lui, tout ce qui suit un $ est interprété comme une variable et replacé par sa valeur. On obtient le code suivant:
2.2.6. Inscription du service du pare-feu
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 cat <<- EOF > /etc/init.d/$parefeu #code ici EOF
C'est l'action finale du script, elle est réalisée par :
2.2.7. Code complet du script
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part update-rc.d $parefeu defaults
Le code complet du script /root/parefeu.sh est:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 #!/bin/sh reset # Emplacement du service parefeu='parefeu' # Configuration du service echo -e "\033[7m INSTALLATION DU PAREFEU \033[0m" echo -e "Recuperation de l'IP du serveur sur eth0" serveur_ip=$(ifconfig eth0 | awk '/Bcast/ {sub(/[a-zA-Z]+\:/,"",$2); print $2;}') echo $serveur_ip echo -e "Recuperation de la portion d'IP du serveur pour le SLA" serveur_24=$(echo $serveur_ip | awk -F "." '{print $1"."$2"."$3;}') echo $serveur_24 echo -e "Recuperation du port SSH" ssh_port=$(awk '/Port/ {print $2;}' /etc/ssh/sshd_config) echo $ssh_port if [ -f "/etc/init.d/$parefeu" ]; then echo -e "Suppression du referencement du service du service" update-rc.d -f $parefeu remove else touch /etc/init.d/$parefeu chmod 755/etc/init.d/$parefeu fi echo -e "Creation du code du service" cat <<- EOF > /etc/init.d/$parefeu #!/bin/sh ### BEGIN INIT INFO # Provides: parefeu # Required-Start: $syslog $network # Required-Stop: $syslog $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start firewall daemon at boot time # Description: Custom Firewall scrip. ### END INIT INFO firewall_start() { # --- # Vider les tables actuelles iptables -t filter -F # Vider les règles personnelles iptables -t filter -X # Interdire toute connexion entrante et sortante iptables -t filter -P INPUT DROP iptables -t filter -P FORWARD DROP iptables -t filter -P OUTPUT DROP # --- # Ne pas casser les connexions etablies iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # Autoriser loopback iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A OUTPUT -o lo -j ACCEPT # Differentes securites echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 0 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route # --- # Règle de rejet et log des tentatives de connexion en trop sur SSH iptables -N SSH_DROP iptables -A SSH_DROP -j LOG --log-prefix '[fw drop -> Attack ssh] : ' iptables -A SSH_DROP -j DROP # --- # Autoriser le fonctionnement du DNS en UDP iptables -t filter -A INPUT -i eth0 -p udp --dport 53 -m state --state NEW -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p udp --dport 53 -m state --state NEW -j ACCEPT # --- # Autoriser ICMP pour les serveur SLA OVH iptables -t filter -A INPUT -i eth0 -p icmp -s 92.222.184.0/24,92.222.185.0/24,92.222.186.0/24,167.114.37.0/24 -m state --state NEW -j ACCEPT iptables -t filter -A INPUT -i eth0 -p icmp -s 37.187.231.251/32,151.80.118.100/32,151.80.231.244/32,151.80.231.245/32,151.80.231.246/32,151.80.231.247/32 -m state --state NEW -j ACCEPT iptables -t filter -A INPUT -i eth0 -p icmp -s 213.186.33.62/32,213.186.45.4/32,213.251.184.9/32,37.59.0.235/32,8.33.137.2/32,213.186.33.13/32,213.186.50.98/32 -m state --state NEW -j ACCEPT iptables -t filter -A INPUT -i eth0 -p icmp -s ${serveur_24}.250/32,${serveur_24}.251/32 -m state --state NEW -j ACCEPT # Autoriser le monitring OVH iptables -t filter -A OUTPUT -o eth0 -p udp -dport 6100:6200 -m state --state NEW -j ACCEPT # --- # Autoriser le ssh avec anti force brute iptables -t filter -A INPUT -i eth0 -p tcp --dport ${ssh_port} -m recent --set --name SSH_BAD iptables -t filter -A INPUT -i eth0 -p tcp --dport ${ssh_port} -m recent --update --seconds 60 --hitcount 4 --name SSH_BAD -j SSH_DROP iptables -t filter -A INPUT -i eth0 -p tcp --dport ${ssh_port} -m state --state NEW -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p tcp --dport ${ssh_port} -m state --state NEW -j ACCEPT # --- # Autoriser DNS, HTTP, HTTPS en TCP iptables -t filter -A INPUT -i eth0 -p tcp -m multiport --dports 53,80,443 -m state --state NEW -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p tcp -m multiport --dports 53,80,443 -m state --state NEW -j ACCEPT # Autoriser le FTP sortant en TCP iptables -t filter -A OUTPUT -o eth0 -p tcp --dport 20:21 -j ACCEPT modprobe ip_conntrack modprobe ip_conntrack_ftp iptables -t filter -A OUTPUT -o eth0 -p tcp --sport 1024:65535 --dport 20 -m state --state ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p tcp --sport 1024:65535 --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A INPUT -i eth0 -p tcp --sport 20 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A INPUT -i eth0 -p tcp -m multiport --sports 21,1024:65535 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT # --- # Autoriser le recalage d'horloge système iptables -t filter -A OUTPUT -p udp --dport 123 -j ACCEPT } firewall_stop() { iptables -F iptables -X iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT # # iptables -t nat -F # iptables -t nat -X # iptables -t nat -P PREROUTING ACCEPT # iptables -t nat -P POSTROUTING ACCEPT # iptables -t nat -P OUTPUT ACCEPT # # iptables -t mangle -F # iptables -t mangle -X # iptables -t mangle -P PREROUTING ACCEPT # iptables -t mangle -P OUTPUT ACCEPT } # Corps du programme case $1 in 'force-reload') echo -e "Demarrage du parefeu" firewall_start exit 0 ;; 'regles' ) echo -e "Regles actuelles du parefeu" iptables -L -v -n exit 0 ;; 'restart') echo -e "Redemarrage du parefeu" firewall_start exit 0 ;; 'start') echo -e "Demarrage du parefeu" firewall_start exit 0 ;; 'status' ) echo -e "Etat du chrgement du parefeu" iptables -L -v -n exit 0 ;; 'stop') echo -e "Arret du parefeu" firewall_stop exit 0 ;; *) echo "usage: parefeu {regles|start|stop|restart|status}" exit 1 ;; esac EOF echo -e "Activation du service" update-rc.d $parefeu defaults exit 0
2.3. Comment est écrit le service pare-feu
2.3.1. Utiliser des fonctions en bash
Pour faciliter la maintenance et permettre la réutilisation, on va placer le code des fonctionnalités du service dans des fonctions. Une fonction s'écrit de la sorte:
L'invocation d'une fonction est vue comme un appel à un utilitaire ou un script, dans la fonction on utilise donc $1 pour désigner le premier paramètre, $2 le second, etc. On peut utiliser exit pour fixer un code d'erreur ou non lors de la sortie de celle-ci. Si on prend l'exemple d'une fonction de décompression générique:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 nom_fonction() { #code du corps de la fonction }
Dans le contexte où elle est définie, si on prend l'exemple de la fonction de décompression, on peut l'invoquer comme suit:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 decompression () { if [ -f $1 ]; then case $1 in (*.7z) 7z x $1 ;; (*.lzma) unlzma $1 ;; (*.rar) unrar x $1 ;; (*.tar) tar xvf $1 ;; (*.tar.bz2) tar xvjf $1 ;; (*.bz2) bunzip2 $1 ;; (*.tar.gz) tar xvzf $1 ;; (*.gz) gunzip $1 ;; (*.tar.xz) tar Jxvf $1 ;; (*.xz) xz -d $1 ;; (*.tbz2) tar xvjf $1 ;; (*.tgz) tar xvzf $1 ;; (*.zip) unzip $1 ;; (*.Z) uncompress ;; (*) echo -e "'$1' est impossible à décompresser..." ;; esac else echo -e "Erreur: '$1' n'est pas un fichier valide!" exit 1 fi }
2.3.2. Les fonctions du script du service
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part decompression fichier
On va donc utiliser les fonctions suivantes dans le script:
- firewall_start() qui sert à mettre en place les règles choisies.
- firewall_stop() qui va supprimer tous les filtrages.
2.3.3. Le corps du script du service
Le premier paramètre est l'action que le service doit réaliser, un case va lui être appliqué pour déterminer sa valeur:
- start, obligatoire, appelle firewall_start().
- stop, obligatoire, appelle firewall_stop().
- restart, obligatoire, appelle firewall_start().
- force-reload, obligatoire, appelle firewall_start().
- status, obligatoire, donne l'activité du service (indépendamment de ce qu'on met dedans) et son historique de chargement.
- règles, particulières à ce service, liste les règles actives et la répartition de chacune d'elles de ce qu'elles ont traité comme octets et paquets.
3. Les règles du pare-feu utilisées dans cet exemple
3.1. Initialisation
3.1.1. Non crypté
On commence par supprimer toutes les règles:
3.1.2. Règles par défaut
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 # Vider les tables actuelles iptables -t filter -F # Vider les règles personnelles iptables -t filter -X
On bloque tout en entrée et sortie:
3.1.3. Non crypté
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 iptables -t filter -P INPUT DROP iptables -t filter -P FORWARD DROP iptables -t filter -P OUTPUT DROP
On maintient toutes les connexions sont déja établies ou les nouvelles qui découle de celles-ci:
On a donc toutes les règles suivantes qui ne concerneront que le droit ou non d'ouvrir un flux, on aura donc dans celles-ci:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
3.1.4. On ouvre la boucle locale
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part -m state --state NEW
On ouvre tout en entrée et sortie sur la boucle locale:
3.1.5. Quelques petits réglages de sécurité
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A OUTPUT -o lo -j ACCEPT
On va mettre en place de réglages pour augmenter la sécurité, mais comme ils sont dépendant du noyau, certains peuvent ne pas fonctionner:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 0 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo 1 > /proc/sys/net/ipv4/conf/all/log_martians echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
3.2. Le service ssh
On va commencer par créer une chaîne de règles, nommée SSH_DROP, pour mettre dans le log les tentatives de connexion avant de les jeter sans notification aux émetteurs des paquets:
On ouvre en entrée et sortie le port qu'on a mis dans la variable [COLOR="#00FF00"]$ssh_port[,/COLOR], mais on impose une limite de 4 connexions par minute pour limiter les tentatives d'attaques par force brute.
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 # Règle de rejet et log des tentatives de connexion en trop sur SSH iptables -N SSH_DROP iptables -A SSH_DROP -j LOG --log-prefix '[fw drop -> Attack ssh] : ' iptables -A SSH_DROP -j DROP
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 iptables -t filter -A INPUT -i eth0 -p tcp --dport ${ssh_port} -m recent --set --name SSH_BAD iptables -t filter -A INPUT -i eth0 -p tcp --dport ${ssh_port} -m recent --update --seconds 60 --hitcount 4 --name SSH_BAD -j SSH_DROP iptables -t filter -A INPUT -i eth0 -p tcp --dport ${ssh_port} -m state --state NEW -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p tcp --dport ${ssh_port} -m state --state NEW -j ACCEPT
3.3. Les principaux services
3.3.1. En TCP
On fait une déclaration multiport pour les services TCP courants (DNS, HTTP, HTTPS):
On notera que le procédé de création de certificats SSL Let's encrypt, maintenant bien supporté, ainsi que les utilitaires apt-get, aptitude et wget utilisent les ports 80 et 443 en entrée et sortie.
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 iptables -t filter -A INPUT -i eth0 -p tcp -m multiport --dports 53,80,443 -m state --state NEW -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p tcp -m multiport --dports 53,80,443 -m state --state NEW -j ACCEPT
3.3.2. En UDP
On ouvre pour le DNS pour son fonctionnement en UDP:
On ouvre le port du service de mise à jour de l'horloge du serveur:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 iptables -t filter -A INPUT -i eth0 -p udp --dport 53 -m state --state NEW -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p udp --dport 53 -m state --state NEW -j ACCEPT
3.3.3. Les autres services TCP et UDP
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part iptables -t filter -A OUTPUT -p udp --dport 123 -j ACCEPT
Ma volonté a été de faire un serveur minimaliste donc les services tels que les serveurs de mails ou FTP ne seront pas abordés ici et seront à rajouter au script si on veut les prendre en compte.
3.4. Le FTP sortant en passif
L'utilitaire wget utilise parfois le protocole FTP. Si en FTP actif, ouvrir les ports 20 et 21 suffit, en mode passif les choses sont plus compliquées, ce qui explique un échec de téléchargement alors que la connexion à l'hôte se passe bien. Cela est dû à une connexion supplémentaire qui se négocie via l'un des ports 20 ou 21. Du coup, les états ESTABLISHED et RELATED ne permettent pas de gérer cette nouvelle connexion. Pour se faire, deux modules optionnels de IPTABLES, ip_conntrack et ip_conntrack_ftp, doivent être activés grâce à modprobe:
Il reste à ouvrir les ports disponibles à partir de 1024 pour la connexion supplémentaire en cas de connexion sur les ports 20 et 21:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 modprobe ip_conntrack modprobe ip_conntrack_ftp
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 iptables -t filter -A OUTPUT -o eth0 -p tcp --sport 1024:65535 --dport 20 -m state --state ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p tcp --sport 1024:65535 --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -o eth0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A INPUT -i eth0 -p tcp --sport 20 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A INPUT -i eth0 -p tcp -m multiport --sports 21,1024:65535 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
3.5. Le monitoring de l'hébergeur
3.5.1. En TCP
Dans le cas d'OVH, on a tout un tas de serveurs qui servent pour voir la présence sur le réseau des serveurs dédiés et VPS. Ils utilisent le protocole ICPM, on le leur permet donc avec leurs IP comme source:
3.5.2. Le service RTM
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 iptables -t filter -A INPUT -i eth0 -p icmp -s 92.222.184.0/24,92.222.185.0/24,92.222.186.0/24,167.114.37.0/24 -m state --state NEW -j ACCEPT iptables -t filter -A INPUT -i eth0 -p icmp -s 37.187.231.251/32,151.80.118.100/32,151.80.231.244/32,151.80.231.245/32,151.80.231.246/32,151.80.231.247/32 -m state --state NEW -j ACCEPT iptables -t filter -A INPUT -i eth0 -p icmp -s 213.186.33.62/32,213.186.45.4/32,213.251.184.9/32,37.59.0.235/32,8.33.137.2/32,213.186.33.13/32,213.186.50.98/32 -m state --state NEW -j ACCEPT iptables -t filter -A INPUT -i eth0 -p icmp -s ${serveur_24}.250/32,${serveur_24}.251/32 -m state --state NEW -j ACCEPT
C'est un script qui envoie à intervalle régulier préprogrammé tout ou partie d'un ensemble d'informations sur l'état du matériel, pour OVH:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part iptables -t filter -A OUTPUT -o eth0 -p udp -dport 6100:6200 -m state --state NEW -j ACCEPT
4. Conclusion
On a ainsi un petit exemple de script facilement personnalisable pour la situation de chacun en rajoutant les services nécessaires. On pourra se baser sur le sujet du site bien connu de alsacreation sur le sujet: ici. On y trouvera des réglages supplémentaires notamment pour OVH
Pour un serveur de mail, on utilisera certaines de ces actions:
Pour un serveur FTP dynamique:
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 # Mail SMTP:25 iptables -t filter -A INPUT -p tcp --dport 25 -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 25 -j ACCEPT # Mail POP3:110 iptables -t filter -A INPUT -p tcp --dport 110 -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 110 -j ACCEPT # Mail IMAP:143 iptables -t filter -A INPUT -p tcp --dport 143 -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 143 -j ACCEPT # Mail POP3S:995 iptables -t filter -A INPUT -p tcp --dport 995 -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 995 -j ACCEPT
Pour un serveur FTP passif, une plage supplémentaire de ports à partir de 1024 sera nécessaire.
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 # FTP Out iptables -t filter -A OUTPUT -p tcp --dport 20:21 -j ACCEPT # FTP In modprobe ip_conntrack_ftp # ligne facultative avec les serveurs OVH iptables -t filter -A INPUT -p tcp --dport 20:21 -j ACCEPT iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT