Tutoriel : Serveur dédié web

J’ai récemment acheté un serveur Kimsufi 2G chez OVH (ici) et après avoir été très patient, j’ai reçu mon premier serveur dédié. Après deux semaine d’utilisation, tout tourne parfaitement et je vais donc vous expliquer ici comment configurer un serveur dédié pour servir un ou plusieurs sites web.

dedicated_server

Ce tutoriel est le résultat de plusieurs essais de configuration. Je ne prétends pas avoir la config parfaite et utiliser les meilleurs logiciels, mais ce tutoriel peut servir de base pour installer votre serveur dédié. Le système de base est une Debian 7 mais la plupart des logiciels et configurations seront identiques pour d’autres distributions comme Ubuntu par exemple.

Installation et configuration

Partitions

Je conseille vivement de refaire les partitions par défaut. Effectivement, une grande place est donnée au home et je travaille beaucoup plus dans mon /var/ que dans mon /home.

Avec OVH, rendez-vous dans votre Manager, puis dans la section Services, cliquez sur Réinstallez/Changez d’OS. Un assistant se lance. Dans la deuxième partie, sélectionnez Partitionnement personnalisé pour indiquer la configuration des partitions. Validez les étapes suivantes et patientez quelques minutes.

Pour ma part, un /home/ de 10Go, un /backup/ de 100Go, un /var/ de 300Go et le reste pour la racine (j’ai appris ensuite qu’il vallait mieux créer une partition pour /tmp/ mais trop tard…). Mon swap fait 4Go pour 2go de RAM.

SSH

Connectez-vous à votre serveur avec la commande ssh user@ip ou avec un logiciel comme Putty.

Pour lancer des commandes d’administration, deux choix sont possibles :

  • lancer les commandes en tant que root (su - pour se connecter)
  • installer sudo (apt-get install sudo puis visudo)

Pour toutes les commandes suivantes, je vais considérer que vous êtes connecté en tant que root.

Lancez une mise à jour des paquets :

apt-get update
apt-get upgrade

Modifiez le mot de passe root (il vous a normalement été envoyé par mail) pour plus de sécurité :

passwd root

Créez un utilisateur, cyril par exemple :

adduser cyril

Installez un éditeur de fichiers, je vous laisse le choix mais j’ai une petite préférence pour vim.

apt-get install vim

Éditez le fichier de configuration du serveur SSH pour améliorer la sécurité :

vim /etc/ssh/sshd_config

Modifiez la ligne Port 22 par Port 42 par exemple. Attention, les prochaines connexions se feront sur le port 42 (ssh -p 42 user@ip).

Interdisez la connexion en tant que root en passant PermitRootLogin yes à PermitRootLogin no. Il faudra désormais se connecter avec l’utilisateur créé précédemment.

Port 42
PermitRootLogin no
Protocol 2
PermitRootLogin no
PermitEmptyPasswords no
MaxStartups 10:30:60

Redémarrez le serveur SSH (service ssh restart) et vérifiez que la connexion fonctionne toujours. Il est très conseillé de fonctionner avec des clés de sécurité. Voici un tutoriel détaillant les étapes nécessaires http://doc.ubuntu-fr.org/ssh#authentification_par_un_systeme_de_cles_publiqueprivee

NTP

Votre machine doit toujours être à l’heure. Pour cela, installez ntp :

apt-get install ntp ntpdate

Editez le fichier /etc/ntp.conf et modifiez les serveurs par défaut avec ceux-ci (serveurs français)

server 0.fr.pool.ntp.org
server 1.fr.pool.ntp.org
server 2.fr.pool.ntp.org
server 3.fr.pool.ntp.org

Redémarrez ensuite le service NTP en faisant :

service ntp restart

Shell

Modifiez le fichier /root/.bashrc et les fichiers .bashrc pour chaque utilisateur et décommentez les lignes suivantes :

export LS_OPTIONS='--color=auto'
eval "`dircolors`"
alias ls='ls $LS_OPTIONS -h'
alias ll='ls $LS_OPTIONS -lah'
alias l='ls $LS_OPTIONS -lAh'

