Archive for the 'OpenBSD' Category

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

OpenBSD 4.3 en client LDAP

Dans le cadre d’une migration de NIS vers LDAP j’ai du lier mes passerelles OpenBSD 4.3 au nouvel annuaire LDAP.
Pour les systèmes “pingouin inside” ca va tout seul, par contre pour le poisson piquant c’est pas la même.

1. Suppression du NIS (headshot !)

# kill -TERM PID de ypbind
# rm /etc/defaultdomain
# rm -rf /etc/yp
# rm -rf /var/yp/binding/domaine_nis.version_nis

2. Installation des paquets

# pkg_add openldap-client
# pkg_add ldap_login

Le paquet openldap-client fourni les utilitaires ldap* (search, add, modify …) ainsi que le fichier de configuration ldap.conf que l’on va s’empresser d’écraser. Le ldap_login étend le fichier /etc/login.conf avec un classe de comptes ldap contenant les paramètres classiques de localisation du (des) serveur(s) LDAP (hostname, version de LDAP, certificats …).

3. Configuration du client LDAP

Tout se passe au niveau du fichier /etc/openldap/ldap.conf :

BASE    dc=my,dc=example,dc=com
URI     ldap://fake_server.my.example.com
 
TLS_CACERT      /etc/openldap/ssl/server_cert.pem
TLS_REQCERT   demand
 
ldap_version 3
ssl start_tls
scope sub
bind_policy soft

Il faut renseigner le login.conf pour que le programme ldap_login puisse réaliser l’opération de bind sur l’annuaire LDAP au moment de l’authentification du compte sur le système. Voici un exemple :

#
# LDAP
#
ldap:\
        :auth=-ldap:\
        :x-ldap-server=fake_server.my.example.com,,starttls:\
        :x-ldap-server-alt=fake_server.my.example.com,,starttls:\
        :x-ldap-basedn=ou=unix_accounts,o=people,dc=my,dc=example,dc=com:\
        :x-ldap-uscope=sub:\
        :x-ldap-noreferrals:\
        :x-ldap-filter=(&(objectclass=posixAccount)(uid=%u)):

On ne renseigne pas les attributs relatifs au chiffrement SSL dans le login.conf car par défaut il les déduit du ldap.conf.

4. Création des utiisateurs

OpenBSD n’intègre pas de système comparable au NSS. Les comptes doivent être crées via la commande useradd en utilisant la classe de login “ldap”. J’ai fait un petit script que l’on peut récuperer ici pour synchroniser les comptes.

Client NIS sous OpenBSD

Ce post est un mémo à moi-même pour configurer un client NIS sous OpenBSD.

    Modification du fichier passwd :
root # vipw

Ajouter : “+:*::::::::/bin/ksh” à la fin (le shell définit dans cette ligne écrase celui des utilisateurs).

root # pwd_mkdb /etc/master.passwd
    Définition du serveur NIS :
root # echo "domaine_par_défaut" > /etc/defaultdomain
root # mkdir /etc/yp
root # echo "nom_serveur_nis" > /etc/yp/domaine_par_défaut
root # domainname domaine_par_défaut
    Lancement des services :
root # portmap
root # ypbind
root # vi /etc/rc.conf.local

Ajouter :

portmap=YES

That’s all folks …

Filtrer un client FTP local au firewall Packet Filter

Le titre du film pourrait être “Client FTP protégé par un pare-feu PF” et il manque cruellement à la FAQ OpenBSD. En effet, ftp-proxy est au poil pour protéger les clients derrière l’interface interne du pare-feu (poétiquement nommée $int_if). Cependant, avez-vous déjà essayé de filtrer le trafic FTP issu d’un programme client local à la machine protégée par PF (machine mono interface avec une adresse publique dans mon cas) ?

Moi oui et c’est la misère car pour faire rentrer le trafic client dans le ftp-proxy on doit passer par une règle de type rdr. Or, si le trafic FTP est issu de la machine elle même (cad avec comme source l’interface de sortie vers le serveur FTP) alors PF ne le fait pas passer dans le règles de réécriture type redirection de port. Donc la transaction FTP n’est pas déroutée vers ftp-proxy. Heureusement, j’ai des amis talentueux (et chanceux). Nono m’a envoyé ce un lien vers ce thread . La solution était là : il faut utiliser les possibilités de routage de PF.

La solution est de dérouter le trafic issu de notre interface réseau et à destination du port 21 vers lo0. Ensuite lo0 va renvoyer le trafic vers notre interface réseau. Cette fois ci, la transaction va passer “à travers” notre interface réseau et va donc être soumise au règle de rdr. Après ça rentre comme papa dans maman. La seule restriction est de bien faire attention à ne pas avoir un set skip on lo0 sinon le paquet part bien vers lo0 mais ne reviens jamais.

En pratique dans le pf.conf :

nat-anchor “ftp-proxy/*”
rdr-anchor “ftp-proxy/*”
rdr pass proto tcp from ($int_if) to any port 21 -> 127.0.0.1 port 8021

pass out on $int_if route-to lo0 proto tcp from ($int_if) to any port 21
pass out quick on $int_if proto tcp from ($int_if) to any port 21 user proxy

Voila, maintenant vous pouvez faire du FTP depuis votre machine en utilisant ftp-proxy.

Bloquer les bruteforces SSH juste avec PF

Les scans SSH sont une véritable plaie.

Il existe une multitude d’outils pour les stopper (sshguard, fail2ban, snort-inline etc.).

Ces outils ont tous des aspects assez contraignants :

  • Ils ajoutent une “couche” logicielle supplémentaire (soit sous forme de scripts interprétés, soit d’exécutable compilés) qui manipulent vos fichiers de logs.
  • Il faut les maintenir, suivre leurs évolutions et mises à jour.
  • Ces couches sont elles même susceptibles de contenir des vulnérabilités.

Ce court billet va vous expliquer comment utiliser des fonctionnalités de Packet Filter (Pare-feu *BSD) pour mettre fin aux scans SSH. Tout est à réaliser dans votre fichier de configuration de PF (pf.conf).

Tout d’abord, il nous faut déclarer une table pour stocker les IP des brutes épaisses.

table <ssh-brute> persist

Cette table va nous permettre de bloquer le trafic issu de ces hôtes indélicats.

block quick from <ssh-brute>

Enfin, nous allons nourrir cette table avec la règle suivante :

pass in on $ext_if proto tcp from any to ($ext_if) port ssh keep state (max-src-conn-rate 2/20, overload <ssh-brute> flush global)

Explications : cette règle qui match les connexions entrantes sur le port 22 (ssh) n’autorise pas plus de deux connexions issues de la même IP¨sur une durée de 20 secondes (max-src-conn-rate 2/20). En cas de dépassement de ces paramètres l’hôte est ajoutée dans la table ssh-brute (overload <ssh-brute>) et ses connexions en cours sont coupées (flush global).

Pour gérer la péremption des enregistrements dans la table <ssh-brute> on peut utiliser le port expiretable disponible dans l’arbre des ports FreeBSD et OpenBSD. Un simple ajout de la ligne suivante dans votre crontab donne une durée de vie de 24 heures aux enregistrements /usr/local/sbin/expiretable -t 24h ssh-brute

Spamd

Spamd est un programme antispam fourni dans le système de base OpenBSD. Il réglemente le trafic vers le MTA (Mail Transfer Agent) en interagissant avec PF (Packet Filter).
Continue reading ‘Spamd’