vendredi, avril 19, 2024
Nom d'utilisateur : Mot de passe :
[NEWS]
Envoyé par unreal
Introduction et objectifs

Les Jails FreeBSD permettent de réaliser une virtualisation légère afin d'héberger plusieurs environnements indépendants sur une seule machine physique. On parle de virtualisation "légère" parce qu'un seul kernel est démarré ; la "virtualisation" ne concerne donc qu'un espace userland dédié à chaque environnement qui partage ainsi certaines ressources avec le système hôte (espace disque chrooté, dev, accès réseau, etc). Cela permet en principe d'héberger un grand nombre d'environnements, car il n'y a pas l'overhead lié au démarrage d'un système complet, mais impose certaines limitations : le système virtualisé sera FreeBSD (il est toutefois possible d'héberger d'autres système), et de préférence de même version que la machine hôte.

Cet article a comme but de configurer un système virtualisé prêt pour la production avec les caractéristiques suivantes :

  • Séparation des rôles ; chaque jail réalisera un nombre réduit de tâches
  • Les services hébergés devront être accessibles en IPv4 et IPv6 (dual stack)
  • Les accès réseau des jails seront fortement restreints
  • Le système hôte disposera d'une IPv4 publique et d'une IPv6 publique ; les jails auront des IP privées.
  • L'essentiel du système de fichiers sera en lecture seule depuis l'intérieur des jails
  • La création de nouveaux jails doit être simple, à base de modèles


Avant de commencer

Avant d'attaquer le vif du sujet, je vous propose un peu de lecture :



Environnement

Nous allons utiliser l'environnement suivant, représenté par le schéma ci-dessous :

  • FreeBSD 9.0
  • Interface réseau publique : ue0
  • Interface réseau jails : lo1
  • 3 jails : adm (DNS, Proxy), mail, www


archi.png



Création de Jails

La documentation officielle propose un tutorial intéressant, que j'ai suivi avec les changements suivants :

  • Les jails sont dans /home/jails
  • Le template se trouve dans /home/jails/skel
  • L'install lecture seule se trouve dans /home/jails/mroot
  • Chaque jail a son point de montage RO dans /home/jails/nomdejail et son espace RW dans /home/jails/nomdejail_rw
  • Le montage de l'espace RW se fait dans /home/jails/nomdejail/data


Ce qui donne l'arborescence suivante pour mes trois jails "adm", "mail" et "www" :

# ls -l /home/jails/
total 32
drwxr-xr-x 14 root wheel 512 Dec 14 17:46 adm
drwxr-xr-x 11 root wheel 512 Dec 14 22:47 adm_rw
drwxr-xr-x 14 root wheel 512 Dec 14 17:46 mail
drwxr-xr-x 11 root wheel 512 Dec 14 22:47 mail_rw
drwxr-xr-x 14 root wheel 512 Dec 14 17:46 mroot
drwxr-xr-x 11 root wheel 512 Dec 14 22:47 skel
drwxr-xr-x 14 root wheel 512 Dec 14 17:46 www
drwxr-xr-x 11 root wheel 512 Dec 14 22:47 www_rw


Niveau /etc/fstab cela donne :

/home/jails/mroot     /home/jails/adm                 nullfs ro             0     0
/home/jails/adm_rw     /home/jails/adm/data            nullfs rw             0     0
/usr/ports             /home/jails/adm/usr/ports     nullfs ro             0     0

/home/jails/mroot     /home/jails/mail                nullfs ro             0     0
/home/jails/mail_rw     /home/jails/mail/data         nullfs rw             0     0
/usr/ports             /home/jails/mail/usr/ports     nullfs ro             0     0

/home/jails/mroot     /home/jails/www                 nullfs ro             0     0
/home/jails/www_rw     /home/jails/www/data            nullfs rw             0     0
/usr/ports             /home/jails/www/usr/ports     nullfs ro             0     0


