Sécuriser son serveur Linux (Partie 2)

Sécuriser son serveur Linux (Partie 2)

21/10/2015 1 Par Vincent

On va pousser la sécurité d’un cran au dessus. Normalement, si vous avez suivi le premier tutorial, vous avez un accès SSH plus sur qui empêche dans un premier temps n’importe qui d’accéder au root. De plus l’accès ssh est restreint également donc plus de sécurité.

Maintenant (je l’avais promis), on passe aux choses sérieuses :

  • Création de règles iptables (configuration du firewall)
  • Protection d’intrusions (Portsentry, Fail2ban, Snort, Rkhunter)
  • Surveillance des logs (logwatch)
  • Testons maintenant notre serveur (scan de ports et vulnérabilités)

Configuration d’iptables (firewall)

Iptables ? C’est LE firewall de Linux. C’est pas mieux, ni moins bien qu’un autre (si si, celui de Windows est très bien s’il est bien configuré) ; tout dépend de sa configuration. En fait, je vous propose ici une méthode mais il existe d’autres choses. Vous devez bien sur avoir iptables d’installé, mais c’est normalement le cas (sinon aller voir le internet comment on fait).

Ma stratégie est la suivante : on bloque tout (toutes les entrées, toutes les sorties et même tous le traffic traversant). Pour les entrées et les sorties, pas besoin de dessin je pense par contre pour le traffic traversant l’idée est d’empêcher une connexion établie sur un port d’être routé à travers notre machine (utile si on ne veut pas être la superbe passerelle entre un pirate lambda et la cible).

Je vous mets le début du fichier, la suite est fonction de votre réseau, serveur… Chez moi, c’est iptables.sh

#!/bin/bash

### Autoriser toutes les connexions
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

### Vider les tables actuelles
iptables -t filter -F

### Vider les règles personnelles
iptables -t filter -X

### --> Les lignes ci-dessous doivent être réalisées permier ###
### Connexions déjà établies
iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
### Accepte le SSH 22 TCP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
### Accepte la boucle Localhost
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A OUTPUT -o lo -j ACCEPT
### Accepte le ping de la machine
iptables -t filter -A INPUT -p icmp -j ACCEPT
iptables -t filter -A OUTPUT -p icmp -j ACCEPT
### --> Les lignes ci-dessus doivent être réalisées en premier ##

##########################################################
### ATTENTION LES LIGNES JUSTE DESSOUS SONT DANGEREUSES ##
##########################################################
### Interdire toute connexion entrante et sortante
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
##########################################################
### ATTENTION LES LIGNES JUSTE DESSUS SONT DANGEREUSES ###
##########################################################

### Serveur DNS (si installé)
iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT

### NTP (Serveur de temps, MAJ de l'heure via internet)
iptables -t filter -A OUTPUT -p udp --dport 123 -j ACCEPT

### HTTP/HTTPS (Serveur web en sortie)
iptables -t filter -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 443 -j ACCEPT

### HTTP/HTTPS (Serveur web en entrée)
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT

Pour l’appliquer, j’utilise à chaque démarrage ce script que je lance via /etc/rc.local. Comme ça je suis tranquille.

Je n’ai volontairement pas créé de règle pour MySQL par exemple (port par défaut : 3306) parceque je n’utilise ma base de donnée que pour mon site local. Bien sur, si d’autres machines doivent se connecter à la base de données, vous devez ouvrir le port, au moins en entrée (les connections établies pourront ressortir selon les premières règles). Ainsi de suite avec tous vos services.

On pourrait être plus restrictif en n’autorisant que certaines IP à accéder au serveur, mais ça pose un problème de taille : les BOX ADSL change d’IP souvent, donc vous seriez dans l’incapacité de contacter votre machine.

Protection initiale Flood/Scanning de ports

On peut à partir d’iptables commencer une protection contre le flood (attaque par dépassement des capacités du serveur en lui soumettant beaucoup de requêtes à la fois) et contre le scanning de ports (très sommairement). Enfin, vous pouvez ajouter ici des IPs que vous souhaitez bannir définitivement de votre machine (si vous repérez par exemple toujours la même machine qui veut se connecter sans raison à votre serveur).

#!/bin/bash

### Configuration avancée du firewall (ajout d'un premier niveau de protection Flood/Scan)

### Protection basique contre le flood (Denis de Service) DDOS
iptables -A FORWARD -p tcp --syn -m limit --limit 1/second -j ACCEPT
iptables -A FORWARD -p udp -m limit --limit 1/second -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT

### Scan de ports basique
iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT

### Bannir une IP dérangeante
### Template iptables -A INPUT -s adresse_ip -j DROP
#iptables -A INPUT -s x.x.x.x -j DROP

Protection d’intrusions

Actuellement, le firewall va bloquer toutes tentatives de connexions sur les ports fermés. Mais qu’en est-il des ports ouverts ? Afin de contrôler plus précisément ce qui se passe dessus, le firewall n’est pas suffisant et nous allons devoir utiliser d’autres outils, appelés IDS (Intrusion Detection System) et IPS (Intrusion Prevention System). Ces deux catégories de logiciels vont – comme leur nom l’indique – surveiller toute tentative d’intrusion sur le serveur.

Portsentry

Portsentry permet de bloquer en temps réel les scans de ports en bloquant la majorité des ports connus et inconnus contre ce type d’attaque. Dans un premier temps, installez-le.

Pour le configurer :

nano /usr/local/psionic/portsentry/portsentry.conf
# ou
nano /etc/portsentry/portsentry.conf

Commentez les lignes:

KILL_HOSTS_DENY

 

Décommettez les lignes :

# Kill_route défini l'action à réaliser envers l'IP qui scan votre machine
KILL_ROUTE="/sbin/iptables -I INPUT -s $TARGET$ -j DROP"

# Mise en route des bans
BLOCK_UDP="1"
BLOCK_TCP="1"

Vous devez ensuite passer en mode « advanced » (avancé) pour que le programme soit le plus efficace /etc/default/portsentry :

# On remplace ceci :
TCP_MODE="tcp"
UDP_MODE="udp"
# Par ceci :
TCP_MODE="atcp"
UDP_MODE="audp"

Pour finir la partie configuration, assurez-vous de mettre votre IP dans le fichier /etc/portsentry/portsentry.ignore de façon à ce que vous ne soyez pas soumis au bannissement pendant vos tests !!!

Pour lancer le processus, il faut prévoir un cron pour les deux lignes là (on le lance en deux fois une pour udp, l’autre pour tcp). Si vous avez un firewall dont les règles correspondent à celles du dessus (-A XXXX DROP), par défaut tout est bloqué donc ce programme n’est pas ultra nécessaire. On peut aussi utiliser un launch_script /etc/init.d/portsentry start/stop/restart depuis la dernière version.

portsentry –audp
portsentry –atcp

Fail2ban

Fail2ban, c’est très simple : c’est un petit programme qui permet de bannir (temporairement ou infiniment) l’ip d’une personne qui essayerait de brute-forcer un accès (ssh ou autre d’ailleurs). Si par exemple, une machine connait l’existence de l’utilisateur admin, il peut lancer une attaque par dictionnaire ou autre pour trouver le mot de passe. Par défaut, il n’y a pas de limite d’erreur. Tant que ça ne fonctionne pas, le serveur redemande de saisir le mot de passe. Fail2ban permet donc de définir le nombre de tentative avant l’exclusion permanent ou d’un temps donné du serveur.

Vous devez donc installer Fail2ban.

Puis dans la configuration :

nano /etc/fail2ban/jail.conf

Je vous encourage à remplir le champ ci-dessous :

[DEFAULT]
# Les IP non concerné par le ban en cas d'échec (localhost) et 8.8.8.8 votre IP (si elle ne change pas).
ignoreip = 127.0.0.1 8.8.8.8
# Recherche de tentative dans les logs (en secondes).
findtime = 3600
# Temps de bannissement en secondes
bantime = 86400

Il y a aussi : destemail -> indiquez une adresse mail si vous voulez recevoir des mails d’alerte de la part de fail2ban.

Attention : fintime défini le temps de recherche dans les logs d’échecs de connexion. Mettre une valeur raisonnable, pas plus d’une heure ou deux. En effet, si vous mettez 1 an par exemple, si vous avez dans la dernière année le nombre maxi d’échecs autorisés, vous serez alors directement banni. Le nombre de tentative n’est pas forcement consécutif, mais plutôt dans un laps de temps. Si vous mettez 1 minutes (60 secs), vous bloqué la bruteforce mais vous vous laisser la possibilité de vous tromper de mot de passe de temps en temps…

Pour chaque service supporter ensuite, il faut :

[ssh]

# Mets en fonction Fail2ban pour ssh
enabled = true

# Spécifie le port contrôé
port    = ssh,sftp
filter  = sshd
# Spécifie le log qu'il surveille
logpath  = /var/log/auth.log
# Spécifie le nombre d'essai avant le ban
maxretry = 6

Enfin pour appliquer la modification, comme d’habitude, on relance le service : /etc/init.d/fail2ban restart

Si vous avez besoin de débannir quelqu’un de la liste (ça peut arriver d’échouer des connexions SSH plusieurs fois de suite), regarder par ici :

fail2ban-client status ssh

Plus d’aide sur fail2ban-client : http://www.fail2ban.org/wiki/index.php/Commands

Rkhunter

Pour finir, ce petit outil est intéressant pour détecter des RootKits et backdoors qui peuvent laisser des pirates qui arriveraient quand même à accéder à votre machine. Ce n’est pas une solution ultime. En fait, c’est même relativement difficile à utiliser. Il va générer des rapports énormes à chaque intervention. Mais ça peut quand même dépanner en cas de problème.

Après installation, vous devez regarder le fichier de configuration /etc/default/rkhunter :

# indiquez un mail pour recevoir des alertes de Rkhunter (c'est très souvent)
REPORT_EMAIL
# mettez « yes » pour une vérification quotidienne de votre machine via un cron
CRON_DAILY_RUN : 

Si vous souhaitez un niveau de protection encore supérieur dans le domaine de la détection de rootkit, je vous laisse regarder du coté de GRsec mais ça requiert énormément de connaissance au niveau du kernel (noyau) de Linux. Bref, c’est super mais inutilisable sur un serveur dédié (ou alors pour les pros…).

Surveillance de logs

C’est quelque chose qu’il est intéressant de mettre en place pour surveiller son serveur sans avoir à se connecter régulièrement et surtout avoir besoin d’ouvrir 15 fichiers de logs pour chaque services installés. Ici nous utiliserons logwatch qui permet de regrouper toutes les données dans un rapport et de les envoyer soit par mail local soit par email à une adresse donnée.

Logwatch

Renseignez-vous de l’installation sur votre serveur (debian/gentoo/centos).

Ensuite, nous copions le fichier standard de configuration dans le dossier /etc et nous le personnalisons :

cp /usr/share/logwatch/default.conf/logwatch.conf /etc/logwatch/conf/logwatch.conf

Ensuite on édite les éléments suivants en fonctionne du résultat attendu :

# Votre dossier contenant vos autres logs
LogDir = /var/log

# La sortie sera du type mail (email)
# ou file (fichier sur le serveur)
Output = mail

# Le format du rapport text (pour mail local)
# ou html (pour mail sur une adresse email)
Format = text

# Encodage none ou base64
Encode = none

# Ici la personne qui va recevoir le mail
# Il peut s'agir d'un utilisateur local (root, admin)
# ou d'une adresse e-mail (admin@gmail.com) ou même
# de plusieurs si tout est séparé par une virgule
MailTo = root

# Vous indiquez ici le nom de l'emetteur de l'email
MailFrom = Logwatch-WEB-LSD

# Le niveau de detail du rapport
# Faible = 0
# Intermediaire = 5
# Eleve = 10
Detail = 10

Maintenant, vous n’avez plus qu’à utiliser cron pour lancer logwatch quand vous voulez (personnellement, tous les jours dans la nuit).

PS : pour l’utilisation de cron, deux techniques en fonction des systèmes :

crontab -l
crontab -e

ou via la mise en place de scripts dans :

/etc/cron.daily
# ou
/etc/cron.hourly
# etc.

Petite ligne de code (la question va venir sinon) sur comment vider la messagerie d’une session linux facilement :

>/var/spool/mail/admin
# Si l'utilisation s'appelle admin bien sur

On teste tout ça maintenant ?

Bon, c’était sympa tout ça. En réalité, on n’est toujours pas à l’abri d’un problème mais bon. On peut tester rapidement via deux outils :

  • nmap pour scanner les ports
  • nessus pour scanner les vulnérabilités

Pour les deux logiciels, vous devez les utiliser sur vos propres serveurs. Pas chez les autres…

Pour namp, faites des essais avec plusieurs paramètres pour voir si la sécurité est améliorée ou non. Vous commencez par ces tests avant les modifications, puis après et vous comparerez. Vous aurez alors un bon visuel sur ce qu’il reste à faire…

nmap -v ip_de_votre_serveur
# pour tester un port en particulier
nmap -p 80 ip_de_votre_serveur
# Essayez ça aussi
nmap -sN ip_de_votre_serveur
nmap -sS ip_de_votre_serveur
nmap -sI ip_de_votre_serveur

Pour nessus, je vous laisse regarder par ici : http://doc.ubuntu-fr.org/nessus

J’en veux encore

Pour aller plus loin, je vous conseille un excellent document pdf issu des recommandations en terme de sécurité informatique de la NSA (vous savez l’organisation qui espionne tout le monde…).

Mais avant le lien quelques commentaires au sujet du documents :

  • Grosse paranoïa dans le pdf (ce sont des cas extrême de sécurité)
  • Tout n’est pas réalisable pour vous (restriction de votre hébergeur de serveur ; matériel incompatible (RAM avec correction d’erreur…, KVM..))
  • Le document est de 2011, certaines technologies ont évolué même si dans l’ensemble, c’est très solide
  • Est-il nécessaire d’aller si loin ? Pour une plateforme qui accueille des centaines d’utilisateurs peut-être mais pour un serveur dédié au web…

Le lien : https://www.nsa.gov/ia/_files/os/redhat/rhel5-guide-i731.pdf

Second lien : http://olivieraj.free.fr/fr/linux/information/firewall/fw-03-04.html