Portsentry

Sécuriser son serveur Debian 9 avec Portsentry

Généralités
Installation
Les dossiers et fichiers de configuration
Activation du mode avancé
Configuration
Tests
Portsentry avec Fail2ban

Portsentry est un programme qui a pour mission de détecter et bloquer (ou pas, selon la config) les scans de ports. Il vous permet par exemple de vous envoyer un mail lors d’un scan suspicieux sur votre serveur. Ou alors il peut carrément bloquer l’attaquant.
Il est donc très utile d’installer et configurer portsentry sur votre serveur. Afin d’obtenir de meilleurs résultats il est possible de le combiner a fail2ban.

Il suffit d'installer le paquet.

apt install portsentry

Un message d'avertissement vous indiquera alors que portsentry ne va appliquer aucun blocage sans que vous lui indiquiez de le faire.

Conrêtement, portsentry s'axe autour de 3 fichiers.

/etc/default/portsentry : Fichier où l'on indique dans quel mode portsentry doit démarrer
/etc/portsentry/portsentry.conf : Fichier de configuration (où l'on indique les actions à effectuer quand un scan est detecté)
/etc/portsentry/portsentry.ignore.static : Nous y plaçons les IPs que nous autorisons (whitelist)

Dans le fichier /etc/default/portsentry, il y a 2 variables TCP_MODE et UDP_MODE, par défaut, celles-ci sont respectivement en mode tcp et udp. Cela signifie que vous devez spécifier à la main les ports à surveiller. Nous préférons donc le mode atcp et audp (a pour avancé).

Pour ce faire, il faut modifier le fichier /etc/default/portsentry.

nano /etc/default/portsentry

Et modifiez le paramètre TCP_MODE="tcp" en TCP_MODE="atcp" et le paramètre UDP_MODE="udp" en UDP_MODE="audp"

TCP_MODE="atcp"
UDP_MODE="audp"

Nous pouvons mettre en place des exceptions afin de ne pas bloquer différentes adresses IP (les IPs de votre réseau par exemple).

Pour mettre en place ces exceptions, nous allons éditer le fichier /etc/portsentry/portsentry.ignore.static.

nano /etc/portsentry/portsentry.ignore.static

Toutes les IPs que vous allez ajouter dans portsentry.ignore.static seront ajoutées dans portsentry.ignore après un redémarrage du service portsentry.Pour ajouter une exception à portsentry, il suffit d'ajouter une adresse IP par ligne. Vous pouvez également et plus simplement ajouter un ou des CIDR.

À présent nous allons nous attaquer au fichier de configuration principale /etc/portsentry/portsentry.conf.

nano /etc/portsentry/portsentry.conf

Avec cette section, portsentry établit une liste des ports d'écoute, TCP et UDP pour bloquer l'hôte se connectant sur ​​ces ports, sauf s'il est présent dans le fichier portsentry.ignore.
Inutile de modifier cette section si vous utilisez le mode avancé, car Portsentry va alors maper automatiquement les ports.

#######################
# Port Configurations #
#######################
...
TCP_PORTS="1,11,15,79,111,119,143,540,635,1080,1524,2000,5742,6667,12345,12346,20034,27665,31337,32771,32772,32773,32774,40421,49724,54320"
UDP_PORTS="1,7,9,69,161,162,513,635,640,641,700,37444,34555,31335,32770,32771,32772,32773,32774,31337,54321"
...

Dans cette section, ajoutez des ports que vous ne souhaitez pas surveiller.
Inutile de modifier cette section si vous utilisez le mode avancé, car Portsentry va alors maper automatiquement les ports.

###########################################
# Advanced Stealth Scan Detection Options #
###########################################
...
ADVANCED_PORTS_TCP="1024"
ADVANCED_PORTS_UDP="1024"
...
ADVANCED_EXCLUDE_TCP="113,139"
ADVANCED_EXCLUDE_UDP="520,138,137,67"
...

Dans cette section, sont définis les emplacement des fichiers de configuration, laissez les choix par défaut.

######################
# Configuration Files#
######################
...
IGNORE_FILE="/etc/portsentry/portsentry.ignore"
...
HISTORY_FILE="/var/lib/portsentry/portsentry.history"
...
BLOCKED_FILE="/var/lib/portsentry/portsentry.blocked"

Cette section active ou déactive la résolution DNS.

##############################
# Misc. Configuration Options#
##############################
...
RESOLVE_HOST = "0"

Cette section définie le mode de réponse aux scans.
Le mode 0, permet de ne pas bloquer lors d’une détection de scan (ne rien faire, juste loguer).
Le mode 1, permet d'effectuer un blocage lors d’une détection de scan, avec 3 modes de bannissements (vous pouvez les utiliser simultanément):
- Bloquage via route ou iptables linux (Directive KILL_ROUTE)
- Bloquage via fichier hosts.deny (Directive KILL_HOSTS_DENY)
- Bloquage via règle custom (Directive KILL_RUN_CMD)
Le mode 2, permet de lancer des scripts externes lors d’une détection de scan (Directive KILL_RUN_CMD).

##################
# Ignore Options #
##################
...
BLOCK_UDP="1"
BLOCK_TCP="1"
...

Cette section définie le bloquage via route ou iptables linux (Directive KILL_ROUTE).
une seule option KILL_ROUTE peut être utilisé à la fois donc ne décommentez pas plusieurs lignes.
Nous allons opter pour un blocage des scans par le biais d'iptables, donc commentez toutes les lignes qui commencent par KILL_ROUTE puis décommentez la ligne suivante.

###################
# Dropping Routes:#
###################
...
KILL_ROUTE="/sbin/iptables -I INPUT -s $TARGET$ -j DROP"

Vous pouvez vérifier que c'est bien le cas, une fois le fichier enregistré en utilisant cat et grep.

cat /etc/portsentry/portsentry.conf | grep KILL_ROUTE | grep -v "#"

Cette section définie le bloquage via le fichier hosts.deny (Directive KILL_HOSTS_DENY).

###############
# TCP Wrappers#
###############
...
KILL_HOSTS_DENY="ALL: $TARGET$ : DENY"

Cette section définie le bloquage via règle custom (Directive KILL_RUN_CMD) grace à une commande externe. 
Vous pouvez par exemple, executer une commande ou un script.

###################
# External Command#
###################
...
#KILL_RUN_CMD_FIRST = "0"
...
#KILL_RUN_CMD="/some/path/here/script $TARGET$ $PORT$ $MODE$"
...

Cette section définie le temps de réaction (nombre de connections à un port) nécessaire pour déclencher Portsentry. La valeur par défaut est 0 qui réagira immédiatement.

#####################
# Scan trigger value#
#####################
...
SCAN_TRIGGER="0"

Cette section définie l’affichage de la bannière, Inutile de faire de la provocation, laissez commenté.

######################
# Port Banner Section#
######################
...
#PORT_BANNER="** UNAUTHORIZED ACCESS PROHIBITED *** YOUR CONNECTION ATTEMPT HAS BEEN LOGGED. GO AWAY."

Puis relancez portsentry.

systemctl restart portsentry

Depuis une autre machine, nous allons effectuer un scan de ports (par exemple avec nmap) de la machine hébergeant portsentry.

nmap -v 192.168.x.x

Maintenent si on regarde les logs générés dans /var/log/syslog  de la machine hébergeant portsentry, en utilisent le mot clé "attackalert".

grep attackalert /var/log/syslog

Nous constatons que l'IP de l’attaquant à bien été bloquée via iptables et hosts.deny.

Pour voir le bloquage de l'IP de l’attaquant via iptables, utilisez cette commande.

iptables -L INPUT -v -n | grep DROP

Pour voir le bloquage de l'IP de l’attaquant via le fichier hosts.deny, utilisez cette commande.

cat /etc/hosts.deny

Fail2ban peut utiliser les logs de portsentry pour effectuer des actions.

Par défaut Fail2ban posséde une prison (jail) et un filtre Portsentry non activé, donc nous pouvons activer la prison portsentry pour que les actions d'une détection de scan de ports soit gérée par Fail2ban.

Portsentry stocke la liste des IPs dans le fichier /var/lib/portsentry/portsentry.history et Fail2ban va utiliser se fichier pour prendre en charge l'action de mise en prison de l'attaquant.

Dans le fichier de configuration de Portsentry nous allons définir le mode de réponse aux scans à 0, car maintenent c'est Fail2ban qui va bannir les IPs.

nano /etc/portsentry/portsentry.conf

Et nous modifions la section comme ceci.

##################
# Ignore Options #
##################
...
BLOCK_UDP="0"
BLOCK_TCP="0"
...

Maintenent il faut activer la prison (jail) portsentry dans le fichier de configuration de Fail2ban.

nano /etc/fail2ban/jail.d/jail.local

Nous pouvons activer la prison portsentry et ajuster sa configuration (en spécifiant par exemple un nombre de tentatives différent de la valeur par défaut, un temps de bannissement différent de la valeur par défaut, etc ...)

[portsentry]
enabled = true
logpath  = /var/lib/portsentry/portsentry.history
maxretry = 1