Nous utilisons nullfs pour monter les espaces RO et RW vers les espaces des jails, ainsi il ne sera pas possible de modifier les options de montage depuis l'intérieur des Jails. Les montages /usr/ports permettent aux jails d'accéder à l'arborescence des ports sans consommer d'espace disque supplémentaire.

Les adresses IP des Jails se configurent depuis /etc/rc.conf. Nous avons choisi de configurer des IPv4 et IPv6 privées pour chaque jail :

ifconfig_ue0="DHCP"

# IPv6 stuff
ifconfig_ue0_ipv6="inet6 accept_rtadv"
ipv6_defaultrouter="<ipv6 du routeur>"

# Jails stuff
cloned_interfaces="lo1"
ifconfig_lo1="inet 192.168.204.254 netmask 255.255.255.0"
ifconfig_lo1_ipv6="inet6 fec0::204:254 prefixlen 64"
ifconfig_lo1_alias0="inet 192.168.204.1 netmask 255.255.255.0"
ifconfig_lo1_alias1="inet 192.168.204.2 netmask 255.255.255.0"
ifconfig_lo1_alias2="inet 192.168.204.3 netmask 255.255.255.0"
ifconfig_lo1_alias3="inet6 fec0::204:1 prefixlen 64"
ifconfig_lo1_alias4="inet6 fec0::204:2 prefixlen 64"
ifconfig_lo1_alias5="inet6 fec0::204:3 prefixlen 64"

jail_enable="YES"                             # Set to NO to disable starting of any jails
jail_list="adm mail www"
jail_sysvipc_allow="YES"

# Adm
jail_adm_rootdir="/usr/home/jails/adm"         # jail's root directory
jail_adm_hostname="adm"                         # jail's hostname
jail_adm_ip="192.168.204.1,fec0::204:1"         # jail's IP address
jail_adm_devfs_enable="YES"                     # mount devfs in the jail
jail_adm_devfs_ruleset="devfsrules_jail"        # devfs ruleset to apply to jail

# Mail
jail_mail_rootdir="/usr/home/jails/mail"
jail_mail_hostname="mail"
jail_mail_ip="192.168.204.2,fec0::204:2"
jail_mail_devfs_enable="YES"
jail_mail_devfs_ruleset="devfsrules_jail"

# Web
jail_www_rootdir="/usr/home/jails/www"
jail_www_hostname="www"
jail_www_ip="192.168.204.3,fec0::204:3"
jail_www_devfs_enable="YES"
jail_www_devfs_ruleset="devfsrules_jail"


Pour finir, il est nécessaire de modifier les /etc/make.conf de chaque jail pour réaliser les builds sur l'espace RW :

WRKDIRPREFIX=/data/portbuild
DISTDIR=/data/distfiles


Pour plus de simplicité, je vous conseille à se stade de redémarrer la machine pour ne pas créer l'interface lo1 et ses alias à la main. Après le reboot, vous pouvez vérifier que les jails sont bien démarrés :

# jls
JID IP Address     Hostname                     Path
     1 192.168.204.1 adm                         /usr/home/jails/adm
     2 192.168.204.2 mail                         /usr/home/jails/mail
     3 192.168.204.3 www                         /usr/home/jails/www


Par ailleurs, ifconfig permet de vérifier que les différentes IP sont configurées :

# ifconfig lo1
lo1: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=3<RXCSUM,TXCSUM>
        inet 192.168.204.254 netmask 0xffffff00
        inet6 fec0::204:254 prefixlen 64
        inet 192.168.204.1 netmask 0xffffff00
        inet 192.168.204.2 netmask 0xffffff00
        inet 192.168.204.3 netmask 0xffffff00
        inet6 fec0::204:1 prefixlen 64
        inet6 fec0::204:2 prefixlen 64
        inet6 fec0::204:3 prefixlen 64
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>


Les jails sont donc bien démarrés, mais sans accès réseau pour l'instant.


