6.6 KiB
% Introduction à la sécurité d'un serveur web % Sylvain Eliade — S.C.O.P. Cadoles
Introduction à la sécurité d'un serveur web
Fail2ban
S'il ne faut en retenir qu'un c'est celui-là !
apt install fail2ban
Il lit les logs en permanence et détecte les tentatives d'intrusion (mauvais mot de passe SSH, email, HTTP…) et bloque les IP automatiquement !
Activer les filtres dans /etc/fail2ban/jail.conf
(passer enabled
à true
). Normalement la plupart des filtres nécessaires sont activés par défaut, mais ça vaut le coup de regarder si on peut en activer d'autres, ou de faire les siens !
Mises à jours de sécurité
Ça semble évident, mais ça ne l'est pas pour tout le monde.
Activer les mises à jour automatique de sécurité avec unattended-upgrades
.
apt install unattended-upgrades
Pare-feu (firewall)
Sous Linux, les ports sont fermés par défaut si un service n'écoute pas dessus, donc c'est "sécurisé" par défaut. Alors pourquoi un firewall ?
Parce que si un attaquant parvient à ouvrir un port sur votre machine il peut s'en servir pour lui donner des ordres, ou faire des requêtes vers d'autres machines (par exemple transformer votre serveur en attaquant DDoS).
Du coup un firewall est utile pour restreindre le risque en cas d'attaque.
Pare-feu Linux
Le noyau Linux contient déjà un pare-feu, c'est Netfilter, accessible via la commande iptables
.
Comme elle est un peu complexe, on conseille en général d'utiliser ufw
(Uncomplicated FireWall), qui est une interface iptables simplifiée.
UFW
Installer avec apt install ufw
, et activer avec ufw enable
.
Consulter le statut avec ufw status verbose
.
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
Lister les règles disponibles : ufw app list
(Dés)Activer le blocage par défaut :
ufw default allow incoming
ufw default deny outgoing
Activer un service :
ufw allow in WWW
ufw allow out VNC
Autoriser un port :
ufw allow 53
ufw allow 25/tcp
Bloquer une IP :
ufw deny from X.X.X.X to any
Restriction par IP
Si on veut restreindre l'accès à un serveur web à certaines IP il y a plusieurs stratégies possibles :
- au niveau du firewall (mieux, car le plus tôt dans la connexion réseau)
- via TCP Wrappers ou systemd
- via le serveur web
Avec UFW
ufw deny 80
ufw allow from X.X.X.X to any port 80
TCP Wrappers
Mécanisme ancien, simple, mais aujourd'hui on utilise un firewall.
Malgré le nom, il gère aussi UDP.
La configuration se fait dans les fichiers /etc/hosts.allow
et /etc/hosts.deny
.
N'est plus supporté par systemd.
# /etc/hosts.allow
sshd: 192.168.1.0/255.255.255.0
# /etc/hosts.deny
sshd: ALL
Restriction avec systemd
Se fait au niveau du fichier .service
:
IPAddressDeny=1.1.1.1
IPAddressAllow=8.8.8.8
Encore une fois, mieux vaut préférer un firewall.
Restriction avec Apache
Avantage : peut se faire par répertoire, vhost, fichier…
Tout autoriser sauf une IP :
<RequireAll>
Require all granted
Require not ip 10.252.46.165
</RequireAll>
Tout bloquer sauf si connexion valide OU adresse IP spécifique :
<RequireAll>
Require all denied
<RequireAny>
Require ip 192.168.1.12
Require valid-user
</RequireAny>
</RequireAll>
Ne pas se tirer une balle dans le pied
- Utiliser PHP 7.2 ou 7.3 ! Abandonnez PHP 5 et PHP 7.0 (plus supportés !) ! Enfin si c'est possible…
- Configurer le serveur web pour n'écouter que sur l'interface / port nécessaire (
/etc/apache2/ports.conf
) - Ne pas exposer sa version de PHP ou Apache (ou nginx)
- Désactiver le vhost par défaut d'apache, dont la page HTML peut contenir des infos utiles à un attaquant
- Bloquer l'accès aux répertoires .svn et .git !
RedirectMatch 404 /\.git
RedirectMatch 404 /\.svn
Cacher les versions
Pourquoi ? Contre les bots qui scannent les serveurs pas à jour.
Dans /etc/apache2/conf-enabled/security.conf
:
ServerTokens Prod
ServerSignature Off
Avant :
Server: Apache/2.4.25 (Debian)
Après :
Server: Apache
Dans /etc/php/7.0/apache/conf.d/local.ini
ajouter :
expose_php = off
Restreindre la surface d'attaque (Apache)
Désactiver les index de répertoires, l'exécution de CGI, les liens symboliques et les inclusions :
<Directory />
Options -Indexes -ExecCGI -FollowSymLinks -Includes
</Directory>
Désactiver les .htaccess si possible.
Restreindre la surface d'attaque (PHP)
Restreindre les répertoires accessibles de PHP (dans le vhost Apache) :
php_admin_value open_basedir /var/www/monsite.com
Interdire l'exécution de programme externe :
disable_functions = exec,passthru,shell_exec,system,proc_open,popen
à mettre dans le /etc/php/7.0/apache/conf.d/local.ini
, ou dans un php_admin_value
par vhost.
Aller plus loin
Vérifier sa config :
- Audit automatisé : mieux que ne rien faire, mais à ne pas faire en prod, laisse pas mal de traces (logs), peut surcharger le serveur
- Audit manuel : de bonnes connaissances en sécu, ou un bon chéquier !
- Hardening PHP : ça restreint certaines fonctions et attaques, mais c'est bien mais ça peut casser des applis :(
- WAF (Web Application Firewall) : idem, ça détecte des attaques connues, bonne stratégie défensive, mais attention aux effets de bord.
- Auditer son site avec Nikto
- Hardening PHP : snuffleupagus (Apache)
- Tester son certificat SSL avec SSL Labs
- Mise en place de WAF avec mod_security pour Apache
- WAF pour nginx avec naxsi
Exercice 1
Installer ufw
et n'autoriser que le port 80 en entrée.
Vérifier avec :
nmap -p 80 ADRESSE_IP
nmap -p 443 ADRESSE_IP
La première doit renvoyer que le port est ouvert, mais pas la seconde.
Exercice 2
Modifier le .htaccess
du répertoire secret
précédemment créé pour autoriser aussi l'adresse IP 127.0.0.1
à y accéder sans mot de passe.
Vérifier avec curl.
Exercice 3
Cacher les versions de PHP et Apache. Vérifier avec Curl.
Exercice 4 (facultatif)
Installer Nikto et scanner les vhosts du serveur web. Nikto est dans les dépôts non-free
de Debian : https://debian-facile.org/doc:systeme:apt:sources.list:sources.list-non-free