On va aussi rendre vim un peu plus utilisable en éditant le fichier /etc/vim/vimrc et en ajoutant (ou modifiant) :

syntax on
set background=dark
set showmatch
set ignorecase

Mail

Pour que votre machine puisse transférer les mails, il faut installer le paquet sendmail :

apt-get install sendmail

et configurer le fichier /etc/aliases avec votre mail :

root: votremail@gmail.com

Sources

Les sources de debian n’étant pas forcément à jour sur les logiciels sensibles comme Apache ou PHP, nous allons ajouter les sources du projet DotDeb qui nous permettront d’avoir les derniers patchs de sécurité. Pour cela, éditez le fichier /etc/apt/sources.list et ajouter les lignes suivantes :

deb http://packages.dotdeb.org wheezy all
deb-src http://packages.dotdeb.org wheezy all

Cette source n’étant pas connue, il faut rajouter la clé correspondante à notre système :

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | sudo apt-key add -

On met ensuite à jour les paquets comme précédemment :

apt-get update
apt-get upgrade

Nginx

J’ai décidé d’installer nginx (prononcer Engine X) plutôt que le très célèbre Apache pour des raisons de performances. J’ai lu plusieurs posts expliquant que nginx, bien configuré, pouvait supporter plus de connexions en parallèle. Je n’ai pas fait de tests probants, mais j’aime la nouveauté et j’ai donc testé nginx. Voici comment installer et configurer un système LEMP.

Installation

Tout simplement (grâce à nos sources modifiées) :

apt-get install nginx

Les commandes à connaître pour nginx :

service nginx stop/start/restart
service nginx configtest //pour tester la configuration avant de la charger
service nginx reload //charge la nouvelle configuration sans coupure

Configuration

La configuration de nginx s’articule autour de 2 éléments. Le fichier /etc/nginx/nginx.conf contient la configuration générale et le dossier /etc/nginx/sites-available/ contient les fichiers de configuration de chaque bloc (site). Commençons par le premier :

#Configuration générale
#Utilisateur
user www-data;
#Nombre de process
worker_processes 4;
#Ficheir du processus
pid /var/run/nginx.pid;
#Nombre de fichiers ouverts en même temps par un process
worker_rlimit_nofile 100000;

#Gestion des connexions
events {
    #Chaque process peut accepter 1024 connections
    worker_connections 1024;
    #Chaque process peut
    multi_accept on;
    #Utilise la distribution des connexions epoll (meilleur pour linux > 2.6)
    use epoll;
}

#Gestion du coeur http
http {
    #Permet l'utilisation de sendfile (au lieu de read/write)
    sendfile on;
    #Envoie les headers en une fois
    tcp_nopush on;
    #N'utilise pas de buffer
    tcp_nodelay on;
    #Gestion des timeouts
    keepalive_timeout 20;
    client_header_timeout 20;
    client_body_timeout 20;
    reset_timedout_connection on;
    send_timeout 20;
    client_max_body_size 20M;

    #Supprime les logs d'accès pour optimiser les accès disques
    access_log off;
    #Loggue uniquement les erreurs critiques (supprimer le crit pour debug)
    error_log /var/log/nginx/error.log crit;
    types_hash_max_size 2048;
    #Sécurité
    server_tokens off;

    #Options pour l'encoding et le type
    include /etc/nginx/mime.types;
    default_type text/html;
    charset UTF-8;

    #Options pour la compression
    gzip on;
    gzip_disable "msie6";
    gzip_proxied any;
    gzip_min_length 256;
    gzip_comp_level 4;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Voici le mien. Pour détailler un peu, voici les directives importantes :

  • worker_processes 4 -> indique le nombre de processus nginx tournant en parallèle. L’idéal est de choisir ce nombre en fonction du nombre de coeurs (fictifs) de votre machine. Pour connaître le nombre de coeurs, aidez vous de la commande grep processor /proc/cpuinfo | wc -l
  • worker_connections 1024; -> Le nombre de connexions simultanées que peut gérer nginx. Ce nombre varie selon la quantité de RAM disponible et selon le processeur. Le nombre de clients connectés en même temps sera donc worker_processes * worker_connections.
  • server_tokens off; -> Indique à nginx de ne pas montrer sa version dans les pages d’erreurs (utile en matière de sécurité).

Ensuite, voici un exemple de fichier de configuration default :

server {
    listen 80;
    listen [::]:80 default_server ipv6only=on;

    server_name domain.com;

    root /var/www/;

    index index.php index.html index.htm;

    access_log /var/log/nginx/access_default.log;
    error_log /var/log/nginx/error_default.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_index index.php;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include /etc/nginx/fastcgi_params;
    }

    # Serve static files directly
    location ~* \.(png|jpe?g|gif|ico)$ {
        expires 1y;
        access_log off;
        try_files $uri $uri/ @rewrite;
        gzip off;
    }
    location ~* \.(css)$ {
        expires 1d;
        access_log off;
    }
    location ~* \.(js)$ {
        expires 1h;
        access_log off;
    }
}