Contrôle des accès réseau avec Packet Filter

Je vous propose quelques rappels sur le fonctionnement de PF :

  • Les opérations de redirection (divert-to, route-to...) se font à l'entrée de l'interface, pas en sortie
  • Les opérations de translation se font en sortie d'interface
  • Les opérations de translation se font avant les opérations de filtrage en sortie d'interface (ce qui signifie que le filtre ne peut voir que les IP translatées)


Il en découle les conséquences suivantes :

  • Il ne sera pas possible proxifier de façon transparente le trafic sortant des jails
  • Il faut utiliser les règles NAT pour filtrer le trafic sortant


Ci-dessous un exemple de configuration PF avec des commentaires :

############################################################
#             PF config for jailed FreeBSD                #
#                                                         #
# Last update: 20111026                                    #
############################################################

############################################################
# Définitions d'interface
ext_if = "ue0"
int_if = "lo1"
# Il est nécessaire de spécifier l'IPv6 de translation, pour ne pas que PF prenne le Local Link par erreur.
ext_ipv6 = "<IPv6 extérieure>"
jail_network = $int_if:network
jail_host_adm = "192.168.204.1"
jail_host_adm_v6 = "fec0::204:1"
jail_host_mail = "192.168.204.2"
jail_host_mail_v6 = "fec0::204:2"
jail_host_www = "192.168.204.3"
jail_host_www_v6 = "fec0::204:3"

# Configuration
set limit states 100000
set timeout tcp.established 86400
set timeout tcp.finwait 30
set skip on lo0
# Par défaut envoyer un TCP reset ou message ICMP en cas de drop
set block-policy return
############################################################

### Tables ###
# Comme on ne peut pas proxifier le FTP, il faut faire une liste blanche
# 87.51.34.132, 149.20.64.73, 204.152.184.73 = ftp.freebsd.org
# 131.111.8.80 = ftp.csx.cam.ac.uk
# 140.186.70.20 = ftp.gnu.org
# 130.133.3.130 = ftp.fu-berlin.de
table <ports_ftp_ips> {
                                87.51.34.132, \
                                149.20.64.73, \
                                204.152.184.73, \
                                \
                                131.111.8.80, \
                                \
                                140.186.70.20, \
                                \
                                130.133.3.130
                        }



### Normaliser les paquets ###
scrub in on $ext_if all

# La translation se fait avant le filtrage, donc nous utilisons la translation pour contrôler les accès vers l'extérieur

# Tous les jails ont un accès FTP vers la liste blanche
nat on $ext_if inet proto tcp from $jail_network to <ports_ftp_ips> port { ftp, >1023 } -> ($ext_if)

### 'Adm' jail ###
# 'Adm' (proxy) est seul à avoir un accès HTTP
nat on $ext_if inet proto tcp from $jail_host_adm to any port { 80, 443 } -> ($ext_if)
nat on $ext_if inet6 proto tcp from $jail_host_adm_v6 to any port { 80, 443 } -> $ext_ipv6

# 'Adm' est seul avoir accès DNS
nat on $ext_if inet proto { tcp, udp } from $jail_host_adm to any port 53 -> ($ext_if)
nat on $ext_if inet6 proto { tcp, udp } from $jail_host_adm_v6 to any port 53 -> $ext_ipv6

### 'Mail' jail ###
# 'Mail' est seul à pouvoir envoyer des mails
nat on $ext_if inet proto tcp from $jail_host_mail to any port 25 -> ($ext_if)
nat on $ext_if inet6 proto tcp from $jail_host_mail_v6 to any port 25 -> $ext_ipv6

### "Www" jail ###
# N'a pas d'accès


# Translation de ports
# Web vers www
rdr on $ext_if proto tcp from any to any port { 80, 443 } -> $jail_host_www
rdr on $ext_if inet6 proto tcp from any to any port { 80, 443 } -> $jail_host_www_v6

