Config particulière d'OpenBSD spamd

Article publié sur le site de RotomaLUG: http://rotomalug.org/spip.php?article224

On trouve de nombreux tutoriels permettant de configurer OpenBSD spamd, dont un sur ce même site d'ailleurs. Néanmoins, dans le cadre d'un projet, je me suis trouvé dans une situation un peu particulière. Afin de migrer tout doucement d'un serveur de mails seul ayant une IP publique vers un spamd(IP publique) + ce même serveur (qui ne doit pas changer) sur le même LAN, j'ai dû mettre en place le type de configuration suivante :
Imaginons la situation suivante :
Avant :
Le MX pointe sur l'adresse IP X. X se trouve être l'adresse IP publique du serveur de mails.

Après :
Le serveur de mail réel garde son adresse en X, mais le MX lui prend une adresse Y.

X et Y doivent être des adresses IP publiques. Par conséquent, la configuration standard d'OpenBSD spamd avec une adresse IP en frontale et le serveur de mail {caché} derrière sur un LAN privé (RFC1918) n'est pas possible ici.

On se retrouve avec ce type d'architecture :

La configuration de pf (packet filter) sera sensiblement la même que celle d'une configuration monolithique (spamd + serveur de mails sur la même machine).
C'est à dire :
# cat /etc/pf.conf
ext_if="vr0"

# Let's make our categories of spammers and non-spammers
# We do this with PF tables
table  persist
table  persist
table  persist file "/etc/whitelist.txt"
table  persist file "/etc/blacklist.txt" 

set skip on lo

scrub in all
rdr pass on $ext_if proto tcp from  to $ext_if port smtp -> 127.0.0.1 port 5000
rdr pass on $ext_if proto tcp from  to $ext_if port smtp -> 127.0.0.1 port 8025
rdr pass on $ext_if proto tcp from  to $ext_if port smtp -> 127.0.0.1 port 8025
rdr pass on $ext_if proto tcp from  to $ext_if port smtp -> 127.0.0.1 port 5000
rdr pass on $ext_if proto tcp from ! to $ext_if port smtp -> 127.0.0.1 port 8025

# SSH Accepted.
pass in quick on $ext_if inet proto tcp from any to $ext_if port 54321

pass out quick on $ext_if inet proto tcp from $ext_if to any modulate state
pass out quick on $ext_if inet proto udp from $ext_if to any keep state
pass out quick on $ext_if inet proto icmp from $ext_if to any keep state

# We also let in any SMTP and SSH traffic, and log the SMTP traffic for spamlogd
pass in log quick on $ext_if inet proto tcp from any to 217.169.a.b port smtp keep state
pass in log quick on $ext_if inet proto tcp from 217.169.a.b to any port smtp keep state
pass in quick on $ext_if inet proto tcp from any to $ext_if port 54321
La subtilité se trouve sur la redirection (rdr) vers le port 5000 sur 127.0.0.1. Non, le serveur de mails n'écoute pas sur le port 5000 de la même machine, mais on a :
# cat /etc/inetd.conf
# Spamd toussa vers le serveur reel
127.0.0.1:5000 stream tcp nowait nobody /usr/bin/nc nc -w 20 217.169.a.b 25
Mais à quoi sert ce vieux hack ?!

Et bien essayez de remplacer la ligne :
rdr pass on $ext_if proto tcp from  to $ext_if port smtp -> 127.0.0.1 port 5000
par :
rdr pass on $ext_if proto tcp from  to $ext_if port smtp -> 217.169.a.b port 5000
qui se trouve être sur le même réseau que votre machine servant de spamd, et bien vous chercherez longtemps pourquoi les paquets ne sont pas redirigés vers 217.169.a.b ;-)
D'où ce hack.

Voili voilou, plus qu'à changer le MX dans votre bind préféré et tout doucement vous vous retrouverez avec du greylisting et vous n'aurez touché à rien sur la machine qui hoste le serveur de mails.