
Guide étape par étape pour durcir un serveur Linux, couvrant la sécurité SSH, les pare-feux, la détection d'intrusion, l'audit, et la configuration système afin de réduire la surface d'attaque et d'améliorer la défense.
Un guide évolutif pour sécuriser un serveur Linux qui, espérons-le, vous apprend également un peu sur la sécurité et pourquoi elle est importante.
(TOC réalisé avec nGitHubTOC)
Le but de ce guide est de vous apprendre à sécuriser un serveur Linux.
Il y a beaucoup de choses que vous pouvez faire pour sécuriser un serveur Linux et ce guide tentera d'en couvrir autant que possible. Plus de sujets/matériel seront ajoutés au fur et à mesure que j'apprends, ou que des gens contribuent.
Les playbooks Ansible de ce guide sont disponibles sur How To Secure A Linux Server With Ansible par moltenbit.
Je suppose que vous utilisez ce guide parce que vous comprenez déjà, espérons-le, pourquoi une bonne sécurité est importante. C'est un sujet lourd en soi et le détailler dépasse le cadre de ce guide. Si vous ne connaissez pas la réponse à cette question, je vous conseille de la rechercher d'abord.
À un niveau élevé, dès qu'un appareil, comme un serveur, est dans le domaine public — c'est-à-dire visible de l'extérieur — il devient une cible pour les acteurs malveillants. Un appareil non sécurisé est un terrain de jeu pour les acteurs malveillants qui veulent accéder à vos données, ou utiliser votre serveur comme un nœud supplémentaire pour leurs attaques DDOS à grande échelle.
Ce qui est pire, c'est que sans une bonne sécurité, vous ne saurez peut-être jamais si votre serveur a été compromis. Un acteur malveillant peut avoir obtenu un accès non autorisé à votre serveur et copié vos données sans rien changer, donc vous ne le saurez jamais. Ou votre serveur peut avoir fait partie d'une attaque DDOS, et vous ne le sauriez pas. Regardez les nombreuses fuites de données à grande échelle dans les actualités — les entreprises ne découvrent souvent la fuite de données ou l'intrusion que longtemps après le départ des acteurs malveillants.
Contrairement à la croyance populaire, les acteurs malveillants ne veulent pas toujours changer quelque chose ou vous verrouiller l'accès à vos données pour de l'argent. Parfois, ils veulent juste les données de votre serveur pour leurs entrepôts de données (il y a beaucoup d'argent dans les big data) ou pour utiliser votre serveur discrètement à des fins néfastes.
Ce guide peut sembler redondant/inutile car il existe d'innombrables articles en ligne qui vous disent comment sécuriser Linux, mais l'information est dispersée dans différents articles, qui couvrent des choses différentes, et de manières différentes. Qui a le temps de parcourir des centaines d'articles ?
Alors que je faisais des recherches pour ma configuration Debian, j'ai pris des notes. À la fin, j'ai réalisé que, combiné à ce que je savais déjà et à ce que j'apprenais, j'avais les bases d'un guide pratique. Je me suis dit que je le mettrais en ligne pour, espérons-le, aider les autres à apprendre et à gagner du temps.
Je n'ai jamais trouvé un seul guide qui couvre tout — ce guide est ma tentative.
Beaucoup de choses abordées dans ce guide peuvent sembler assez basiques/triviales, mais la plupart d'entre nous n'installons pas Linux tous les jours, et il est facile d'oublier ces choses basiques.
Il existe de nombreux guides fournis par des experts, des leaders de l'industrie et les distributions elles-mêmes. Il n'est pas pratique, et parfois contraire aux droits d'auteur, d'inclure tout ce qui provient de ces guides. Je vous recommande de les consulter avant de commencer avec ce guide.
Ce guide...
Il existe de nombreux types de serveurs et différents cas d'utilisation. Bien que je souhaite que ce guide soit aussi générique que possible, il y aura certaines choses qui peuvent ne pas s'appliquer à tous les autres cas d'utilisation. Utilisez votre meilleur jugement lorsque vous parcourez ce guide.
Pour aider à contextualiser les nombreux sujets abordés dans ce guide, mon cas d'utilisation/configuration est :
Je suis très paresseux et je n'aime pas éditer des fichiers à la main si je n'en ai pas besoin. Je suppose aussi que tout le monde est comme moi. :)
Ainsi, quand et où c'est possible, j'ai fourni des extraits de code pour faire rapidement ce qui est nécessaire, comme ajouter ou modifier une ligne dans un fichier de configuration.
Les extraits de code utilisent des commandes de base comme echo, cat, sed, awk, et grep. Le fonctionnement des extraits de code, comme ce que chaque commande/partie fait, dépasse le cadre de ce guide — les pages man sont vos amies.
Remarque : Les extraits de code ne valident/vérifient pas que la modification a bien été effectuée — c'est-à-dire que la ligne a été réellement ajoutée ou modifiée. Je vous laisse la partie vérification entre vos mains compétentes. Les étapes de ce guide incluent la prise de sauvegardes de tous les fichiers qui seront modifiés.
Toutes les modifications ne peuvent pas être automatisées avec des extraits de code. Ces modifications nécessitent une édition manuelle classique. Par exemple, vous ne pouvez pas simplement ajouter une ligne à un fichier de type INI. Utilisez votre éditeur de texte Linux préféré.
Je voulais mettre ce guide sur GitHub pour faciliter la collaboration. Plus les gens contribuent, meilleur et plus complet deviendra ce guide.
Pour contribuer, vous pouvez forker et soumettre une pull request ou soumettre un nouveau ticket.
Avant de commencer, vous voudrez identifier quels sont vos principes. Quel est votre modèle de menace ? Quelques éléments à considérer :
Ce ne sont là que quelques éléments à considérer. Avant de commencer à sécuriser votre serveur, vous voudrez comprendre contre quoi vous essayez de vous protéger et pourquoi, afin de savoir ce que vous devez faire.
Ce guide est destiné à être agnostique en matière de distribution afin que les utilisateurs puissent utiliser n'importe quelle distribution de leur choix. Cela dit, il y a quelques points à garder à l'esprit :
Vous voulez une distribution qui...
L'installation de Linux dépasse le cadre de ce guide car chaque distribution le fait différemment et les instructions d'installation sont généralement bien documentées. Si vous avez besoin d'aide, commencez par la documentation de votre distribution. Quel que soit la distribution, le processus de haut niveau se déroule généralement comme suit :
Lorsque c'est applicable, utilisez l'option d'installation experte pour avoir un contrôle plus strict sur ce qui est exécuté sur votre serveur. N'installez que ce dont vous avez absolument besoin. Personnellement, je n'installe rien d'autre que SSH. Cochez également l'option de chiffrement de disque.
sudo apt update && sudo apt upgrade sur les systèmes basés sur Debian)./etc/fstabmanapt appropriées qui devraient fonctionner sur toutes les distributions basées sur Debian. Si quelqu'un est prêt à fournir les commandes respectives pour d'autres distributions, je les ajouterai.Les playbooks Ansible de ce guide sont disponibles sur How To Secure A Linux Server With Ansible.Assurez-vous de modifier les variables selon vos besoins et de lire toutes les tâches au préalable pour confirmer que cela ne casse pas votre système. Après avoir exécuté les playbooks, assurez-vous que tous les paramètres sont configurés selon vos besoins !
5. Modifiez toutes les variables dans *group_vars/variables.yml* selon vos besoins.
6. Activez l'accès root SSH avant d'exécuter les playbooks : ```
nano /etc/ssh/sshd_config
[...]
PermitRootLogin yes
[...]
Exécutez le playbook des prérequis en utilisant le mot de passe root que vous avez spécifié lors de l'installation du serveur :
ansible-playbook --inventory hosts.yml --ask-pass requirements-playbook.yml
Exécutez le playbook principal avec le mot de passe du nouvel utilisateur que vous avez spécifié dans le fichier variables.yml :
ansible-playbook --inventory hosts.yml --ask-pass main-playbook.yml
Si vous devez exécuter les playbooks plusieurs fois, n'oubliez pas d'utiliser la clé SSH et le nouveau port SSH :
ansible-playbook --inventory hosts.yml -e ansible_ssh_port=SSH_PORT --key-file /PATH/TO/SSH/KEY main-playbook.yml
Il est fortement recommandé de garder un second terminal ouvert vers votre serveur avant d'apporter et d'appliquer des modifications à la configuration SSH. Ainsi, si vous vous verrouillez hors de votre première session terminal, vous avez encore une session connectée pour pouvoir corriger.
Merci à Sonnenbrand pour cette idée.
L'utilisation de clés publiques/privées SSH est plus sécurisée que l'utilisation d'un mot de passe. Cela rend également la connexion à notre serveur plus facile et plus rapide, car vous n'avez pas à saisir de mot de passe.
Consultez les références ci-dessous pour plus de détails mais, à un niveau élevé, les clés publiques/privées fonctionnent en utilisant une paire de clés pour vérifier l'identité.
Pour SSH, une clé publique et privée est créée sur le client. Vous devez garder les deux clés en sécurité, en particulier la clé privée. Même si la clé publique est destinée à être publique, il est sage de s'assurer qu'aucune des deux clés ne tombe entre de mauvaises mains.
Lorsque vous vous connectez à un serveur SSH, SSH recherchera une clé publique qui correspond au client à partir duquel vous vous connectez dans le fichier ~/.ssh/authorized_keys sur le serveur auquel vous vous connectez. Notez que le fichier se trouve dans le dossier personnel de l'ID auquel vous essayez de vous connecter. Ainsi, après avoir créé la clé publique, vous devez l'ajouter à ~/.ssh/authorized_keys. Une approche consiste à la copier sur une clé USB et à la transférer physiquement vers le serveur. Une autre approche consiste à utiliser ssh-copy-id pour transférer et ajouter la clé publique.
Une fois les clés créées et la clé publique ajoutée à ~/.ssh/authorized_keys sur l'hôte, SSH utilise les clés publique et privée pour vérifier l'identité puis établir une connexion sécurisée. La manière dont l'identité est vérifiée est un processus complexe mais Digital Ocean a un très bon article expliquant son fonctionnement. À un niveau élevé, l'identité est vérifiée par le serveur qui chiffre un message de défi avec la clé publique, puis l'envoie au client. Si le client ne peut pas déchiffrer le message de défi avec la clé privée, l'identité ne peut pas être vérifiée et une connexion ne sera pas établie.
Elles sont considérées comme plus sûres car vous avez besoin de la clé privée pour établir une connexion SSH. Si vous définissez PasswordAuthentication no dans /etc/ssh/sshd_config, alors SSH ne vous permettra pas de vous connecter sans la clé privée.
Vous pouvez également définir une phrase de passe pour les clés, ce qui vous obligerait à saisir la phrase de passe de la clé lors de la connexion avec des clés publiques/privées. Gardez à l'esprit que cela signifie que vous ne pouvez pas utiliser la clé pour l'automatisation car vous n'aurez aucun moyen d'envoyer la phrase de passe dans vos scripts. ssh-agent est un programme fourni avec de nombreuses distributions Linux (et généralement déjà en cours d'exécution) qui vous permet de conserver votre clé privée non chiffrée en mémoire pendant une durée configurable. Exécutez simplement ssh-add et il vous demandera votre phrase de passe. Vous ne serez plus invité à saisir votre phrase de passe jusqu'à ce que la durée configurable soit écoulée.
Nous utiliserons des clés Ed25519 qui, selon https://linux-audit.com/ :
Utilise un schéma de signature à courbe elliptique, offrant une meilleure sécurité que ECDSA et DSA. En même temps, il offre également de bonnes performances.
man ssh-keygenman ssh-copy-idman ssh-addDepuis l'ordinateur que vous allez utiliser pour vous connecter à votre serveur, le client, pas le serveur lui-même, créez une clé Ed25519 avec ssh-keygen :
ssh-keygen -t ed25519
Generating public/private ed25519 key pair. Enter file in which to save the key (/home/user/.ssh/id_ed25519): Created directory '/home/user/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/user/.ssh/id_ed25519. Your public key has been saved in /home/user/.ssh/id_ed25519.pub. The key fingerprint is: SHA256:F44D4dr2zoHqgj0i2iVIHQ32uk/Lx4P+raayEAQjlcs user@client The key's randomart image is: +--[ED25519 256]--+ |xxxx x | |o.o +. . | | o o oo . | |. E oo . o . | | o o. o S o | |... .. o o | |.+....+ o | |+.=++o.B.. | |+..=**=o=. | +----[SHA256]-----+
Remarque : Si vous définissez une phrase de passe, vous devrez la saisir à chaque fois que vous vous connecterez à votre serveur en utilisant cette clé, sauf si vous utilisez ssh-agent.
Maintenant, vous devez ajouter la clé publique ~/.ssh/id_ed25519.pub de votre client au fichier sur votre serveur. Puisque nous sommes probablement encore à la maison sur le réseau local, nous sommes probablement à l'abri des attaques , nous allons donc utiliser pour transférer et ajouter la clé publique :
C'est maintenant un bon moment pour effectuer toute tâche spécifique à votre configuration.
Pour faciliter le contrôle de qui peut se connecter en SSH au serveur. En utilisant un groupe, nous pouvons rapidement ajouter/supprimer des comptes du groupe pour autoriser ou non rapidement l'accès SSH au serveur.
Nous utiliserons l'option AllowGroups dans le fichier de configuration SSH /etc/ssh/sshd_config pour indiquer au serveur SSH de n'autoriser les utilisateurs à se connecter en SSH que s'ils sont membres d'un certain groupe UNIX. Toute personne ne faisant pas partie du groupe ne pourra pas se connecter en SSH.
/etc/ssh/sshd_config pour limiter qui peut se connecter en SSH au serveurAllowGroup défini dans Sécuriser /etc/ssh/sshd_config.man groupaddman usermodCréez un groupe :
sudo groupadd sshusers
Ajoutez le(s) compte(s) au groupe :
sudo usermod -a -G sshusers user1
sudo usermod -a -G sshusers user2
sudo usermod -a -G sshusers ...
Vous devrez faire cela pour chaque compte sur votre serveur qui a besoin d'accès SSH.
/etc/ssh/sshd_configSSH est une porte d'entrée vers votre serveur. Cela est particulièrement vrai si vous ouvrez des ports sur votre routeur pour pouvoir vous connecter en SSH à votre serveur depuis l'extérieur de votre réseau domestique. S'il n'est pas correctement sécurisé, un acteur malveillant pourrait l'utiliser pour obtenir un accès non autorisé à votre système.
/etc/ssh/sshd_config est le fichier de configuration par défaut utilisé par le serveur SSH. Nous utiliserons ce fichier pour indiquer les options que le serveur SSH doit utiliser.
man sshd_configFaites une sauvegarde du fichier de configuration du serveur OpenSSH /etc/ssh/sshd_config et supprimez les commentaires pour le rendre plus facile à lire :
sudo cp --archive /etc/ssh/sshd_config /etc/ssh/sshd_config-COPY-$(date +"%Y%m%d%H%M%S")
sudo sed -i -r -e '/^#|^$/ d' /etc/ssh/sshd_config
Modifiez /etc/ssh/sshd_config puis trouvez et modifiez ou ajoutez ces paramètres qui doivent être appliqués indépendamment de votre configuration/setup :
Remarque : SSH n'aime pas les paramètres contradictoires en double. Par exemple, si vous avez ChallengeResponseAuthentication no puis ChallengeResponseAuthentication yes, SSH respectera le premier et ignorera le second. Votre fichier /etc/ssh/sshd_config peut déjà contenir certaines des lignes/paramètres ci-dessous. Pour éviter les problèmes, vous devrez parcourir manuellement votre fichier /etc/ssh/sshd_config et traiter les paramètres contradictoires en double.
Remarque : Si vous utilisez OpenSSH 9.1 ou une version ultérieure, décommentez la ligne RequiredRSASize 3072 dans la configuration ci-dessous. Cela impose une taille minimale de clé RSA de 3072 bits et rejettera les clés RSA plus petites lors de l'authentification. Cela n'affecte que les clés RSA. Si vous utilisez des clés ED25519 ou ECDSA, vous n'êtes pas concerné. Vous pouvez vérifier le type et la taille de votre clé avec . Sur les versions plus anciennes d'OpenSSH, laissez la ligne commentée car elle empêcherait sshd de démarrer.
Selon les directives OpenSSH de Mozilla pour OpenSSH 6.7+, "tous les modules Diffie-Hellman utilisés doivent avoir une longueur d'au moins 3072 bits".
L'algorithme Diffie-Hellman est utilisé par SSH pour établir une connexion sécurisée. Plus le module (taille de clé) est grand, plus le chiffrement est fort.
man moduliFaites une sauvegarde du fichier de modules SSH /etc/ssh/moduli :
sudo cp --archive /etc/ssh/moduli /etc/ssh/moduli-COPY-$(date +"%Y%m%d%H%M%S")
Supprimez les modules courts :
sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp
sudo mv /etc/ssh/moduli.tmp /etc/ssh/moduli
Même si SSH est un assez bon gardien de sécurité pour vos portes et fenêtres, c'est toujours une porte visible que les acteurs malveillants peuvent voir et essayer de forcer par brute force. Fail2ban surveillera ces tentatives de brute force, mais il n'y a pas de sécurité excessive. Exiger deux facteurs ajoute une couche de sécurité supplémentaire.
L'utilisation de l'authentification à deux facteurs (2FA) / authentification multi-facteurs (MFA) oblige toute personne entrante à avoir deux clés pour entrer, ce qui rend plus difficile pour les acteurs malveillants. Les deux clés sont :
Sans les deux clés, ils ne pourront pas entrer.
Beaucoup de gens peuvent trouver l'expérience encombrante ou ennuyeuse. Et, l'accès à votre système dépend de l'application d'authentification qui génère le code.
Sur Linux, PAM est responsable de l'authentification. Il y a quatre tâches pour PAM que vous pouvez lire sur https://en.wikipedia.org/wiki/Linux_PAM. Cette section parle de la tâche d'authentification.
Lorsque vous vous connectez à un serveur, que ce soit directement depuis la console ou via SSH, la porte par laquelle vous êtes passé enverra la demande à la tâche d'authentification de PAM, et PAM demandera et vérifiera votre mot de passe. Vous pouvez personnaliser les règles que chaque porte utilise. Par exemple, vous pourriez avoir un ensemble de règles pour la connexion directe depuis la console et un autre ensemble de règles pour la connexion via SSH.
Cette section modifiera les règles d'authentification pour la connexion via SSH afin d'exiger à la fois un mot de passe et un code à 6 chiffres.Nous utiliserons le module PAM libpam-google-authenticator de Google pour créer et vérifier une clé TOTP. https://fastmail.blog/2016/07/22/how-totp-authenticator-apps-work/ et https://jemurai.com/2018/10/11/how-it-works-totp-based-mfa/ proposent de très bonnes explications sur le fonctionnement de TOTP.
Ce que nous allons faire, c'est dire à la configuration PAM SSH du serveur de demander à l'utilisateur son mot de passe puis son jeton numérique. PAM vérifiera ensuite le mot de passe de l'utilisateur et, s'il est correct, il routra la demande d'authentification vers libpam-google-authenticator qui demandera et vérifiera votre code à 6 chiffres. Si, et seulement si, tout est bon, l'authentification réussira et l'utilisateur pourra se connecter.
Installez libpam-google-authenticator.
Sur les systèmes basés sur Debian :
sudo apt install libpam-google-authenticator
Assurez-vous d'être connecté avec l'identifiant pour lequel vous voulez activer la 2FA/MFA et exécutez google-authenticator pour créer les données de jeton nécessaires :
google-authenticator
Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/user@host%3Fsecret%3DR4ZWX34FQKZROVX7AGLJ64684Y%26issuer%3Dhost ... Your new secret key is: R3NVX3FFQKZROVX7AGLJUGGESY Your verification code is 751419 Your emergency scratch codes are: 12345678 90123456 78901234 56789012 34567890 Do you want me to update your "/home/user/.google_authenticator" file (y/n) y Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y By default, tokens are good for 30 seconds. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. If you experience problems with poor time synchronization, you can increase the window from its default size of +-1min (window size of 3) to about +-4min (window size of 17 acceptable tokens). Do you want to do so? (y/n) y If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting (y/n) y
sudo permet aux comptes d'exécuter des commandes en tant qu'autres comptes, y compris root. Nous voulons nous assurer que seuls les comptes que nous souhaitons peuvent utiliser sudo.
Debian crée le groupe sudo. Pour voir les utilisateurs qui font partie de ce groupe (donc qui ont les privilèges sudo) :
cat /etc/group | grep "sudo"
RedHat crée le groupe wheel
sudo ne nécessite pas de mot de passe. Merci à sbrl d'avoir partagé.Créez un groupe :
sudo groupadd sudousers
Ajoutez le(s) compte(s) au groupe :
sudo usermod -a -G sudousers user1
sudo usermod -a -G sudousers user2
sudo usermod -a -G sudousers ...
Vous devrez faire cela pour chaque compte sur votre serveur qui a besoin des privilèges sudo.
Faites une sauvegarde du fichier de configuration de sudo /etc/sudoers :
sudo cp --archive /etc/sudoers /etc/sudoers-COPY-$(date +"%Y%m%d%H%M%S")
Modifiez le fichier de configuration de sudo /etc/sudoers :
sudo visudo
Dites à sudo de n'autoriser que les utilisateurs du groupe sudousers à utiliser sudo en ajoutant cette ligne si elle n'est pas déjà présente :
%sudousers ALL=(ALL:ALL) ALL
su permet également aux comptes d'exécuter des commandes en tant qu'autres comptes, y compris root. Nous voulons nous assurer que seuls les comptes que nous souhaitons peuvent utiliser su.
Créez un groupe :
sudo groupadd suusers
Ajoutez le(s) compte(s) au groupe :
sudo usermod -a -G suusers user1
sudo usermod -a -G suusers user2
sudo usermod -a -G suusers ...
Vous devrez faire cela pour chaque compte sur votre serveur qui a besoin des privilèges su.
Faites en sorte que seuls les utilisateurs de ce groupe puissent exécuter /bin/su :
sudo dpkg-statoverride --update --add root suusers 4750 /bin/su
Il est nettement préférable, pour de nombreuses applications, de les exécuter dans un bac à sable.
Les navigateurs (encore plus les navigateurs propriétaires) et les clients de messagerie électronique sont fortement recommandés.
Installez le logiciel :
sudo apt install firejail firejail-profiles
Remarque : pour Debian 10 Stable, le backport officiel est recommandé :
sudo apt install -t buster-backports firejail firejail-profiles
Permettez à une application (installée dans /usr/bin ou /bin) de s'exécuter uniquement dans un bac à sable (voir quelques exemples ci-dessous) :
sudo ln -s /usr/bin/firejail /usr/local/bin/google-chrome-stable
sudo ln -s /usr/bin/firejail /usr/local/bin/firefox
sudo ln -s /usr/bin/firejail /usr/local/bin/chromium
sudo ln -s /usr/bin/firejail /usr/local/bin/evolution
sudo ln -s /usr/bin/firejail /usr/local/bin/thunderbird
Exécutez l'application comme d'habitude (via un terminal ou un lanceur) et vérifiez si elle s'exécute dans une prison :
firejail --list
Permettez à une application en bac à sable de s'exécuter à nouveau comme avant (exemple : firefox)
sudo rm /usr/local/bin/firefox
De nombreux protocoles de sécurité utilisent l'heure. Si l'heure de votre système est incorrecte, cela peut avoir un impact négatif sur votre serveur. Un client NTP peut résoudre ce problème en maintenant l'heure de votre système synchronisée avec les serveurs NTP mondiaux.
NTP signifie Network Time Protocol (protocole de temps réseau). Dans le cadre de ce guide, un client NTP sur le serveur est utilisé pour mettre à jour l'heure du serveur avec l'heure officielle provenant de serveurs officiels. Consultez https://www.pool.ntp.org/en/ pour tous les serveurs NTP publics.
Remarque : À partir de Debian 13 (Trixie), le paquet
ntpclassique a été supprimé. L'exécution desudo apt install ntpéchouera avec "Package ntp has no installation candidate". Puisque ce guide utilise NTP uniquement comme client (pour synchroniser l'horloge du serveur), l'approche recommandée sur Debian 13+ est d'utilisersystemd-timesyncd, qui est déjà préinstallé et ne nécessite aucun paquet supplémentaire. Voir les étapes pour Debian 13+ ci-dessous.
systemd-timesyncd est un client SNTP léger déjà inclus dans Debian. Contrairement au démon ntpd complet, il n'écoute sur aucun port, ce qui réduit la surface d'attaque. Pour les besoins de ce guide - maintenir l'horloge de votre serveur synchronisée - il suffit.
Activez la synchronisation NTP :
sudo timedatectl set-ntp true
Vérifiez que cela fonctionne :
timedatectl status
Vous devriez voir NTP service: active et System clock synchronized: yes dans la sortie.
Configurez des serveurs NTP de confiance. Faites une sauvegarde du fichier de configuration, puis modifiez-le :
sudo cp --archive /etc/systemd/timesyncd.conf /etc/systemd/timesyncd.conf-COPY-$(date +"%Y%m%d%H%M%S")
Modifiez /etc/systemd/timesyncd.conf et décommentez/définissez la section [Time] :
[Time]
NTP=pool.ntp.org
FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org
sudo sed -i -r -e "s/^#?NTP=.*$/NTP=pool.ntp.org # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
sudo sed -i -r -e "s/^#?FallbackNTP=.*$/FallbackNTP=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/systemd/timesyncd.conf
Remarque : Ces étapes s'appliquent uniquement à Debian 12 et antérieures. Sur Debian 13+, le paquet
ntpn'est plus disponible — utilisez plutôt les étapes systemd-timesyncd ci-dessus.
Installez ntp.
Sur les systèmes basés sur Debian :
sudo apt install ntp
Faites une sauvegarde du fichier de configuration du client NTP /etc/ntp.conf :
sudo cp --archive /etc/ntp.conf /etc/ntp.conf-COPY-$(date +"%Y%m%d%H%M%S")
La configuration par défaut, au moins sur Debian, est déjà assez sécurisée. La seule chose que nous voulons garantir est d'utiliser la directive pool et non les directives server. La directive pool permet au client NTP de cesser d'utiliser un serveur s'il ne répond pas ou fournit une heure erronée. Pour ce faire, commentez toutes les directives server et ajoutez ce qui suit à /etc/ntp.conf.
pool pool.ntp.org iburst
sudo sed -i -r -e "s/^((server|pool).*)/# \1 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/ntp.conf
echo -e "\npool pool.ntp.org iburst # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ntp.conf
Pour citer https://linux-audit.com/linux-system-hardening-adding-hidepid-to-proc/ :
En regardant dans
/proc, vous découvrirez de nombreux fichiers et répertoires. Beaucoup d'entre eux ne sont que des nombres, qui représentent les informations relatives à un identifiant de processus (PID) particulier. Par défaut, les systèmes Linux sont déployés pour permettre à tous les utilisateurs locaux de voir toutes ces informations. Cela inclut les informations de processus des autres utilisateurs. Cela pourrait inclure des détails sensibles que vous ne souhaitez peut-être pas partager avec d'autres utilisateurs. En appliquant quelques ajustements de configuration du système de fichiers, nous pouvons changer ce comportement et améliorer la sécurité du système.
Remarque : Cela peut ne pas fonctionner sur certains systèmes systemd. Veuillez consulter https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/37 pour plus d'informations. Merci à nlgranger d'avoir partagé.
/proc monté avec hidepid=2 afin que les utilisateurs ne puissent voir que les informations relatives à leurs propres processusFaites une sauvegarde de /etc/fstab :
sudo cp --archive /etc/fstab /etc/fstab-COPY-$(date +"%Y%m%d%H%M%S")
Ajoutez cette ligne à /etc/fstab pour que /proc soit monté avec hidepid=2 :
proc /proc proc defaults,hidepid=2 0 0
echo -e "\nproc /proc proc defaults,hidepid=2 0 0 # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/fstab
Redémarrez le système :
sudo reboot now
Remarque : Vous pouvez également remonter /proc sans redémarrer avec sudo mount -o remount,hidepid=2 /proc
Par défaut, les comptes peuvent utiliser n'importe quel mot de passe, y compris les mauvais. pwquality/pam_pwquality comble cette lacune de sécurité en fournissant "un moyen de configurer les exigences de qualité de mot de passe par défaut pour les mots de passe du système" et en vérifiant "sa force par rapport à un dictionnaire système et un ensemble de règles pour identifier les mauvais choix."
Sur Linux, PAM est responsable de l'authentification. Il existe quatre tâches pour PAM que vous pouvez lire sur https://en.wikipedia.org/wiki/Linux_PAM. Cette section traite de la tâche de mot de passe.Lorsqu'il est nécessaire de définir ou de changer un mot de passe de compte, la tâche de mot de passe de PAM gère la demande. Dans cette section, nous demanderons à la tâche de mot de passe de PAM de transmettre le nouveau mot de passe demandé à libpam-pwquality pour s'assurer qu'il répond à nos exigences. Si les exigences sont satisfaites, il est utilisé/défini ; s'il ne répond pas aux exigences, une erreur est générée et l'utilisateur en est informé.
Installer libpam-pwquality.
Sur les systèmes basés sur Debian :
sudo apt install libpam-pwquality
Faire une sauvegarde du fichier de configuration des mots de passe de PAM /etc/pam.d/common-password :
sudo cp --archive /etc/pam.d/common-password /etc/pam.d/common-password-COPY-$(date +"%Y%m%d%H%M%S")
Indiquer à PAM d'utiliser libpam-pwquality pour imposer des mots de passe forts en éditant le fichier /etc/pam.d/common-password et modifier la ligne qui commence comme ceci :
password requisite pam_pwquality.so
en ceci :
password requisite pam_pwquality.so retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec
Les options ci-dessus sont :
retry=3 = inviter l'utilisateur 3 fois avant de renvoyer une erreur.minlen=10 = la longueur minimale du mot de passe, en tenant compte des crédits (ou débits) de ceux-ci :
dcredit=-1 = doit contenir au moins Il est important de maintenir un serveur à jour avec les derniers correctifs de sécurité critiques et mises à jour. Sinon, vous risquez d'être exposé à des vulnérabilités de sécurité connues que des acteurs malveillants pourraient utiliser pour obtenir un accès non autorisé à votre serveur.
À moins que vous ne prévoyiez de vérifier votre serveur tous les jours, vous voudrez un moyen de mettre à jour automatiquement le système et/ou de recevoir des emails concernant les mises à jour disponibles.
Vous ne voulez pas faire toutes les mises à jour car chaque mise à jour comporte un risque de casse. Il est important de faire les mises à jour critiques, mais tout le reste peut attendre que vous ayez le temps de le faire manuellement.
Les mises à jour automatiques et non supervisées peuvent casser votre système et vous pourriez ne pas être à proximité de votre serveur pour le réparer. Cela serait particulièrement problématique si cela cassait votre accès SSH.
Sur les systèmes basés sur Debian, vous pouvez utiliser :
Nous utiliserons unattended-upgrades pour appliquer les correctifs de sécurité critiques. Nous pouvons également appliquer les mises à jour stables car elles ont déjà été minutieusement testées par la communauté Debian.
/etc/apt/apt.conf.d/50unattended-upgradesInstaller unattended-upgrades, apt-listchanges et apticron :
sudo apt install unattended-upgrades apt-listchanges apticron
Nous devons maintenant configurer unattended-upgrades pour appliquer automatiquement les mises à jour. Cela se fait généralement en éditant les fichiers /etc/apt/apt.conf.d/20auto-upgrades et /etc/apt/apt.conf.d/50unattended-upgrades créés par les paquets. Cependant, comme ces fichiers peuvent être écrasés lors d'une mise à jour future, nous allons plutôt créer un nouveau fichier. Créez le fichier /etc/apt/apt.conf.d/51myunattended-upgrades et ajoutez ceci :
// Enable the update/upgrade script (0=disable)
APT::Periodic::Enable "1";
// Do "apt-get update" automatically every n-days (0=disable)
APT::Periodic::Update-Package-Lists "1";
// Do "apt-get upgrade --download-only" every n-days (0=disable)
APT::Periodic::Download-Upgradeable-Packages "1";
// Do "apt-get autoclean" every n-days (0=disable)
APT::Periodic::AutocleanInterval "7";
// Send report mail to root
// 0: no report (or null string)
// 1: progress report (actually any string)
// 2: + command outputs (remove -qq, remove 2>/dev/null, add -d)
// 3: + trace on APT::Periodic::Verbose "2";
APT::Periodic::Unattended-Upgrade "1";
// Automatically upgrade packages from these
Unattended-Upgrade::Origins-Pattern {
"o=Debian,a=stable";
"o=Debian,a=stable-updates";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
};
// You can specify your own packages to NOT automatically upgrade here
Unattended-Upgrade::Package-Blacklist {
};
// Run dpkg --force-confold --configure -a if a unclean dpkg state is detected to true to ensure that updates get installed even when the system got interrupted during a previous run
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
//Perform the upgrade when the machine is running because we wont be shutting our server down often
Unattended-Upgrade::InstallOnShutdown "false";
// Send an email to this address with information about the packages upgraded.
Unattended-Upgrade::Mail "root";
// Always send an e-mail
Unattended-Upgrade::MailOnlyOnError "false";
// Remove all unused dependencies after the upgrade has finished
Unattended-Upgrade::Remove-Unused-Dependencies "true";
// Remove any new unused dependencies after the upgrade has finished
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// Automatically reboot WITHOUT CONFIRMATION if the file /var/run/reboot-required is found after the upgrade.
Unattended-Upgrade::Automatic-Reboot "true";
// Automatically reboot even if users are logged in.
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
WIP
WIP
WIP
Installer rng-tools.
Sur les systèmes basés sur Debian :
sudo apt-get install rng-tools
Nous devons maintenant définir le périphérique matériel utilisé pour générer des nombres aléatoires en ajoutant ceci à /etc/default/rng-tools :
HRNGDEVICE=/dev/urandom
echo "HRNGDEVICE=/dev/urandom" | sudo tee -a /etc/default/rng-tools
Redémarrer le service :
sudo systemctl stop rng-tools.service
sudo systemctl start rng-tools.service
Tester l'aléatoire :
Un outil intéressant pour ajouter une sécurité supplémentaire au mot de passe, contre les attaques physiques (en personne) méthodes de rançon/vol/agression.
pamduress ajoutera à l'utilisateur X un mot de passe secondaire (mot de passe de panique), lorsque ce mot de passe correspond, il lancera un script (ce script fait ce que vous voulez que l'utilisateur fasse lorsqu'il se connecte avec CE mot de passe de panique).
Exemple pratique & réel :
"Quelqu'un envahit une maison et vole le serveur (contenant des sauvegardes importantes d'entreprise, des souvenirs de vie, etc.). Il n'y a aucune cryptage de disque/démarrage. Le voleur démarre le serveur dans sa « zone sûre » et lance une attaque par force brute. Il a cassé le mot de passe local via SSH avec l'utilisateur sudoer admin avec succès, oui un mot de passe bidon, pas le Fort/principal. Il commence une session SSH/physique avec ce mot de passe bidon/de panique avec l'utilisateur sudoer admin. Il commence à sentir que le serveur semble trop occupé en moins de 2 minutes jusqu'à ce qu'il se fige... 'wtf!?! redémarrons et continuons à voler des infos'... désolé l'ami. toutes les données et le système ont été détruits."
Conclusion, le voleur a cracké le mot de passe bidon/panique/secondaire, et avec ce mot de passe, un script associé supprimera tous les fichiers, la configuration, le système, le démarrage, puis commencera à charger la RAM et le CPU pour forcer le voleur à redémarrer le système.
Empêcher une personne malveillante d'accéder aux informations du serveur lorsqu'elle obtient un mot de passe par la force (agression, arme, rançon, ...). Bien sûr, cela est utile dans d'autres situations.
cat > "$ScriptFile" <<-EOF #!/bin/bash sudo rm -rf /home
EOF ####################################################### } echo "Lets Config a PANIC PASSWORD ;)" && sleep 1 read -r -p "Want you REALLY configure A PANIC PASSWORD?? Write [ OK ] : " PAMDUR if [[ "$PAMDUR" = "OK" ]]; then echo "Lets Config a PANIC USER, PASSWORD and SCRIPT ;)" && sleep 1 while [ -z "$PANICUSR" ] do read -r -p "WRITE a Panic User to your pam-duress user [ root ]: " PANICUSR PANICUSR=${PANICUSR:=root} done if [ -z "$ScriptLoc" ]; then read -r -p "SET Script Directory with FULL PATH [ /root/.duress ]: " ScriptLoc ScriptLoc=${ScriptLoc:=/root/.duress} ScriptFile="$ScriptLoc/PanicScript.sh" fi else echo "NOT Use PAM DURESS aKa Panic Password!!! Bye" exit 1 fi
sudo apt install -y git build-essential libpam0g-dev libssl-dev
cd "$HOME" || exit 1 git clone https://github.com/nuvious/pam-duress.git cd pam-duress || exit 1 make sudo make install make clean #make uninstall
mkdir -p $ScriptLoc sudo mkdir -p /etc/duress.d myownscript duress_sign $ScriptFile chmod -R 500 $ScriptLoc chmod 400 $ScriptLoc/*.sha256 chown -R $PANICUSR $ScriptLoc
sudo cp --preserve /etc/pam.d/common-auth /etc/pam.d/common-auth.bck
echo " auth [success=2 default=ignore] pam_unix.so nullok_secure auth [success=1 default=ignore] pam_duress.so auth requisite pam_deny.so auth required pam_permit.so " | sudo tee /etc/pam.d/common-auth
read -r -p "Press Key to Finish PAM DURESS Script!" exit 0
([Table of Contents](#table-of-contents))
## Le Réseau
### Pare-feu avec UFW (Uncomplicated Firewall)
#### Pourquoi
Dites-moi paranoïaque, et vous n'êtes pas obligé d'être d'accord, mais je veux bloquer tout le trafic entrant et sortant de mon serveur, sauf ce que j'autorise explicitement. Pourquoi mon serveur enverrait-il du trafic sortant que je ne connais pas ? Et pourquoi du trafic externe essaierait-il d'accéder à mon serveur si je ne sais pas qui ou quoi c'est ? Quand il s'agit de bonne sécurité, mon opinion est de rejeter/bloquer par défaut et d'autoriser par exception.
Bien sûr, si vous n'êtes pas d'accord, c'est tout à fait acceptable et vous pouvez configurer UFW selon vos besoins.
Dans les deux cas, garantir que seul le trafic que nous autorisons explicitement passe est le rôle d'un pare-feu.
#### Comment ça marche
Le noyau Linux offre des capacités pour surveiller et contrôler le trafic réseau. Ces capacités sont exposées à l'utilisateur final via des utilitaires de pare-feu. Sous Linux, le pare-feu le plus courant est [iptables](https://en.wikipedia.org/wiki/Iptables). Cependant, iptables est plutôt compliqué et déroutant (à mon humble avis). C'est là qu'UFW intervient. Considérez UFW comme une interface frontale pour iptables. Il simplifie le processus de gestion des règles iptables qui indiquent au noyau Linux quoi faire avec le trafic réseau.
**UFW** fonctionne en vous permettant de configurer des règles qui :
- **autorisent** ou **bloquent**
- le trafic **entrant** ou **sortant**
- **vers** ou **depuis** des ports
Vous pouvez créer des règles en spécifiant explicitement les ports ou avec des configurations d'application qui spécifient les ports.
#### Objectifs
- tout le trafic réseau, entrant et sortant, bloqué sauf ceux que nous autorisons explicitement
#### Remarques
- Au fur et à mesure que vous installez d'autres programmes, vous devrez activer les ports/applications nécessaires.
#### Références
- https://launchpad.net/ufw
#### Étapes
1. Installez ufw.
Sur les systèmes basés sur Debian :
``` bash
sudo apt install ufw
```
1. Bloquez tout le trafic sortant :
``` bash
sudo ufw default deny outgoing comment 'deny all outgoing traffic'
```
> ```
> Default outgoing policy changed to 'deny'
> (be sure to update your rules accordingly)
> ```
Si vous n'êtes pas aussi paranoïaque que moi et ne voulez pas bloquer tout le trafic sortant, vous pouvez l'autoriser à la place :
``` bash
sudo ufw default allow outgoing comment 'allow all outgoing traffic'
```
1. Bloquez tout le trafic entrant :
``` bash
sudo ufw default deny incoming comment 'deny all incoming traffic'
```
1. Évidemment, nous voulons autoriser les connexions SSH entrantes. L'utilisation de `limit` au lieu de `allow` bloquera automatiquement les connexions d'une adresse IP si elle tente d'initier 6 connexions ou plus dans une fenêtre de 30 secondes :
``` bash
sudo ufw limit in ssh comment 'allow SSH connections in'
```
> ```
> Rules updated
> Rules updated (v6)
> ```
1. Autorisez le trafic supplémentaire selon vos besoins. Quelques cas d'usage courants :
``` bash
# allow traffic out to port 53 -- DNS
sudo ufw allow out 53 comment 'allow DNS calls out'
# allow traffic out to port 123 -- NTP
sudo ufw allow out 123 comment 'allow NTP out'
# allow traffic out for HTTP, HTTPS, or FTP
# apt might needs these depending on which sources you're using
sudo ufw allow out http comment 'allow HTTP traffic out'
sudo ufw allow out https comment 'allow HTTPS traffic out'
sudo ufw allow out ftp comment 'allow FTP traffic out'
# allow whois
sudo ufw allow out whois comment 'allow whois'
# allow mails for status notifications -- choose port according to your provider
sudo ufw allow out 25 comment 'allow SMTP out'
sudo ufw allow out 587 comment 'allow SMTP out'
# allow traffic out to port 68 -- the DHCP client
# you only need this if you're using DHCP
sudo ufw allow out 67 comment 'allow the DHCP client to update'
sudo ufw allow out 68 comment 'allow the DHCP client to update'
```
**Remarque :** Vous devrez autoriser HTTP/HTTPS pour installer des paquets et beaucoup d'autres choses.
1. Démarrez ufw :
``` bash
sudo ufw enable
```
> ```
> Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
> Firewall is active and enabled on system startup
> ```
1. Si vous voulez voir le statut :
``` bash
sudo ufw status
```
> ```
> Status: active
>
> To Action From
> -- ------ ----
> 22/tcp LIMIT Anywhere # allow SSH connections in
> 22/tcp (v6) LIMIT Anywhere (v6) # allow SSH connections in
>
> 53 ALLOW OUT Anywhere # allow DNS calls out
> 123 ALLOW OUT Anywhere # allow NTP out
> 80/tcp ALLOW OUT Anywhere # allow HTTP traffic out
> 443/tcp ALLOW OUT Anywhere # allow HTTPS traffic out
> 21/tcp ALLOW OUT Anywhere # allow FTP traffic out
> Mail submission ALLOW OUT Anywhere # allow mail out
> 43/tcp ALLOW OUT Anywhere # allow whois
> 53 (v6) ALLOW OUT Anywhere (v6) # allow DNS calls out
> 123 (v6) ALLOW OUT Anywhere (v6) # allow NTP out
> 80/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTP traffic out
> 443/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTPS traffic out
> 21/tcp (v6) ALLOW OUT Anywhere (v6) # allow FTP traffic out
> Mail submission (v6) ALLOW OUT Anywhere (v6) # allow mail out
> 43/tcp (v6) ALLOW OUT Anywhere (v6) # allow whois
> ```
ou
``` bash
sudo ufw status verbose
```
> ```
> Status: active
> Logging: on (low)
> Default: deny (incoming), deny (outgoing), disabled (routed)
> New profiles: skip
>
> To Action From
> -- ------ ----
> 22/tcp LIMIT IN Anywhere # allow SSH connections in
> 22/tcp (v6) LIMIT IN Anywhere (v6) # allow SSH connections in
>
> 53 ALLOW OUT Anywhere # allow DNS calls out
> 123 ALLOW OUT Anywhere # allow NTP out
> 80/tcp ALLOW OUT Anywhere # allow HTTP traffic out
> 443/tcp ALLOW OUT Anywhere # allow HTTPS traffic out
> 21/tcp ALLOW OUT Anywhere # allow FTP traffic out
> 587/tcp (Mail submission) ALLOW OUT Anywhere # allow mail out
> 43/tcp ALLOW OUT Anywhere # allow whois
> 53 (v6) ALLOW OUT Anywhere (v6) # allow DNS calls out
> 123 (v6) ALLOW OUT Anywhere (v6) # allow NTP out
> 80/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTP traffic out
> 443/tcp (v6) ALLOW OUT Anywhere (v6) # allow HTTPS traffic out
> 21/tcp (v6) ALLOW OUT Anywhere (v6) # allow FTP traffic out
> 587/tcp (Mail submission (v6)) ALLOW OUT Anywhere (v6) # allow mail out
> 43/tcp (v6) ALLOW OUT Anywhere (v6) # allow whois
> ```
7. Si vous devez supprimer une règle
``` bash
sudo ufw status numbered
[...]
sudo ufw delete 3 #line number of the rule you want to delete
```
#### Applications par défaut
ufw est livré avec quelques applications par défaut. Vous pouvez les voir avec :``` bash
sudo ufw app list
```
> ```
> Available applications:
> AIM
> Bonjour
> CIFS
> DNS
> Deluge
> IMAP
> IMAPS
> IPP
> KTorrent
> Kerberos Admin
> Kerberos Full
> Kerberos KDC
> Kerberos Password
> LDAP
> LDAPS
> LPD
> MSN
> MSN SSL
> Mail submission
> NFS
> OpenSSH
> POP3
> POP3S
> PeopleNearby
> SMTP
> SSH
> Socks
> Telnet
> Transmission
> Transparent Proxy
> VNC
> WWW
> WWW Cache
> WWW Full
> WWW Secure
> XMPP
> Yahoo
> qBittorrent
> svnserve
> ```
Pour obtenir des détails sur l'application, comme les ports qu'elle inclut, tapez :``` bash
sudo ufw app info [app name]
```
> ``` bash
> sudo ufw app info DNS
> ```
>
> ```
> Profile: DNS
> Title: Internet Domain Name Server
> Description: Internet Domain Name Server
>
> Port:
> 53
> ```
>
> #### Application personnalisée
>
> Si vous ne souhaitez pas créer de règles en fournissant explicitement le(s) numéro(s) de port, vous pouvez créer vos propres configurations d'application. Pour cela, créez un fichier dans `/etc/ufw/applications.d`.
>
> Par exemple, voici ce que vous utiliseriez pour [Plex](https://support.plex.tv/articles/201543147-what-network-ports-do-i-need-to-allow-through-my-firewall/) :``` bash
cat /etc/ufw/applications.d/plexmediaserver
```
> ```
> [PlexMediaServer]
> title=Plex Media Server
> description=This opens up PlexMediaServer for http (32400), upnp, and autodiscovery.
> ports=32469/tcp|32413/udp|1900/udp|32400/tcp|32412/udp|32410/udp|32414/udp|32400/udp
> ```
Vous pouvez ensuite l'activer comme n'importe quelle autre application :```bash
sudo ufw allow plexmediaserver
```
([Table of Contents](#table-of-contents))
### Détection et prévention des intrusions avec iptables et PSAD
#### Pourquoi
Même si vous avez un pare-feu pour garder vos portes, il est possible de tenter de forcer l'entrée par l'une d'elles. Nous voulons surveiller toute l'activité réseau pour détecter les tentatives d'intrusion potentielles, comme les tentatives répétées d'accès, et les bloquer.
#### Comment ça marche
Je ne peux pas mieux l'expliquer que l'utilisateur [FINESEC](https://serverfault.com/users/143961/finesec) de https://serverfault.com/ ne l'a fait sur : https://serverfault.com/a/447604/289829.
> Fail2BAN analyse les fichiers journaux de diverses applications telles qu'Apache, SSH ou FTP et bannit automatiquement les adresses IP présentant des signes malveillants comme des tentatives de connexion automatisées. PSAD, de son côté, analyse les messages des journaux iptables et ip6tables (généralement /var/log/messages) pour détecter et éventuellement bloquer les scans et autres trafics suspects comme les tentatives de déni de service distribué (DDoS) ou d'identification du système d'exploitation. Il est acceptable d'utiliser les deux programmes simultanément car ils opèrent à des niveaux différents.
Et, comme nous utilisons déjà [UFW](#ufw-uncomplicated-firewall), nous suivrons les excellentes instructions de [netson](https://gist.github.com/netson) sur https://gist.github.com/netson/c45b2dc4e835761fbccc pour faire fonctionner PSAD avec UFW.
#### Références
- http://www.cipherdyne.org/psad/
- http://www.cipherdyne.org/psad/docs/config.html
- https://www.thefanclub.co.za/how-to/how-install-psad-intrusion-detection-ubuntu-1204-lts-server
- https://serverfault.com/a/447604/289829
- https://serverfault.com/a/770424/289829
- https://gist.github.com/netson/c45b2dc4e835761fbccc
- Merci à [moltenbit](https://github.com/moltenbit) d'avoir signalé le problème ([#61](https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/61)) lié à `psadwatchd`.
#### Étapes
1. Installez psad.
Sur les systèmes basés sur Debian :
``` bash
sudo apt install psad
```
1. Faites une sauvegarde du fichier de configuration de psad `/etc/psad/psad.conf` :
``` bash
sudo cp --archive /etc/psad/psad.conf /etc/psad/psad.conf-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Vérifiez et mettez à jour les options de configuration dans `/etc/psad/psad.conf`. Portez une attention particulière à celles-ci :
|Paramètre|Définir sur
|--|--|
|[`EMAIL_ADDRESSES`](http://www.cipherdyne.org/psad/docs/config.html#EMAIL_ADDRESSES)|votre ou vos adresse(s) e-mail|
|`HOSTNAME`|le nom d'hôte de votre serveur|
|`EXPECT_TCP_OPTIONS`|`EXPECT_TCP_OPTIONS Y;`|
|`ENABLE_PSADWATCHD`|`ENABLE_PSADWATCHD Y;`|
|[`ENABLE_AUTO_IDS`](http://www.cipherdyne.org/psad/docs/config.html#ENABLE_AUTO_IDS)|`ENABLE_AUTO_IDS Y;`|
|`ENABLE_AUTO_IDS_EMAILS`|`ENABLE_AUTO_IDS_EMAILS Y;`|
Consultez le fichier de configuration et la documentation de psad sur http://www.cipherdyne.org/psad/docs/config.html pour plus de détails.
1. <a name="psad_step4"></a>Nous devons maintenant apporter quelques modifications à ufw pour qu'il fonctionne avec psad, en demandant à ufw de journaliser tout le trafic afin que psad puisse l'analyser. Pour cela, modifiez **deux fichiers** et ajoutez ces lignes **à la fin, mais avant la ligne COMMIT**.
Faites des sauvegardes :
``` bash
sudo cp --archive /etc/ufw/before.rules /etc/ufw/before.rules-COPY-$(date +"%Y%m%d%H%M%S")
sudo cp --archive /etc/ufw/before6.rules /etc/ufw/before6.rules-COPY-$(date +"%Y%m%d%H%M%S")
```
Modifiez les fichiers :
- `/etc/ufw/before.rules`
- `/etc/ufw/before6.rules`
Et ajoutez ceci **à la fin mais avant la ligne COMMIT** :
```
# log all traffic so psad can analyze
-A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
-A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
```
**Remarque** : Nous ajoutons un préfixe de journalisation à tous les logs iptables. Cela nous sera utile pour [séparer les logs iptables dans leur propre fichier](#separate-iptables-log-file).
Par exemple :
> ```
> ...
>
> # log all traffic so psad can analyze
> -A INPUT -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
> -A FORWARD -j LOG --log-tcp-options --log-prefix "[IPTABLES] "
>
> # don't delete the 'COMMIT' line or these rules won't be processed
> COMMIT
> ```
1. Nous devons maintenant recharger/redémarrer ufw et psad pour que les changements prennent effet :
``` bash
sudo ufw reload
sudo psad -R
sudo psad --sig-update
sudo psad -H
```
1. Analysez les règles iptables pour détecter les erreurs :
``` bash
sudo psad --fw-analyze
```
> ```
> [+] Parsing INPUT chain rules.
> [+] Parsing INPUT chain rules.
> [+] Firewall config looks good.
> [+] Completed check of firewall ruleset.
> [+] Results in /var/log/psad/fw_check
> [+] Exiting.
> ```
**Remarque** : En cas de problème, vous recevrez un e-mail avec l'erreur.
1. Vérifiez l'état de psad :
``` bash
sudo psad --Status
```
> ```
> [-] psad: pid file /var/run/psad/psadwatchd.pid does not exist for psadwatchd on vm
> [+] psad_fw_read (pid: 3444) %CPU: 0.0 %MEM: 2.2
> Running since: Sat Feb 16 01:03:09 2019
>
> [+] psad (pid: 3435) %CPU: 0.2 %MEM: 2.7
> Running since: Sat Feb 16 01:03:09 2019
> Command line arguments: [none specified]
> Alert email address(es): root@localhost
>
> [+] Version: psad v2.4.3
>
> [+] Top 50 signature matches:
> [NONE]
>
> [+] Top 25 attackers:
> [NONE]
>
> [+] Top 20 scanned ports:
> [NONE]
>
> [+] iptables log prefix counters:
> [NONE]
>
> Total protocol packet counters:
>
> [+] IP Status Detail:
> [NONE]
>
> Total scan sources: 0
> Total scan destinations: 0
>
> [+] These results are available in: /var/log/psad/status.out
> ```
([Table of Contents](#table-of-contents))
### Détection et prévention des intrusions applicatives avec Fail2Ban
#### Pourquoi
UFW indique à votre serveur quelles portes condamner pour que personne ne puisse les voir, et quelles portes autoriser aux utilisateurs légitimes. PSAD surveille l'activité réseau pour détecter et prévenir les intrusions potentielles — les tentatives répétées d'accès.
Mais qu'en est-il des applications/services que votre serveur exécute, comme SSH et Apache, pour lesquels votre pare-feu est configuré pour autoriser l'accès ? Même si l'accès est autorisé, cela ne signifie pas que toutes les tentatives d'accès sont valides et inoffensives. Que faire si quelqu'un tente de forcer l'accès à une application web que vous hébergez sur votre serveur ? C'est là que Fail2ban intervient.
#### Comment ça marche
Fail2ban surveille les journaux de vos applications (comme SSH et Apache) pour détecter et prévenir les intrusions potentielles. Il surveille le trafic réseau/les journaux et empêche les intrusions en bloquant les activités suspectes (par exemple, plusieurs échecs de connexion successifs dans un court laps de temps).
#### Objectifs
- Surveillance réseau des activités suspectes avec bannissement automatique des adresses IP incriminées
#### Remarques
- Pour l'instant, le seul service tournant sur ce serveur est SSH, nous voulons donc que Fail2ban surveille SSH et bannisse si nécessaire.
- Au fur et à mesure que vous installerez d'autres programmes, vous devrez créer/configurer les prisons appropriées et les activer.
#### Références
- https://www.fail2ban.org/
- https://blog.vigilcode.com/2011/05/ufw-with-fail2ban-quick-secure-setup-part-ii/
- https://dodwell.us/security/ufw-fail2ban-portscan.html
- https://www.howtoforge.com/community/threads/fail2ban-and-ufw-on-debian.77261/
#### Étapes
1. Installez fail2ban.
Sur les systèmes basés sur Debian :
``` bash
sudo apt install fail2ban
```
1. Nous ne voulons pas modifier `/etc/fail2ban/fail2ban.conf` ou `/etc/fail2ban/jail.conf` car une future mise à jour pourrait les écraser ; nous allons donc créer une copie locale à la place. Créez le fichier `/etc/fail2ban/jail.local` et ajoutez-y ceci après avoir remplacé `[LAN SEGMENT]` et `[votre e-mail]` par les valeurs appropriées :
```
[DEFAULT]
# the IP address range we want to ignore
ignoreip = 127.0.0.1/8 [LAN SEGMENT]
# who to send e-mail to
destemail = [votre e-mail]
# who is the email from
sender = [votre e-mail]
# since we're using exim4 to send emails
mta = mail
# get email alerts
action = %(action_mwl)s
```
**Remarque** : Votre serveur doit être capable d'envoyer des e-mails pour que Fail2ban puisse vous informer des activités suspectes et lorsqu'il a banni une adresse IP.
1. Nous devons créer une prison pour SSH qui indique à fail2ban de surveiller les journaux SSH et d'utiliser ufw pour bannir/débannir les IP si nécessaire. Créez une prison pour SSH en créant le fichier `/etc/fail2ban/jail.d/ssh.local` et en y ajoutant ceci :
```
[sshd]
enabled = true
banaction = ufw
port = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 5
```
[Pour les paresseux](#editing-configuration-files---for-the-lazy) :
``` bash
cat << EOF | sudo tee /etc/fail2ban/jail.d/ssh.local
[sshd]
enabled = true
banaction = ufw
port = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 5
EOF
```
1. Dans ce qui précède, nous indiquons à fail2ban d'utiliser ufw comme `banaction`. Fail2ban est livré avec un fichier de configuration d'action pour ufw. Vous pouvez le trouver dans `/etc/fail2ban/action.d/ufw.conf`.
1. Activez fail2ban :
``` bash
sudo fail2ban-client start
sudo fail2ban-client reload
sudo fail2ban-client add sshd # Cela peut échouer sur certains systèmes si la prison sshd a été ajoutée par défaut
```
1. Pour vérifier l'état :
``` bash
sudo fail2ban-client status
```
> ```
> Status
> |- Number of jail: 1
> `- Jail list: sshd
> ```
``` bash
sudo fail2ban-client status sshd
```
> ```
> Status for the jail: sshd
> |- Filter
> | |- Currently failed: 0
> | |- Total failed: 0
> | `- File list: /var/log/auth.log
> `- Actions
> |- Currently banned: 0
> |- Total banned: 0
> `- Banned IP list:
> ```
#### Prisons personnalisées
Je n'ai pas encore eu besoin de créer une prison personnalisée. Une fois que ce sera le cas et que j'aurai compris comment faire, j'actualiserai ce guide. Ou, si vous savez comment faire, n'hésitez pas à [contribuer](#contributing).
#### Débannir une IP
Pour débannir une IP, utilisez cette commande :
`````` bash
fail2ban-client set [jail] unbanip [IP]
```
`[jail]` est le nom du jail qui contient l'adresse IP bannie et `[IP]` est l'adresse IP que vous souhaitez débannir. Par exemple, pour débannir `192.168.1.100` de SSH vous feriez :``` bash
fail2ban-client set sshd unbanip 192.168.1.100
```
([Table of Contents](#table-of-contents))
### Détection et prévention d'intrusion applicative avec CrowdSec
#### Pourquoi
UFW indique à votre serveur quelles portes condamner pour que personne ne puisse les voir, et quelles portes autoriser aux utilisateurs légitimes. PSAD surveille l'activité réseau pour détecter et prévenir les tentatives d'intrusion – les tentatives répétées d'entrée.
CrowdSec est similaire à Fail2Ban en ce qu'il surveille les journaux de vos applications (comme SSH et Apache) pour détecter et prévenir les tentatives d'intrusion. Cependant, CrowdSec est couplé à une communauté qui partage des renseignements sur les menaces avec CrowdSec, qui à son tour distribue une liste de blocage communautaire à tous les utilisateurs.
#### Comment ça fonctionne
CrowdSec surveille les journaux de vos applications (comme SSH et Apache) pour détecter et prévenir les tentatives d'intrusion. Il surveille le trafic réseau / les journaux et empêche les intrusions en bloquant les activités suspectes (par exemple, plusieurs échecs de connexion successifs dans un court laps de temps). Une fois qu'une adresse IP malveillante est détectée, elle est ajoutée à votre liste de décision locale et les informations sur la menace sont partagées avec CrowdSec pour mettre à jour la liste de blocage communautaire des adresses IP malveillantes. Lorsqu'une adresse IP atteint un certain seuil d'activité malveillante, elle est automatiquement propagée à tous les autres utilisateurs de CrowdSec pour un blocage proactif.
#### Objectifs
- surveillance réseau des activités suspectes avec bannissement automatique des IP incriminées
#### Remarques
- Pour l'instant, seul SSH fonctionne sur ce serveur, nous voulons donc que CrowdSec surveille SSH et bannisse si nécessaire.
- Au fur et à mesure que vous installez d'autres programmes, vous devrez installer des collections supplémentaires et configurer les acquisitions appropriées.
#### Références
- https://www.crowdsec.net/
- [Lisez comment CrowdSec gère la liste de blocage communautaire](https://www.crowdsec.net/our-data)
- [Lisez quelles informations sur les menaces sont partagées avec CrowdSec](https://docs.crowdsec.net/docs/next/central_api/intro#signal-meta-data)
- https://docs.crowdsec.net/
#### Étapes
1. Installer le moteur de sécurité CrowdSec. (IDS)
Sur toute distribution Linux (y compris les systèmes basés sur Debian)
Installez le dépôt CrowdSec :
``` bash
curl -s https://install.crowdsec.net | sudo sh
```
Installez le moteur de sécurité CrowdSec :
``` bash
sudo apt install crowdsec
```
> [!TIP]
> si `curl | sh` n'est pas votre tasse de thé, vous trouverez d'autres méthodes d'installation [ici](https://docs.crowdsec.net/u/getting_started/installation/linux).
Par défaut, lors de l'installation du moteur de sécurité, CrowdSec découvre automatiquement vos applications installées et installe les parseurs et scénarios appropriés. Comme nous savons que la plupart des serveurs Linux exécutent SSH dès le départ, CrowdSec le configurera automatiquement pour vous.
2. Installer un composant de remédiation. (IPS)
CrowdSec lui-même est un moteur de détection ; comme dans la plupart des infrastructures modernes, vous pouvez avoir un pare-feu ou un WAF en amont, CrowdSec ne bloquera pas lui-même les adresses IP. Vous pouvez installer un composant de remédiation pour bloquer les adresses IP détectées par CrowdSec.
```bash
sudo apt install crowdsec-firewall-bouncer-iptables
```
> [!TIP]
> Si votre installation d'UFW n'utilise pas `iptables` comme backend, vous pouvez alternativement installer `crowdsec-firewall-bouncer-nftables`. Il n'y a pas de différence dans les binaires installés, seul le fichier de configuration diffère.
Par défaut, lors de l'installation du composant de remédiation, celui-ci configure automatiquement les paramètres nécessaires pour fonctionner avec le moteur de sécurité s'il est déployé sur la même machine (et si le moteur de sécurité n'est pas dans un environnement conteneurisé).
3. Vérifier que la détection et la remédiation fonctionnent comme prévu :
Le paquet CrowdSec inclut un outil en ligne de commande pour vérifier l'état du moteur de sécurité et du composant de remédiation.
```bash
sudo cscli metrics
```
```bash
Acquisition Metrics:
╭────────────────────────┬────────────┬──────────────┬────────────────┬────────────────────────┬───────────────────╮
│ Source │ Lines read │ Lines parsed │ Lines unparsed │ Lines poured to bucket │ Lines whitelisted │
├────────────────────────┼────────────┼──────────────┼────────────────┼────────────────────────┼───────────────────┤
│ file:/var/log/auth.log │ 5 │ 4 │ 1 │ 10 │ - │
│ file:/var/log/syslog │ 30 │ - │ 30 │ - │ - │
╰────────────────────────┴────────────┴──────────────┴────────────────┴────────────────────────┴───────────────────╯
Local API Decisions:
╭────────────────────────────────────────────┬────────┬────────┬───────╮
│ Reason │ Origin │ Action │ Count │
├────────────────────────────────────────────┼────────┼────────┼───────┤
│ crowdsecurity/http-backdoors-attempts │ CAPI │ ban │ 73 │
│ crowdsecurity/http-bad-user-agent │ CAPI │ ban │ 4836 │
│ crowdsecurity/http-path-traversal-probing │ CAPI │ ban │ 87 │
│ crowdsecurity/http-probing │ CAPI │ ban │ 2010 │
│ crowdsecurity/thinkphp-cve-2018-20062 │ CAPI │ ban │ 88 │
│ crowdsecurity/CVE-2019-18935 │ CAPI │ ban │ 7 │
│ crowdsecurity/CVE-2023-49103 │ CAPI │ ban │ 5 │
│ crowdsecurity/http-admin-interface-probing │ CAPI │ ban │ 91 │
│ ltsich/http-w00tw00t │ CAPI │ ban │ 3 │
│ crowdsecurity/apache_log4j2_cve-2021-44228 │ CAPI │ ban │ 18 │
│ crowdsecurity/nginx-req-limit-exceeded │ CAPI │ ban │ 280 │
│ crowdsecurity/ssh-slow-bf │ CAPI │ ban │ 3412 │
│ crowdsecurity/spring4shell_cve-2022-22965 │ CAPI │ ban │ 1 │
│ crowdsecurity/ssh-cve-2024-6387 │ CAPI │ ban │ 24 │
│ crowdsecurity/CVE-2023-22515 │ CAPI │ ban │ 2 │
│ crowdsecurity/http-cve-2021-41773 │ CAPI │ ban │ 172 │
│ crowdsecurity/netgear_rce │ CAPI │ ban │ 14 │
│ crowdsecurity/ssh-bf │ CAPI │ ban │ 2000 │
│ crowdsecurity/CVE-2022-35914 │ CAPI │ ban │ 1 │
│ crowdsecurity/http-cve-2021-42013 │ CAPI │ ban │ 2 │
│ crowdsecurity/jira_cve-2021-26086 │ CAPI │ ban │ 9 │
│ crowdsecurity/http-sensitive-files │ CAPI │ ban │ 166 │
│ crowdsecurity/http-wordpress-scan │ CAPI │ ban │ 272 │
│ crowdsecurity/CVE-2022-26134 │ CAPI │ ban │ 5 │
│ crowdsecurity/http-generic-bf │ CAPI │ ban │ 7 │
│ crowdsecurity/http-open-proxy │ CAPI │ ban │ 948 │
│ crowdsecurity/http-crawl-non_statics │ CAPI │ ban │ 339 │
│ crowdsecurity/http-cve-probing │ CAPI │ ban │ 5 │
│ crowdsecurity/CVE-2017-9841 │ CAPI │ ban │ 117 │
│ crowdsecurity/CVE-2022-37042 │ CAPI │ ban │ 1 │
│ crowdsecurity/fortinet-cve-2018-13379 │ CAPI │ ban │ 5 │
╰────────────────────────────────────────────┴────────┴────────┴───────╯
Local API Metrics:
╭──────────────────────┬────────┬──────╮
│ Route │ Method │ Hits │
├──────────────────────┼────────┼──────┤
│ /v1/alerts │ GET │ 2 │
│ /v1/decisions/stream │ GET │ 5 │
│ /v1/usage-metrics │ POST │ 2 │
│ /v1/watchers/login │ POST │ 4 │
╰──────────────────────┴────────┴──────╯
Local API Bouncers Metrics:
╭────────────────────────────────┬──────────────────────┬────────┬──────╮
│ Bouncer │ Route │ Method │ Hits │
├────────────────────────────────┼──────────────────────┼────────┼──────┤
│ cs-firewall-bouncer-1729025592 │ /v1/decisions/stream │ GET │ 5 │
╰────────────────────────────────┴──────────────────────┴────────┴──────╯
Local API Machines Metrics:
╭──────────────────────────────────────────────────┬────────────┬────────┬──────╮
│ Machine │ Route │ Method │ Hits │
├──────────────────────────────────────────────────┼────────────┼────────┼──────┤
│ <your_machine_id_will_be_here> │ /v1/alerts │ GET │ 2 │
╰──────────────────────────────────────────────────┴────────────┴────────┴──────╯
Parser Metrics:
╭─────────────────────────────────┬──────┬────────┬──────────╮
│ Parsers │ Hits │ Parsed │ Unparsed │
├─────────────────────────────────┼──────┼────────┼──────────┤
│ child-crowdsecurity/sshd-logs │ 41 │ 4 │ 37 │
│ child-crowdsecurity/syslog-logs │ 35 │ 35 │ - │
│ crowdsecurity/dateparse-enrich │ 4 │ 4 │ - │
│ crowdsecurity/sshd-logs │ 5 │ 4 │ 1 │
│ crowdsecurity/syslog-logs │ 35 │ 35 │ - │
╰─────────────────────────────────┴──────┴────────┴──────────╯
Scenario Metrics:
╭─────────────────────────────────────┬───────────────┬───────────┬──────────────┬────────┬─────────╮
│ Scenario │ Current Count │ Overflows │ Instantiated │ Poured │ Expired │
├─────────────────────────────────────┼───────────────┼───────────┼──────────────┼────────┼─────────┤
│ crowdsecurity/ssh-bf │ 1 │ - │ 1 │ 4 │ - │
│ crowdsecurity/ssh-bf_user-enum │ 1 │ - │ 1 │ 1 │ - │
│ crowdsecurity/ssh-slow-bf │ 1 │ - │ 1 │ 4 │ - │
│ crowdsecurity/ssh-slow-bf_user-enum │ 1 │ - │ 1 │ 1 │ - │
╰─────────────────────────────────────┴───────────────┴───────────┴──────────────┴────────┴─────────╯
```
La sortie ci-dessus peut être intimidante, mais c'est un bon moyen de vérifier que le moteur de sécurité lit les journaux et que le composant de remédiation bloque les adresses IP. Voici un décryptage rapide de chaque section :
- **Acquisition Metrics** : Cette section montre les journaux que le moteur de sécurité lit et analyse. Si vous voyez des entrées dans la colonne `Lines unparsed`, cela signifie que le moteur de sécurité n'arrive pas à analyser les journaux. Cela peut être dû à une mauvaise configuration ou au fait que les journaux ne sont pas au format attendu.
- **Local API Decisions** : Cette section montre les décisions que le moteur de sécurité a dans sa base de données. Si vous voyez des entrées dans la colonne `Count`, cela signifie que le moteur de sécurité a détecté une activité malveillante et a bloqué l'adresse IP.
- Origin : indique d'où vient la décision. Dans ce cas, elle provient de l'API centrale (CAPI).
- **Local API Metrics** : Cette section montre le nombre de requêtes à l'API locale. C'est l'API que le moteur de sécurité utilise pour communiquer avec le composant de remédiation.
- **Local API Bouncers Metrics** : Cette section montre le nombre de requêtes à l'API locale par le composant de remédiation.
- **Local API Machines Metrics** : Cette section montre le nombre de requêtes à l'API locale par le moteur de sécurité (si vous exécutez plusieurs moteurs de sécurité dans une configuration centralisée, vous pouvez voir plusieurs identifiants ici).
- **Parser Metrics** : Cette section montre les parseurs utilisés par le moteur de sécurité. Si vous voyez des entrées dans la colonne `Unparsed`, cela signifie que le moteur de sécurité n'arrive pas à analyser les journaux. Cela peut être dû à une mauvaise configuration ou au fait que les journaux ne sont pas au format attendu.
- **Scenario Metrics** : Cette section montre les scénarios utilisés par le moteur de sécurité. Si vous voyez des entrées dans la colonne `Current Count`, cela signifie que le moteur de sécurité a détecté une activité malveillante et suit l'adresse IP.
#### Débannir une IP
Pour débannir une IP, utilisez cette commande :
```bash
sudo cscli decisions delete --ip <adresse_ip>
`````` bash
cscli decisions delete --ip [IP]
```
`[IP]` est l'adresse IP que vous souhaitez débloquer. Par exemple, pour débloquer `192.168.1.100` de SSH vous feriez :``` bash
cscli decisions delete --ip 192.168.1.100
```
## L'audit
### Surveillance de l'intégrité des fichiers/dossiers avec AIDE (WIP)
#### Pourquoi
WIP
#### Comment ça fonctionne
WIP
#### Objectifs
WIP
#### Références
- https://aide.github.io/
- https://www.hiroom2.com/2017/06/09/debian-8-file-integrity-check-with-aide/
- https://blog.rapid7.com/2017/06/30/how-to-install-and-configure-aide-on-ubuntu-linux/
- https://www.stephenrlang.com/2016/03/using-aide-for-file-integrity-monitoring-fim-on-ubuntu/
- https://www.howtoforge.com/how-to-configure-the-aide-advanced-intrusion-detection-environment-file-integrity-scanner-for-your-website
- https://www.tecmint.com/check-integrity-of-file-and-directory-using-aide-in-linux/
- https://www.cyberciti.biz/faq/debian-ubuntu-linux-software-integrity-checking-with-aide/
- https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/83
#### Étapes
1. Installer AIDE.
Sur les systèmes basés sur Debian :
``` bash
sudo apt install aide aide-common
```
1. Faire une sauvegarde du fichier de valeurs par défaut d'AIDE :
``` bash
sudo cp -p /etc/default/aide /etc/default/aide-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Parcourez `/etc/default/aide` et définissez les valeurs par défaut d'AIDE selon vos besoins. Si vous souhaitez qu'AIDE s'exécute quotidiennement et vous envoie un e-mail, assurez-vous de définir `CRON_DAILY_RUN` sur `yes`.
1. Faire une sauvegarde des fichiers de configuration d'AIDE :
``` bash
sudo cp -pr /etc/aide /etc/aide-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Sur les systèmes basés sur Debian :
- Les fichiers de configuration d'AIDE se trouvent dans `/etc/aide/aide.conf.d/`.
- Vous devrez parcourir la documentation d'AIDE et les fichiers de configuration pour les définir selon vos besoins.
- Si vous souhaitez de nouveaux paramètres, par exemple pour surveiller un nouveau dossier, vous devrez les ajouter à `/etc/aide/aide.conf` ou `/etc/aide/aide.conf.d/`.
- Faites une sauvegarde des fichiers de configuration d'origine : `sudo cp -pr /etc/aide /etc/aide-COPY-$(date +"%Y%m%d%H%M%S")`.
1. Créer une nouvelle base de données et l'installer.
Sur les systèmes basés sur Debian :
``` bash
sudo aideinit
```
> ```
> Running aide --init...
> Start timestamp: 2019-04-01 21:23:37 -0400 (AIDE 0.16)
> AIDE initialized database at /var/lib/aide/aide.db.new
> Verbose level: 6
>
> Number of entries: 25973
>
> ---------------------------------------------------
> The attributes of the (uncompressed) database(s):
> ---------------------------------------------------
>
> /var/lib/aide/aide.db.new
> RMD160 : moyQ1YskQQbidX+Lusv3g2wf1gQ=
> TIGER : 7WoOgCrXzSpDrlO6I3PyXPj1gRiaMSeo
> SHA256 : gVx8Fp7r3800WF2aeXl+/KHCzfGsNi7O
> g16VTPpIfYQ=
> SHA512 : GYfa0DJwWgMLl4Goo5VFVOhu4BphXCo3
> rZnk49PYztwu50XjaAvsVuTjJY5uIYrG
> tV+jt3ELvwFzGefq4ZBNMg==
> CRC32 : /cusZw==
> HAVAL : E/i5ceF3YTjwenBfyxHEsy9Kzu35VTf7
> CPGQSW4tl14=
> GOST : n5Ityzxey9/1jIs7LMc08SULF1sLBFUc
> aMv7Oby604A=
>
>
> End timestamp: 2019-04-01 21:24:45 -0400 (run time: 1m 8s)
> ```
1. Tester que tout fonctionne sans modifications.
Sur les systèmes basés sur Debian :
``` bash
sudo aide.wrapper --check
```
> ```
> Start timestamp: 2019-04-01 21:24:45 -0400 (AIDE 0.16)
> AIDE found NO differences between database and filesystem. Looks okay!!
> Verbose level: 6
>
> Number of entries: 25973
>
> ---------------------------------------------------
> The attributes of the (uncompressed) database(s):
> ---------------------------------------------------
>
> /var/lib/aide/aide.db
> RMD160 : moyQ1YskQQbidX+Lusv3g2wf1gQ=
> TIGER : 7WoOgCrXzSpDrlO6I3PyXPj1gRiaMSeo
> SHA256 : gVx8Fp7r3800WF2aeXl+/KHCzfGsNi7O
> g16VTPpIfYQ=
> SHA512 : GYfa0DJwWgMLl4Goo5VFVOhu4BphXCo3
> rZnk49PYztwu50XjaAvsVuTjJY5uIYrG
> tV+jt3ELvwFzGefq4ZBNMg==
> CRC32 : /cusZw==
> HAVAL : E/i5ceF3YTjwenBfyxHEsy9Kzu35VTf7
> CPGQSW4tl14=
> GOST : n5Ityzxey9/1jIs7LMc08SULF1sLBFUc
> aMv7Oby604A=
>
>
> End timestamp: 2019-04-01 21:26:03 -0400 (run time: 1m 18s)
> ```
1. Tester que tout fonctionne après avoir apporté quelques modifications.
Sur les systèmes basés sur Debian :
``` bash
sudo touch /etc/test.sh
sudo touch /root/test.sh
sudo aide.wrapper --check
sudo rm /etc/test.sh
sudo rm /root/test.sh
sudo aideinit -y -f
```
> ```
> Start timestamp: 2019-04-01 21:37:37 -0400 (AIDE 0.16)
> AIDE found differences between database and filesystem!!
> Verbose level: 6
>
> Summary:
> Total number of entries: 25972
> Added entries: 2
> Removed entries: 0
> Changed entries: 1
>
> ---------------------------------------------------
> Added entries:
> ---------------------------------------------------
>
> f++++++++++++++++: /etc/test.sh
> f++++++++++++++++: /root/test.sh
>
> ---------------------------------------------------
> Changed entries:
> ---------------------------------------------------
>
> d =.... mc.. .. .: /root
>
> ---------------------------------------------------
> Detailed information about changes:
> ---------------------------------------------------
>
> Directory: /root
> Mtime : 2019-04-01 21:35:07 -0400 | 2019-04-01 21:37:36 -0400
> Ctime : 2019-04-01 21:35:07 -0400 | 2019-04-01 21:37:36 -0400
>
>
> ---------------------------------------------------
> The attributes of the (uncompressed) database(s):
> ---------------------------------------------------
>
> /var/lib/aide/aide.db
> RMD160 : qF9WmKaf2PptjKnhcr9z4ueCPTY=
> TIGER : zMo7MvvYJcq1hzvTQLPMW7ALeFiyEqv+
> SHA256 : LSLLVjjV6r8vlSxlbAbbEsPcQUB48SgP
> pdVqEn6ZNbQ=
> SHA512 : Qc4U7+ZAWCcitapGhJ1IrXCLGCf1IKZl
> 02KYL1gaZ0Fm4dc7xLqjiquWDMSEbwzW
> oz49NCquqGz5jpMIUy7UxA==
> CRC32 : z8ChEA==
> HAVAL : YapzS+/cdDwLj3kHJEq8fufLp3DPKZDg
> U12KCSkrO7Y=
> GOST : 74sLV4HkTig+GJhokvxZQm7CJD/NR0mG
> 6jV7zdt5AXQ=
>
>
> End timestamp: 2019-04-01 21:38:50 -0400 (run time: 1m 13s)
> ```
1. Voilà. Si vous définissez `CRON_DAILY_RUN` sur `yes` dans `/etc/default/aide`, alors cron exécutera `/etc/cron.daily/aide` tous les jours et vous enverra la sortie par e-mail.
#### Mise à jour de la base de données
Chaque fois que vous apportez des modifications aux fichiers/dossiers qu'AIDE surveille, vous devrez mettre à jour la base de données pour capturer ces changements. Pour ce faire sur les systèmes basés sur Debian :``` bash
sudo aideinit -y -f
```
([Table des matières](#table-of-contents))
### Analyse antivirus avec ClamAV (Travail en cours)
#### Pourquoi
Travail en cours
#### Comment ça marche
- ClamAV est un scanner de virus
- ClamAV-Freshclam est un service qui maintient les définitions de virus à jour
- ClamAV-Daemon maintient le processus `clamd` en exécution pour accélérer l’analyse
#### Objectifs
Travail en cours
#### Remarques
- Ces instructions **ne** vous disent **pas** comment activer le service du démon ClamAV pour garantir que `clamd` fonctionne en permanence. `clamd` n’est utilisé que si vous exploitez un serveur de messagerie et ne fournit pas une surveillance en temps réel des fichiers. Vous devrez plutôt analyser les fichiers manuellement ou selon un calendrier.
#### Références
- https://www.clamav.net/documents/installation-on-debian-and-ubuntu-linux-distributions
- https://wiki.debian.org/ClamAV
- https://www.osradar.com/install-clamav-debian-9-ubuntu-18/
- https://www.lisenet.com/2014/automate-clamav-to-perform-daily-system-scan-and-send-email-notifications-on-linux/
- https://www.howtoforge.com/tutorial/configure-clamav-to-scan-and-notify-virus-and-malware/
- https://serverfault.com/questions/741299/is-there-a-way-to-keep-clamav-updated-on-debian-8
- https://askubuntu.com/questions/250290/how-do-i-scan-for-viruses-with-clamav
- https://ngothang.com/how-to-install-clamav-and-configure-daily-scanning-on-centos/
#### Étapes
1. Installer ClamAV.
Sur les systèmes basés sur Debian :
``` bash
sudo apt install clamav clamav-freshclam clamav-daemon
```
1. Faire une sauvegarde du fichier de configuration de `clamav-freshclam` `/etc/clamav/freshclam.conf` :
``` bash
sudo cp --archive /etc/clamav/freshclam.conf /etc/clamav/freshclam.conf-COPY-$(date +"%Y%m%d%H%M%S")
```
1. Les paramètres par défaut de `clamav-freshclam` sont probablement suffisants, mais si vous souhaitez les modifier, vous pouvez soit éditer le fichier `/etc/clamav/freshclam.conf`, soit utiliser `dpkg-reconfigure` :
``` bash
```
---
[Read more](https://github.com/imthenachoman/how-to-secure-a-linux-server)
~/.ssh/authorized_keysssh-copy-idssh-copy-id user@server
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub" The authenticity of host 'host (192.168.1.96)' can't be established. ECDSA key fingerprint is SHA256:QaDQb/X0XyVlogh87sDXE7MR8YIK7ko4wS5hXjRySJE. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys user@host's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'user@host'" and check to make sure that only the key(s) you wanted were added.
ssh-keygen -l -f ~/.ssh/id_rsa########################################################################################################
# début des paramètres de https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67 en date du 2019-01-01
########################################################################################################
# Algorithmes HostKey supportés par ordre de préférence.
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
KexAlgorithms [email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256,[email protected]
# LogLevel VERBOSE enregistre l'empreinte de la clé de l'utilisateur lors de la connexion. Nécessaire pour avoir une piste d'audit claire de quelle clé a été utilisée pour se connecter.
LogLevel VERBOSE
# Utiliser les mécanismes de sandbox du noyau lorsque possible dans les processus non privilégiés
# Systrace sur OpenBSD, Seccomp sur Linux, seatbelt sur MacOSX/Darwin, rlimit ailleurs.
# Remarque : Ce paramètre est obsolète dans OpenSSH 7.5 (https://www.openssh.com/txt/release-7.5)
# UsePrivilegeSeparation sandbox
########################################################################################################
# fin des paramètres de https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67 en date du 2019-01-01
########################################################################################################
# ne pas laisser les utilisateurs définir des variables d'environnement
PermitUserEnvironment no
# Journaliser l'accès au niveau fichier sftp (lecture/écriture/etc.) qui ne serait pas facilement journalisé autrement.
Subsystem sftp internal-sftp -f AUTHPRIV -l INFO
# désactiver la redirection X11 car X11 est très peu sécurisé
# vous ne devriez vraiment pas exécuter X sur un serveur de toute façon
X11Forwarding no
# désactiver le transfert de port
AllowTcpForwarding no
AllowStreamLocalForwarding no
GatewayPorts no
PermitTunnel no
# ne pas autoriser la connexion si le compte a un mot de passe vide
PermitEmptyPasswords no
# ignorer .rhosts et .shosts
IgnoreRhosts yes
# vérifier que le nom d'hôte correspond à l'IP
UseDNS yes
Compression no
# TCP keepalive peut être usurpé (s'exécute en dehors du canal chiffré)
# Utilisez ClientAlive à la place (s'exécute à l'intérieur du canal chiffré)
TCPKeepAlive no
AllowAgentForwarding no
PermitRootLogin no
# ne pas autoriser .rhosts ou /etc/hosts.equiv
HostbasedAuthentication no
# OpenSSH 9.1 et versions ultérieures
# Imposer une taille minimale de clé RSA de 3072 bits
# https://www.keylength.com/en/compare/
# RequiredRSASize 3072
# https://github.com/imthenachoman/How-To-Secure-A-Linux-Server/issues/115
HashKnownHosts yes
Ensuite, trouvez et modifiez ou ajoutez ces paramètres, et définissez les valeurs selon vos besoins :
| Paramètre | Valeurs valides | Exemple | Description | Remarques |
|---|---|---|---|---|
| AllowGroups | nom de groupe UNIX local | AllowGroups sshusers | groupe auquel autoriser l'accès SSH | |
| ClientAliveCountMax | nombre | ClientAliveCountMax 3 | nombre maximum de messages de maintien de connexion client envoyés sans réponse | |
| ClientAliveInterval | nombre de secondes | ClientAliveInterval 15 | délai d'expiration en secondes avant une demande de réponse | |
| ListenAddress | liste séparée par des espaces d'adresses locales |
| adresses locales sur lesquelles sshd doit écouter | Voir Issue #1 pour des détails importants. |
| LoginGraceTime | nombre de secondes | LoginGraceTime 30 | temps en secondes avant l'expiration de la connexion | |
| MaxAuthTries | nombre | MaxAuthTries 2 | nombre maximum de tentatives de connexion autorisées | |
| MaxSessions | nombre | MaxSessions 2 | nombre maximum de sessions ouvertes | |
| MaxStartups | nombre | MaxStartups 2 | nombre maximum de sessions de connexion | |
| PasswordAuthentication | yes ou no | PasswordAuthentication no | si la connexion avec un mot de passe est autorisée | |
| Port | n'importe quel numéro de port ouvert/disponible | Port 22 | port sur lequel sshd doit écouter |
Consultez man sshd_config pour plus de détails sur la signification de ces paramètres.
Assurez-vous qu'il n'y a pas de paramètres en double qui se contredisent. La commande ci-dessous ne devrait produire aucune sortie.
awk 'NF && $1!~/^(#|HostKey)/{print $1}' /etc/ssh/sshd_config | sort | uniq -c | grep -v ' 1 '
Redémarrez ssh :
sudo service sshd restart
Vous pouvez vérifier que les configurations ont fonctionné avec sshd -T et vérifier la sortie :
sudo sshd -T
port 22 addressfamily any listenaddress [::]:22 listenaddress 0.0.0.0:22 usepam yes logingracetime 30 x11displayoffset 10 maxauthtries 2 maxsessions 2 clientaliveinterval 15 clientalivecountmax 3 streamlocalbindmask 0177 permitrootlogin no ignorerhosts yes ignoreuserknownhosts no hostbasedauthentication no ... subsystem sftp internal-sftp -f AUTHPRIV -l INFO maxstartups 2:30:2 permittunnel no ipqos lowdelay throughput rekeylimit 0 0 permitopen any
Remarquez que cela ne s'exécute pas en tant que root.
Sélectionnez l'option par défaut (y dans la plupart des cas) pour toutes les questions posées et n'oubliez pas de sauvegarder les codes de secours d'urgence.
Faites une sauvegarde du fichier de configuration PAM pour SSH /etc/pam.d/sshd :
sudo cp --archive /etc/pam.d/sshd /etc/pam.d/sshd-COPY-$(date +"%Y%m%d%H%M%S")
Maintenant, nous devons l'activer en tant que méthode d'authentification pour SSH en ajoutant cette ligne à /etc/pam.d/sshd :
auth required pam_google_authenticator.so nullok
Remarque : Consultez ici pour savoir ce que signifie nullok.
echo -e "\nauth required pam_google_authenticator.so nullok # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/pam.d/sshd
Dites à SSH de l'utiliser en ajoutant ou en modifiant cette ligne dans /etc/ssh/sshd_config :
ChallengeResponseAuthentication yes
sudo sed -i -r -e "s/^(challengeresponseauthentication .*)$/# \1 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/I" /etc/ssh/sshd_config
echo -e "\nChallengeResponseAuthentication yes # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")" | sudo tee -a /etc/ssh/sshd_config
Redémarrez ssh :
sudo service sshd restart
Redémarrez le service pour appliquer les modifications :
sudo systemctl restart systemd-timesyncd
Vérifiez l'état de la synchronisation :
timedatectl timesync-status
Server: 108.61.56.35 (pool.ntp.org) Poll interval: 32s (min: 32s; max: 34min 8s) Leap: normal Version: 4 Stratum: 2 Reference: C342F10A Precision: 1us (2^0) Root distance: 24.054ms (max: 5s) Offset: +2.156ms Delay: 48.567ms Jitter: 1.452ms Packet count: 3
Exemple de /etc/ntp.conf :
driftfile /var/lib/ntp/ntp.drift statistics loopstats peerstats clockstats filegen loopstats file loopstats type day enable filegen peerstats file peerstats type day enable filegen clockstats file clockstats type day enable restrict -4 default kod notrap nomodify nopeer noquery limited restrict -6 default kod notrap nomodify nopeer noquery limited restrict 127.0.0.1 restrict ::1 restrict source notrap nomodify noquery pool pool.ntp.org iburst # added by user on 2019-03-09 @ 10:23:35
Redémarrez ntp :
sudo service ntp restart
Vérifiez l'état du service ntp :
sudo systemctl status ntp
● ntp.service - LSB: Start NTP daemon Loaded: loaded (/etc/init.d/ntp; generated; vendor preset: enabled) Active: active (running) since Sat 2019-03-09 15:19:46 EST; 4s ago Docs: man:systemd-sysv-generator(8) Process: 1016 ExecStop=/etc/init.d/ntp stop (code=exited, status=0/SUCCESS) Process: 1028 ExecStart=/etc/init.d/ntp start (code=exited, status=0/SUCCESS) Tasks: 2 (limit: 4915) CGroup: /system.slice/ntp.service └─1038 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 108:113 Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 0 v6wildcard [::]:123 Mar 09 15:19:46 host ntpd[1038]: Listen and drop on 1 v4wildcard 0.0.0.0:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 2 lo 127.0.0.1:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 3 enp0s3 10.10.20.96:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 4 lo [::1]:123 Mar 09 15:19:46 host ntpd[1038]: Listen normally on 5 enp0s3 [fe80::a00:27ff:feb6:ed8e%2]:123 Mar 09 15:19:46 host ntpd[1038]: Listening on routing socket on fd #22 for interface updates Mar 09 15:19:47 host ntpd[1038]: Soliciting pool server 108.61.56.35 Mar 09 15:19:48 host ntpd[1038]: Soliciting pool server 69.89.207.199 Mar 09 15:19:49 host ntpd[1038]: Soliciting pool server 45.79.111.114
Vérifiez l'état de ntp :
sudo ntpq -p
remote refid st t when poll reach delay offset jitter ============================================================================== pool.ntp.org .POOL. 16 p - 64 0 0.000 0.000 0.000 *lithium.constan 198.30.92.2 2 u - 64 1 19.900 4.894 3.951 ntp2.wiktel.com 212.215.1.157 2 u 2 64 1 48.061 -0.431 0.104
ucredit=-1 = doit contenir au moins une lettre majusculelcredit=-1 = doit contenir au moins une lettre minusculeocredit=-1 = doit contenir au moins un caractère non alphanumériquedifok=3 = au moins 3 caractères du nouveau mot de passe ne doivent pas figurer dans l'ancien mot de passemaxrepeat=3 = autoriser un maximum de 3 caractères répétésgecoschec = ne pas autoriser les mots de passe contenant le nom du comptesudo sed -i -r -e "s/^(password\s+requisite\s+pam_pwquality.so)(.*)$/# \1\2 # commented by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")\n\1 retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3 gecoschec # added by $(whoami) on $(date +"%Y-%m-%d @ %H:%M:%S")/" /etc/pam.d/common-password
Remarques :
/usr/lib/apt/apt.systemd.daily pour plus de détails sur les options APT::PeriodicUnattended-UpgradeEffectuer un essai à blanc de unattended-upgrades pour vous assurer que votre fichier de configuration est correct :
sudo unattended-upgrade -d --dry-run
Si tout est correct, vous pouvez le laisser s'exécuter selon son calendrier prévu ou forcer une exécution avec unattended-upgrade -d.
Configurez apt-listchanges selon vos préférences :
sudo dpkg-reconfigure apt-listchanges
Pour apticron, les paramètres par défaut sont suffisants mais vous pouvez les vérifier dans /etc/apticron/apticron.conf si vous souhaitez les modifier. Par exemple, ma configuration ressemble à ceci :
EMAIL="root" NOTIFY_NO_UPDATES="1"