Installation d'un serveur web sous Debian GNU/Linux

De Centre de Ressources Numériques - Labomedia
Révision de 19 juin 2017 à 03:36 par Benjamin (discussion | contributions) (SSH)

(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à : navigation, rechercher

Installation de base

A l'installation de Debian, lorsque la selection de logiciels se présentera, cochez les cases indispensables à un serveur web :

  • serveur web
  • bases de données SQL
  • serveur SSH
  • utilitaires usuels du système

Un peu de moquette dans la console

Pour donner un peu de couleurs à la console et aux différentes commandes et activer quelques alias simples, il faut modifier le fichier /root/.bashrc afin qu'il ressemble à ça :

# ~/.bashrc: executed by bash(1) for non-login shells.

# Note: PS1 and umask are already set in /etc/profile. You should not
# need this unless you want different defaults for root.
# PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ '
# umask 022

# colorisation console
export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

# You may uncomment the following lines if you want `ls' to be colorized:
export LS_OPTIONS='--color=auto'
eval "`dircolors`"
alias ls='ls $LS_OPTIONS'
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'

# Some more alias to avoid making mistakes:
# alias rm='rm -i'
# alias cp='cp -i'
# alias mv='mv -i'

Besoin de firmware propriétaires ?

Parfois, votre machine a besoin de firmware spécifiques pour faire fonctionner correctement les différents matériels. Pour se faire, ajouter au fichier de source des paquets /etc/apt/sources.list le dépôt jessie-updates (dans le cas d'une debian 8) :

# jessie-updates, previously known as 'volatile'
deb http://debian.proxad.net/debian/ jessie-updates main contrib non-free
deb-src http://debian.proxad.net/debian/ jessie-updates main contrib non-free

Puis resynchroniser les sources, et installer les firmwares :

$ apt-get update
$ apt-get install firmware-linux-nonfree

Utilitaires et paquets utiles

  • htop : pour voir la charge du serveur "graphiquement" en temps réel
  • nload : pour voir le debit de données en entrée et en sortie en temps réel
  • iotop : pour voir les entrées/sorties (lecture/écriture) sur le disque dur en temps réel
  • mcrypt : librairie d'encryption servant à plein de paquets
  • curl : permet d'interroger des URL distantes (notamment)
  • unzip : permet la compression/décompression des fichiers .zip
  • rsync : permet de synchroniser des répertoires locaux et/ou distants

La commande qui va bien :

$ apt-get install htop nload iotop mcrypt curl unzip rsync

SSH

Le serveur est accessible par défaut sur le port 22 en SSH et c'est plutôt pas très très bien. Avant de modifier la configuration SSH, ajouter un nouvel utilisateur à travers lequel se connecter en remplacement de root (qui sera donc interdit de se connecter) en tapant la commande suivante dans le terminal :

$ adduser usersympa

Puis, modifier le fichier /etc/ssh/sshd_config en changeant quelques paramètres comme suit :

Pour changer le port de connection SSH (mettre une valeur au-delà de 10000 idéalement) :

Port 43210

Pour interdire la connection avec l'utilisateur root (d'où la création de l'utilisateur usersympa ci-dessus) :

PermitRootLogin no

Puisque c'est un serveur sans interface graphique, pas besoin de ça :

X11Forwarding no

Pour limiter la liste des utilisateurs autorisés à se connecter en SSH :

AllowUsers usersympa autreuser encoreunuser

FTP avec VSFTPD

Nous utiliserons VSFTPD parce qu'il faut bien en choisir un.

On va configurer VSFTPD pour :

  • restreindre les utilisateurs qui se connectent dans leur home : ils n'ont pas accès au reste des fichiers du serveurs. Une petite prison dorée quoi.
  • avoir une connection sécurisée SSL/TLS (appelée aussi SSL implicite)

Avant tout, penser à désactiver SFTP, la méthode classique de connection FTP qui accompagne SSH, en commentant la ligne suivante dans le fichier /etc/ssh/sshd_config :

#Subsystem sftp /usr/lib/openssh/sftp-server

Installation :

$ apt-get install vsftpd

Pour que la connection soit sécurisée, on va devoir créer un certificat et la clef (valables ici pendant 10 ans) qui va avec en tapant la commande :

$ openssl req -x509 -nodes -days 3650 -newkey rsa:1024 -keyout /etc/ssl/private/vsftpd.key.pem -out /etc/ssl/certs/vsftpd.cert.pem

Puis dans le fichier /etc/vsftpd.conf, modifier comme suit :

# Write enable
write_enable=YES

# Default umask for local users
local_umask=022

# Login banner
ftpd_banner=Message d'accueil affiché lors d'une connection réussie

# Chroot les users avec droits d'ecriture
chroot_local_user=YES
chroot_list_enable=YES
# Décommenter et créer ce fichier pour y mettre un user par ligne qui NE SERA PAS chrooté (pas de prison dorée pour lui)
# chroot_list_file=/etc/vsftpd.no_chroot_list

# Activer SSL
ssl_enable=YES

Mais il faut aussi ajouter à la fin de ce même fichier :

# SSL Session reuse (breaks many FTP clients if YES)
require_ssl_reuse=NO

# Passive mode
pasv_enable=YES

# Ports du Passive mode de 3000 à 3005 (à vous d'adapter si besoin)
pasv_min_port=3000
pasv_max_port=3005

# Complément au support SSL
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=YES
ssl_sslv3=YES

# Les chemins vers le certificat et la clef précédemment créés
rsa_cert_file=/etc/ssl/certs/vsftpd.cert.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.key.pem

Fail2Ban

Fail2Ban permet de bannir des IPs qui tenteraient de se connecter trop souvent (via SSH notamment) sans connaitre le mot de passe d'un compte. La technique la + classique des robots est de tester des milliers/millions de mot de passe et ça s'appelle la Force Brute ("Brut Force" pour briller dans les diners). Fail2Ban limite ces tentatives à 5 et banni l'IP 10mn par défaut.

Installation :

$ apt-get install fail2ban

Puis dans le fichier /etc/fail2ban/jail.conf modifier les valeurs comme suit (penser à mettre le bon port SSH configuré auparavant) :

destemail = votre-mail@votre-nom-de-domaine.org

action = %(action_)s

[ssh]

enabled = true
port    = 43210
filter  = sshd
logpath  = /var/log/auth.log
maxretry = 5

[ssh-ddos]

enabled = true
port    = 43210
filter  = sshd-ddos
logpath  = /var/log/auth.log
maxretry = 5

Firewall avec IPTables

Ressources

Commandes utiles

Lister les règles actuelles :

$ iptables -L

Exporter les règles actuelles :

$ iptables-save > monserveur.rules

Restorer les règles d'un fichier :

$ iptables-restore < monserveur.rules

Vider toutes les règles :

$ iptables -F

Voir les modules chargés :

$ lsmod | grep ip

Script pour remettre les règles par defaut

Dans un coin sécurisé de votre serveur, par exemple /root/scripts, créer un fichier firewall-reset.sh et restreindre son usage à root :

$ touch firewall-reset.sh
$ chmod 700 firewall-reset.sh

Dans ce fichier, mettre ceci :

#!/bin/sh

echo ""
echo "* Remet les règles iptables par default"

#----------
# Back to default Policy ACCEPT
#----------
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

#----------
# Back to default Policy for table NAT
#----------
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT

#----------
# Flush all rules
#----------
iptables -F
iptables -t nat -F

#----------
# Remove user rules
#----------
iptables -X
iptables -t nat -X

echo "[OK]"
echo ""

#----------
# Reset Fail2Ban (si installé)
#----------
service fail2ban restart

exit 0

Pour executer le fichier, mettez vous dans son répertoire et tappez :

$ ./firewall-reset.sh

Règles de base bien pratiques (script)

Toujours dans le même coin sécurisé de votre serveur, par exemple /root/scripts, créer un fichier firewall-start.sh et restreindre son usage à root :

$ touch firewall-start.sh
$ chmod 700 firewall-start.sh

Dans ce fichier, mettre ce qui suit. Notez que les ports 300 à 3005 sont ouverts pour le FTP car nous utilisons VSFTPD (voir plus haut) et que nous l'avons configuré comme tel :

#!/bin/sh

#----------
# Load needed modules
#----------
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp

#----------
# Local loop
#----------
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
iptables -A OUTPUT -o lo -j ACCEPT

#----------
# Connexions already established
#----------
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#----------
# NTP (123)
#----------
iptables -A OUTPUT -p udp --dport 123 -j ACCEPT

#----------
# NetBios (137)
#----------
iptables -A INPUT -p udp --sport 137 -j ACCEPT
iptables -A OUTPUT -p udp --dport 137 -j ACCEPT

#----------
# PING
#----------
iptables -A INPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 8 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

#----------
# DNS (53)
#----------
# UDP
iptables -A INPUT -i eth0 -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
# TCP
iptables -A INPUT -i eth0 -p tcp --sport 53 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT

#----------
# WHOIS (43)
#----------
iptables -A OUTPUT -p tcp --dport 43 -j ACCEPT

#----------
# SSH (22022)
#----------
# Incoming (22022)
iptables -A INPUT -i eth0 -p tcp --dport 22022 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22022 -m state --state ESTABLISHED -j ACCEPT
# Outgoing (22)
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# Outgoing (22022)
iptables -A INPUT -i eth0 -p tcp --sport 22022 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 22022 -m state --state NEW,ESTABLISHED -j ACCEPT

#----------
# HTTP (80)
#----------
# Incoming
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
# Outgoing
iptables -A INPUT -p tcp --sport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT

#----------
# HTTPS (443)
#----------
# Incoming
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
# Outgoing
iptables -A INPUT -p tcp --sport 443 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT

#----------
# FTP (21,3000:3005)
#----------
# Incoming
iptables -A INPUT -i eth0 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT

iptables -A INPUT -i eth0 -p tcp --dport 3000:3005 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 3000:3005 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth0 -p udp --dport 3000:3005 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -o eth0 -p udp --sport 3000:3005 -m state --state ESTABLISHED,RELATED -j ACCEPT

#----------
# SMTP (25,587)
#----------
# Incoming
iptables -A INPUT -i eth0 -p tcp --dport 25 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 25 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 587 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 587 -j ACCEPT
# Outgoing
iptables -A INPUT -i eth0 -p tcp --sport 25 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 587 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 587 -j ACCEPT

#----------
# MUNIN (4949)
#----------
iptables -A OUTPUT -p tcp --dport 4949 -j ACCEPT

#----------
# Logs
#----------
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied INPUT: " --log-level error
iptables -A OUTPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied OUTPUT: " --log-level error

#----------
# DROP everything else
#----------
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
iptables -A FORWARD -j DROP

#----------
# Reload Fail2Ban (si installé)
#----------
service fail2ban restart

exit 0

Et pour démarrer ce script automatiquement au (re)démarrage de votre serveur, modifier le fichier /etc/rc.local et avant la dernière ligne exit 0 mettre :

/root/scripts/firewall-start.sh

Script pour redémarrer le Firewall avec toutes les règles

Toujours dans le même coin sécurisé de votre serveur, par exemple /root/scripts, créer un fichier firewall-restart.sh et restreindre son usage à root :

$ touch firewall-restart.sh
$ chmod 700 firewall-restart.sh

Et dans ce fichier mettre :

#!/bin/sh

# Reset le firewall
echo ""
echo "Reset le Firewall"
/root/scripts/firewall-reset.sh
echo "[OK]"

# Start le firewall avec mes règles
echo ""
echo "Charge les règles personnalisées"
/root/scripts/firewall-start.sh
echo "[OK]"
echo ""

exit 0