formations/cesi/hebergement_web/05-security.md

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.


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