Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Tag: Firewall

Niveau :      
Résumé : ipset; IN A

Ceci n'est pas une amélioration de l'article précédent, mais un complément.

Un firewall basé sur le DNS

On veut être indépendant des ip utilisées par les gens que l'on filtre. On se propose cette fois de faire des règles de filtrage basées sur le forward DNS et non plus le reverse DNS.

Cette fois, on ne peut plus utiliser l'IP du paquet pour récupérer le nom de domaine, mais on peut mettre au jour automatiquement les règles de firewall en fonction d'un domaine défini et non plus avec des IP statiques.

Encore une fois, les précautions précédentes s'appliquent :

  • on base une règle sur quelque chose qu'on ne maitrise pas, voire qu'un attaquant pourrait maitriser : la base dns de la source
  • on devient dépendant du résolveur dns et donc de ses failles

Mais à la différence de la dernière fois, le dns est potentiellement sous contrôle d'un ami (si on parle de whitelist et non de blacklist). De plus on peut imaginer utiliser DNSSEC pour gagner en sécurité.

Changeons de technologie. Puisque nous ne faisons plus de reverse DNS, nous devons connaître à l'avance l'intégralité des domaines. Donc on ne peut plus avoir de regex ou de wildcard. Et puisque nous devons les connaître à l'avance, nous pouvons juste faire des requêtes, stocker les IP résultantes et les utiliser directement dans le firewall.

La technologie du jour s'appelle donc ipset. Elle permet d'utiliser un pool d'ip que l'on peut faire varier dynamiquement dans une règle iptables.

Iptables

Son usage est simple :

# on ne matche que sur l'ip source
iptables -A ... -m --match-set chezmoi.com src -j ...
# on matche sur un couple source/destination
iptables -A ... -m --match-set friendzone src -j ...

Ensuite il suffit de créer les set

ipset --create chezmoi.com iphash
# ip ipset create chezmoi.com hash:ip  (pour ceux qui ont une ancienne version d'ipset)
ipset --create friendzone iphash
# ip ipset create friendzone.com hash:ip  (pour ceux qui ont une ancienne version d'ipset)

Règles en live

Il ne nous reste plus qu'à mettre à jour les set dynamiquement, par exemple en interrogeant régulièrement les serveurs dns.

# on utilise un ipset temporaire pour que le firewall continue de fonctionner pendant nos opérations
ipset --create temp iphash

for rule in rules
do
    ipset --flush temp
    for i in domains[$rule]
    do
        host $rule | 
        xargs ipset --add $rule $ip
    done
    ipset --swap temp $rule
done

ipset --destroy temp

Il n'y a plus qu'a lancer ce script régulièrement grâce à notre ami cron.

Et voila !

Notez qu'il y a moyen avec ipset de matcher plusieurs adresses à la fois (ip, mac, source, destination), de matcher des réseaux et même de matcher des ports.

Niveau :      
Résumé : perl, libipq, IN PTR

Le problème

Les firewall ne proposent jamais de faire une règle qui couperait la connexion en fonction du domaine de l'appelant. C'est gênant car on aimerait bien pouvoir devenir indépendant de l'ip de notre partenaire.

Si on ouvre un accès à un ami, pourquoi devrait-il nous avertir lorsqu'il change d'ip alors qu'il a fait correctement son travail en mettant à jour son DNS.

En réalité il y a de bonnes raisons à cela, en effet le domaine ne se trouve pas dans le paquet il faut donc aller le chercher quelque part. Et cela implique :

  • qu'on base une règle sur quelque chose qu'on ne maîtrise pas, voire pire, qu'un attaquant pourrait maîtriser : la base dns de la source
  • qu'on devient dépendant du résolveur dns et donc de ses failles
  • qu'il est possible que le firewall empêche le firewall d'aller chercher l'info sur le serveur dns
  • qu'il faut attendre que le dns réponde et donc les performances d'un tel firewall risquent d'être catastrophiques