# Tout ce qui veut sortir mais qui n'a pas été tranlaté est dropé
block out quick log on $ext_if inet proto tcp from $jail_network
block out quick log on $ext_if inet6 proto tcp from $jail_network
block out quick log on $ext_if from $jail_network



Astuces et mot de fin

  • Comme le jail 'Mail' est seul autorisé à relayer vers l'extérieur, il faut configurer les serveurs d'email locaux à utiliser Mail comme smarthost.
  • Exportez la variable d'environnement http_proxy pour utiliser 'Adm' comme proxy Web
  • Editez /etc/resolv.conf pour utiliser 'Adm' comme serveur DNS


En suivant ces conseils, vous avez une plateforme d'hébergement très sécurisée :

  • Un jail compromis n'a pas la possibilité de contaminer d'autres jails ou de modifier la partie lecture seule de son espace disque
  • Un jail compromis ne peut difficilement émettre du trafic non désirable sur le réseau (spam, flood) car ce trafic est bloqué et loggé par Packet Filter
  • Un utilisateur indélicat ne pourra lancer des services en écoute sur le réseau car les jails sont en IP privée
  • Un jail ne peut charger de module kernel ou passer les interfaces en mode 'promiscuous'


Historique

20111228 - version initiale

Posté le 28/12/11 à 11:51 - 0 Commentaires...

[NEWS]
Envoyé par unreal
Qu'est ce que c'est ?

L'utilitaire setfib a fait son apparition dans FreeBSD 7.1 et permet gérer plusieurs tables de routage au sien d'une seule instance du système d'exploitation. Il est complémentaire avec les politiques de routage PF parce qu'il permet de spécifier une table de routage par application, alors que le routage PF se fait selon des critères réseau (IP, protocole, port).


Préparer son kernel

Le kernel GENERIC ne supporte qu'une seule table de routage. Il faut donc compiler un kernel personnalisé avec l'option suivante :

options         ROUTETABLES=2


Vous pouvez bien entendu remplacer "2" par le nombre de tables souhaitées.


Utiliser setfib

La syntaxe de setfib est ci-dessous :

setfib <table de routage> <commande à lancer>


La table de routage est indexée sur 0 (zéro). Nous allons utiliser la 2ième table dans l'exemple ci-dessous :

# setfib 1 route delete -net 0.0.0.0 # Supprimer de la route par défaut
# setfib 1 route add -net 0.0.0.0 1.2.3.4 # Utiliser 1.2.3.4 comme route par défaut
# setfib 1 netstat -rn # Visualiser la table de routage
# setfib 1 ping www.free.fr # Tester la connexion



Configurer setfib au démarrage de la machine

Le plus simple est de créer /etc/rc.local pour démarrer les services spécifiques sur des tables de routage supplémentaires.

setfib 1 route delete -net 0.0.0.0
setfib 1 route net 0.0.0.0 1.2.3.4
setfib 1 service lighttpd onestart


Historique

20110217 - version initiale

Posté le 17/02/11 à 23:36 - 0 Commentaires...

[NEWS]
Envoyé par unreal
Introduction

Le but de ce dossier est de sauvegarder une machine Mac OS X vers un serveur dédié *nix de façon ultra sécurisée. Les prérequis sont les suivants :

  • L'image déposée sur le serveur dédié doit être chiffrée
  • La sauvegarde doit être initiée par le client
  • La communication entre le client Mac et le serveur doit être sécurisée
  • La sauvegarde doit se faire de façon automatisée
  • Après la sauvegarde initiale, les sauvegardes successives doivent être rapides


Pour ce faire, nous allons utiliser plusieurs technologies intéressantes, notamment MacFuse, SSHFS et Rsync, selon le schéma suivant :

dossier_sshfs_schema.png


