- Modifié
- Pour un usage "à la maison", en remplacement d'un Windows sur leur PC,
- Pour un usage dit (globalement) de seedbox, donc sur un serveur dédié.
Soit par méconnaissance soit parce qu'on utilise un logiciel tiers qui permet de gérer le pare-feu de manière visuelle, soit tout simplement du fait qu'un script (d'installation de VPN par exemple) s'occupe d'ajouter des règles à la place de l'utilisateur. Ne pas connaître IPtables n'est pas une tare ; je ne compte, ni n'ai les connaissances pour d'ailleurs, faire ici un "cours" sur ce que c'est et comment ça fonctionne, je vais me contenter d'apporter des pistes pour mieux appréhender des règles de pare-feu.
Je n'ai rien contre les UFW, FirewallBuilder etc qui permettent de gérer des règles IPtables de manière simplifiée. Ce que je trouve dommage en revanche c'est qu'en ce qui concerne la sécurité d'un serveur (Seedbox, Cloud, VPN etc) on rencontre souvent des outils qui sont clairement soit des usines à gaz soit sur-dimensionnés pour ce genre d'utilisation (ça me file une idée d'article d'ailleurs, petite réflexion après celui-ci). C'est vrai qu'installer OSSEC, rkHunter, Fail2ban, PortSentry, SSH_key, DNSSEC, HSTS, DHParam, configurer son moteur Web pour bloquer les -petits-DDoS (beh ouais ma bonne Dame !) sur sa SB ou son blog est super incontournable. T'es mort si jamais tu le fais pas. Enfin en tous cas t'es hasbeen, tu passes pour un c*n qui non seulement ne sait pas de quoi on te parle mais en plus ne sait pas "sécuriser" une machine. C'te naze ! LOL ...
Bref. Les seedboxes sont plus sécurisées que PayPal. Et si jamais c'est pas le cas c'est presque pas normal. Toutes ces discussions, ces tutoriels sont fort intéressants, globalement, mais au final n'aident pas vraiment à comprendre comment fonctionne la sécurité de base, niveau réseau : IPtables. EDIT : je précise que je parle d'une manière générale et que j'ai publié cet article sur mon blog et ensuite recopié ici, je ne vise donc PAS Mondédié et sa formidable communauté d’entre-aide ^^
Et sur un PC personnel alors là... Si tout Windowsien, juste après avoir installé le crack de son OS, installe un firewall-anti-virus-spam-spoof-splif, cracké lui aussi, dès qu'il passe à Linux il se sent en totale sécurité. Sauf que nan. Certes on croise moins de virus sur nix que Win mais le firewall n'a pas vraiment à voir avec ça, c'est plus dans l'idée de bloquer des accès non désirés à sa machine. Encore qu'il faille passer au travers des boxes Internet et des routeurs/FW, pour ceux qui en ont, avant d'atteindre le dit PC. Ce qui n'est pas donné à tout le monde contrairement à ce qu'on voit dans les films de h4ck3rzzzz.
Bon, je viens d'écrire l'autre article, sur le rapport à la technologie/informatique, j'en suis encore empeigné et donc assez cinglant dans mes exemples et remarques. J'abrège et passe au vif du sujet.
IPtables c'est quoi ?
C'est un outil de filtrage des échanges réseau de Linux. Pour être complet, IPtables filtre les IPv4 et IP6tables les IPv6, EBtables filtre Ethernet/MAC et ARPtable s'occupe des ARP. Ils sont maintenus par l'équipe de http://www.netfilter.org/
┬─[ayx@Aerya:~]─[17:41:09]
╰─>$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (1 references)
target prot opt source destination
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
┬─[ayx@Aerya:~]─[17:41:17]
╰─>$ sudo ip6tables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
┬─[ayx@Aerya:~]─[17:41:30]
╰─>$ ebtables-compat -L
Bridge table: filter
┬─[ayx@Aerya:~]─[17:41:44]
╰─>$ arp -e
Address HWtype HWaddress Flags Mask Iface
192.168.1.101 ether 00:XX:XX:XX:XX:XX C enp8s0
192.168.1.110 ether 00:XX:XX:XX:XX:XX C enp8s0
gateway ether e8:XX:XX:XX:XX:XX C enp8s0
192.168.1.2 ether b8:XX:XX:XX:XX:XX C enp8s0
La plupart des scripts/outils qu'on utilise, dans notre univers des geeks-amateurs-de-P2P-and-co, n'influent que sur IPtables. Donc IPv4. IPv6 n'est en effet pas encore très répandu, non pas sur nos serveurs qui en sont tous pourvus, mais chez nos FAI ou hébergeurs de VPN/VPS (dans le cas d'un VPN personnel). IPtables va donc permettre de filtrer les requêtes selon leur type, destination (port), origine, contenu, qualité... et aussi de rediriger du trafic d'un port à un autre ou d'une interface à une autre, dans le cas notamment d'un serveur VPN. L'analyse des paquets se fait selon des règles définies.
Je me contente de survoler, en ne mentionnant que ce qui revient souvent dans les besoins/discussions que je lis.
Comme son nom l'indique subtilement IPtables est composé de tables permettant de traiter les paquets (IP) :
- raw : permet de marquer des paquets qui ne seront alors pas filtrés
- filter : table par défaut, et qui nous intéressera dans cet article, où on filtre les paquets. Ce sont donc les règles de firewall
- nat : permet de faire des traduction d'adresse réseau
- mangle : permet de modifier un paquet, par exemple sa durée de vie
- security : utilisée pour lescontrôle d'accès mandataire (MAC)
Ces tables contiennent à leur tour des chaînes permettant d'appliquer les règles définies aux paquets en fonction de leur route :
- INPUT : paquets entrants
- OUTPUT : paquets sortants
- FORWARD : paquets à passer d'une interface vers une autre, dans le cas de passerelles telles que VPN, proxy... (MASQUERADE)
- PREROUTING : modifier l'adresse de destination d'un paquet avant routage (DNAT)
- POSTROUTING : modifier l'adresse source d'un paquet après routage (SNAT)
- LOG : affiche le résultat de sortie (log)
- ACCEPT : autorise un paquet
- REJECT : rejette un paquet en l'indiquant à l'expéditeur
- DROP : rejette un paquet SANS l'indiquer à l'expéditeur
Principes de base
Le plus simple afin d'être certain d'appliquer les bonnes règles de filtrage est d'interdire tout trafic et de n'autoriser ensuite que le nécessaire. A titre personnel, j'applique souvent ce principe uniquement en entrée et non en sortie. Je considère en effet que sur certaines machines, étant le seul à y avoir accès et connaissant les services installés, ce n'est pas la peine de m'enquiquiner à faire des règles de sortie spécifiques. C'est donc dans ce contexte que je vous présenterai des exemples de règles IPtables dans cet article.
Un paquet est comparé aux règles d'une table dans leur ordre chronologique. Si un paquet est autorisé par la règle D mais que ses critères correspondent à la règle B, alors le paquet suivra ce qui est indiqué par la règle B et non la D. On peut passer outre mais c'est le fonctionnement par défaut d'IPtables.
Commandes de base
Si jamais IPtables n'était pas installé sur votre distribution
sudo apt-get install iptables
-A = ajouter une règle à la fin de la chaîne, ici INPUT-I = insérer une règle dans la chaîne où X = un nombre, qui détermine l'emplacement chronologique que la règle (ordre application des règles IPtables). Si on ne précise aucun chiffre, alors la règle s'ajoute au début de la chaîne
-p = protocole
--dport = port de destination
--sport = port source
-m = multiport, permet de mettre plusieurs ports dans sport ou dport
-j = politique appliquée au paquet correspondant à la règle
-s = source (IP)
-d = destination (IP)
-i = interface d'entrée
-o = interface de sortie
-f = paquet fragmenté
--tcp-flags = spécifier des FLAGS (TCP), à rejeter par exemple
--icmp-type = ping, permet de bloquer ou autoriser le ping, pour tous ou selon IP
--mac-source = filtrer un accès par adresse MAC (= -s pour les IP)
--state = spécifier l'état d'un paquet :
- ESTABLISHED : connexion déjà établie
- NEW : nouvelle connexion
- INVALID : connexion inconnue
- RELATED : nouvelle connexion mais liée (FTP, VPN...)
--to-destination = spécifier une destination (DNAT) (ex. VPN...)
--to-source = spécifier une adresse source (SNAT)
-L = lister les règles actives
--line-numbers = les lister par numéro (plus simple si vous voulez modifier/retirer la règle 1 ou 3 ou 12)
-t = table
Afficher les règles d'IPtables par défaut, donc des chaînes de la table Filter
sudo iptables -L
Afficher les règles d'IPtables par défaut, donc des chaînes de la table Filter avec les règles numérotées
sudo iptables -L --line-numbers
Afficher les règles de la chaîne INPUT de la table Filter
sudo iptables -L INPUT
Afficher les règlesdes chaînes de la table NAT : -t TABLE
sudo iptables -L -t NAT
Remettre à zéro IPtables
sudo iptables -F
Supprimer les règles personnelles
sudo iptables -X
Ajouter une règle, par exemple accepter les paquets entrant sur le port TCP 80 (serveur Web HTTP)
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
ou
sudo iptables -I INPUT X -p tcp --dport 80 -j ACCEPT
Supprimer une chaîne
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPOT
ou
sudo iptables -D INPUT X
X = numéro de la règle à supprimer dans la chaîne INPUTRemplacer une chaîne
sudo iptables -R INPUT X -p tcp -s 123.456.789.10 --dport 80 -j ACCEPT
Ici je remplace la règle X de la chaîne INPUT, qui spécifiait que j'autorisais tous les paquets entrants sur le port 80, par une nouvelle règle qui stipule que je n'accepte maintenant que les paquets en provenance de l'IP 123.456.789.10Autoriser les paquets entrant sur le port TCP 80, sauf ceux de l'IP 987.654.321.01
sudo iptables -A INPUT X -p tcp -s ! 987.654.321.01 --dport 80 -j DROP
Créer une nouvelle chaîne
sudo iptables -N port-scan
Ici je crée la chaîne port-scan dans la laquelle je vais placer mes règles en cas de détection de scanne de ports.Ajouter une règle à la chaîne port-scan
sudo iptables -A PORT-SCAN ....
Même principe que pour ajouter/retirer/modifier une règle dans une autre chaîneNotions utiles
Il y a plusieurs méthodes pour ajouter des règles. A la main bien entendu, ce qu'on voit au travers des commandes exemples du dessus.
Via un script, à exécuter, qui sera de cette forme
#!/bin/sh
### BEGIN INIT INFO
# Provides: vpn.7.yourserver.tor
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: vpn.7.yourserver.tor
### END INIT INFO
# Remettre les regles IPtables a 0
iptables -F
iptables -X
# Autoriser le routage IPv4
echo "1" > /proc/sys/net/ipv4/ip_forward
# Autoriser tout trafic sortant
iptables -P OUTPUT ACCEPT
# Autoriser le trafic existant
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#Autres règles
...
# Sauvegarder les regles pour qu elles soient chargees si reboot
iptables-save -c > /etc/iptables-save
Le préparer avec les règles/IP/ports utiles selon les besoins, l'enregistrer sous nom_que_vous_voulez.sh, le rendre exécutable via sudo chmod +x nom_que_vous_voulez.sh
et l'exécuter sudo bash nom_que_vous_voulez.sh
Directement en créant un fichier de règles.rules (par exemple iptables.firewall.rules). Ici un exemple pour la chaîne Filter, indiqué par *filter en début de fichier.
sudo nano /etc/iptables.firewall.rules
Le préparer avec les règles/IP/ports selon les besoins, sous cette forme (COMMIT à la fin)
*filter
# Purge des regles IPtables
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P FORWARD ACCEPT
-F
-X
# Regles de base
# Autorisation de tout trafic sortant
-P OUTPUT ACCEPT
# Rejeter tout le trafic entrant sauf règles qui suivent
-P INPUT DROP
# Autorisation des connexions entrantes deja etablies
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Autorisation des connexions internes (loopback)
-A INPUT -i lo -j ACCEPT
# Autorisations entrantes des services
# SSH / autorisation IP VPN 1
-I INPUT -p tcp -s xx.xx.xx.xx --dport yyy -j ACCEPT
# Autres règles
...
COMMIT
Le rendre exécutable
sudo iptables-restore < /etc/iptables.firewall.rules
Puis sauvegarder les règles et les rendre exécutables au boot en installant iptables-persistent
sudo apt-get install iptables-persistent
Sauvegarder les règles (une fois ajoutées à la main ou à mettre à la fin d'un script)
sudo -s iptables-save -c
Les rendre persistantes au démarrage (une fois ajoutées dans un fichier de configuration)
sudo apt-get install iptables-persistent
Fonctionne pour IPv4 et v6. Les règles sont dans /etc/iptables/rules.va & .v6. Fichier à modifier si vous changez vos règles ensuite. Ou effacez-les, retirer iptables-persistent, modifiez vos règles et réinstallez-le. Y'a le bon chasseur et le mauvais chasseur 
Pour permettre à une connexion déjà ouverte de continuer à recevoir du trafic
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
Sur certaines distributions, notamment sur les VPS OpenVZ, IPtables n'est pas à jour (et ne peut pas l'être vu le kernel utilisé), la règle est alors
sudo iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
Exemples d'interfaces réseau
Les visualiser via ip link ou ifconfig
lo : loopback, interface locale
ethX... : interface Ethernet
vmbrX... : interface de bridge, par exemple utilisée sous ProxMox pour connecter des VM et/ou CT en NAT
vethX : interface virtuelle d'un container LXC
venethX : interface virtuelle OpenVZ
dockerX : interface virtuelle d'un container docker
tunX : interface virtuelle notamment utilisée pour OpenVPN
Les noms dépendent des distributions, des fonctions...
VPN OpenVPN : règles IPtables serveur VPN sur VPS OpenVZ. Pour un serveur tournant sur le port TCP 848
# Autoriser le routage IPv4
echo "1" > /proc/sys/net/ipv4/ip_forward
# Autoriser le trafic en provenance du range IP des clients VPN
iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
# Router le trafic VPN entrant vers l IP de sortie
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source IP_de_votre_serveur
# Autoriser OpenVPN
iptables -A INPUT -p tcp --dport 848 -j ACCEPT
# Autoriser loopback
iptables -A INPUT -i lo -j ACCEPT
# Autoriser tout trafic venant de l interface VPN
iptables -A INPUT -i tun0 -j ACCEPT
VPN OpenVPN : règles IPtables serveur VPN sur VPS LXC. Pour un serveur tournant sur le port TCP 848
# Autoriser le routage IPv4
echo "1" > /proc/sys/net/ipv4/ip_forward
# Autoriser OpenVPN
iptables -A INPUT -p tcp --dport 848 -j ACCEPT
# Autoriser tout trafic venant de l interface VPN
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -j ACCEPT
# Routage
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
Restreindre l'accès au FTP, port 21, à une seule IP
sudo iptables -A INPUT -p tcp -s 123.456.789.10 --dport 21 -j ACCEPT
SYN, FIN, FLOOD, XMAS, NULL...
Ce sont des entêtes TCP. (les FLAGS évoqués plus haut)
Le port SSH : ATTENTION !!!
Restreindre un accès SSH selon un IP ou même selon un ordre (port knocking) est risqué en cas de mauvaise configuration ou de perte d'accès à l'IP autorisée. N'utilisez ces techniques que si vous savez ce que vous faites et testez-les avant de les activer, en tous cas de déconnecter la session SSH en cours.
Exemples
Script pour serveur OpenVPN sur VPS OpenVZ (ProxMox < 4)
Particularités (donc à modifier dans le script selon votre configuration) :
- Mon range d'IP pour les clients VPN est 10.8.0.0/24
- Mon port de connexion au serveur VPN est 848 en TCP (mais mettez ce que vous voulez)
- Mon port SSH est XXXX
- J'ai aussi installé Tor sur ce VPS d'où le fait qu'il soit dans les règles
- Il n'y a aucun autre service sur sur ce VPS, qui est 100% anonyme. Si vous avez d'autres services dessus pensez à ouvrir les ports !
- # Router le trafic VPN entrant vers l IP de sortie : remplacez IP_venet0:0 par l'IP de votre VPS
#!/bin/sh
### BEGIN INIT INFO
# Provides: vpn.7.yourserver.tor
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: vpn.7.yourserver.tor
### END INIT INFO
# Remettre les regles IPtables a 0
iptables -F
iptables -X
# Autoriser le routage IPv4
echo "1" > /proc/sys/net/ipv4/ip_forward
# Autoriser tout trafic sortant
iptables -P OUTPUT ACCEPT
# Autoriser le trafic existant
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Autoriser le trafic en provenance du range IP des clients VPN
iptables -A FORWARD -s 10.8.0.0/24 -j ACCEPT
# Rejeter tout autre trafic
iptables -A FORWARD -j REJECT
# Router le trafic VPN entrant vers l IP de sortie
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source IP_venet0:0
# Autoriser OpenVPN
iptables -A INPUT -p tcp --dport 848 -j ACCEPT
# Autoriser ICMP (ping)
iptables -A INPUT -p icmp -j ACCEPT
# Protection Syn flood
iptables -A FORWARD -p tcp --syn -m limit --limit 1/second -j ACCEPT
iptables -A FORWARD -p udp -m limit --limit 1/second -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT
# Protection scan
iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
# Autoriser loopback
iptables -A INPUT -i lo -j ACCEPT
# Autoriser tout trafic venant de l interface VPN
iptables -A INPUT -i tun0 -j ACCEPT
# Autoriser SSH
iptables -A INPUT -p tcp --dport XXXX -j ACCEPT
# Autoriser Tor
iptables -A INPUT -p tcp --dport 9050 -j ACCEPT
iptables -A INPUT -p udp --dport 5090 -j ACCEPT
# Sauvegarder les regles pour qu elles soient chargees si reboot
iptables-save -c > /etc/iptables-save
Fichier de règles IPv4 pour serveur OpenVPN sur VPS LXC (ProxMox > 4)
*filter
# Regles de base
# Autorisation de tout trafic sortant
-P OUTPUT ACCEPT
# Rejeter tout le trafic entrant sauf règles qui suivent
-P INPUT DROP
# Autorisation des connexions entrantes deja etablies
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Autorisation des connexions internes (loopback)
-A INPUT -i lo -j ACCEPT
# Autorisation entrantes des services
# SSH / autorisation selon IP VPN 1
-I INPUT -p tcp -s xxx.xxx.xxx.xxx --dport 233 -j ACCEPT
# SSH / autorisation selon IP VPN 2
-I INPUT -p tcp -s xxx.xxx.xxx.xxx --dport 233 -j ACCEPT
# Port OpenVPN
-I INPUT -p udp -m udp --dport 415 -j ACCEPT
# Ping depuis IP VPN 1
-I INPUT -p icmp -s xxx.xxx.xxx.xxx --icmp-type echo-request -j ACCEPT
# TUN
-I INPUT -i tun0 -j ACCEPT
-I FORWARD -i tun0 -j ACCEPT
# Routing
-I FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
-I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Regles de protection + logs
# DROP paquets autres que SYN
-A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
# DROP paquets invalides
-A INPUT -m conntrack --ctstate INVALID -j DROP
# DROP paquets incomplets
-A INPUT -f -j DROP
# DROP NULL
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# DROP XMAS
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# DROP SYNFIN
-A INPUT -p tcp --tcp-flags ALL SYN,FIN -j DROP
# DROP FIN scan
-A INPUT -p tcp --tcp-flags ALL FIN -j DROP
# DROP SYN RST
-A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# DROP NMAP XMAS
-A INPUT -p tcp --tcp-flags ALL URG,PSH,FIN -j DROP
# DROP NMAP
-A INPUT -p tcp --tcp-flags ALL URG,PSH,SYN,FIN -j DROP
# DROP SYN FLOOD
-N SYN-FLOOD
-A SYN-FLOOD -m limit --limit 1/sec --limit-burst 4 -j RETURN
-A SYN-FLOOD -j DROP
# DROP port scans
-N PORT-SCAN
-A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j PORT-SCAN
-A PORT-SCAN -m limit --limit 1/s --limit-burst 4 -j RETURN
-A PORT-SCAN -j DROP
# Blocage IP attaque 24h
-A INPUT -m recent --name DUMBASS --rcheck --seconds 86400 -j DROP
-A FORWARD -m recent --name DUMBASS --rcheck --seconds 86400 -j DROP
# Levee du blocage
-A INPUT -m recent --name DUMBASS --remove
-A FORWARD -m recent --name DUMBASS --remove
# Logging des paquets entrants droppes
-N LOGGING
-A INPUT -j LOGGING
-A LOGGING -m limit --limit 3/min -j LOG --log-prefix "IPtables_DROP: " --log-level 7
-A LOGGING -j DROP
COMMIT
Pour en savoir plus, il faut lire et pratiquer :
- http://www.netfilter.org/documentation/index.html#documentation-howto
- https://wiki.archlinux.fr/Iptables
- http://www.inetdoc.net/index.html
NB : mes scripts IPtables sont fonctionnels mais incomplets dans le sens où il manque des éléments concernant la sécurité.