Les deux derniers problèmes sont purement techniques et ont donc une solution technique acceptable moyennant quelques compromis. Par contre les deux premiers problèmes concernent la sécurité et il faut donc garder en tête que si on met en place une telle règle, elle est là pour nettoyer les flux qui traversent notre firewall, mais qu'elle n'apporte que peu de sécurité par rapport à l'absence de règle.

La solution

Maintenant que nous savons qu'il ne faut pas le faire, voyons comment faire :-)

Tout d'abord il y a deux possibilités, se baser sur le forward DNS (IN A et IN AAAA) ou sur le reverse dns (IN PTR). Aujourd'hui je vous propose le pire des cas, le reverse DNS, puisque votre configuration est directement tributaire de la volonté de l'attaquant.

Commençons par un prototype, donc en perl, parce que je le veux bien.

Le point important ici est de faire la résolution dns en espace utilisateur. Pour cela il faut d'utiliser libipq, la bibliothèque permettant de communiquer entre l'espace utilisateur et netfilter la partie noyau du firewall linux.

Il nous faut donc :

  • libipq : IPTables::IPv4::IPQueue
  • parser les paquets ip : NetPacket::IP
  • faire des requêtes dns : Net::DNS

Et voici le script tout simple, le reste de l'article est en commentaire dans le script.


continue reading...

Niveau :      
Résumé : iptables android

Maintenant nous savons tout ce qui passe par la tête d'un android. Mais on a découvert des choses qui ne nous plaisent pas.

Couper des communications

Donc vous voulez interdire certaines communications, par exemple la connexion au serveur de votre ennemi héréditaire (on ne sait jamais, la paranoïa peut mener loin).

C'est simple linux a un firewall, profitez-en et utilisez iptables pour couper la communication :

# toujours sur le téléphone
$ chroot $ROOT
$ iptables -A OUTPUT -d 10.0.0.1 -j DROP

Au fait vous savez comment s'affichent les pubs ? ;-)

Proxy transparent

Vous pouvez même filtrer un peu mieux tout simplement en, redirigeant le traffic vers un service adapté.

C'est simplement la technique du portail captif, mais cette fois à votre avantage. Par exemple pour rediriger le DNS vers votre serveur local :

$ iptables -A OUTPUT -p udp --port 53 -j REDIRECT
$ iptables -A OUTPUT -p tcp --port 53 -j REDIRECT
/// 

Bien sûr il faut mettre un serveur dns local que vous maitrisez.

Et bien sûr vous pouvez faire pareil avec un proxy http qui prendra la décision au niveau du dessus.

$ iptables -A OUTPUT -p tcp --port 80 -j REDIRECT ///

Et pour ceux qu'android n'intéresse pas, n'oubliez pas que ça marche aussi sur votre passerelle à l'entrée de votre réseau ou n'importe quel PC ...

Niveau :      
Résumé : iptables -m hashlimit

Aujourd'hui un ami me dit "hey j'ai un truc pour toi" et il me file sa configuration iptables pour limiter les barbares qui viennent lui détruire son serveur et sa connectivité à coup de robots farceurs.