Cette méthodologie présente plusieurs avantages d'un pointe de vue sécurité :

  • L'image de disque sur le serveur est chiffrée en AES 128 ou 256 bits ; elle sera totalement inexploitable si le serveur est compromis
  • Comme la sauvegarde est initiée par le client, il sera très complexe de compromettre le client à partir du serveur
  • La couche SSHFS protège totalement d'attaques de type man in the middle ; le client connaît l'empreinte du serveur SSH, si celle-ci devait changer la communication serait interrompue


Les prérequis

Le serveur peut être n'importe quelle machine *nix (Linux, FreeBSD, OpenSolaris...), à partir du moment où le protocole sftp et l'authentification par certificat sont activés. Pour cet article, une machine FreeBSD 8.0 a été utilisée.

Côté client OS X, il faut installer MacFuse et le binaire sshfs pour Macfuse :



Téléchargez le binaire sshfs, copiez-le et rendez-le exécutable :

cp ~/sshfs-static-leopard /usr/local/bin/sshfs
chmod +x /usr/local/bin/sshfs


Le Keypair SSH

Le client devra pouvoir se connecter automatiquement sur le serveur de backup. Vous devez donc générer un keypair SSH et le copier la clef publique sur le serveur de backup.

Sur le client :

# mkdir ~/.ssh
# chmod 700 ~/.ssh
# ssh-keygen -q -f ~/.ssh/id_rsa -t rsa
# scp ~/.ssh/id_rsa.pub username@hostname:~/id_rsa.pub


Ensuite sur le serveur :

$ mkdir ~/.ssh
$ chmod 700 ~/.ssh
$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
$ mkdir backups


Création de l'image chiffrée

Mac OS X intègre un outil pratique pour manipuler les images de disques qui s'appelle hdiutil. Nous avons utiliser cet outil pour générer une image de disque chiffrée protégée avec un mot de passe complexe, puis scp pour le copier sur le serveur.

Vérifiez qu'il n'est pas nécessaire de taper le mot de passe pour copier le fichier avec scp.

# hdiutil create -size 200g -encryption AES-128 -fs HFS+J -type SPARSE -volname Offsite_Backup Offsite_Backup
Enter a new password to secure "Offsite_Backup.sparseimage": <votremotdepasse>
# scp Offsite_Backup.sparseimage username@hostname:~/backups/


L'image de type sparse occupera initialement quelques centaines de Mo sur le disque, mais s'adaptera automatiquement pour contenir jusqu'à 200Go.

Le script de sauvegarde

Copiez le script suivant dans /usr/local/bin et éditez la configuration, notamment les lignes en gras :

#!/bin/bash

############################################################
# Filename: securebackup.sh                                #
# Description: secure push backup script for OS X using    #
#             encrypted AES sparse disk images and sshfs #
#             file transfers.                             #
# Last update: 20100929                                    #
# Changelog: v1.0 - initial version                     #
#            v1.1 - improved rsync error handling         #
#            v1.11 - various bug fixes                     #
#            v1.12 - return value bugfix in senderror     #
#            v1.13 - fixed PATH                            #
############################################################

#<Config>
BACKUPHOST=backup.serveur.fr
EMAILTO=root@localhost


SSHFSBIN=/usr/local/bin/sshfs
SSHFSMOUNT=/Volumes/$BACKUPHOST
SSHFSPARAM="toto@$BACKUPHOST:/home/backups"

SPARSEIMGPW=motdepasse

SPARSEIMGPATH=$SSHFSMOUNT/Offsite_Backup.sparseimage

# Space separated list, no trailing slashes.
SYNC_DIR="/net/nas.localdomain/usr/home/exports/backup \
/net/nas.localdomain/usr/home/exports/Web \
/net/nas.localdomain/usr/home/exports/work \
/private/etc \
/private/var/cron/tabs \
/private/var/www \
/Users/unreal \
/usr/local"

#</Config>

export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