Détaillons encore quelques éléments de la configuration :

  • listen 80 -> indique le port d’écoute du serveur web.
  • server_name -> indique le nom de domaine associé à ce bloc. En définissant plusieurs blocs, vous pouvez héberger plusieurs domaines sur le même serveur nginx.
  • root /var/www/ -> indique le dossier où se trouvent les fichiers web (PHP, HTML, …)
  • index -> indique la liste des fichiers considérés comme des index.
  • access_log -> indique le fichier de log pour les accès. Il peut être utile de donner un fichier de log par domaine.
  • error_log -> la même chose pour les logs en erreur (erreurs nginx et php).
  • location -> indique des options particulières pour des fichiers/dossiers. Ici, pour les fichiers statiques (css, images, js), on les sert directement et on ne les logue pas.

Pour activer un bloc (site), il faut faire un lien symbolique dans le répertoire sites-enabled :

ln -s /etc/nginx/sites-available/exemple /etc/nginx/sites-enabled/

Une fois ces fichiers modifiés, vous pouvez tester la configuration et recharger nginx.

service nginx configtest
service nginx reload

Si tout fonctionne bien, vous pouvez vous connecter sur votre domaine ou directement via l’ip de votre machine sur un navigateur. Une page avec Welcome to nginx! doit s’afficher.

On trouve beaucoup de tutoriels et de documentation sur nginx. N’hésitez pas à tester plusieurs configurations pour optimiser votre serveur.

php5-fpm

Nginx ne gère pas les fichiers php. Pour cela, il faut installer PHP-FPM qui est un gestionnaire de processus FastCGI pour PHP. Pour cela, la commande habituelle :

apt-get install php5-fpm

Rien à configurer pour l’instant, juste à démarrer :

service php5-fpm start

Grâce à ces lignes précédemment ajoutées dans le fichier de configuration de nginx, les accès aux fichiers php sont transmis par nginx aux processus php-fpm :

location ~ .php$ {
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    include /etc/nginx/fastcgi_params;
    fastcgi_index index.php;
}

Il peut aussi être utile d’installer quelques extensions php :

apt-get install php5-cgi php5-mysql php5-curl php5-gd

Créons maintenant un fichier index.php tout simple pour vérifier que tout fonctionne :

vim /var/www/index.php

Connectez-vous à l’adresse http://domain.com pour tester.

Il est possible d’optimiser nginx et php5-fpm en fonction de votre RAM et du processeur. Je ferai sûrement un article prochainement détaillant cette partie.

php-apc

PHP est un langage qui demande que chaque page php soit traitée au moment où un visiteur la demande. Nous allons installer un cache PHP qui permettra d’alléger php-fpm. Attention, php-apc est la version debian et php5-apc est la version Dotdeb (plus récente).

apt-get install php5-apc

Rien à configurer pour que cela fonctionne. Vous pouvez éditer le fichier /etc/php5/fpm/conf.d/20-apc.ini pour modifier la taille du cache ou d’autres options. Si le taux de fragmentation augmente, c’est que la taille du cache n’est pas assez grande.