De coup je me suis penché sur son script et je vous le livre avec son accord (toujours accorder un complément d'objet webesque comme dirait la métraisse).

Le script

Il est court mais bref :

IPT=/sbin/iptables
WEBMAXPERMIN="260"
WEBBURST="40"

$IPT -N throttle

# hashlimit-htable-expire en millisecondes 
$IPT -A throttle -m hashlimit \
 --hashlimit-name webthrottle \
 --hashlimit-upto $WEBMAXPERMIN/minute \
 --hashlimit-mode srcip \
 --hashlimit-burst $WEBBURST \
 --hashlimit-htable-expire 300000 \
-j ACCEPT
$IPT -A throttle -j LOG --log-prefix "FREIN " --log-level 1
$IPT -A throttle -j REJECT

#puis dans  le INPUT
$IPT -A INPUT -d $ETH00 -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -j throttle


continue reading...

Niveau :      
Résumé : ferm

Ferm

Vous battez-vous toujours avec vos scripts shell pour configurer les firewall de vos serveurs ? Ne ramez plus, j'ai la solution : Ferm.

Pourquoi ferm ? Ben pourquoi pas ?

Je l'ai choisi car il ne fait qu'une chose (et le fait bien), il remplace vos scripts shell de lancement de firewall. Et c'est tout ! Pas d'interface graphique, pas d'assistance à création de règle, pas de gestion de votre serveur DHCP ...

Donc si votre machine de bureau sert de passerelle vers internet, ou si vous ne connaissez pas bien iptables, ce n'est probablement pas le meilleur outil. Par contre si vous avez l'habitude d'écrire des scripts shell pour gérer votre firewall, ferm est là pour vous simplifier la vie.

Configuration

Ferm génère des règles iptables à partir de son fichier de configuration. Il n'invente rien, il ne fait qu'écrire sous forme hiérarchique les règles iptables et vous permet d'utiliser des variable et des listes. Il faut donc les connaître un peu.

Petit exemple pour vous montrer comment gagner du temps (il se comprend tout seul) :


continue reading...

Niveau :      
Résumé : conntrack

I'm back !
Désolé de vous avoir fait attendre, j'étais en quelque sorte en vacances.

Firewall

Cette fois nous allons parler de firewall. Comme vous le savez, netfilter, le firewall intégré à linux, est statefull par défaut. Ce qui veut dire que si on ne lui dit pas de ne pas le faire, il trace l'état de toutes les connexions qui le traversent. C'est grâce à cela qu'il sait filtrer les connexions avec des règles "simples" ou qu'il est capable de filtrer proprement le ftp.

Pour cela il garde en mémoire une table des connexions établies, qu'il peut communiquer au reste du monde, autrement appelé espace utilisateur. Il expose ces infos dans /proc/net/ip_conntrack* (entre autre, mais n'hésitez pas à regarder le contenu de ce répertoire pour plein de choses intéressantes).

La commande conntrack, du paquet éponyme sert à manipuler la table en question. Toute machine ayant un firewall, ou presque, on peut s'amuser à l'utiliser sur son PC. Mais c'est bien plus rigolo de faire ça sur un routeur ;->

D'ailleurs, si vous avez un serveur qui ne fait pas firewall et qui gère beaucoup de connexions (un serveur de twitter par exemple), vous pouvez désactiver le "connection tracking" pour soulager le noyau de cette tâche. Mais il faut entièrement désactiver le module, ce qui n'est pas des plus simple.

Conntrack

D'abord, commençons par lister les connexions connues :

$ conntrack -L

Pour une machine qui ne fait pas routeur, la liste est similaire à celle obtenue par netstat -atu. Notez les informations intéressantes : état de la connexion, détail de la connexion (remarquez la répétition nécessaire pour le NAT), et surtout nombre de paquets et d'octets passés par cette connexion. Ce compteur peut être réinitialisé avec l'option -z de conntrack :

$ conntrack -L -z

Pratique quand on veut détecter les changements.

Vous pouvez aussi regarder ce qui se passe en direct sur votre routeur :

$ conntrack -E

Mais lisez bien le manuel, pour limiter la sortie, car sur un vrai routeur, il faut filtrer. Man conntrack contient toutes les explications.

Et le plus rigolo sur un routeur partagé, on enlève l'entrée :

# Attention, il faut tout spécifier pour être sûr qu'on parle de la bonne connexion
$ conntrack -D -s 1.2.3.4 -d 4.3.2.1 -p tcp --orig-port-src 5678 --orig-port-dst 22

Cela devrait couper la connexion si le firewall est bien configuré (et probablement aussi s'il est mal configuré). C'est tout de même moins artisanal que l'ancienne technique.