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.
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
puisvisudo
)
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
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 commandegrep 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 doncworker_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.
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; }
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.
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.
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
Derniers commentaires