Archives pour l'étiquette iptables

iptables: FAI ou VPN il faut choisir

plop à tous …

Un article que je voulais écrire depuis longtemps, mais par manque de temps je l’ai zappé.
Ici le but de la manoeuvre est d’utiliser iptables (et la magie du routage de linux) pour choisir ce qui passe par l’IP du VPN (P2P, …) et par votre FAI (Browsing, …) (on peut aussi rajouter la connexion 3G du téléphone pour ceux qui veulent taper comme un sourd dans la BP 😉 et avoir des latences minimal pour le browsing).

Note : les – – sont à faire sans espace, il s’agit d’un bug de wordpress :s
Continuer la lecture de iptables: FAI ou VPN il faut choisir

iptables module owner : comment autoriser spécifiquement les connexions des utilisateurs

plop

Un rapide mémo/article, sur comment autoriser des connexions établit par des utilisateurs spécifiques avec iptables.
L’idée générale étant que l’on drop tout par défaut, et que l’on autorise seulement certaines connexions par ports/logiciels, le soucis étant que si l’on ne connait pas les ports de sortie de notre services sur de nouvelles connexion (cas de serveurs tor/P2P dans lesquels les ports peuvent être aléatoire), on est obligé de passer en policy accept pour profiter un maximum du service (au risque que si le service http soit compromis un hacker puisse depuis le process ouvrir une connexion inverse pour bypass le firewall en drop sur l’entrée).
Continuer la lecture de iptables module owner : comment autoriser spécifiquement les connexions des utilisateurs

Ossec et Iptables : ban à durée variable

Plop à tous …
Encore de l’ossec et de l’iptables au menu, ici le but est de faire face aux crackers et autres kiddies sans se faire spammer de mails toutes les 6 minutes parce qu’un mec s’est planté 3 fois de suite de mot de passe sur SSH (un mec a tenté pendant deux jours de cracker mon ssh, résultat : une bonne centaines de mails d’alertes inutiles (le temps que je lui mettent un ban définitif)).
Continuer la lecture de Ossec et Iptables : ban à durée variable

Protection Ddos (soft)

Plop …

un petit retour sur le Ddos de ce week-end … conformément aux prédictions de certains concernant mon précédent article, un ban permanent n’est généralement pas une bonne idée, notemment lorsque les paquets sont forgés :

  • ça remplit inutilement les règles du firewall (la dernière attaque avait finit avec 600 lignes de DROP, ce qui rend difficile la lecture des règles mise en place)
  • en cas de ban d’un « client/joueur », il est banni à vie
  • il y a un risque si l’attaquant connait l’ip de l’admin et la fait bannir en floodant avec son ip

Donc on m’a filé une autre commande, plus courte et aussi performante, sans remplir inutilement les règles iptables :
(il faut supprimer l’espace entre les deux – – dans les commandes suivantes, wordpress les transforme en un seul -)

/sbin/iptables -A INPUT -p tcp - -dport 25565 -m state - -state NEW -m recent - -set
/sbin/iptables -A INPUT -p tcp - -dport 25565 -m state - -state NEW -m recent - -update - -seconds 60 - -hitcount 5 -j DROP

Ici, on surveille tout les nouveaux paquets sur le port 25565 et si la même ip renvoit de nouveaux paquets on incremente un compteur, si celui-ci atteint le hitcount (ici 5) dans les 60 secondes, on drop les paquets.

Si le visiteur lambda se fait drop, il devra juste attendre la fin de l’intervalle depuis son dernier paquet envoyé (ici 60 secondes à chaque fois),

Si c’est une attaque dos, il ne pourra envoyer que 5 nouveaux paquets par minutes, réduisant de ce fait la puissance de son attaque (si à chaque syn envoyé une nouvelle ip est forgée, cette protection ne servira à rien … et mon ban permanent aussi d’ailleurs ;)).

Et maintenant que la machine est « protégée » (c’est relatif hein ;)), il faut tester la sécurité ^^, on flood donc notre machine en envoyant des paquets SYN (avec scapy) sur le port du service que nous avons protégé.

On crée donc un fichier avec ce contenu en changeant les valeurs des ip, la valeur du loop et le port (derrière une NAT ça remplace l’ip source par votre adresse ip) :

