Skip to content

Linux Attitude

Le libre est un état d'esprit

Archive

Archive for June, 2012

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é : ip link add link eth0 vlan1 type vlan id 1

Je suis de retour !

Désolé pour le lag ... mais je réponds aux commentaires.

Problème

Aujourd'hui, un problème qu'on m'a posé récemment. Comment faire lorsqu'on a un parc de box (routeur wifi, machine embarquée, ...) et qu'on veut pouvoir à tout moment se connecter physiquement sur son port ethernet et la configurer en utilisant ip (par ssh, snmp ...).

La première solution est d'avoir une configuration réseau immuable sur ces machines ET de répertorier d'une façon ou d'une autre un identifiant unique pour chacune de ces machines qu'on peut alors faire correspondre à une ip. C'est assez contraignant et ça impacte fortement la configuration réseau des machines. Ça risque de nous empêcher de réutiliser ce port pour communiquer dans un réseau existant le reste du temps.

La deuxième solution serait d'utiliser un protocole type zeroconf pour configurer automatiquement le réseau lorsqu'on se branche, l'inconvénient est de réussir à le désactiver lorsque la machine se retrouve dans son réseau de destination qui n'utilise pas nécessairement zeroconf tout en le gardant actif pour le configurateur.

Je vous propose donc une solution différente : l'ip unique. Toutes les machines à configurer ont la même IP. C'est bien beau me direz-vous, mais comment fait-on pour éviter les conflits sur le réseau de destination ? Et comment fait-on pour que ces machines communiquent ensemble ?

C'est tout simple, on met cette IP sur un vlan prédéfini. Ainsi vous n'avez plus aucune contrainte sur la configuration réseau de l'appareil. Ce peut être une box en bridge ou en routeur, une machine physique avec un routage complexe, ou une machine configurée en dhcp.

Solution pour linux

Pour ajouter une interface réseau virtuelle associée à un vlan :

# le vlan 1 sur l'interface eth0 sera dans l'interface virtuelle vlan1 
$ ip link add link eth0 vlan1 type vlan id 1 

# ou, pour ceux qui n'aiment pas le couteau suisse, ip, il y a l'outil d'origine
$ vconfig add eth0 1 # pas le choix, l'interface s'appellera nécessairement eth0.1

Et il suffit de lui configurer une ip choisie en dur et c'est fini, vous pouvez mettre n'importe quelle configuration pour eth0 ...

$ ip addr add 192.168.254.254/28 dev eth0.1

Pour faire ceci en statique, sur une debian like il faut modifier /etc/network/interfaces en nommant l'interface à configurer eth0.1 Pour les redhat like il faut créer le fichier /etc/sysconfig/network-script/ifcfg-eth0.1