Le but de cette petite doc est de résumer les bonnes manières en matière de sécurité d'une machine GNU/Linux et de ses services.
La partie liée au services (Apache, etc...) est evidemment indépendante de l'OS et peut s'appliquer aux autres OS hormis mention contraire.
Les services: durcissement de la configuration et chroot
Apache
Dans un premier temps, il est necessaire de configurer les paramètres du core telles que le nombre de requêtes maximales par fils, etc...
Certains paramètres peuvent ensuite être redéfinis en fonction des hôtes virtuelles tels que le nom du serveur, le port d'écoute ...
Puis pour des paramètres plus sensibles, tels que les droits de consultations, les authentifications et les méthodes autoriées, il est possible de de travailler par répetoires.
Les droits par défaut son hérités de ceux du DocumentRoot.
Les points à vérifier pour s'assurer un niveau de sécurité convenable sont:
- mod_security:
mod_security est un module apache filtrant les requêtes des utilisateurs en fonction d'un certain nombre de critères.
Un jeu de règles de bases est présent sur le site à l'adresse http://www.modsecurity.org/projects/rules/index.html.
Il convient ensuite d'adapter et d'étoffer ces règles aux sites servis par le serveur.
Il est possible de rechercher des motifs sur toute la requête ou sur seulement une partie de celle ci. Les actions possbiles ensuite vont du bête accept/deny à l'execution d'un binaire.
Il convient donc de charger le module, généralement, la liste des modules est dans (/usr/local)/etc/apache/modules.conf:
LoadModule security_module /usr/lib/apache/1.3/mod_security.so
La définition des règles ressemble ensuite à cela:
<IfModule mod_security.c> SecFilterEngine On SecFilterDefaultAction "deny,log" SecFilter /bin/sh SecFilter /etc/passwd SecFilter hidden SecFilter \|$ </IfModule>
- chroot:
Apache n'est pas initialement prévu pour être chrooté. Toutefois, il est toujours possible de le faire en produisant une arborescence remplissant les prérequis pour lancer le binaire d'une part (librairies dynamiques), et pour que celui ci retrouve les éléments qui lui sont necessaires (DocumentRoot, répértoire des fichiers de journaux ...).
Une méthode permettant de chrooter un service quelconque est décrite à la fin de ce document.
- Bannières:
La signature du serveur fournie par Apache lors d'erreur 404 ou autre est paramétrable via les directives ServerTokens et ServerSignature.
Les valeurs permettants une fuite d'informations minimale sont:ServerSignature Off ServerTokens Min
- Méthodes autorisées:
Pour une utilisation "normale" en serveur Web, les méthodes HTTP GET, HEAD et POST sont amplement suffisantes. Si votre site n'offre aucune interaction à l'utilisateur de type formulaire et autre, alors il est même possible de supprimer la méthode POST.
Le fichier de configuration par défaut intégre un certains nombres de limitations:
<Limit DELETE CONNECT OPTIONS PATCH PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK> Order Allow,Deny Deny from All </Limit>
Les menaces de sécurité liées au web sont rarement dues au serveur web et à ses modules, mes plus souvent aux scripts PHP ou CGI des utilisateurs.
Il est donc necessaire de restreindre au maximum les possibilitées offertes par PHP, en essayant de laisser une libertée maximale à l'utilisateur.
- PHP: safe mode.
- PHP: magic quote.
- PHP: interdiction de certaines fonctions.
- PHP: upload de fichier.
- CGI: suEXEC et cgiwrap.
Ne pas perdre de vue que tout les paramètres relatifs aux scripts CGI et aux script PHP peuvent être placés par répertoires. Ne pas hesiter donc à mettre un maximum de restrictions pour ensuite autoriser certaines fonctions au cas par cas.
SSH
- Authentification par clefs.
Une pratique courante et offrant une sécurité accrue est de forcer l'utilisation de clefs pour l'authentification.
Les prérequis sont d'autoriser ce type d'authentification, ce necessite l'ajout des directives suivantes dans le fichier de configuration du daemon ssh (couramment /etc/ssh/sshd_config):PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys
Ensuite, l'utilisateur doit générer une paire de clefs à l'aide de la commande ssh-keygen:[gco@gc]:~% ssh-keygen -b 2048 -t dsa -f key Generating public/private dsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in key. Your public key has been saved in key.pub. The key fingerprint is: e3:6c:60:18:ff:06:16:5f:96:ce:24:0e:fd:c4:68:90 gco@gc
Pour finir, l'utilisateur doit copier la clef nouvellement crée dans le fichier $HOME/.ssh/id_rsa ou $HOME/.ssh/id_dsa en fonction du type de clef, et ajouter et copier le contenu du fichier id_rsa.pub (dans l'exemple précedent, le fichier en question est nommé key.pub) dans le fichier $HOME/.ssh/authorized_keys de la machine distante.
A noter qu'il est possible d'avoir un trousseau de clef, afin d'éviter d'utiliser la même clef partout. Le fichier $HOME/.ssh/config permet de définir quelle clef utiliser en fonction de la machine. (Directive IdentityFile). Une fois les clefs publiques copiées sur l'hôte distante, il est possible d'interdire les connexions par mot de passe via l'ajout de la directive suivante:PasswordAuthentification no
- Autoriser le V2 seul.
Il a été démontré que la version 1 du protocole SSH était vulnérable à un certain nombre d'attaque.
Il est donc important de forcer l'utilisation de la version du protocole:Protocol 2
- Interdire les logins en tant que root et/ou n'autoriser que certains utilisateurs à se connecter (AllowUsers):
La directive AllowUsers a été implémentée dans ce but. Par exemple un:AllowUsers toto tata
Interdira toute connexions d'utilisateurs autre que toto et tata. Attention, le séparateur à utiliser dans ce cas est un espace ! Par contre, si l'on veut simplement interdire les connexions en tant que root, l'ajout suivant suffit:PermitRootLogin no
- Restreindre le port forwarding.
OpenSSH offre des mecanismes de forwarding de port, que cela soit locaux ou distants via les options de la ligne de commande -L et -R ainsi que via les directives de configuration LocalForward et RemoteForward.
Une utilisation maladroite ou malveillante de cette fonctionnalité peut mener, par exemple, à rendre publique un service n'écoutant que sur l'interface de loopback pour des raisons de sécurité (MySQL par exemple).
Il est possible d'interdire le forwarding de port via l'ajout de la directive suivante dans le fichier de configuration de OpenSSH:AllowTcpForwarding no
- Port knocking.
- Divers autres sources potentielles de problème:
Par défaut, OpenSSH offre un niveau de sécurité relativement élevé. Toutefois, certaines directives peuvent s'avérer dangereuses telles que PermitUserEnvironment. Une bonne approche est de lire de manière approfondie la page de manuel sshd_config(5).
Bind
- chroot:
Bind inclut de base un mecanisme de chroot. Celui ci peut être activé via l'option -t en ligne de commande.
Il faut bien evidemment veiller à ce que le repertoire du chroot contiennent bien les fichiers de zones, ainsi qu'un socket d'écoute pour syslog.
- Interdire les requêtes récursives pour les clients non autorisés:
Une requête DNS récursive est, comme son nom l'indique plus ou moins, une requête ou le serveur interrogé va suivre tout le cheminement depuis la zone . jusqu'au domaine demandé pour fournir lui même la réponse au client.
Ce genre de requête peut, malicieusement exploité, mener au deni de service (DOS).
Il convient donc d'autoriser les requêtes recursives que pour les clients légitimes du serveur.
Ces restrictions se font via la directive allow-recursion dans le bloc d'options du fichier named.conf.
Par exemple:
allow-recursion { 127.0.0.1; 192.168.1.0/24; };
- Interdire les transferts de zone pour les hôtes non DNS secondaires:
Ceci est possible via la directive allow-transfer, par exemple:allow-transfer { 127.0.0.1; ip NS secondaire; ... };
- Cacher la version de bind.
Postfix
- Interdire le vrfy.
- Chrooter un maximum de service.
- Vérifier les règles de relayage.
snmpd
- Communauté Read-Only/Read-Write
- Utilisation de version 2 ou 3 permet authentification plus fine.
syslogd
- Dans la mesure du possible logguer vers une machine distante dédiée.
- Remplacer eventuellement par syslog-ng.
inetd
- Suppression des services inutiles.
- host.(allow|deny).
ProFTPD
- Dans la mesure du possible, interdire les accès anonymes.
- Dans la mesure du possible forcer le chiffrement du canal de commandes.
- Chrooter les utilisateurs dans leurs répertoires home.
MySQL
- Placer un mot de passe pour root.
- Ne pas faire écouter sur le réseau.
Cyrus
Le système: noyau et userland
Noyau
Compilation
- grsec:
Le patch grsec (http://grsecurity.net/) est une étape necessaire à la sécurisation d'un serveur Linux. Il intègre des protections contre les débordements de tampon (pile non executable), les formats strings (adresse de la pile rendue aléatoire), mais rend également les tentatives de fuite de chroot inutiles.
Les possbilités de journalisation sont également étoffées avec la possibilité de logguer les exec(), chdir()...
Pour finir, grsec amène un système de politique de sécurité dont le fonctionnement, bien que complexe à mettre en oeuvre, est particulièrement efficace.
Il est possible via ce mecanisme (RBAC) de définir quel processus à le droit d'accéder à quelles ressources. Ces ressources sont des fichiers (avec des droits bien particulier), mais également des sockets...
- pas de support des modules:
Une machine en production est très généralement une machine dont la configuration ne bougera pas et, hormis quelques pilotes tiers, tout les pilotes de périphériques peuvent être inclus en dur dans le noyau. C'est donc une bonne idée de supprimer le support des modules car une grande majorité des piratages réussis se termineront par la mise en place d'un rootkit sous forme de module.
Des méthodes existent toujours pour compromettre le kernel land d'une machine, toutefois, la desactivation des modules est déjà un premier obstacle non negligeable.
Configuration
Paramètres réseaux:
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.default.accept_source_route=0
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.tcp_max_syn_backlog=4096
Réseau
Firewalling
Filtrer les entrées et les sorties et n'autoriser que ce qui est réellement necessaire.Les entrées pour éviter que l'attaquants puisse "binder" un interpréteur de commande sur un port pour ensuite élever ses privlièges. Les sorties pour éviter que ce dernier n'utilise une méthode dite de "connect-back" ou la backdoor se connecte à la machine de l'attaquant
Prochainement ici, un jeu de règle standard pour un serveur web en production.
Table ARP
C'est une bonne idée d'utiliser de forcer certaines entrées délicates de la table ARP à être statique. Par exemple, forcer l'adresse de la gateway à être statique permet de se prémunir contre les attaques de man-in-the-middle via l'ARP Spoofing.La méthode pour placer des adresses statiques différe en fonction du système. Voir à cet effet la page de manuel de arp(8).
Userland
Binaires à proscrire sur une machine de production
- Binaire permettant à l'attaquant de récuperer exploits et autres: wget, links, lynx, w3m, ncftp, ncftpget, ftp, ...
- Binaire permettant la compilation ou l'execution d'exploits et autres: gcc, as, perl, python, ...
Partitionnement
- /tmp à part et noexec/nosuid
- /var et /home dans la mesure du possible avec noexec/nosuid (attention, sur les sytèmes Debian, il est necessaire que /var/lib/dpkg soit executables car le système de paquet utilise /var/lib/dpkg/info pour stocker les fichiers de pré/post-installation des paquets).
- / seul à le droit au device
Intégrité du système
- tripwire / somme md5 et sha1.
- chkrootkit.
Permissions
- Bit SUID et SGID:
Les binaires avec le bit-suid placé sont executés avec les privilèges du propriétaire du binaire en question.
Cela permet par exemple de permettre aux utilisateurs "normaux" de lancer la commande ping qui utilise les sockets de type RAW, normalement accessible qu'à l'utilisateur root.
Pour trouver les binaires suidé:
find / -type f -perm -4110 -ls
Et pour ôter le bit-suid:
find / -type f -perm -4110 -exec chmod -s {} \;
Attention, cette commande peut s'avérer dangereuse !! (su sans son bit-suid ne sert plus à rien !). Une alternative au chmod -s est de changer le groupe du binaire et de n'accorder le droit d'execution qu'à l'utilisateur et au membre du groupe. Par exemple:chown root:adm /bin/su chmod 4750 /bin/su
Ainsi, seuls les utilisateurs appartenant au groupe adm pourront executer ce binaire.
- Permissions sur /etc, /tmp, /var/log, ...