#!/usr/bin/python
from scapy.all import *
send(IP(src=RandIP("0.0.0.0/0"),dst="ipserv")/TCP(sport=1337,dport=port du service,flags="S"),loop=5,inter=0.01)

Pour vérifier que les paquets sont drop, on fait un tcpdump sur le port en question et on compte le nombre de paquets provenant du port 1337.

tcpdump dst port 80 and src port 1337

(Si la règle en interdit plus de 5 et qu’on reçoit les 10 y’a un problème) ou l’on check les stats d’iptables via

iptables -L -v -n

Par contre, on peut s’amuser avec scapy à randomiser les ip (à faire sur des machines non natées) et tenter de flooder le service sans se faire drop un seul paquet :

#!/usr/bin/python
from scapy.all import *
sendp(Ether(src=RandMAC('*:*:*:*:*:*'),dst="port mac passerelle")/IP(src=RandIP("0.0.0.0/0"),dst="ip serveur")/TCP(sport=RandShort(),dport=port du service,flags="S"),loop=100,inter=0.01)

Et là on se rend compte que l’on peut facilement contourner la règle iptables précédente, et qu’il devient important de mettre en place une règle globale pour toute les ip sur un service en particulier.

Donc pour mettre en place une limite globale par exemple sur le port 80 qui peut traiter au max 1000 connexions en parallèle (en imaginant qu’une requête est traitée en 1 seconde (téléchargement d’une page web en générale) ce qui n’est pas forcément vrai pour tout les services, donc on laisse au mimimum 10% du nombres des connexions pour les connexions en cours) ce qui donne :

iptables -A INPUT -p tcp - -syn - -dport 80 -m limit - -limit 900/s -j ACCEPT

Et si l’on rebalance un SYN flood avec le script précédent, en lançant plus de 1000 syn en parallele, seul une partie d’entre eux devrait passer.

Ce système permet surtout de protéger les services derrière le firewall en cas d’attaque permettant de passer les règles présentées jusque là.

Mise en place d’un portknocking pour limiter les ports accessibles sur le net

Hello …

Protéger des services non-public (type ssh) d’être accédés par n’importe qui ça peut être assez utile (pour éviter les connexions intempestives pour la prise d’information, tentative de login/bruteforce …), le tout sans avoir à déclarer d’ip, …

On peut utiliser pour cela du portknocking, le but étant de mettre en place une séquence de « toc toc qui est là » qui permettra ensuite d’ouvrir la porte, et si la séquence n’est pas bonne … ^^).
Continuer la lecture de Mise en place d’un portknocking pour limiter les ports accessibles sur le net

Iptables : quelques trucs sympa

Bijour …

Suite à mes redirections de ports par iptables dans le tuto précédent, je me suis dit que ça pouvait être intéressant de voir un peu plus loin ce que propose iptables, et j’ai trouvé quelques truc sympa (que je cherchais pas ^^), dont on parle pas très souvent :

Je pars du principe que l’on bloque tout par défaut …

Limitation de certains flags sur un port précis :

Ici on autorise un syn par seconde, ça permet d’éviter les floods

[sourcecode language=bash]
/sbin/iptables -A allow-ssh-traffic-in -m limit –limit 1/second -p tcp –tcp-flags \
ALL SYN –dport ssh -j ACCEPT
[/sourcecode]

On peut aussi utiliser limit-burst pour augmenter le nombre de paquets qui équivaudront à un limit genre pour un limit-burst 5, il faudra 5 paquets pour faire un limit … cqfd^^

Détection de certaine méthodes de scan de nmap (et d’autre scanner)

Ici on va pouvoir logger et bloquer les scans de type XMAS, NULL et SYN*