Voici ma configuration :

extension=apc.so
; enable APC
apc.enabled=1
; The number of shared memory segments
apc.shm_segments=1
; The size of each shared memory segment
apc.shm_size=256M
;Max file size cached
apc.max_file_size=10M
;Max files cached
apc.num_files_hint=20000
apc.user_entries_hint=20000
; The number of seconds a cache entry is allowed to idle in a slot in case this
; cache entry slot is needed by another entry.
apc.ttl=7200
apc.user_ttl=7200
apc.gc_ttl=3600
;Filter
;apc.filters = "-apc\.php"

 

Pour suivre l’état du cache, il suffit de télécharger un fichier :

wget -O /var/www/apc.php http://svn.php.net/viewvc/pecl/apc/tags/APC-3.1.14/apc.php?revision=328952&view=co

Rendez-vous ensuite sur la page http://domain.com/apc.php pour voir l’état du cache.

Ici, après 1 heure d’utilisation, 99% des requêtes utilisent le cache APC.

apc

Mysql

Installons Mysql et phpmyadmin qui permettra d’administrer plus facilement nos bases :

apt-get install mysql-server phpmyadmin
mysql_secure_installation

La deuxième commande va modifier le mot de passe root, interdire l’accès depuis l’extérieur et supprimer quelques tables inutiles.

Piwik

Piwik collecte des données sur les visiteurs comme Google Analytics. Le grand avantage est que les données sont chez vous, donc sous votre contrôle et anonymes.

Pour l’installer, je vous invite à suivre la doc officielle.

Munin

Munin est ou outil de monitoring de vos différents services et du système. Il permet d’obtenir des graphiques et d’alerter lorsque certaines valeurs dépassent des seuils. Pour l’installer, suivre mon précédent tutoriel. A vous de l’adapter pour monitorer les services nécessaires.

Pour nginx, deux choses à faire. Premièrement, activer les plugins Munin et redémarrer munin :

ln -s /usr/share/munin/nginx* /etc/munin/plugins/
service munin-node restart

Deuxièmement, activer nginx-status en ajoutant ce bout de code dans le fichier de configuration /etc/nginx/sites-available/default

location /nginx_status {
    stub_status on;
    access_log   off;
    allow 127.0.0.1;
    deny all;
}

munin_example

Fail2ban

Fail2ban est outil qui permet de se protéger contre les éventuelles attaques. L’idée est de scanner les fichiers logs de votre système pour trouver les ip posant problème (attaque ddos ou recherche de faille) et de les bannir via des règles iptables.

Attention, si vous configurez mal Fail2ban, vous pouvez vous bloquer vous-même 🙁

apt-get install fail2ban

Modifier  le fichier /etc/fail2ban/jail.conf :

[ssh-ddos]
enabled  = true 

