Ce document à pour but de présenter les mesures de sécurité par ordre de priorité donné par l’ANSSI. Ce document démontre aussi comment mettre en place ses mesures.
Toutes les mesures seront misent en place sur une machine Debian
Suite à l’installation du serveur, la première étape à réaliser est un lancement de scan debsecan et lynis afin de vérifier le niveau de sécurité initial du serveur.
debsecan --suite $(lsb_release --codename --short) --only-fixed --format detail
# Returns nothing
debsecan --suite $(lsb_release --codename --short) --format detail
# CVE-2022-3037
# Use After Free in GitHub repository vim/vim prior to 9.0.0322. ...
# installed: xxd 2:8.2.2434-3+deb11u1
# (built from vim 2:8.2.2434-3+deb11u1)
# [...]
Analyse lynis
/usr/sbin/lynis audit system | ansi2html -la > report.html
# Hardening index : 61 [############ ]
Le scan de Lynis nous à mis une note de xx, nous allons mettre en place des mesures de durcissement afin d’augmenter ce score.
Le hardening est effectué en se basant sur nos expériences personnelles et principalement sur différents référentiels de l’ANSSI:
https://www.ssi.gouv.fr/uploads/2016/01/linux_configuration-fr-v1.2.pdf
https://www.ssi.gouv.fr/uploads/2014/01/NT_OpenSSH.pdf
https://www.ssi.gouv.fr/uploads/2013/05/anssi-guide-recommandations_mise_en_oeuvre_site_web_maitriser_standards_securite_cote_navigateur-v2.0.pdf
Niveau de durcissement : I
Cette section consiste à modifier les options des différents points de montage (voir page 16 du référentiel) de sorte à restreindre certains droits
echo 'proc /proc proc defaults,nosuid,nodev,noexec,relatime,hidepid=2 0 0' >> /etc/fstab
echo 'tmpfs /dev/shm tmpfs defaults,nodev,nosuid,noexec 0 0' >> /etc/fstab
Niveau de durcissement : R
La modification de UMASK et des droits des répertoires /home est important pour le durcissement du serveur. En effet, cela empêche que différents utilisateurs voient les documents des autres utilisateurs.
Les dossiers présents dans /home doivent être lisible seulement par les utilisateurs auxquels ils appartiennent. Cette mesure empêche d’avoir la main sur des fichiers potentiellement sensibles et à caractère personnel.
chmod 770 /home/*
sed -i 's/^UMASK.*/UMASK 0077/g' /etc/login.defs
Ici, nous commençons par changer les droits des répertoires déjà existants avant de modifier le fichier de configuration utilisé lors de la création de nouveaux utilisateurs.
Niveau de durcissement : I
Les modifications au niveau de la configuration SSH sont mises en place afin d’éviter une connexion root et renforce le système d’authentification.
En mettant en place les mesures suivantes, nous rajoutons une couche de sécurité supplémentaire au service SSH
Les méthodes utilisées
Dans /etc/ssh/sshd_config
PermitRootLogin no
Obliger l’authentification par clé ET mot de passe (tutorial : method 2)
#PasswordAuthentication no
AuthenticationMethods "publickey,password"
Dans le cadre de ce projet, nous allons autoriser seulement notre machine à se connecter au serveur
AllowUsers debian@10.0.2.2
Niveau de durcissement : R
Ici, nous allons faire en sorte de que restreindre les accès au serveur SFTP.
Nous autorisons l’utilisateur ftp-user à utiliser seulement le serveur SFTP. Dans notre scénario, cet utilisateur a seulement besoin de récupérer ou déposer des fichiers. Obtenir un shell sur le serveur n’est donc pas nécessaire.
useradd ftp-user -m -s /bin/false
/etc/ssh/sshd_configSubsystem sftp /usr/lib/openssh/sftp-server
Match Group ftp-user
ChrootDirectory /srv/sftp
ForceCommand internal-sftp
AllowTCPForwarding no
X11Forwarding no
Niveau de durcissement : R
Sur notre serveur (du moins pour le moment) cron n’est d’aucune utilité et peut être désactivé. Cela empêche un utilisateur malveillant d’exploiter une commande (souvent exécutée en tant que root) afin de faire de la latéralisation voire de l’élévation de privilèges.
systemctl stop cron
systemctl disable cron
Niveau de durcissement : I
En ayant des paquets à jours, nous pouvons installer les patchs dès leur publication. Les paquets suivants permettent d’effectuer les mises à jour de manière automatique.
apt-get install unattended-upgrades apt-listchanges
Niveau de durcissement : R
Cette mesure empêche un attaquant de charger des modules noyaux malveillants
Ajouter ceci dans le fichier /etc/sysctl.conf
kernel.modules_disabled = 1
Niveau de durcissement : I
Cette mesure nous permet de configurer des paramètres réseaux et systèmes au niveau du noyau dans le but de désactiver ceux qui sont inutilisés ou qui pourrait faire office de vecteur d’attaque.
Ajouter ceci dans le fichier /etc/sysctl.conf
# Pas de routage entre les interfaces
net.ipv4.ip_forward = 0
# Filtrage par chemin inverse
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ne pas envoyer de redirections ICMP
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# Refuser les paquets de source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Ne pas accepter les ICMP de type redirect
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Loguer les paquets ayant des IPs anormales
net.ipv4.conf.all.log_martians = 1
# RFC 1337
net.ipv4.tcp_rfc1337 = 1
# Ignorer les réponses non conformes à la RFC 1122
net.ipv4. icmp_ignore_bogus_error_responses = 1
# Augmenter la plage pour les ports éphémères
net.ipv4.ip_local_port_range = 32768 65535
# Utiliser les SYN cookies
net.ipv4.tcp_syncookies = 1
# Désactiver le support des "router solicitations"
net.ipv6.conf.all.router_solicitations = 0
net.ipv6.conf.default.router_solicitations = 0
# Ne pas accepter les "router preferences" par "router advertisements"
net.ipv6.conf.all.accept_ra_rtr_pref = 0
net.ipv6.conf.default.accept_ra_rtr_pref = 0
# Pas de configuration auto des prefix par "router advertisements"
net.ipv6.conf.all.accept_ra_pinfo = 0
net.ipv6.conf.default.accept_ra_pinfo = 0
# Pas d'apprentissage du routeur par défaut par "router advertisements"
net.ipv6.conf.all.accept_ra_defrtr = 0
net.ipv6.conf.default.accept_ra_defrtr = 0
# Pas de configuration auto des adresses à partir des "router advertisements "
net.ipv6.conf.all.autoconf = 0
net.ipv6.conf.default.autoconf = 0
# Ne pas accepter les ICMP de type redirect
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
# Refuser les packets de source routing
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0
# Nombre maximal d'adresses autoconfigurées par interface
net.ipv6.conf.all.max_addresses = 1
net.ipv6.conf.default.max_addresses = 1
Niveau de durcissement : I
Ajouter ceci dans le fichier /etc/sysctl.conf
# Désactivation des SysReq
kernel.sysrq = 0
# Pas de core dump des exécutables setuid
fs.suid_dumpable = 0
# Interdiction de déréférencer des liens vers des fichiers dont
# l'utilisateur courant n'est pas le propriétaire
# Peut empêcher certains programmes de fonctionner correctement
fs.protected_symlinks = 1
fs.protected_hardlinks = 1
# Activation de l'ASLR
kernel.randomize_va_space = 2
# Interdiction de mapper de la mémoire dans les adresses basses (0)
vm.mmap_min_addr = 65536
# Espace de choix plus grand pour les valeurs de PID
kernel.pid_max = 65536
# Obfuscation des adresses mémoire kernel
kernel.kptr_restrict = 1
# Restriction d'accès au buffer dmesg
kernel.dmesg_restrict = 1
# Restreint l'utilisation du sous système perf
kernel.perf_event_paranoid = 2
kernel. perf_event_max_sample_rate = 1
kernel.perf_cpu_time_max_percent = 1
Niveau de durcissement : R
Yama permet d’empêcher la manipulation des processus en cours avec ptrace et potentiellement voler des identifiants utilisateurs sans avoir à faire de phishing
Ajouter ceci dans le fichier /etc/sysctl.conf
kernel.yama.ptrace_scope = 3
Le simple fait de paramétrer Yama nous a permis de gagner 2 points de score Lynis
Niveau de durcissement : R
Désactiver les comptes utilisateurs non utilisés permet d’empêcher ces utilisateurs de se connecter et ainsi restreindre leur accès au serveur
usermod -L www-data
usermod -s /bin/false www-data
Niveau de durcissement : R
Cette mesure permet de déconnecter une session laissée ouverte trop longtemps afin d’empêcher l’accès à partir d’un compte compromis
Ici, nous modifions les fichiers chargés au démarrage d’un shell bash de sorte à set la variable d’environnement (page 28)
echo 'export TMOUT=1800' >> /home/debian/.bashrc
echo 'export TMOUT=1800' >> /etc/skel/.bashrc
Niveau de durcissement : R
Nous changeons la politique de mot de passe du programme passwd de sorte que les mots de passe fassent au minimum 12 caractères et contenant 3 classes de caractères différents.
Grâce à cette mesure, si le hash d’un mot de passe est récupéré, il sera difficile à casser et ralentira grandement un attaquant pendant sa tentative de compromission d’un compte utilisateur
apt install libpam-cracklib
# /etc/pam.d/passwd
password required pam_cracklib.so minlen=12 minclass=3 \
dcredit=0 ucredit=0 lcredit=0 \
ocredit=0 maxrepeat=1 \
maxsequence=1 gecoscheck \
reject_username enforce_for_root
Nous bloquons les comptes pendant 5 minutes après 3 échecs d’authentification. Cela permet non seulement de détecter les tentatives d’attaques par dictionnaire mais aussi de les empêcher.
Dans /etc/pam.d/sshd ; /etc/pam.d/login
auth required pam_tally.so deny=3 lock_time=300
Nous changeons l’algorithme de hachage des mots de passe afin d’utiliser SHA-512
Cette mesure rend la phase de bruteforce hors-ligne beaucoup plus lente car l’algorithme est complexe
password required pam_unix.so obscure sha512 rounds=65536
Niveau de durcissement : I
Mettre en place cette mesure empêche un attaquant d’exécuter un programme en tant qu’un autre utilisateur et potentiellement prendre possession du compte en question si le programme est vulnérable.
En utilisant cette liste nous pouvons retirer certains droits SUID qui peuvent être dangereux dans certains cas de figure
chmod -s /usr/bin/mount
chmod -s /usr/bin/umount
chmod -s /usr/bin/chsh
chmod -s /usr/bin/gpasswd
chmod -s /usr/bin/newgrp
chmod -s /usr/bin/passwd
chmod -s /usr/bin/crontab
chmod -s /usr/bin/chage
chmod -s /usr/bin/wall
chmod -s /usr/bin/chage
Niveau de durcissement : I
Créer un répertoire temporaire dédié pour chaque utilisateur permet de restreindre l’accès à des fichiers potentiellement sensibles à n’importe qui.
apt install libpam-tmpdir -y
Niveau de durcissement : R
En journalisation l’activité d’un serveur par auditd nous pouvons avoir des traces sur ce qui est fait dessus et ainsi détecter des comportements anormaux voire malveillants.
cat > /etc/audit/audit.rules << EOF
-w /sbin/insmod -p x
-w /sbin/modprobe -p x
-w /sbin/rmmod -p x
-w /etc/ -p wa
-a exit ,always -S mount -S umount2
-a exit ,always -S ioperm -S modify_ldt
-a exit ,always -S get_kernel_syms -S ptrace
-a exit ,always -S prctl
-a exit ,always -F arch=b64 -S unlink -S rmdir -S rename
-a exit ,always -F arch=b64 -S creat -S open -S openat -F exit=-EACCESS
-a exit ,always -F arch=b64 -S truncate -S ftruncate -F exit=-EACCESS
-e 2
EOF
Niveau de durcissement : I
On créé le groupe sudogrp et donne accès au binaire seulement aux utilisateurs membres de ce groupe (ici, debian a le droit d’utiliser sudo)
Cela permet d’avoir la main sur les utilisateurs autorisés à utiliser sudo
groupadd sudogrp
usermod -a -G sudogrp debian
chgrp sudogrp $(which sudo)
chmod 4750 $(which sudo)
Niveau de durcissement : M
Il ne faut jamais mettre la directive NOPASSWD dans une règle sudo car cela permet de bypass l’authentification des utilisateurs pour exécuter une commande privilégiée
Arguments explicites dans les spécifications sudo
Niveau de durcissement : I
Il n’est pas recommandé d’utiliser de wildcard telles que * dans les droits sudo car cela pourrait permettre d’ajouter des arguments inattendus dans la commande. L’absence
d’arguments auprès d’une commande doit être spécifiée par la présence d’une chaîne
vide « »
Niveau de durcissement : I
Afin de ne pas corrompre l’utilisation de la commande sudo et le fichier sudoers il est vital de passer par la commande sudoedit lorsque l’on souhaite modifier les privilèges des utilisateurs
Niveau de durcissement : E
Ce logiciel permet d’associer à chaque programme un profil de sécurité qui restreint les capacités de celui-ci
C’est un outil qui permet de verrouiller les applications en limitant strictement leur accès aux seules ressources auxquelles elles ont droit sans perturber leur fonctionnement.
Installation
L’installation et la configuration de AppArmor a été faite en se basant sur ce blog post
apt install apparmor apparmor-utils apparmor-profiles apparmor-profiles-extra
mkdir -p /etc/default/grub.d
echo 'GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT apparmor=1 security=apparmor"' > /etc/default/grub.d/apparmor.cfg
cp /usr/share/apparmor/extra-profiles/* /etc/apparmor.d/
aa-enforce /etc/apparmor.d/*
NB : pas applicable ici - pour référence
cat > /etc/apparmor.d/usr.sbin.nginx << EOF
#include <tunables/global>
/usr/sbin/nginx {
#include <abstractions/base>
#include <abstractions/nameservice>
#include <abstractions/apache2-common>
#include <abstractions/nis>
#include <abstractions/openssl>
#include <abstractions/ssl_keys>
capability dac_override,
capability dac_read_search,
capability net_bind_service,
capability setgid,
capability setuid,
network inet tcp,
# pour écrire dans la console
/dev/pts/[0-9] rw,
# binary, pid
/usr/bin/nginx mr,
/run/nginx.pid rw,
/usr/bin/php8.1 mrix,
# configuration
/etc/nginx r,
/etc/nginx/** rl,
/usr/share/nginx r,
/usr/share/nginx/** r,
/etc/ssl r,
/etc/ssl/openssl.cnf r,
# cache
owner /var/cache/nginx rw,
owner /var/cache/nginx/** rw,
owner /var/lib/nginx rw,
owner /var/lib/nginx/** rw,
# webroot
owner /var/www/html rw,
owner /var/www/html/** rw,
# logs
owner /var/log/nginx/* rw,
}
EOF
aa-enforce /usr/sbin/nginx
cat >> /etc/apparmor.d/usr.sbin.php-fpm << EOF
#include <tunables/global>
profile php-fpm /usr/sbin/php-fpm{7.4,8.0,8.1} flags=(attach_disconnected) {
#include <abstractions/base>
#include <abstractions/openssl>
#include <abstractions/ssl_certs>
capability setuid,
capability setgid,
capability chown,
capability kill,
capability dac_read_search,
capability dac_override,
network unix,
audit deny network inet,
# CONF
/etc/php/** rl,
/etc/hosts r,
/etc/host.conf r,
/etc/gai.conf r,
/etc/resolv.conf r,
/etc/nsswitch.conf r,
/etc/ImageMagick-6/ r,
/etc/ImageMagick-6/** r,
# php libraries
/usr/share/php*/ r,
/usr/share/php*/** mr,
/usr/share/ImageMagick-6 r,
/usr/share/ImageMagick-6/** r,
# Xlibs
/usr/X11R6/lib{,32,64}/lib*.so* mr,
# php extensions
/usr/lib{64,}/php/*/*.so mr,
# ICU (unicode support) data tables
/usr/share/icu/*/*.dat r,
/proc/@{pid}/attr/current rw,
/sys/devices/system/node r,
/sys/devices/system/node/** r,
/tmp/ rw,
/tmp/** rwk,
# Sessions
/var/lib/php/sessions rw,
/var/lib/php/sessions/** rwk,
# LOG
/var/log/php7.4-fpm.log rw,
/var/log/php8.0-fpm.log rw,
/var/log/php8.1-fpm.log rw,
# SOCKET
/run/php/php7.4-fpm.sock rwlk,
/run/php/php8.0-fpm.sock rwlk,
/run/php/php8.1-fpm.sock rwlk,
/run/php/php7.4-fpm.pid rwlk,
/run/php/php8.0-fpm.pid rwlk,
/run/php/php8.1-fpm.pid rwlk,
# CACHE
owner /var/cache/opcache rw,
# WEBROOT
owner /var/www/** rwk,
}
EOF
aa-enforce /usr/sbin/php-fpm8.1
Avec cette configuration, les webshells php tels que system($_GET[‹ cmd ›]); seront bloqués par AppArmor
Niveau de durcissement : I
nftables est un sous-système du noyau Linux fournissant le filtrage et la classification des paquets.
Grâce à celui-ci, nous allons seulement autoriser la communication avec les ports 22,80 et 443. Pour cela nous devons commencer par créer les règles.
nft add rule my_incoming_filter input tcp dport 80 accept
nft add rule my_incoming_filter input tcp dport 443 accept
nft add rule my_incoming_filter input tcp dport 22 accept
nft add rule my_incoming_filter input drop
On autorise donc les ports 22,80 et 443 en entrée grâce à tcp dport pour destination port qui permet de cibler le port de destination des paquets et la commande drop permet de refuser tous les autres ports.
Pour voir le changement que nous avons fait il suffit de taper
nft list table ip my_incoming_filter