/ OpenBSD

OpenSMTPD & Dovecot sous OpenBSD 6.0 avec support MySQL et SPAMD

This article is in French and available in English here !


Cet article s’inscrit dans la continuité du tutoriel OPENSMTPD SOUS OPENBSD 6.0 AVEC SSL/VIRTUALUSERS/DOVECOT. Nous nous baserons sur la même installation et une configuration identique. Nous allons ajouter les briques logicielles permettant :

  • D’appuyer nos domaines, alias, comptes virtuels sur une base MySQL (MariaDB sous OpenBSD). Dans le cas où vous auriez besoin d’aide concernant le déploiement de MariaDB sous OpenBSD, vous trouverez des informations ici.
  • Interfacer SPAMD avec **OpenSMTPD **dans le but d’obtenir une solution antispam efficace.

C’est parti !

Intégration et configuration du support MySQL :

Nous allons passer par le système de packages d’OpenBSD, vérifiez que les informations contenues dans /etc/pkg.conf soient exactes.

Installation du support MySQL pour OpenSMTPD & Dovecot :

# pkg_add opensmtpd-extras-mysql 
# pkg_add dovecot-mysql

On crée notre base SQL nommée « smtpd » :

# mysql -uroot -p -e 'create database smtpd'

On crée notre compte utilisateur « opensmtpd » on lui accorde les privilèges sur notre base SQL et on lui attribue un mot de passe :

# mysql -uroot -p -e "GRANT ALL ON smtpd.* to 'opensmtpd'@'127.0.0.1' IDENTIFIED BY 'opensmtpdpass'"

Ressortez vos cours SQL mécréants, Merise c’est pas de la confiture ! On crée la structure de notre base SQL:

# vi smtpd.sql

DROP TABLE IF EXISTS valias;
DROP TABLE IF EXISTS vdomains;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS userinfo;

CREATE TABLE IF NOT EXISTS valias (
alias_id INT(8) NOT NULL AUTO_INCREMENT,
addr varchar(42) NOT NULL,
alias varchar(42) NOT NULL,
PRIMARY KEY (alias_id)
) ENGINE=InnoDB ;

CREATE TABLE IF NOT EXISTS vdomains (
domain_id INT(11) NOT NULL AUTO_INCREMENT,
domain VARCHAR(42) NOT NULL,
PRIMARY KEY (domain_id)
) ENGINE=InnoDB ;

CREATE TABLE IF NOT EXISTS userinfo (
user_id INT(11) NOT NULL AUTO_INCREMENT,
user VARCHAR(42) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
uid INT(42) DEFAULT 106,
gid INT(42) DEFAULT 107,
maildir VARCHAR(255) DEFAULT '/var/empty',
PRIMARY KEY (user_id)
) ENGINE=InnoDB ;

CREATE TABLE IF NOT EXISTS users (
user_id INT(8) NOT NULL AUTO_INCREMENT,
username TEXT NOT NULL,
domain TEXT NOT NULL,
mailbox TEXT NOT NULL,
password TEXT NULL,
home TEXT NOT NULL,
uid INTEGER NOT NULL,
gid INTEGER NOT NULL,
PRIMARY KEY (user_id)
) ENGINE=InnoDB ;

A noter que certains éléments de la base sont présents uniquement parce que Dovecot y accède par défaut, sans eux Dovecot retourne une erreur SQL.

On en profite pour intégrer nos données de base afin de gagner du temps :

On commence par générer un mot de passe chiffré en Blowfish (et oui nous sommes sous OpenBSD !) pour nos utilisateurs :

# smtpctl encrypt mon-mot-de-passe-smtp $2b$10$nNLSbqFDLlLx9JRyxvhjI.FVzTgEEqVyEjYHf108S7cA49cqED6da

On créé nos tables en y intégrant nos données :

# vi users.sql

DELETE FROM valias;
DELETE FROM vdomains;
DELETE FROM userinfo;

INSERT INTO valias VALUES('','lina@cagedmonster.net', 'lina');

INSERT INTO vdomains VALUES('','cagedmonster.net');

INSERT INTO userinfo VALUES('','lina','$2b$10$JiGuncDXUcT2/hS/7Ty4KubsbuCjO0zsRhOQ7isFPCEcSLnIb.JMi',default,default,default);

On pousse le tout vers notre base de données :

# mysql -uroot -p smtpd < smtpd.sql 
# mysql -uroot -p smtpd < users.sql 
# mysql -uroot -p -e 'FLUSH PRIVILEGES'

Il est temps de configurer OpenSMTPD :

# vi /etc/mail/smtpd.conf 

pki mail.cagedmonster.net certificate "/etc/ssl/server.crt" 
pki mail.cagedmonster.net key "/etc/ssl/private/server.key" 

