Monthly Archive for January, 2010

NAT authentifié avec authpf

A mon sens le NAT est une horrible (mais nécessaire) verrue. Le pire étant quand même lorsque l’on ose qualifier de sécurité le fait de NATer des machines : “On peut initier des connexions vers l’exterieur mais pas l’inverse“. C’est vrai, sauf que les machines compromises initient des connexions vers l’extérieur pour signifier à leur botnet de raccordement leur disponibilité. Devant garantir un minimum de traçabilité de ces accès, j’ai décidé de mettre en place une passerelle de NAT authentifié avec authpf. Authpf permet de jouer des règles PF via les ancres lors d’une connexion SSH. The big picture :




La machine authpf est un OpenBSD 4.6. La problématique est que cette machine n’est pas notre pare-feu principal (snif …). Les flux doivent donc être routés vers cette machine au niveau du pare-feu en fonction du réseau source. Ceci n’est possible qu’en appliquant du “policy routing” qui permet d’appliquer des règles de routage en fonction d’autres critères que le réseau (ou la machine) de destination. On définit ensuite le routeur externe comme passerelle du NAT authentifié et c’est gagné.

1. Configuration de la passerelle

Au niveau de la passerelle, il faut ajouter les lignes suivantes au niveau du rc.conf :

pf=YES
pf_rules=/etc/pf.conf.local

J’aime bien mettre mes règles PF dans un fichier à part.

Examinons le pf.conf.local (seule les sections intéressantes sont affichées) :

set skip on lo
block in log all
block out log all
 
nat-anchor "authpf/*"
rdr-anchor "authpf/*"
binat-anchor "authpf/*"
 
anchor "authpf/*"

On laisse tout passer sur 127.0.0.1 (lo), ensuite on bloque tout et on loggue en entrée et en sortie. Enfin, on pose les ancres pour ajouter dynamiquement les règles des utilisateurs authpf.

2. Création des utilisateurs

Dans tout organisme moderne, on dispose d’un LDAP avec les utilisateurs dedans (et surtout un uid associé à un userPassword). Dans ce cas, on peut connecter son NAT authentifié au LDAP. Pour ce faire, deux options : ypldap ou login_ldap. J’ai choisi la méthode via login_ldap car je ne dispose pas de vrai posixAccount dans mon LDAP et des informations telles que l’UID sont nécessaires. Voila ma section dans le /etc/login.conf pour associer LDAP et authpf :

ldap-authpf:\
        :auth=-ldap:\
        :x-ldap-server=monldap.mondomaine:\
        :x-ldap-basedn=ou=People,dc=mondomaine:\
        :x-ldap-binddn=cn=toto,ou=user4bind,dc=mondomaine:\
        :x-ldap-bindpw=azerty:\
        :x-ldap-filter=(&(objectClass=inetOrgPerson)(uid=%u)):\
        :welcome=/etc/motd.authpf:\
        :shell=/usr/sbin/authpf:\
        :tc=default:

Pour créer les utilisateurs :
useradd -L ldap-authpf -d /var/empty -s /usr/sbin/authpf -r 1500..3000 -g =uid pastounus
Cela crée l’utilisateur pastounus avec une home bidon (-d /var/empty) qui va utiliser la “login class” ldap-authpf (-L ldap-authpf) ainsi que le shell authpf (-s /usr/sbin/authpf) et un groupe privé UPG (-g =uid).

3. Utilisation

On ajoute les règles de l’utilisateur pastounus dans le fichier /etc/authpf/users/pastounus/authpf.rules :

int_if=bge0
 
nat pass log on $int_if from $user_ip to any -> XXX.XXX.XXX.XXX

Et voila : une fois authentifié, pastounus est naté ! On notera quand même qu’il convient d’ajouter les routes de retour sur la passerelle pour les réseaux derrière le NAT authentifié. La passerelle devra également proxifier les réponses ARP pour les IP vers lesquelles elle effectue les translations. Tout cela se passe dans le rc.local. Dans notre exemple XXX.XXX.XXX.XXX est l’adresse de NAT, YYY.YYY.YYY.YYY est le réseau privé à NATer et ZZZ.ZZZ.ZZZ.ZZZ est la patte du pare-feu sur laquelle est raccordée la passerelle.

# Add your local startup actions here.
 
echo '.'
route add -net YYY.YYY.YYY.YYY/24 ZZZ.ZZZ.ZZZ.ZZZ
 
arp -s XXX.XXX.XXX.XXX @mac_nat_auth pub