Juste un post pour indiquer la mise en ligne ce jour d’un article soumis sous “creative commons” à Linux Magazine. Je trouve ce principe particulièrement intéressant de publier l’article sur le web librement accessible quelques mois après sa parution. Il est disponible ici.
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
Voila un petit mois que je n’ai rien posté sur ce blog. J’avais un peu la tête sous l’eau. J’ai donc passé mes serveurs FreeBSD hébergeant des jail en 8.0. Seulement, je me suis loupé dans la procédure d’upgrade. J’ai upgradé un jail en 8.0 puis en rappelant la commande freebsd-update j’ai omis le -b pour lui donner comme racine un jail donc il a mis à jour le système de base. Je n’ai pas voulu interrompre la procédure donc je l’ai laissé finir.
Le problème lorsque l’on utilise freebsd-update pour mettre à jour ses jails c’est qu’il se base sur la version renvoyée par uname. Si l’on met à jour le système de base avant les jails, alors freebsd-update lancé sur le jail considère que le système est déjà à jour. Pour s’en sortir, deux options :
1) Création d’un faux uname
On move /usr/bin/uname vers /usr/bin/uname.org et on se fait un petit script du style :
#!/bin/sh /usr/bin/uname.org $* | sed s/"8.0-RELEASE"/"7.2-RELEASE-p4"/g
Ok c’est encore plus crade que du porno thaïlandais …
2) Copie d’un jail “master”
Directement inspiré d’un post trouvé ici. Cette méthode propose de disposer d’un master jail à répliquer. J’étais un peu dans cette configuration avec comme “master jail” celui que j’avais upgradé avant ma boulette. Les installations des différents jails étant assez homogènes (ferme de serveur FreeBSD / Apache / Trac / SVN) il me suffisait de répliquer ce jail et de recoller les data de /usr/local/[svn|www]-trac qui contiennent respectivement les instances subversion et Trac associées. Pour copier un jail, ne surtout pas faire un bête cp mais plutôt :
# cd /jail/masterjail
# tar -cpf - . | tar -C /jail/newjail -xpf –
Pour conserver les permissions, la nature du fichier (surtout les liens) etc. Quand on combine tar et ssh on obtient même un “master jail” deployable de façon sécurisée sur tous les serveurs partageant son architecture (uname -m). A noter que cette manipulation a quand même nécessité la recompilation du port www/apache22 sur le newjail.
Parti pour tester les possibilités de monitoring du package OMSA sur des Dell Poweredge R410 flambants neufs, je me suis cassé le nez sur la carte réseau. Celle ci est une Broadcom tout ce qu’il y a de plus classique simplement les drivers du chipset BCM 5716 sont absents du noyau 2.6.26 compilé pour lenny. S’en est suivi une journée de bataille pour tenter de se créer un CD netinst.iso customizé avec le noyau 2.6.30 des backports. Autant le dire tout de suite, j’ai perdu la bataille !
Pour moi la manipulation a consisté à récupérer le noyau 2.6.30 des backports ainsi que le firmware qui va avec (comme dirait Sefyu) sur une clé USB. Armé de tout ca, on peut démarrer une install standard via le netinst.iso classique. Une fois le système installé, reboot. Il est aussi conseillé de récupérer les packages virtuels associés dans les backports (linux-image-2.6-686-bigmem et firmware-bnx2) pour suivre les mises à jour.
Pour la suite, on va monter la clé et installer les deux packages backportés :
mount -t vfat /dev/sdb1 /mnt/usb
cp /mnt/usb/*.deb /root
cd /root
dpkg -i linux-image-2.6.30-bpo.1-686-bigmem[...].deb
dpkg -i firmware-bnx2_0.17~bpo50+1_all.deb
dpkg -i llinux-image-2.6-686-bigmem_[...].deb
dpkg -i firmware-bnx2.deb
Ensuite, comme on a utilisé les backports, il faut les ajouter dans notre /etc/apt/sources.list :
deb http://www.backports.org/debian lenny-backports main contrib non-free
Ensuite, il faut mettre à jour le cache apt et récupérer le keyring des backports :
apt-get update
apt-get install debian-backports-keyring
Enfin pour gérer les mises à jour, il faut que nos 2 packages backportés pointent sur les dépôts backports. Pour se faire, il faut créer ou modifier le fichier /etc/apt/preferences :
Package: linux-image-2.6-686-bigmem_[...].deb Pin: release a=lenny-backports Pin-Priority: 999 Package: firmware-bnx2 Pin: release a=lenny-backports Pin-Priority: 999
Et hop, maintenant la mise à jour devrait se faire trankilou. Il est important de noter que l’emploi des logiciels backportés a des implications au niveau sécurité. Les mises à jour sont au bon vouloir du mainteneur. Les problèmes ouverts pour lenny sont consultables ici.
Pour éviter de NATer à tort et à travers nos (chers) utilisateurs, nous avons décidé de mettre en place un proxy FTP. Nous pensions pouvoir trouver une multitude d’outils pour rendre ce service. Hé bien non, il n’y en a que deux :
- frox qui n’est pas tout jeune (2004) et qui semble causer des soucis avec les kernel 2.6 en mode transparent.
- ftp-proxy qui est un peu plus récent (2005) et qui lui ne semble pas avoir de problèmes connus.
Notre choix s’est porté sur ftp-proxy. Ce produit fait partie de la proxy-suite développée par SuSE (mais elle avale pas). L’installation sur une Debian Lenny est d’une simplicité biblique.
Tout d’abord, installons le package :
apt-get install ftp-proxy
Ensuite, il faut autoriser le démarrage du service en mode daemon dans /etc/default/ftp-proxy :
RUN_DAEMON=yes
Enfin, il faut modifier le fichier /etc/proxy-suite/ftp-proxy.conf. J’ai mis l’intégralité de mon fichier purgé des commentaires :
[-Global-] AllowMagicUser yes AllowTransProxy no DestinationAddress localhost DestinationTransferMode client Group nogroup LogDestination /var/log/ftp-proxy/ftp-proxy.log LogLevel INF Port 2121 User nobody
Une petite explication des paramètres. AllowMagicUser permet de “mettre de la magie” dans le nom de l’utilisateur. En gros ça permet d’interpréter une chaine type utilisateur@serveur:port ce qui est assez courant pour les clients FTP en ligne de commande. AllowTransProxy permet d’autoriser ou non le proxy transparent. J’ai choisi de le désactiver. DestinationAddress est utile quand on veut utiliser ftp-proxy en reverse devant un de nos serveurs FTP (pour interdire des commande ou bloquer du trafic non FTP). Dans ce cas on doit aussi activer le mode transparent. DestinationTransferMode permet de forcer le mode de fonctionnement en actif ou en passif. Ici je laisse le choix au client. Group et User fixent l’identité sous laquelle le service s’exécute. LogDestination et LogLevel l’emplacement et le niveau de détails des événements remontés. Enfin Port donne le port utilisé par ftp-proxy. Il n’y a plus qu’a le lancer :
/etc/init.d/ftp-proxy start
Et voila !
Aujourd’hui j’ai participé à une install party organisé par LUG orléannais Cenabumix. Cette manifestation s’est passée dans les locaux de l’IUT Informatique d’Orléans. Au programme : installation et dépannage de GNU\Linux et deux conférences sur les thèmes de la messagerie Jabber et des logiciels libres. Ambiance très sympa et atmosphère studieuse. Ce qui m’a frappé c’est d’abord le monde. Plus d’une centaines de personnes sont passées et les conférences ont fait le plein. L’audience était fortement hétérogène avec quand même une forte population d’age mure qui n’ont pas peur de se lancer dans le monde du libre. Un de nos sémillant ancêtre m’a même dit “Moi je garde une partoche windows pour mes petits enfants quand ils viennent jouer, sinon je n’aurais que Ubuntu !”. En discutant avec eux, il semble que les principales raison qui leur on fait opter pour un système Linux sont :
- Le foutage de gueule de Microsoft avec Vista et Seven. En effet, un geste élégant aurait été d’offrir Seven : “ce qu’aurait du être Vista” selon l’adage. Mais non la tu passes deux fois à la caisse.
- Le prix des systèmes propriétaires non négligeable.
- La complexité des nouveaux systèmes. Ce qui plait avec Ubuntu et Mandriva c’est le système de gestion de paquets. En 1 clic, nos pappys récupèrent Opera, Thunderbird, Audacity etc. Et ça, ça n’existe ni sous Windows, ni sous OSX (fink et Darwin porcs = LOL).
- Les systèmes Linux sont plus virus-free que Windows c’est indéniable.
Bref, nos ancêtres sont des as du clic, rebelles dans l’âme qui recherchent avant tout la simplicité. Une position dont devraient s’inspirer nombre de décideurs qui persistent sur les chemins du logiciel fermé avec une surface d’attaque aussi importante que le montant de la maintenance annuelle.
Tutorial rapide pour chrooter bind9. Le but est d’avoir un répertoire /var/lib/named ou se va se chrooter bind9. La configuration va se faire dans le etc relatif au chroot et les zones seront stockées dans le var relatif au chroot. Les manipulation sont faites sur une Debian Lenny. Créons d’abord les répertoires :
mkdir /var/lib/named
mkdir -p /var/lib/named/etc
mkdir /var/lib/named/dev
mkdir -p /var/lib/named/var/cache/bind
mkdir /var/lib/named/var/log
mkdir -p /var/lib/named/var/run/bind/run
On déplace la configuration :
mv /etc/bind /var/lib/named/etc
On fait un lien au cas on voudrait facilement le déchrooté (et aussi pour les upgrades) :
ln -s /var/lib/named/etc/bind /etc/bind
On se crée un socket en écoute dans le chroot pour rsyslog. Dans /etc/rsyslog.conf :
$AddUnixListenSocket /var/lib/named/dev/log
On crée les devices dans le chroot
mknod /var/lib/named/dev/null c 1 3
mknod /var/lib/named/dev/random c 1 8
chmod 666 /var/lib/named/dev/null /var/lib/named/dev/random
On fixe les permissions :
chown -R bind:bind /var/lib/named/var/*
chown -R bind:bind /var/lib/named/etc/bind
Enfin dans /etc/defaults/bind9 :
OPTIONS="-u bind -t /var/lib/named"
Un restart de rsyslogd et bind et c’est parti !
Un petit post pour mémoire sur le fonctionnement d’un client Windows XP avec KFW (Kerberos For Windows) et les outils Mozilla. Mon but est de proposer une authentification Kerberos aux utilisateurs itinérants : non raccordés à un domaine, compte local à la machine et authentification (au moment du login) non liée au KDC. KFW est un utilitaire distribué par le MIT qui permet d’intégrer une couche GSSAPI “traditionnelle” dans Windows. En effet, Windows utilise une variante fermée de la GSSAPI qui se nomme SSPI (Security Support Provider Interface). L’installation de KFW n’est pas compliquée (suivant, suivant et terminer). Une fois installée, on doit configurer le fichier krb5.ini (qui ressemble comme deux goutes d’eau au krb5.conf). Voici un exemple minimal :
[libdefaults]
default_realm = MONDOMAINE.FR
[realms]
MONDOMAINE.FR = {
kdc = kdc.mondomaine.fr
}
[domain_realm]
.monrealm.fr = MONDOMAINE.FR
mondomaine.fr = MONDOMAINE.FREnsuite, il suffit de cliquer pour obtenir les credentials (TGT). Ensuite, pour les applications Mozilla il faut faire un petit réglage. En effet, Firefox et Thunderbird utilisent par défaut la SSPI. On peut forcer l’utilisation de la GSSAPI en désactivant le SSPI. Pour ce faire, dans “Outils”, “Options” et “Editeur de configuration” placez le network.auth.use-sspi à false.
Hier soir j’ai terminé le livre “Extrusion Detection : Security Monitoring for Internal Intrusions” de Richard Bejtlich. Ce livre est dédié à l’étude du phénomène d’extrusion. L’extrusion est un acte malveillant initié depuis le réseau interne. Cet acte peut avoir comme résultat la fuite d’information. Il peut aussi être la conséquence de compromissions de vos machines. Une fois sous le contrôle d’un pirates, vos machines peuvent se mettre à initier des attaques vers d’autres sites. Sur une dizaine de chapitres, l’auteur propose des méthodes basées sur l’analyse du trafic réseau pour mettre ces malveillances en lumières. Les aspects techniques sont largement couverts : l’instrumentation du réseau (sondes, boitiers TAP etc.), la collecte des éléments réseau (statistiques globales, données de sessions et stockage des payloads), leur analyse (le plus souvent via des outils libres : sguil, argus, snort etc.). De bonnes astuces sont également livrées, telles que le “sink hole” qui consiste à introduire des routes plus larges que celles réellement utilisées afin de capturer le trafic illégitime. Ce livre est à mon sens excellent dans la mesure ou il donne des pistes exploitables pour garder un oeuil sur l’activité de son réseau et surtout de pouvoir présenter des éléments en cas de compromission. L’auteur propose également un livre entièrement dédié à l’analyse du trafic réseau dans un optique plus classique de détection d’intrusion. Il est déjà sur ma table de nuit …
Après moult jours de tripatouillage, je suis parvenu à faire fonctionner l’authentification Kerberos avec Postfix. En effet, on trouve dans les howtos un nombre impressionnant de façon d’y arriver (avec comme toujours certaines configurations dont on peut se demander comment elles fonctionnent). Installons d’abord les paquets :
$ apt-get install postfix
$ apt-get install libsasl2-modules-gssapi-mit
Le daemon saslauthd est inutile. Passons maintenant à l’enregistrement du service SMTP dans le KDC en créeant un ticket pour le service (smtp/fqdn).
$ kadmin.local
kadmin: addprinc -randkey smtp/mailtest.mondomaine
kadmin: ktadd -k /etc/smtp.keytab smtp/mailtest.mondomaine
Il faut ensuite recopier le /etc/smtp.keytab depuis le KDC vers le serveur de mail (mailtest). Sur mailtest ce fichier doit être installé dans le chroot de Postfix car par défaut le processus smtpd acceptant les connexions authentifiées pour l’envoi de messages est chrooté dans /var/spool/postfix. Tant que l’on est à parler du chroot, il faut aussi recopier le répertoire temporaire /var/tmp dans /var/spool/postfix/var car il est utilisé par le processus krb5.login. Il nous faut aussi le /etc/krb5.conf dans /var/spool/postfix/etc. Dernière note sur le chroot, on peut aller voir dans le script de démarrage (/etc/init.d/postfix) les fichiers copiés automatiquement dans le chroot au démarrage du service.
Une fois le chroot configuré, passons au master.cf pour activer un smtpd en SSL sur le port 465 :
smtps inet n - - - - smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING
Occupons nous aussi du main.cf :
import_environment = KRB5_KTNAME=/etc/smtp.keytab
[...]
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = cyrus
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destinationLe import_environment est super important car il permet de positionner l’emplacement d fichier keytab utilisé par le service smtp kerberisé. On redémarre un coup Postfix et on test les méthodes d’authentification présentées aux clients avec la classqiue commande “ehlo” :
$ openssl s_client -connect mailtest.univ-orleans.fr:465
Nous renvoie la sortie suivante :
220 mailtest.mondomaine ESMTP Postfix (Debian/GNU) ehlo mailtest.mondomaine 250-mailtest.mondomaine 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH GSSAPI DIGEST-MD5 NTLM CRAM-MD5 PLAIN LOGIN 250-AUTH=GSSAPI DIGEST-MD5 NTLM CRAM-MD5 PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN
La GSSAPI est bien notre mécanisme d’authentification par défaut. Testons maintenant avec un Thunderbird. Pour le configurer, allez dans les propriétés du compte puis “serveur sortant smtp”. Ajoutez en un avec comme nom de serveur mailtest.mondomaine, port 465, selectionnez “Utiliser un nom d’utilisateur et un mot de passe” et enfin choisissez “Utiliser un connexion sécurisée SSL”. Vous devriez maintenant pouvoir envoyer tous vos messages authentifié via Kerberos. Sus au spam interne !
Le debugging est assez complexe, surtout avec le chroot de Postfix. Pour vous aider, vous pouvez utiliser à mort strace en l’attachant au processus “master” de Postfix en suivant tout les types de fork (option -fF) et en sélectionnant certains appels systèmes (-e).