table vdomains mysql:/etc/mail/mysql.conf
table vusers mysql:/etc/mail/mysql.conf
table userinfo mysql:/etc/mail/mysql.conf
table credentials mysql:/etc/mail/mysql.conf

listen on lo0 listen on egress port 25 tls pki mail.cagedmonster.net 
listen on egress port 587 tls-require pki mail.cagedmonster.net auth <credentials>

accept from any for domain <vdomains> virtual <vusers> userbase <userinfo> deliver to lmtp "/var/dovecot/lmtp" 
accept from local for any relay

Nous nous trouvons ici avec une configuration similaire à celle du précédent tutoriel, la différence réside dans le stockage des informations de comptes et leur emplacement.

On crée notre fichier mysql.conf et on le configure :

# vi /etc/mail/mysql.conf 

host 127.0.0.1
username opensmtpd
password opensmtpdpass
database smtpd

query_credentials SELECT user,password FROM userinfo WHERE user=?; 

query_domain SELECT domain FROM vdomains WHERE domain=? LIMIT 1; 

query_userinfo SELECT uid,gid,maildir FROM userinfo where user=?; 

query_alias SELECT alias FROM valias WHERE addr=?;

Configuration de Dovecot.conf :

# vi /etc/dovecot.conf 

ssl = yes 
!include conf.d/auth-sql.conf.ext 
ssl_cert = </etc/ssl/server.crt 
ssl_key = </etc/ssl/private/server.key 
userdb { 
        driver = static 
        args = uid=virtmail gid=virtmail home=/var/virtmail/%u 
       } 

mail_location = maildir:/var/virtmail/%u 
mail_uid = virtmail 
mail_gid = virtmail 

passdb { 
        driver = sql 
        args = /etc/dovecot/dovecot-sql.conf.ext 
       } 

protocols = lmtp imap 
base_dir = /var/dovecot/ 
postmaster_address = postmaster@cagedmonster.net

On configure le fichier auth-sql.conf.ext

# vi /etc/dovecot/conf.d/auth-sql.conf.ext  

passdb { 
        driver = sql 
        args = /etc/dovecot/dovecot-sql.conf.ext 
        } 
userdb { 
        driver = sql 
        args = /etc/dovecot/dovecot-sql.conf.ext 
        }

On configure le fichier dovecot-sql.conf.ext

# vi /etc/dovecot/dovecot-sql.conf.ext 

driver = mysql 

connect = host=127.0.0.1 dbname=smtpd user=opensmtpd password=opensmtpdpass

default_pass_scheme = BLF-CRYPT 

password_query = \ 
  SELECT user, password \ 
  FROM userinfo WHERE user = '%u'

Le chiffrement des mots de passe ayant été réalisé avec BLOWFISH, il est important de le préciser.

On relance nos services :

# rcctl restart smtpd dovecot

Reste à tester le bon fonctionnement :

On s’envoie un mail sauvage.

$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.cagedmonster.net ESMTP OpenSMTPD
HELO COPAIN
250 mail.cagedmonster.net Hello COPAIN [127.0.0.1], pleased to meet you
MAIL FROM:<test@tutodelinasovereign.com>
250 2.0.0: Ok
RCPT TO:<lina@cagedmonster.net>
250 2.1.5 Destination address valid: Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
C'est un test et ça a intérêt à fonctionner cette histoire !
.
250 2.0.0: 408391e3 Message accepted for delivery
QUIT
221 2.0.0: Bye
Connection closed by foreign host.

On vérifie les logs :

$ cat /var/log/maillog
Aug 20 18:25:41 mail smtpd[65810]: e31eedb08a3c2f01 smtp event=message msgid=408391e3 from=<test@tutodelinasovereign.com> to=<lina@cagedmonster.net> size=241 ndest=1 proto=SMTP
Aug 20 18:25:41 mail smtpd[65810]: 0000000000000000 mda event=delivery evpid=408391e380f6c1e2 from=<test@tutodelinasovereign.com> to=<lina@cagedmonster.net> user=lina method=lmtp delay=13s result=Ok stat=Delivered

On regarde physiquement si notre mail a bien été délivré :

# cat /var/virtmail/lina/new/1471710341.M714123P83824.mail.cagedmonster.net,S\=536,W\=548\:2,

Return-Path: <test@tutodelinasovereign.com>
Delivered-To: lina
Received: from mail.cagedmonster.net
by mail.cagedmonster.net (Dovecot) with LMTP id 9Dn0KYWEuFdwRwEA8Z+lxA
for <lina>; Sat, 20 Aug 2016 18:25:41 +0200
Return-Path: test@tutodelinasovereign.com
Delivered-To: lina@cagedmonster.net
Received: from COPAIN (localhost [127.0.0.1])
by mail.cagedmonster.net (OpenSMTPD) with SMTP id 408391e3
for <lina@cagedmonster.net>;
Sat, 20 Aug 2016 18:25:30 +0200 (CEST)
C'est un test et ça a intérêt à fonctionner cette histoire ! 