# Functions
function senderror {
        MSG=$1
        SPARSEMOUNT=$2
        echo "The following error occured:"
        echo " $MSG"
        echo "Backup quitted with the following error: $MSG" | mail -s "Backup error on $HOSTNAME" $EMAILTO
        echo

        # We'll try to unmount the filesystems anyway.
        echo -n "-> Trying to unmount filesystems ... "
        [ "$SPARSEMOUNT" ] && hdiutil detach "$SPARSEMOUNT" 2>/dev/null >/dev/null
        sleep 2
        umount "$SSHFSMOUNT" 2>/dev/null
        RV=$?
        [ $RV -ne 0 ] && echo "Fail"
        [ $RV -eq 0 ] && echo "OK"

        exit 1
}


# Check SSHFS isn't already mounted
echo -n "-> Checking mounts ... "
CHECK=`mount | grep $SSHFSMOUNT`

[ "$CHECK" ] && echo "Fail" && senderror "SSHFS already mounted."
echo "OK"

# Mount SSHFS share
echo -n "-> Mounting SSHFS to $SSHFSMOUNT ... "
[ ! -d "$SSHFSMOUNT" ] && mkdir $SSHFSMOUNT
$SSHFSBIN $SSHFSPARAM $SSHFSMOUNT 2>/dev/null
RV=$?
sleep 2
[ $RV -ne 0 ] && echo "Fail" && senderror "sshfs command returned error $RV."
echo "OK"

# Mounting crypted image file
echo -n "-> Mounting $SPARSEIMGPATH ... "
[ ! -f "$SPARSEIMGPATH" ] && echo "Fail" && senderror "Sparse image file not found."
CHECK=`echo -n "$SPARSEIMGPW" | hdiutil attach -stdinpass $SPARSEIMGPATH 2>/dev/null`
RV=$?
[ $RV -ne 0 ] && echo "Fail" && senderror "hdiutil returned error $RV."
# Work out mount path
SPARSEMOUNT=`echo -n "$CHECK" | grep "Apple_HFS" | awk '{ print $3; }'`
echo "OK (mounted to $SPARSEMOUNT)"

# Backup
for ONEDIR in $SYNC_DIR; do
        if [ ! -d "$SPARSEMOUNT/$HOSTNAME$ONEDIR" ]; then
                mkdir -p "$SPARSEMOUNT/$HOSTNAME$ONEDIR"
        fi

        echo -n "-> Backing-up $ONEDIR ... "

        rsync --archive --delete --compress $ONEDIR `dirname "$SPARSEMOUNT/$HOSTNAME$ONEDIR"` 2>/dev/null >/dev/null
        RV=$?
        [ $RV -ne 0 ] && [ $RV -ne 23 ] && [ $RV -ne 24 ] && echo "Fail" && senderror "rsync returned error $RV." "$SPARSEMOUNT"
        echo -n "OK"
        [ $RV -eq 23 ] && echo -n " (partial)"
        [ $RV -eq 24 ] && echo -n " (partial, some files vanished before they were copied)"
        echo
done

# Unmounting
echo -n "-> Unmounting $SPARSEMOUNT ... "
hdiutil detach "$SPARSEMOUNT" 2>/dev/null >/dev/null
RV=$?
sleep 2
[ $RV -ne 0 ] && echo "Fail" && senderror "hdiutil returned error $RV."
echo "OK"
echo -n "-> Unmounting $SSHFSMOUNT ... "
umount "$SSHFSMOUNT" 2>/dev/null
RV=$?
[ $RV -ne 0 ] && echo "Fail" && senderror "umount command returned error $RV."
echo "OK"

exit 0


Exécutez-le avec le compte root, et la sauvegarde devrait démarrer automatiquement. Le script est conçu de telle façon à détecter les erreurs pour adopter un comportement intelligent et envoyer des e-mails d'avertissement en cas d'erreur bloquante.

L'exécution normale du script doit ressembler à ceci :

