Bloquer le trafic sortant de ses jails avec packet filter

Si comme moi vous utilisez une FreeBSD avec pleins de services/utilisateurs dans des jails, il vous est peut être arrivé de vouloir restreindre un peu plus le possibilité réseau dans vos jails. Par exemple empêcher qu’un de vos utilisateur (réel ou non) utilise votre IP pour faire des choses malsaine (un script qui envoie du spam par exemple).

Pour cela j’utilise Packet filter et ses tags. Le problème c’est qu’une fois que la NAT pour les jails est écrite, le paquet apparaît comme provenant de l’hôte et non de la jail. Comme toujours un bon fichier de conf vaut mieux qu’un long discourt :

ext_if = "fxp0"


# Network Description 
jails   = "10.0.0.0/24"    # Jails


set block-policy return
set skip on { lo0, lo1 }
set loginterface $ext_if
scrub in


# Nat for jails, we tag these packets to make filtering on out packets
nat on $ext_if from $jails  tag TAG_JAILS  -> $ext_if


# Block rules
block log all


# Pass out rules
pass out on $ext_if proto { tcp, udp } all ! tagged TAG_JAILS
pass out on $ext_if proto tcp to port { http ftp ircd  6697 domain 9418 } tagged TAG_JAILS
anchor "ftpsesame/*" on $ext_if


# Antispoofing
antispoof log for { $ext_if, lo0 } inet

Voilà, quand le paquet arrive sur la NAT, il est taggé avec TAG_JAIL et on effectue du filtrage ensuite sur ce tag, tout le trafic sortant passe pour les paquets qui ne proviennent pas des jails et le traffic qui provient des jails passe uniquement si le port de direction est autorisé. L’ancre “ftpsesame/*” est là pour autoriser le traffic sortant ftp, ce qui n’est pas aussi évident que l’on pense, voir ce billet.