Mission accomplie…

Il vous reste à déployer un serveur http sécurisé et y configurer un bon webmail tel que : roundcube !

Passons à la suite : SPAMD !

OpenSMTPD & SPAMD :

SPAMD est un service simulant un faux serveur SMTP et s’appuyant sur un strict respect de la RFC afin de déterminer si le serveur délivrant un mail est un spammer ou non. Les messages transitent via PackFilter vers SPAMD et sont redirigés si le serveur SMTP en face est valide. Pour ce faire, SPAMD se base sur trois (3) types de listes :

  1. Blacklist : Serveur reconnu en tant que SPAMMER, les messages reçus seront retardés le plus longtemps possible afin d’handicaper au maximum le nuisible en termes de temps et ressources. A la fin du temps imparti il se verra retourner une fin de non-recevoir et le message ne sera jamais transmis à notre vrai serveur mail.
  2. Greylist : Dans ce cas précis, SPAMD n’a pas encore déterminé si le serveur SMTP était un spammer ou non. Il va donc se baser sur les rouages de la RFC afin d’envoyer une erreur temporaire au serveur distant. S’il s’agit d’un serveur SMTP authentique, la RFC veut qu’une nouvelle tentative soit effectuée dans un délai assez court (entre une vingtaine de minutes et quatre heures environ) et ce jusqu’à délivrance du message jusqu’à un temps donné (environ 5 jours de manière générale).  Si la RFC est respectée, SPAMD va whitelister le serveur.
  3. Whitelist : Le serveur est reconnu comme authentique et fiable, il ne transite pas par SPAMD et est relayé directement à notre serveur OPENSMTPD.

Configuration de SPAMD :

Lancement de SPAMD & SPAMLOGD au démarrage du système :

 # rcctl enable spamd spamlogd

Configuration des flags de SPAMD :

SPAMD offre un nombre important de fonctionnalités, nous allons en utiliser quelques unes afin d’être les plus pénalisants possibles pour les SPAMMERS :

 # rcctl set spamd flags -4 -G25:4:864 -h cagedmonster.net -l127.0.0.1 -S60 -s1 -v -w1
  • -4 : Fin de non-recevoir de base : « 451 Temporary failure, please try again later. »
  • -G25:4:744 : Il s’agit du paramètre permettant de tester un serveur en Greylist. Dans ce cas précis, le serveur a entre 25 minutes et 4 heures afin d’effectuer une nouvelle tentative d’envoi pour être en Whitelist. Une fois en Whitelist l’host sera conservé durant une période de 744 heures, soit un mois de 31 jours.
  • – h : Domaines valides, ils ne seront pas testés
  • -l127.0.0.1 : SPAMD n’écoute qu’en local
  • -S60 : va faire patienter les serveurs SMTP en Blacklist & Greylist pendant 60 secondes. Ce paramètre est configurable entre 1 et 90 secondes
  • -s1 : Configure le nombre de caractères acceptés par SPAMD par secondes.
  • -v : Nous permet de logger ce que va nous envoyer le serveur distant, toujours instructif
  • -w1 : l’option ultime en terme de ralentissement de l’hôte distant. Ralenti au maximum la fenêtre d’envoi des données lors de la connexion, faisant perdre un temps considérable aux spammers.

PS : Il est également possible d’ajouter l’option -n OpenSMTPD afin de changer l’entête par défaut : 220 cagedmonster.net ESMTP spamd IP-based SPAM blocker; Mon Aug 22 11:29:00 2016

Configuration de PacketFilter :

# vi /etc/pf.conf

table <spamd-white> persist

pass in log on egress inet proto tcp from <spamd-white> to egress port smtp keep state rdr-to lo0
pass in log on egress inet proto tcp from !<spamd-white> to egress port smtp keep state rdr-to lo0 port spamd

# pfctl -f /etc/pf.conf

Si l’hôte distant est dans on redirige directement vers notre serveur SMTP, sinon on le fait passer par le filtre de SPAMD. J’aime bien utiliser l’expression « egress » car elle fait directement référence aux interfaces gérant les routes par défaut.

Configuration de SPAMD :

# vi /etc/spamd.conf

nixspam:\
    :black:\
    :msg="Your address %A is in the nixspam list\n\
    See http://www.heise.de/ix/nixspam/dnsbl_en/ for details":\
    :method=http:\
    :file=www.openbsd.org/spamd/nixspam.gz

# crontab -e

0       *       *       *       *       sleep $((RANDOM \% 1800)) && /usr/libexec/spamd-setup

Démarrage de SPAMD & SPAMLOGD :

# rcctl start spamd spamlogd

Besoin d’aide ?

CagedMonster

CagedMonster

« I know everyone I've been everywhere I know everything Because I'm everybody » Ether - Nothingface

Read More