et ajouter pour nginx
[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

[nginx-proxy]
enabled = true
action = iptables-multiport[name=NoProxy, port="http,https"]
filter = nginx-proxy
logpath = /var/log/nginx*/*access*.log
maxretry = 0
bantime  = 86400 # 1 day

Créer ensuite les filtres suivants dans /etc/fail2ban/filter.d/ :

# Proxy filter /etc/fail2ban/filter.d/nginx-proxy.conf:
#
# Block IPs trying to use server as proxy.
#
# Matches e.g.
# 192.168.1.1 - - "GET http://www.something.com/
#
[Definition]
failregex = ^<HOST> -.*GET http.*
ignoreregex =

# Noscript filter /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 = ^<HOST> -.*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: <HOST>
            user .* was not found in.*client: <HOST>
            user .* password mismatch.*client: <HOST>

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 = ^<HOST> -.*POST /sessions HTTP/1\.." 200
ignoreregex =

Pour voir les ip bannies pour ssh, faire un fail2ban-client status ssh.
Pour autoriser à nouveau une ip, fail2ban-client get ssh actionunban 10.0.0.1 par exemple.

fail2ban

Monit

Monit est un outil d’alerting. Son objectif est de tester tous les services critiques et de les redémarrer s’il détecte un problème. Si le service ne redémarre pas, un mail vous sera envoyé.

Monit est à installer en tout dernier, car vous allez beaucoup jouer avec les configurations des services installés plus tôt. A chaque fois que vous allez les redémarrer, vous allez recevoir un mail.

apt-get install monit

Ensuite, il faut modifier le fichier /etc/monit/conf.d/maconfig pour indiquer les services à surveiller :

set daemon  120                                # On vérifie toutes les 120 secondes
set logfile syslog facility log_daemon
set mailserver localhost
set mail-format {
subject: [Monit] $HOST - $SERVICE $EVENT
}
set alert votremail@gmail.com                     # Destinataire
set httpd port 1357 and                        # Port pour l'accès à l'interface web
allow user:password                         # login et mot de passe de connexion

# Scripts de surveillance des services
# Nginx2
check process nginx with pidfile /var/run/nginx.pid
group www
start program = "/etc/init.d/nginx start"
stop program = "/etc/init.d/nginx stop"
if failed host domain.fr port 80
protocol http then restart
if 5 restarts within 5 cycles then timeout
if cpu > 80% for 2 cycles then alert
if cpu > 90% for 5 cycles then restart
if children > 250 then restart

# MySQL
check process mysqld with pidfile /var/run/mysqld/mysqld.pid  # a adapter au serveur
group database
start program = "/etc/init.d/mysql start"
stop program = "/etc/init.d/mysql stop"
if failed host 127.0.0.1 port 3306 then restart
if 5 restarts within 5 cycles then timeout

# SSH
check process sshd with pidfile /var/run/sshd.pid
group ssh
start program "/etc/init.d/ssh start"
stop program "/etc/init.d/ssh stop"
if failed host 127.0.0.1 port 42 protocol ssh then restart
if 5 restarts within 5 cycles then timeout

En suivant les exemples ci-dessus, vous pouvez ajouter autant de services que vous voulez. Ensuite, rendez-vous à l’adresse http://domain.com:port pour voir l’état du monitoring.
monit

Backup

Utilisez backup-manager pour effectuer les sauvegardes.

Astuces

J’ai installé le paquet htop, qui est une version améliorée de top (visualisation des programmes, consommation mémoire/cpu).

Voilà, ce tutoriel touche à sa fin. N’hésitez pas à commenter si vous avez besoin d’aide ou si j’ai fait une erreur.
Voici mes sources, désolé si j’en ai oublié:

Serveur
http://www.alsacreations.com/tuto/lire/621-Configuration-d-un-serveur-dedie-de-A-a-Z.html
http://www.papygeek.com/series/installer-un-serveur-web-guide-complet/
http://www.pontikis.net/blog/debian-wheezy-web-server-setup

Nginx
http://nls.io/post/optimize-nginx-and-php-fpm-max_children
http://www.howtoforge.com/running-phpmyadmin-on-nginx-lemp-on-debian-squeeze-ubuntu-11.04
https://blog.pablo-ruth.fr/index.php/optimisation-web-installer-nginx-php-fpm-apc-sur-debian-squeeze/
http://howtounix.info/howto/nginx-php-fpm-apc-on-debian
http://willdurand.fr/dedibox-v3-nginx-php-fpm-apache2-apc-memcached-mysql/
http://jbma.me/blog/un-site-enfin-performant-grace-a-nginx-et-varnish/
http://rasberrypibeginnersguide.tumblr.com/post/27283563130/nginx-php5-on-raspberry-pi-debian-wheezy
http://www.tropfacile.net/doku.php/raspberry-pi/comment-installer-un-serveur-web-nginx

APC
http://gregrickaby.com/the-perfect-apc-configuration/
http://www.woueb.net/2011/04/11/accelerateur-php-apc/

Fail2ban
http://buzut.fr/2012/11/19/installer-et-parametrer-fail2ban/
http://snippets.aktagon.com/snippets/554-how-to-secure-an-nginx-server-with-fail2ban
http://www.fail2ban.org/wiki/index.php/NginX

Vous aimerez aussi...

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *