Hardening serveur Linux
Quelques bonnes pratiques à suivre pour renforcer la sécurité d'un serveur/poste Linux
Sécuriser le BIOS
Protégez le BIOS par mot de passe, même si le mot de passe est volatile suite à l’enlèvement de la pile
Désactivez le boot via CD/DVD, USB, Périphérique externe, le Boot live permet à quiconque ayant un accès physique à la machine d’accéder au système.
Sécuriser le GRUB
GRUB est le chargeur de démarrage Linux, en démarrant en mode rescue quiconque ayant un accès physique à la machine peut modifier le mot de passe root.
https://www.tecmint.com/password-protect-grub-in-linux/
Chiffrer le système
Chiffrer ses données c'est important, en cas de vol ou d’intrusion un simple boot en live permet d'accéder aux données.
(Voir mon article sur chiffrer un disque)
Partitionner son système
Partitions = meilleure sécurité des données en cas de sinistre.
un disque permet également d’avoir des fonctionnalités supplémentaires (chiffrement, LVM, etc …)
Par pitié, utilisez LVM afin d’agrandir/réduire les partition sans abîmer le FS.
#Exemple de partition
/
/boot
/usr
/var
/home
Utilisez seulement les paquets nécessaire
Éviter d’installer des paquets inutiles, ça minimise les risques de vulnérabilités.
yum install list #Afficher le spaquets installés (CentOS & redhat)
chkconfig --list| grep '3:on' #afficher les services démarré en lvl 3
dpkg --list #afficher les paquets installés (debian)
Sécuriser SSH
Par défaut la sécurité de SSH peut-être amélioré (incontournable puisque SSH est un des services les plus attaqués !)
https://k-lfa.info/securiser-ssh/
Interdire les utilisateurs au cron
Cron permet d'autoriser / interdire des utilisateurs via /etc/cron.allow et /etc/cron.deny
Pour interdire tout les utilisateurs et en autoriser certains
echo ALL >> /etc/cron.deny
echo user >> /etc/cron.allow
Interdire les périphériques USB
Permet d'éviter la diffusion de malware via USB ou rubberDuck
echo "install usb-storage /bin/true" >> /etc/modprobe.d/no-usb
Renforcer le control d'accès noyau (SELinux)
SELinux est un mécanisme de sécurité du contrôle d'accès dans le noyau. Si le serveur est accessible depuis le net, je vous conseille de l'activer.
- Enforcing : Mode par défaut qui active et applique la stratégie de sécurité SELinux sur la machine.
- Permissive : SELinux n'appliquera pas la politique de sécurité, mais avertira seulement et enregistrera les actions. (Mettez au moins celui la pour avoir des traces)
- Désactivé
sestatus #pour avoir l'état du SELinux
setenforce permissive #Activer le SELinux en permissive
Se configure aussi dans /etc/selinux/config
Supprimer l'interface graphique / Bureau
Hors de question de voir des serveurs linux avec un bureau ! C'est moche et sa ouvre des failles de sécurité potentielle
#YouHaveSkillOrNot?
Désactiver IPv6 (Si non utilisé)
A faire dans le contexte ou vous n'utilisez pas l'IPv6
Dans /etc/sysctl.conf
# désactivation de ipv6 pour toutes les interfaces
net.ipv6.conf.all.disable_ipv6 = 1
# désactivation de l’auto configuration pour toutes les interfaces
net.ipv6.conf.all.autoconf = 0
# désactivation de ipv6 pour les nouvelles interfaces (ex:si ajout de carte réseau)
net.ipv6.conf.default.disable_ipv6 = 1
# désactivation de l’auto configuration pour les nouvelles interfaces
net.ipv6.conf.default.autoconf = 0
sysctl -p #Recharger la configuration
Empêcher d'utiliser un ancien mot de passe
Très utile au cas ou il y aurait d'autres administrateur sur le serveur
#Copiez le fichier par sécurité en cas d'ereur : cp /etc/pam.d/common-password /root
#dans /etc/pam.d/common-password (Ajoutez à la fin du fichier)
auth sufficient pam_unix.so likeauth nullok
#Ajouter en dessous de la section password (se souvient des 5 derniers pass)
password sufficient pam_unix.so nullok use_authtok md5 shadow remember=5
Appliquer une politique de mot de passe fort
Incontournable surtout si plusieurs administrateurs s'occupent du serveur
apt-get install libpam-cracklib
#Copiez le fichier par sécurité en cas d'ereur : cp /etc/pam.d/common-password /root
#Dans /etc/pam.d/common-password (ajouter la ligne dans la section password)
password required pam_cracklib.so try_first_pass retry=3 minlen=12 difok=2 ucredit=-2 lcredit=-2 dcredit=-2 ocredit=-2 reject_username
- Retry=3 (Autorise 3 essais pour la saisie du mot de passe
- Minlen=12 (Longueur minimale de 12 caractères obligatoire)
- Difok=3 (Nombre de caractères qui doivent être différents entre l'ancien et nouveau mot de passe)
- ucredit=-2 (Doit contenir au moins 2 minuscules)
- lcredit=-2 (Doit contenir au moins 2 majuscules)
- dcredit=-2 (Doit contenir au moins 2 chiffres)
- ocredit=-2 (Doit contenir au moins 2 symboles/caractères spéciaux)
Obliger un utilisateur à changer de mot de passe quotidiennement
Se couple très bien avec les deux précédents (Une bonne stratégie de mot de passe c'est 50% d'attaque bruteforce en moins)
chage -M 30 -m 7 -W 2 username
- -M : Nombre maximum de jours
- -m : Nombre minimum de jours
- -W : Nombre de jours d'avertissement
Activer le parefeu
Encore plus si le serveur est accessible depuis le net (Un bon parefeu empêche les attaques DDOS)
https://www.tecmint.com/basic-guide-on-iptables-linux-firewall-tips-commands/
# Autoriser port 22,80 et 443
iptables -A INPUT -i eth0 -p tcp --dport 80,443,22 -j ACCEPT
iptables -A INPUT -i eth0 -j REJECT
# Anti FLOOD/DDOS
iptables -A INPUT -p tcp --syn -m limit --limit 1/second -j ACCEPT
iptables -A INPUT -p udp -m limit --limit 1/second -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT
iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
Désactiver Cntrl + Alt + Sup (inittab)
Depuis un accès physique ce raccourcis oblige a redémarrer le processus (conseillé si plusieurs personnes ont un accès physique)
#Dans /etc/inittab commentez les lignes suivantes :
# Trap CTRL-ALT-DELETE
#ca::ctrlaltdel:/sbin/shutdown -t3 -r now
Surveiller les activités utilisateurs
les outils psacct et acct surveillent les activités et processus des utilisateurs
https://www.tecmint.com/how-to-monitor-user-activity-with-psacct-or-acct-tools/
Lecture des logs
Incontournable pour surveiller l'état de santé d'un service/serveur
/var/log/*
/var/log/apt/* Logs des paquets installés
/var/log/aptitude Logs d'aptitude (actions demandées & abandonnées)
/var/log/auth.log Logs de connexions et méthode d'authentification utilisée.
/var/log/boot.log Logs enregistrées lors du démarrage du système (non activé par défaut)
/var/log/btmp Semblable à /var/log/wtmp
#lastb Affiche les connexions/déconnexions au système
#last lit le fichier /var/log/wtmp
/var/log/cron Logs sur les tâches cron
/var/log/daemon.log Logs enregistrées par les différents daemons
/var/log/debug Logs de debugging.
/var/log/dmesg Logs du noyau Linux depuis le démarrage.
/var/log/dpkg.log Logs des paquets installés ou retirés via dpkg
/var/log/faillog Les échecs de connexion. #faillog -u root.
/var/log/kern.log Logs enregistrées par le noyau (Utile pour débogguer un noyau personnalisé)
/var/log/lastlog Logs de connexion récente de tous les utilisateurs #lastlog pour afficher le contenu de ce fichier
/var/log/mail.* Mail reçu en local
/var/log/messages Les messages du système, y compris les messages qui sont enregistrés au démarrage
/var/log/syslog Tous les messages, hormis les connexions des utilisateurs
/var/log/user.log Les informations sur tous les journaux de niveau utilisateur
/var/log/wtmp Toutes les connexions et déconnexions: #last -f /var/log/wtmp.
Analyse anti rootkit
L'outil rkhunter est un bon outil pour faire cela (il va checker les SUID, les binaires systèmes et le FS) il est facilement automatisable via cron
rkhunter -c #Lancer un check du système
Boot en lecture seul
Le passage en lecture seule réduit le risque de modification non autorisée de fichiers de démarrage critiques.
/!\ Attention lors d'une mise à jours remettez la configuration d'origine /!\
#Dans /etc/fstab copiez et commentez la ligne sous #/boot was on /dev/sda1 during installation
#UUID=f57ec5... /boot ext2 defaults 0 2
UUID=f57ec5... /boot ext2 defaults,ro 1 2
Lors des mises à jours commentez la nouvelle et réactivez la première
UUID=f57ec5... /boot ext2 defaults 0 2
#UUID=f57ec5... /boot ext2 defaults,ro 1 2
Sécuriser le kernel des attaques réseaux
Renforcer la pile TCP du noyau permet d’empêcher certains type d'attaques comme limiter la configuration transmise par le réseau pour IPv4/IPv6, activer la protection execshield, activer la vérification de l'adresse IP source, empêcher une attaque d'IP spoofing ...
Cela se configure via sysctl etc /etc/sysctl.conf
# Ce qui suit convient aux serveurs Web dédiés, mail, ftp, Attention au services de forwarding reseau (DNS, routage, ...)
# Contrôle le transfert de paquets IP
net.ipv4.ip_forward = 0
# Ne pas accepter le routage source
net.ipv4.conf.default.accept_source_route = 0
# Contrôle la fonctionnalité de débogage des requêtes système du noyau
kernel.sysrq = 0
# Contrôle si le core dumps ajoutera le PID au nom de fichier principal, utile pour le débogage d'applications multithreads
kernel.core_uses_pid = 1
# Contrôle l'utilisation des syncookies TCP
# Activer les protections SYN-flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 5
# Envoyer les redirections, si routeur, only for server (pas de routage autorisé)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# refuser les paquets avec l'option SRR
net.ipv4.conf.all.accept_source_route = 0
# Accepter les redirections? only for server (pas de routage)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
# Journaliser les paquets avec des adresses impossibles dans le journal du noyau
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Ignorer toutes les requêtes ICMP ECHO et TIMESTAMP via broadcast/multicast
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Prévenir contre les 'attaques syn flood' courantes
net.ipv4.tcp_syncookies = 1
# Activer la validation de la source par chemin inversé, comme spécifié dans la RFC1812
net.ipv4.conf.all.rp_filter = 1
# Contrôle la vérification de l'itinéraire source
net.ipv4.conf.default.rp_filter = 1
########### Hardening IPv6 ##############
# Nombre de sollicitations de routeur à envoyer jusqu'à supposer qu'aucun routeur ne soit présent.
# Ceci est l'hôte et non le routeur
net.ipv6.conf.default.router_solicitations = 0
# Accepter les préférences de routeur dans RA?
net.ipv6.conf.default.accept_ra_rtr_pref = 0
# Apprendre les informations de préfixe dans la publicité du routeur
net.ipv6.conf.default.accept_ra_pinfo = 0
# Setting définit si le système accepte les paramètres de limite de sauts d'une publication de routeur.
net.ipv6.conf.default.accept_ra_defrtr = 0
#publications de routeur peuvent amener le système à attribuer une adresse unicast globale à une interface
net.ipv6.conf.default.autoconf = 0
# nombre de sollicitations de voisins à envoyer par adresse?
net.ipv6.conf.default.dad_transmits = 0
# Combien d'adresses IPv6 unicast globales peuvent être attribuées à chaque interface?
net.ipv6.conf.default.max_addresses = 1
#Hardening TCP
#Enable ExecShield protection
Valeur #Set à 1 ou 2 (recommandé)
# kernel.exec-shield = 2
# kernel.randomize_va_space = 2
# Optimisation TCP et mémoire
# augmentation de la taille maximale du tampon TCP configurable à l'aide de setsockopt ()
# net.ipv4.tcp_rmem = 4096 87380 8388608
# net.ipv4.tcp_wmem = 4096 87380 8388608
# augmenter le réglage automatique de Linux des limites de mémoire tampon TCP
# net.core.rmem_max = 8388608
# net.core.wmem_max = 8388608
# net.core.netdev_max_backlog = 5000
# net.ipv4.tcp_window_scaling = 1
# augmenter la limite de descripteur de fichier système
fs.file-max = 65535
#Permet pour plus de PID
kernel.pid_max = 65536
#Augmenter les limites de port IP du système
net.ipv4.ip_local_port_range = 2000 65000
#Correction de la RFC 1337
net.ipv4.tcp_rfc1337 = 1
#Redémarrer la machine après un kernel panic
kernel.panic=10
#Les adresses de la base mmap, de la pile et de la page VDSO sont randomisées
kernel.randomize_va_space = 2
#Ignorer les erreurs ICMP
net.ipv4.icmp_ignore_bogus_error_responses = 1
#Protège contre l'attaque de liens symbolique/physique dans certaines conditions
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
https://www.cyberciti.biz/faq/linux-kernel-etcsysctl-conf-security-hardening/
Externaliser / monitorer les logs
La meilleur des sécurités est d'avoir un serveur de log centralisant les logs de votre infrastructure (SIEM), pour un petit serveur dédié des alternatives existent comme logwatch et logcheck
- logcheck : système de gestion de journaux identifiant les problèmes inconnus et les violations de la sécurité dans les fichiers journaux
- logwatch : analyseur et un rapporteur de fichiers journaux facilement personnalisable auquel de nombreux plugins et script peuvent être greffés
Utiliser un IDS pour surveiller les requêtes réseau/applicatives
Snort / Tripwire sont de bons IDS open source
Attention, avant d'avoir un IDS bien configuré vous passerez par des faux positifs. Ne pas sous estimé la période de test
Renforcer la sécurité avec Fail2ban
Fail2ban est un IPS et permet de bannir une IP temporairement lorsque plusieurs échecs d'authentification sont détectés
Pour configurer fail2ban : https://k-lfa.info/securiser-fail2ban/
Sauvegarde du système
La base de la base en cas d'attaque si on à pas de sauvegarde c'est mort (vous pourrez toujours demandé une copie de vos données à la NSA)
quelques outils à connaître :
- rsync : Outils de sauvegarde via réseau en plusieurs mode (synchronisation copie ou actualisation)
- tar : pour créer un tarbal et compresser les fichiers/données à sauvegarder (le plus simple pour un serveur VPS)
- bacula : outil de sauvegarde, de récupération et de vérification de données (idéal en contexte d'infra ou entreprise)
- backupninja : outil de sauvegarde qui permet d'effectuer des sauvegardes sécurisées, distantes et incrémentielles sur un réseau
- backuppc : outil de sauvegarde et restauration réseau (idéal en contexte d'infra ou entreprise)
Séparer les services du système
Pour les services accessibles depuis le net, la bonne pratique est de les séparer du systèmes (éviter un FTP, Web, SQL sur le même système)
Aujourd'hui grace à la technologie de conteneur comme docker cela est tout à fait possible d'isoler les services du système principal.
https://www.tecmint.com/install-run-and-delete-applications-inside-docker-containers/
https://www.tecmint.com/install-apache-web-server-in-a-docker-container/