[sourcecode language=bash]
$IPTABLES -N check-flags
$IPTABLES -F check-flags
$IPTABLES -A check-flags -p tcp –tcp-flags ALL FIN,URG,PSH -m limit \
–limit 5/minute -j LOG –log-level alert –log-prefix "NMAP-XMAS:"
$IPTABLES -A check-flags -p tcp –tcp-flags ALL FIN,URG,PSH -j DROP
$IPTABLES -A check-flags -p tcp –tcp-flags ALL ALL -m limit –limit \
5/minute -j LOG –log-level 1 –log-prefix "XMAS:"
$IPTABLES -A check-flags -p tcp –tcp-flags ALL ALL -j DROP
$IPTABLES -A check-flags -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG \
-m limit –limit 5/minute -j LOG –log-level 1 –log-prefix "XMAS-PSH:"
$IPTABLES -A check-flags -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$IPTABLES -A check-flags -p tcp –tcp-flags ALL NONE -m limit \
–limit 5/minute -j LOG –log-level 1 –log-prefix "NULL_SCAN:"
$IPTABLES -A check-flags -p tcp –tcp-flags ALL NONE -j DROP
$IPTABLES -A check-flags -p tcp –tcp-flags SYN,RST SYN,RST -m limit \
–limit 5/minute -j LOG –log-level 5 –log-prefix "SYN/RST:"
$IPTABLES -A check-flags -p tcp –tcp-flags SYN,RST SYN,RST -j DROP
$IPTABLES -A check-flags -p tcp –tcp-flags SYN,FIN SYN,FIN -m limit \
–limit 5/minute -j LOG –log-level 5 –log-prefix "SYN/FIN:"
$IPTABLES -A check-flags -p tcp –tcp-flags SYN,FIN SYN,FIN -j DROP
[/sourcecode]

Au pire, on peut aussi s’amuser à logger les mauvaises combinaisons de flags tcp du genre :(certaine règles peuvent rentrer en collision avec les précédentes … par contre, je me souviens plus de où j’ai trouvé ça …)

[sourcecode language=bash]

/sbin/iptables -N BADFLAGS
/sbin/iptables -A BADFLAGS -j LOG –log-prefix "IPT BADFLAGS: "
/sbin/iptables -A BADFLAGS -j DROP

/sbin/iptables -N TCP_FLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags ACK,FIN FIN             -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags ACK,PSH PSH             -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags ACK,URG URG             -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags FIN,RST FIN,RST         -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags SYN,FIN SYN,FIN         -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags SYN,RST SYN,RST         -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags ALL ALL                 -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags ALL NONE                -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags ALL FIN,PSH,URG         -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags ALL SYN,FIN,PSH,URG     -j BADFLAGS
/sbin/iptables -A TCP_FLAGS -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG -j BADFLAGS

[/sourcecode]

Marquer les paquets pour des traitements futures …

Bon, ici c’est vraiment pour faire geek, mais ça peut permettre de faire des limitations d’utilisation de bande passante ou … limiter l’accès à un service ^^ genre : seul les paquets marqués d’un « 2 » sont autorisés à ce connecter à mon serveur ssh (c’est une hypothèse bien sûr … ça peut être un autre chiffre ;)), mais ça donne ça :
Coté serveur :
[sourcecode language=bash]
/sbin/iptables -A INPUT -m mark –mark 2 -p tcp -dport 22 -j ACCEPT
#on drop le reste
/sbin/iptables -A INPUT -p tcp -dport 22 -j DROP
[/sourcecode]
Coté client :
On marque les paquets à destination du port 22 de l’ip 192.168.0.1
[sourcecode language=bash]
/sbin/iptables -t mangle -A PREROUTING -p tcp -d 192.168.0.1 -dport 22 -j MARK –set-mark 2
[/sourcecode]
Comme dit … suffit de ce faire sniffer les paquets et l’intrus remarquera rapidement le marquage des paquets, et bruteforcer le marquage n’est pas très dur, donc c’est pas très sécurisé comme technique mais ça peut ralentir une attaque 😉

Filtrer le contenu de certain paquets et faire une « chaine » de filtre :

Ici ça deviens intéressant … le firewall peut carrément lire le contenu de certain paquet tcp pour les drops!! (cf. lien SpamCleaner), ici, le but est de supprimer les sympatiques : GET /w00tw00t.at.ISC.SANS de nos logs apache

[sourcecode language=bash]
# création de notre chaîne w00t :
iptables -N w00t

# redirige les paquets TCP sur notre chaîne :
iptables -A INPUT -p tcp -j w00t

# recherche du premier SYN et création de la liste :
iptables -A w00t -m recent -p tcp –syn –dport 80 –set

