Outils pour utilisateurs

Outils du site


firewall

Firewall

Un serveur étant tout le temps connecté à Internet il est accessible par tout le monde. C'est donc une cible de choix pour des attaquants qui peuvent y trouver des informations confidentielles ou se servir de ce dernier dans un botnet. Il est donc important de ne pas négliger la sécurité d'un serveur. Beaucoup de pages sur le web décrivent comment mettre en place un firewall pour linux, mais la majorité d'entre elles fait l'impasse sur le filtrage de l'IPv6.

Cette page décrit la mise en place d'un firewall utilisant iptables et ip6tables pour bloquer le trafic non souhaité en IPv4 et en IPv6. Il ne s'agit pas d'une solution parfaite mais elle apporte une sécurité non négligeable.

Filtrage

Ce firewall peut être catégorisé comme restrictif. En effet il va bloquer tout le trafic entrant et sortant et n'autoriser que des protocoles spécifiques :

  • Tout le trafic sur l'interface loopback
  • Tous les paquets ICMP en IPv4
  • Les paquets ICMP en IPv6 sauf redirect et router-solicitation packets qui sont destinés à un usage en tant que routeur
  • Les ports TCP et UDP en entrée ou en sortie que vous voulez

Un port ouvert en entrée INPUT correspond à un service hébergé sur votre machine, par exemple un service IMAP sur le port TCP 143. Un port ouvert en sortie OUTPUT correspond lui à un service que vous voulez contacter à l'extérieur, par exemple un serveur HTTP sur le port 80 (utile pour faire les mises à jour APT) Il est important de noter que ces listes sont distinctes et peuvent être totalement différentes. L'erreur couramment rependue est de penser qu'il faut ouvrir un port en entrée pour accéder à un service.

Fonctionnement du script

Ce firewall fonctionne comme un script shell qui exécute des commandes iptables et ip6tables. Il sera placé dans le répertoire /etc/init.d/ qui regroupe des scripts lancés au démarrage du système. Ce script se base sur une distribution Debian Squeeze. Si le fonctionnement d'iptables est similaire sur toutes les distribution, les scripts de démarrages peuvent eux fonctionner différemment.

Script

Le script se situera dans le fichier /etc/init.d/firewall.

#!/bin/sh
### BEGIN INIT INFO
# Provides:          firewall
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Should-Start:      $time $network $syslog iptables firehol shorewall ipmasq arno-iptables-firewall
# Should-Stop:       $network $syslog iptables firehol shorewall ipmasq arno-iptables-firewall
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Applies iptables rules
# Description:       Applies iptables rules to enable firewall protection on IPv4 and IPv6
### END INIT INFO


##### START USER CONFIG
# Do you want to log dropped packets in /var/log/messages ?
LOG_DROPPED=1
#
# List of ports to open
TCP_INPUT_PORTS="22 53 25 465 143 993"
TCP_OUTPUT_PORTS="53 25 465 143 993 80 443"
UDP_INPUT_PORTS="53"
UDP_OUTPUT_PORTS="53 123"
#
# List of IP to allow
IPV4_ALLOWED="x.x.x.251"
#
##### END USER CONFIG

# Delete tables
iptables -t filter -F
ip6tables -t filter -F

# Remove personal rules
iptables -t filter -X
ip6tables -t filter -X

# Drop all trafic
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT DROP
ip6tables -t filter -P INPUT DROP
ip6tables -t filter -P FORWARD DROP
ip6tables -t filter -P OUTPUT DROP

# Do not break established connections
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Allow loopback
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT
ip6tables -t filter -A INPUT -i lo -j ACCEPT
ip6tables -t filter -A OUTPUT -o lo -j ACCEPT

# ICMPv4
iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -p icmp -j ACCEPT

# ICMPv6
# (drop redirect et router-solicitation packets)
for type in packet-too-big destination-unreachable time-exceeded parameter-problem echo-request echo-reply router-advertisement neighbour-solicitation neighbour-advertisement
do
	ip6tables -A INPUT -p icmpv6 --icmpv6-type $type -j ACCEPT
	ip6tables -A OUTPUT -p icmpv6 --icmpv6-type $type -j ACCEPT
done