-> Checking mounts ... OK
-> Mounting SSHFS to /Volumes/backup.serveur.fr ... OK
-> Mounting /Volumes/backup.serveur.fr/Offsite_Backup.sparseimage ... OK (mounted to /Volumes/Offsite_Backup)
-> Backing-up /net/nas.localdomain/usr/home/exports/backup ... OK
-> Backing-up /net/nas.localdomain/usr/home/exports/Web ... OK (partial)
-> Backing-up /net/nas.localdomain/usr/home/exports/work ... OK
-> Backing-up /private/etc ... OK
-> Backing-up /private/var/cron/tabs ... OK
-> Backing-up /private/var/www ... OK
-> Backing-up /Users/unreal ... OK
-> Backing-up /usr/local ... OK
-> Unmounting /Volumes/Offsite_Backup ... OK
-> Unmounting /Volumes/backup.serveur.fr ... OK


La sauvegarde initiale peut être assez longue, surtout si vous avez beaucoup de données à envoyer. Les sauvegardes successives devraient être rapides grâce à rsync qui n'enverra que les nouveaux fichiers.

Automatisation et conclusion

Vous allez bien entendu utiliser cron pour automatiser l'exécution du script de backup :

0 5 * * *     /usr/local/bin/securebackup.sh


Voilà, c'est fini. Vous bénéficiez maintenant d'une sauvegarde automatisée et ultra sécurisée de vos données vers un serveur dédié.

Comme toujours, n'hésitez à me faire des retours via le système de commentaires ou message privé.

Historique

- 20100925 - version initiale
- 20101008 - améliorations du script

Posté le 24/09/10 à 16:56 - 0 Commentaires...

[NEWS]
Envoyé par unreal
Apprendre à maintenir une machine FreeBSD sans effort excessif.

[Lire la suite]

Posté le 05/08/10 à 17:46 - 0 Commentaires...

[NEWS]
Envoyé par unreal
Cela faisait longtemps, mais force de constater que les bots chercheurs d'open relay sont de retour. Voici ce que je découvre dans mes logs ce matin :

# grep "Relay access denied" /var/log/maillog | wc -l
24708


Il va falloir donc faire quelque chose.

Paramétrage du firewall

Heureusement pour moi, Packet Filter dispose d'options utiles pour se protéger contre ce genre de bots. Nous allons le configurer pour bannir les IP faisant trop de connexions au serveur SMTP :

pf.conf
# SMTP open relay bots
block drop in quick on $ethif0 from <smtp-bruteforce>
pass in on $ethif0 proto tcp from any to any port smtp flags S/SA keep state (max-src-conn-rate 3/60, overload <smtp-bruteforce> flush global)


PF va donc surveiller le port 25, et si trois nouvelles connexions sont détectées en moins de 60 secondes, l'IP sera ajoutée dans la table smtp-bruteforce.

Pour éviter que les IP restent bloquées jusqu'au redémarrage de PF, on rajoute un crontab. Ici, la durée de ban est fixée à 12h.

Versions récentes de PF (FreeBSD >= 7.0) :
*/5 * * * *             /sbin/pfctl -t smtp-bruteforce -T expire 43200 2>/dev/null


Versions plus anciennes de PF (il faut installer expiretable) :
*/5 * * * *             /usr/local/sbin/expiretable -t 43200 smtp-bruteforce



Configuration Postfix

Postfix est trop clément avec les spammeurs et autres réseaux de bots dans sa configuration par défaut. Il est donc intéressant de modifier smtpd_hard_error_limit pour améliorer la détection par PF. En effet, beaucoup de bots n'ouvrent qu'une seule connexion TCP et exploitent la clémence de Postfix pour faire un grand nombre d'essais. Réduire la limite du nombre d'échecs par connexion va forcer les bots à ouvrir plusieurs connexions, et ainsi déclencher le blocage au niveau du firewall.

# antibots
smtpd_hard_error_limit = 5


Posté le 14/05/10 à 12:22 - Commentaires désactivés

2 pages... [1-5][6-10]