# recherche du paquet SYN,ACK et mise à jour la liste :
iptables -A w00t -m recent -p tcp –tcp-flags PSH,SYN,ACK SYN,ACK –sport 80 –update

# recherche du paquet ACK et mise à jour la liste
iptables -A w00t -m recent -p tcp –tcp-flags PSH,SYN,ACK ACK –dport 80 –update

# recherche de la signature de DFind dans le prenier PSH+ACK.
# Si elle est présente, on DROP.
# On supprime la liste pour ne pas filtrer les paquets suivants
iptables -A w00t -m recent -p tcp –tcp-flags PSH,ACK PSH,ACK –dport 80 –remove \
-m string –to 70 –algo bm –string "GET /w00tw00t.at.ISC.SANS." -j DROP
[/sourcecode]

Là on se rend compte que ça peut être pas mal puissant.

Si en plus on couple ce genre de méthode avec modsecurity ou fail2ban on peut arriver à faire quelque choses de pas trop mal côté sécurité.

Bon bien sûr, j’allais pas faire un tour complet des possibilités d’iptables donc voici mes sources, si vous voulez continuer la lecture …

Mes différentes sources : (et ouai je ne suis qu’un kevin!! je repique tout!!, par contre, j’ai mis des liens avec des trucs dont je n’ai pas parlé plus haut … ou pas)

  • Gentoo security
  • RateLimit
  • SpamCleaner Le w00tw00t[1] le fail2ban[2]
  • Google ?!?
  • Marquage de paquet et limitation de bande passante [3] et la version fr [4] un autre en fr [6]
  • Marquage de paquet [5]

Sinon, quelques liens à lire sur iptables :

  • La doc d’ubuntu!! Pour les gros noob only!! (attention je fais du tracking toutes vos connexion seront marqués « GROS NOOB » :p)

Accès restreint sur certain ports dans le temps

Bijour à tous

Ben voilà … pour des raisons de sécurité évidente, il est souvent utile de bloquer l’accès sur certains ports depuis l’extérieur, et parfois on se rend compte qu’il faut tout de même laisser un accès sur ces services depuis l’extérieur (genre un TP qui nécessite une base de données … Oracle pour ne pas le citer), et bien sûr, on a pas envie de laisser l’accès ouvert en continu, d’autant plus que si les personnes ont une ip dynamique faire une liste des ip et sous-réseau autorisés risque d’être long, donc la solution (j’avoue que j’ai pas cherché si des logiciels faisaient ça) :

Faire 2 scripts :
– l’un qui reset les règles du firewall en tâche cron une fois par jour qui contiendrait quelques chose du genre :

#!/bin/bash
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
#les ports dont on veut bloquer l'acces par défaut ici le port 1337 allez savoir pourquoi 😉
iptables -A INPUT -p tcp --dport 1337 -j DROP

-l’autre qui autorise les ip contenu dans un fichier (en taches cron toutes les 5 minutes) du genre :

#!/bin/sh
IP_FILE="/var/www/ip.txt"
if [ -f $IP_FILE ]
then
        for i in `cat $IP_FILE`
        do
        #t=`echo $i|tr "-" " "`
        if [ -n $i ]
        then
                t="iptables -I INPUT 1 -p tcp -s $i --dport 1337 -j ACCEPT"
                #echo $t
                $t
        fi
        done
        rm $IP_FILE
fi

et hop, faut juste faire un script PHP qui rajoute les IPs (voir les ports, mais faudra modifier le script d’ajout des IP) dans le fichier txt pointé par le fichier txt du genre :

 $f=fopen("ip.txt","a+");
fwrite($f,$_SERVER['REMOTE_ADDR']."\n");
fclose($f);

Bien sûr, il faudra mettre une authentification dessus … sinon, c’est la porte ouverte à tout et n’importe quoi. Et voilà, vous pouvez dormir sur vos deux oreilles maintenant 😉

A noter que si vous le faites pour votre serveur SSH, faudrait pas que votre script plante, sinon, vous perdez tous les accès à votre serveur, mais ça peut permettre de pas mal réduire les tentatives de brute force, puisque par défaut personne ne pourra ce connecter dessus, il faudra juste passer par votre page web pour autoriser votre IP a y accéder et hop …

En espérant que ça puisse être utile 😉 Bon week-end.