# Allow selected IP
for ip in $IPV4_ALLOWED
do
	iptables -t filter -A INPUT --source $ip -j ACCEPT
	iptables -t filter -A OUTPUT --destination $ip -j ACCEPT
done

# Open selected ports
for port in $TCP_INPUT_PORTS
do
	iptables -t filter -A INPUT -p tcp --dport $port -j ACCEPT
	ip6tables -t filter -A INPUT -p tcp --dport $port -j ACCEPT
done

for port in $TCP_OUTPUT_PORTS
do
        iptables -t filter -A OUTPUT -p tcp --dport $port -j ACCEPT
        ip6tables -t filter -A OUTPUT -p tcp --dport $port -j ACCEPT
done

for port in $UDP_INPUT_PORTS
do
        iptables -t filter -A INPUT -p udp --dport $port -j ACCEPT
        ip6tables -t filter -A INPUT -p udp --dport $port -j ACCEPT
done

for port in $UDP_OUTPUT_PORTS
do
        iptables -t filter -A OUTPUT -p udp --dport $port -j ACCEPT
        ip6tables -t filter -A OUTPUT -p udp --dport $port -j ACCEPT
done

# Logging
if test $LOG_DROPPED -eq 1
then
	# IPv4
	iptables -N LOGGING
	iptables -A INPUT -j LOGGING
	iptables -A OUTPUT -j LOGGING
        iptables -A LOGGING -p udp --sport 67 --dport 68 -j DROP # Do not log DHCP requests from bad admins
	iptables -A LOGGING -m limit --limit 4/hour --limit-burst 2 -j LOG --log-prefix "iptables dropped: " --log-level 4
	iptables -A LOGGING -j DROP

	# IPv6
        ip6tables -N LOGGING
        ip6tables -A INPUT -j LOGGING
        ip6tables -A OUTPUT -j LOGGING
        ip6tables -A LOGGING -p icmpv6 -j DROP # Do not log dropped icmpv6 paquets
        ip6tables -A LOGGING -m limit --limit 4/hour --limit-burst 2 -j LOG --log-prefix "ip6tables dropped: " --log-level 4
        ip6tables -A LOGGING -j DROP
fi

Après avoir créé ce fichier il faut l'adapter à vos besoin en configurant :

  • Si vous voulez logger les paquets droppés dans /var/log/messages (0=Non et 1=Oui)
  • La liste des ports autorisés (n'oubliez pas d'autoriser l'accès SSH en entrée sinon votre serveur ne sera plus accessible)
  • Les adresses IP qui seront automatiquement autorisés (dans cet exemple il s'agit d'autoriser le serveur de monitoring MRTG d'OVH)

Ensuite il faut lui attribuer les bonnes permissions : chown root:root /etc/init.d/firewall && chmod 755 /etc/init.d/firewall

Vous pouvez à présent tester ce firewall : /etc/init.d/firewall Si vous avez toujours accès à votre serveur c'est que tout se déroule bien.

Vous pouvez vérifier la liste des ports ouverts avec : iptables -L -v et ip6tables -L -v

Exécution au démarrage du système

En l'état actuel le firewall filtre bien vos connexions aussi bien en IPv4 qu'en IPv6. Cependant si vous redémarrez le serveur les règles iptables seront remises à zéro. Pour éviter cela il faut enregistrer le script en tant que script de démarrage avec la commande : insserv firewall Rappel : Sur d'autres systèmes que Debian et Ubuntu le système de script de démarrage peut fonctionner différemment, à vous de l'adapter à vos besoins.

Enfin si vous souhaitez le désinstaller : insserv -r firewall

Filtrage des logs

Même si iptables est configuré pour ne mettre que quatre enregistrements par heure dans le fichier de log pour une même requête, le journal peut grossir considérablement à cause de requêtes inoffensives qu'il n'est pas utile de garder. C'est le cas des broadcasts DHCP que certains serveurs font à tort. Pour éviter d'enregistrer ces requêtes une règle supplémentaire est disponible dans la partie logging du script.

Vous pouvez consulter les logs à l'aide de : grep “iptables dropped:” /var/log/messages | tail -n 20 ou grep “ip6tables dropped:” /var/log/messages | tail -n 20

firewall.txt · Dernière modification: 2019/04/02 11:14 (modification externe)