mardi 21 janvier 2014

Un serveur web oui mais .... comment faire pour que ce ne soit pas une passoire - partie 2

Maintenant que nous avons accès à notre server de manière sécurisée, nous allons installer notre serveur web en https et renforcer la sécurité avec 3 points :

  • le firewall avec un petit tour sur les IpTables
  • bloquer le scan des ports  avec PortSentry
  • bloquer les tentatives frauduleuses sur nos services avec fail2ban


0) le serveur web

Bien que de nombreux site présente l'installation de NginX peu le font avec une configuration en HTTPS, c'est ce que détaillera ce chapitre.

On commence par installer le paquet :
apt-get install ngnix

Si l'on regarde la structure des répertoires :

nous avons deux répertoires important :

  • sites-available : qui contient tous les fichiers de configuration de vos sites web
  • sites-enabled : qui contient des liens vers les fichiers du répertoire sites-available et qui active le site.
on commence donc par vider le répertoire : sites-enabled
rm ./sites-enabled/*
Nous allons maintenant générer les certificats SSL, pour ce faire on installe le paquet : openssl puis on génère les clès :

sudo apt-get install openssl
cd /etc/ssl
sudo openssl req -new -key server.key -out server.csr

sudo openssl genrsa -out server.key 2048


sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt


Voila nous avons les fichiers certificats : 
server.crt et server.key

Nous allons maintenant créer le fichier de configuration minimal de NgniX, dans le répertoire /etc/nginx/sites-available.
creér le fichier myssl.conf comme suit : 
# redirect http to https.
server {
  listen 80;
  server_name dardevil;
  return 301 https://$server_name$request_uri;  # enforce https
}
# My ssl server
server {
  listen 443 ssl;
  server_name 192.168.1.30;
  ssl_certificate /etc/ssl/server.pem;
  ssl_certificate_key /etc/ssl/server.key;
  root /usr/share/nginx/www;
  index index.html index.htm;
}
le fichier de configuration redirige votre port 80 vers le port ssl automatiquement, les fichiers du site se trouve dans le répertoire par défaut /usr/share/nginx/www.

Activez le site en plaçant un lien symbolique dans sites-enabled :
sudo ln -s ../sites-available/myssl.conf myssl.conf

Voila on a server web tout beau en https.

1) le Firewall 



Nous allons maintenant renforcer la sécurité de notre système via le paramètrage des flux réseaux autorisés.

Notre objectif est d'ouvrir vers l'exterieur seulement les ports dont nous avons besoin : le SSH et le port HTTPS.

voici donc les règles que je vous propose pour l'extérieur de notre réseau : 

A) on jete tous les paquets par défaut
B) on autorise le port HTTP, HTTPS,ICMP,NTP et DNS en entrée
C) on autorise le port 1022 pour notre SSH
D) on autorise tous les ports en sortie 

Attention avec cette technique si vous ajoutez des services il faudra ouvrir les ports correspondant dans votre FireWall

Créer un fichier avec le script suivant (j'ai mis des services complémentaires pour les activités enlevez le # des commentaires, pour ajouter des services ) 
#!/bin/sh 
# Réinitialise les règles
sudo iptables -t filter -F 
sudo iptables -t filter -X 
# Bloque tout le trafic
sudo iptables -t filter -P INPUT DROP 
sudo iptables -t filter -P FORWARD DROP 
sudo iptables -t filter -P OUTPUT DROP 
# Autorise les connexions déjà établies et localhost
sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
sudo iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
sudo iptables -t filter -A INPUT -i lo -j ACCEPT 
sudo iptables -t filter -A OUTPUT -o lo -j ACCEPT 
# ICMP (Ping)
sudo iptables -t filter -A INPUT -p icmp -j ACCEPT 
sudo iptables -t filter -A OUTPUT -p icmp -j ACCEPT 
# SSH
sudo iptables -t filter -A INPUT -p tcp --dport 1022 -j ACCEPT 
sudo iptables -t filter -A OUTPUT -p tcp --dport 1022 -j ACCEPT 
# DNS
sudo iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT 
sudo iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT 
sudo iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT 
sudo iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT 
# HTTP
sudo iptables -t filter -A OUTPUT -p tcp --dport 80 -j ACCEPT 
sudo iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT 
# HTTPS
sudo iptables -t filter -A OUTPUT -p tcp --dport 443 -j ACCEPT 
sudo iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT 
# FTP 
#sudo iptables -t filter -A OUTPUT -p tcp --dport 20:21 -j ACCEPT 
#sudo iptables -t filter -A INPUT -p tcp --dport 20:21 -j ACCEPT 
# Mail SMTP 
#iptables -t filter -A INPUT -p tcp --dport 25 -j ACCEPT 
#iptables -t filter -A OUTPUT -p tcp --dport 25 -j ACCEPT 
# Mail POP3
#iptables -t filter -A INPUT -p tcp --dport 110 -j ACCEPT 
#iptables -t filter -A OUTPUT -p tcp --dport 110 -j ACCEPT 
# Mail IMAP
#iptables -t filter -A INPUT -p tcp --dport 143 -j ACCEPT 
#iptables -t filter -A OUTPUT -p tcp --dport 143 -j ACCEPT 
# NTP (horloge du serveur) 
sudo iptables -t filter -A OUTPUT -p udp --dport 123 -j ACCEPT
#anti flood
iptables -A FORWARD -p tcp --syn -m limit --limit 1/second -j ACCEPT
iptables -A FORWARD -p udp -m limit --limit 1/second -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT


Avec un chmod +x on le rend exécutable.

Maintenant nous allons rendre cette configuration permanente.
Nous allons créer dans /etc un fichier de configuration qui sera lu au démarrage à l'up de l'interface réseaux , puis mettre un script après l'initialisation du réseaux 

1) on crée le fichier avec la commande sudo iptables-save > iptables.conf
2) on copie le fichier créer dans /etc
3) dans le répertoire /etc/network/if-up.d on créer le script de chargement de notre fichier de configuration.



#!/bin/sh
/sbin/iptables-restore < /etc/iptables.conf

un petit chmod +x de notre fichier de lancement pour le rendre exécutable et nous avons fini.

Pour vérifier on redémarre, et on lance la commande sudo iptables -L vous devriez voire l'ensemble de vos règles.

2) Scan des ports : pas bien je bloque 


L'idée est d'empêcher que l'on scan la machine pour connaître quels sont les ports ouverts à l'extérieur. Pour cela nous allons installer portsentry.
Pour ceux à qui le scan de port ne parle pas voici la définition

Tapez la commande : apt-get install portsentry

Il n'y a que 2 modifications à faire pour avoir une configuration de base qui fonctionne : 

Dans le fichier de configuration général : /etc/portsentry/portsentry.conf demander lui de bloquer le scan des ports : 

Dans la section "Ignore Option"  changer les lignes : 

BLOCK_UDP="0"
BLOCK_TCP="0"

par 

BLOCK_UDP="1"
BLOCK_TCP="1"

Puis dans la configuration du service activé le mode automatique (qui est le plus efficace, comme cela si vous ajouter des services vous n'aurez pas à modifier la configuration de portsentry). Cela se passe dans le fichier /etc/default/portsentry, changer les lignes pour avoir : 

TCP_MODE="atcp" 
UDP_MODE="audp"

Voila faites un test de scan de port avec nmap depuis une autre machine puis allez voir dans /etc/host.deny, vous verrez que la machine est bannie.

3) bloquer les utilisateurs qui provoque des erreurs répéter : Fail2Ban

Pour cela nous allons installer Fail2Ban. Ce programme scrute les log,si il détecte une ip répétitive qui a un comportement suspect; il l'a banni en ajoutant une règle au firewall.
Tous le jeux est de définir ce qu'est un comportement suspect, les fichiers ci-dessous pare un certains nombres d'attaques courantes



On installe le logiciel :


sudo apt-get install fail2ban

le fichier de configuration général
/etc/fail2ban/fail2ban.conf

le fichier relatifs à vos prisons
/etc/fail2ban/jail.conf

le dossier filer.d qui contient tous les filtres définis dans le jail.conf
/etc/fail2ban/filter.d

Nous allons configurer le fichier jail.conf comme suit pour se protèger des attaques courantes : 
# mettez ici votre adresse ip histoire de ne pas vous blacklister tout seul
# il est possible de mettre plusieurs adresses, il suffit pour cela de les séparer par un espace 
# pour le bantime, je met 900, il est à 600 par défaut
ignoreip = 127.0.0.1/8
bantime  = 900
maxretry = 3

[ssh-ddos]
# j'active cette jail pour protéger mon ssh des Ddos
enabled  = true  
port     = ssh
filter   = sshd-ddos
logpath  = /var/log/auth.log
maxretry = 6

# Protect against DOS attack
# 360 requests in 2 min > Ban for 10 minutes
[http-get-dos]

enabled = true
port = http,https
filter = http-get-dos
logpath = /var/log/varnish/access.log
maxretry = 360
findtime = 120
action = iptables[name=HTTP, port=http, protocol=tcp]
mail-whois-lines[name=%(__name__)s, dest=%(destemail)s, logpath=%(logpath)s]
bantime = 600

[nginx-w00tw00t]
enabled = true
filter = nginx-w00tw00t
action = iptables[name=nginx-w00tw00t,port=80,protocol=tcp]
logpath = logpath = /var/log/varnish/access.log
maxretry = 1

[nginx-auth]
 enabled = true
 filter = nginx-auth
 action = iptables-multiport[name=NoAuthFailures, port="http,https"]
 logpath = /var/log/nginx*/*error*.log
 bantime = 600 # 10 minutes
 maxretry = 6
 
 [nginx-login]
 enabled = true
 filter = nginx-login
 action = iptables-multiport[name=NoLoginFailures, port="http,https"]
 logpath = /var/log/nginx*/*access*.log
 bantime = 600 # 10 minutes
 maxretry = 6
  
 [nginx-badbots]
 enabled  = true
 filter = apache-badbots
 action = iptables-multiport[name=BadBots, port="http,https"]
 logpath = /var/log/nginx*/*access*.log
 bantime = 86400 # 1 day
 maxretry = 1
  
 [nginx-noscript]
 enabled = true
 action = iptables-multiport[name=NoScript, port="http,https"]
 filter = nginx-noscript
 logpath = /var/log/nginx*/*access*.log
 maxretry = 6
 bantime  = 86400 # 1 day

Mettre les fichiers de filtres correspondants aux prisons dans filter.d
sudo nano /etc/fail2ban/filter.d/http-get-dos.conf


# Fail2Ban configuration file

#

# Author: http://www.go2linux.org

#

[Definition]

# Option: failregex
# Note: This regex will match any GET entry in your logs, so basically all valid and not valid entries are a match.
# You should set up in the jail.conf file, the maxretry and findtime carefully in order to avoid false positives.
failregex = ^.*"GET
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#

ignoreregex =

sudo nano /etc/fail2ban/filter.d/nginx-w00tw00t.conf



[Definition]

failregex = ^ -.*"GET \/w00tw00t\.at\.ISC\.SANS\.DFind\:\).*".*

ignoreregex =



sudo nano /etc/fail2ban/filter.d/nginx-noscript.conf



# Block IPs trying to execute scripts such as .php, .pl, .exe and other funny scripts.
 #
 # Matches e.g.
 # 192.168.1.1 - - "GET /something.php
 #
 [Definition]
 failregex = ^ -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\scgi)
 ignoreregex =
  
 #
 # Auth filter /etc/fail2ban/filter.d/nginx-auth.conf:
 #
 # Blocks IPs that fail to authenticate using basic authentication
 #
 [Definition]
  
 failregex = no user/password was provided for basic authentication.*client: 
             user .* was not found in.*client: 
             user .* password mismatch.*client: 
  
 ignoreregex =

 #
 # Login filter /etc/fail2ban/filter.d/nginx-login.conf:
 #
 # Blocks IPs that fail to authenticate using web application's log in page
 #
 # Scan access log for HTTP 200 + POST /sessions => failed log in
 [Definition]
 failregex = ^ -.*POST /sessions HTTP/1\.." 200
 ignoreregex =

Voilà on redémarre le service :
sudo service fail2ban restart


4) Conclusion : 

Nous avons un serveur web administrable à distance un tant soit peu sécurisé en tout cas suffisamment pour un site perso qui n'ont pas de données critiques. Un backup régulier pour éviter les soucis et vous voilà plus serein.