Skip to content

Installation d’un serveur Ubuntu

Je reprends ce blog à l’occasion du démarrage d’un serveur Ubuntu dont j’ai besoin pour mon travail.

Je souhaite y héberger SugarCRM, une application de gestion de la relation client.

Mon choix s’est porté sur un serveur RPS de OVH. J’ai choisi de démarrer par le serveur d’entrée de gamme: Processeur Atom 1,60 Ghz et 512 Mo de RAM avec un disque ISCSI de 10 Go. Ce serveur modulaire est économique et facilement évolutif mais je m’interroge sur sa performance.

Une fois ma commande faite auprès de OVH, j’ai reçu par email l’adresse IP  du serveur et le mot de passe root, ce qui m’a permis de me connecter avec Putty en mode console.

Mon choix s’est porté sur Ubuntu 8.4 LTS en attendant la prochaine sortie de Ubuntu 10.4 LTS pour laquelle une bêta est actuellement disponible.

Je pars de l’idée que cette configuration devrait être déjà plus confortable qu’un hébergement mutualisé qui ne me donnait pas satisfaction en terme de temps de réponse.

Je vais dans ce blog retracer mes actions de prise en mains du serveur.

J’ai commencé par mettre à jour les dépôts (apt-get update) puis j’ai installé l’excellent gestionnaire de fichiers en console Midnight Commander avec un apt-get install mc.

Je peux maintenant parcourir l’arborescence et m’offrir une mise à jour de la distribution avec apt-get upgrade qui déclenche 114 mises à jour.

Mes premières actions seront

  1. d’y installer le serveur web apache avec le moteur php et les bases de donnée MySQL,
  2. de le sécuriser avec un parefeu et une surveillance des tentatives d’intrusions,
  3. d’y créer un utilisateur pour éviter de me connecter en root,
  4. de paramétrer les hôtes virtuels du serveur web pour héberger des domaines,
  5. d’y installer le script phpmyadmin pour gérer les bases MySQL, en sécurisant l’accès au script,
  6. d’activer l’envoi des emails par la fonction mail() de php.

J’aimerais en 24h pouvoir tester cette configuration de base avec SugarCRM.

script de sauvegarde d’une base MySQL

Maintenant que je sais programme une tâche cron, je peux mettre en place mon script de sauvegarde.

#!/bin/bash
host=localhost
user=mon_utilisateur
password=mon_mot_de_passe
dir=/home/utilisateur/backup/
db=ma_base
ext=.sql
file=$db$ext
cd $dir
mysqldump -u$user -p$password -h$host $db > $file
mutt -s "backup de la base " -a $file  moi@email.com <.
date=$(date '+%d-%m-%Y | %H:%M')
echo "$date Sauvegarde réalisée et envoyée"

Ce petit script très simple réalise un dump et l’envoie par email grâce au programme mutt que j’ai installé au préalable.

Mise en place d’une tâche cron

Je viens de découvrir le fonctionnement des tâches cron qui se lancent à une date, un horaire fixe, indispensables pour effectuer des sauvegardes régulières des bases MySQL par exemple.

cron, du grec chronos, est le programme qui permet d’exécuter des scripts à date ou heure déterminée à l’avance et crontab le programme qui permet d’éditer les tables du programme cron.

cron est un service qui tourne en tâche de fond.

sudo ps -edf | grep cron

permet de vérifier que le service cron tourne bien en tâche de fond.

A défaut,il faut le relancer avec

sudo /etc/init.d/cron reload

Pour paramétrer une tâche, j’utilise donc crontab

crontab -l permet de lister pour mon utilisateur les tâches cron existantes.

crontab -e permet d’éditer la table pour créer/modifier ou supprimer une tâche.

Chaque ligne de la table correspond à une tâche à exécuter et est notée de la façon suivante :

mm hh jj MMM JJJ tâche > log

Dans cette syntaxe :

  • mm représente les minutes (de 0 à 59)
  • hh représente l’heure (de 0 à 23)
  • jj représente le numéro du jour du mois (de 1 à 31)
  • MMM représente le numéro du mois (de 1 à 12) ou l’abréviation du nom du mois (jan, feb, mar, apr, …)
  • JJJ représente l’abréviation du nom du jour ou le chiffre correspondant au jour de la semaine (0 représente le dimanche, 1 représente le lundi, …, 7 représente le dimanche)
  • tâche représente la commande ou le script shell à exécuter
  • log représente le nom d’un fichier dans lequel stocker le journal des opérations. Si la clause > log n’est pas spécifiée, cron enverra automatiquement un courriel de confirmation.

Envoyer des emails avec php

Mon problème avec ma découverte du serveur RPS sous Ubuntu est de réussir à capitaliser mon expérience.

Mon objectif serait de pouvoir paramétrer en 1 heure un serveur web complet en partant d’une distribution nue.

Aujourd’hui, je me suis reposé la question, après avoir réinstallé complètement mon serveur, de comment envoyer un email avec php.

En installant les paquets apache, php5 et MySql,  j’ai pu installer un site opérationnel sous WordPress mais je n’ai pas reçu le mot de passe comme j’aurais du le recevoir.

Pourtant le serveur de messagerie exim est bien installé dans la distribution de base mais sa configuration par défaut ne lui permet d’envoyer des emails vers des domaines externes au serveur.


sudo dpkg-reconfigure exim4-config

Une reconfiguration d’Exim permet de modifier l’option. J’ai choisi l’option « site internet » et tout fonctionne.

Contrôler le démarrage du serveur

Le runlevel est un niveau de démarrage dans Linux.

Selon le runlevel activé, des scripts bash seront ou pas lancés au démarrage pour mettre en route certains services.

Ces scripts shell sont dans le répertoire /etc/init.d avec des liens symboliques pointant vers scripts dans les répertoires /etc/rc0.d, /etc/rc1.d, /etc/rc2.d, /etc/rc3.d, /etc.rc4.d, /etc/rc5.d, /etc/rc6.d et /etc/rcS.D.

Pour inscrire un script pour tous les runlevel on utilisera la commande:


update-rc.d mon_script defaults

Le script peut comporter des ordres start ou stop pour s’exécuter ou pas à un runlevel donné. Par défaut, il sera exécuté à tous les runlevel.


Un outil est bien pratique pour faire le point sur les scrips qui sont démarrés:  rcconf


sudo apt-get install rcconf
sudo rcconf


Apparemment, rcconf ne prends toutes les applications en compte dans sa synthèse mais seulement les plus répandues.

Les services avec une étoile sont actifs, les autres non. La barre d’espacement permet d’inverser le statut.

Une autre application est sysv-rc-conf qui permet de visualiser tous les services.

Chaque ligne représente un service et chaque colonne représente un niveau d’exécution.

La barre d’espacement permet de changer le statut d’un service.

Pour mémoire, il existe donc 6 runlevel sous Ubuntu:

  1. Le runlevel 0 correspond à l’arrêt du système,
  2. Le runlevel 1 correspond au démarrage single-user,
  3. Le runlevel 2 correspond mode de démarrage normal,
  4. Les runlevels 3-5 correspondent à des modes de démarrage que l’on peut se configurer,
  5. Le runlevel 6 correspond au redémarrage.

Surveiller les logs

Surveiller les logs est bien utile pour gérer un serveur dédié.


Quelques logs utiles que je suis particulièrement:

/var/log/auth.log –> les logs de connexion utilisateur,

/var/log/apache2/error.log –> les logs d’erreur apache,

/var/log/apache2/access.log –> les logs de connexion à apache, pratique pour repérer les moteurs de recherche.


LA solution pour lire les logs confortablement est d’utiliser tail. Par défaut, tail affiche les 10 dernières lignes du fichier.

tail /var/log/auth.log 

Créer des hôtes virtuels sur le serveur web

Le principe d’un hôte virtuel est de pouvoir faire fonctionner plusieurs serveurs web sur une même machine.

Ainsi, un même serveur physique peut répondre à des requêtes http://www.domaine1.com et http://www.domaine2.com ou encore http://forum.domaine3.com.

L’internaute ne s’aperçoit pas qu’il s’agit d’un même serveur physique.

Le fonctionnement des hôtes virtuels avec apache est à la base des hébergements mutualisés.

Avec apache1, ces hôtes virtuels étaient créés dans le fichier de configuration /etc/apache/httpd.conf.

Apache2 procède différemment : il utilise un fichier de configuration par site hébergé, à positionner dans le répertoire /etc/apache2/sites-available/ .

Dans ce répertoire vous trouverez un fichier intitulé default.


NameVirtualHost *
<VirtualHost *>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www/
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog /var/log/apache2/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /var/log/apache2/access.log combined
        ServerSignature On

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

</VirtualHost>


Pour héberger un nouveau site, il sera donc nécessaire de créer un fichier de configuration ad-hoc.

Copiez le fichier default avec

cp /etc/apache2/sites-available/default /etc/apache2/sites-available/domaine1.com


puis éditez ce fichier ainsi créé pour le personnaliser ainsi:


NameVirtualHost *:80
<VirtualHost *:80>
        ServerAdmin monadresse@domaine1.com
        ServerName domaine1.com
        ServerAlias www.domaine1.com
        DocumentRoot /var/www/domaine1.com
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/domaine1.com>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

Le reste du fichier est inchangé.

La racine d’apache est dans /var/www et des sous-répertoires seront donc nécessaires pour chaque hôte. Ce sous-répertoire peut être éventuellement localisé ailleurs dans l’arborescence pourvu que vous spécifiez l’adresse dans le fichier de configuration avec la directive DocumentRoot.

Un paramétrage du fichier /etc/hosts sera également nécessaire pour permettre la résolution de noms.


127.0.0.1       domaine1.com


L’article ici expose la configuration des hôtes virtuels en les distinguant par leur nom. D’autres méthodes reposent soit sur une différenciation par l’adresse IP lorsque le serveur physique dispose de plusieurs cartes réseaux avec autant d’adresses IP, soit sur une différenciation par le port.

La documentation de référence est parfois utile.

Création d’un utilisateur

Il est temps de me connecter sur mon serveur autrement qu’en root.

Pour créer un utilisateur, deux solutions sont à ma disposition: soit la commande useradd, soit la commande adduser.

La commande adduser présente l’avantage de poser de façon interactive les questions:

root@r1234:~# adduser donald
 Ajout de l'utilisateur « donald »...
 Ajout du nouveau groupe « donald» (1000)...
 Ajout du nouvel utilisateur « donald » (1000) avec le groupe « donald »...
 Création du répertoire personnel « /home/donald »...
 Copie des fichiers depuis « /etc/skel »...
 Entrez le nouveau mot de passe UNIX :
 Retapez le nouveau mot de passe UNIX :
 passwd: password updated successfully
 Changing the user information for donald
 Enter the new value, or press ENTER for the default
 Full Name []: Donald
 Room Number []:
 Work Phone []:
 Home Phone []:
 Other []:
 Ces informations sont-elles correctes ? [o/N] o

Maintenant je pourrais me connecter en tant que Donald et j’utiliserais la commande sudo lorsque j’aurais besoin des privilèges administrateur. Cela nécessite toutefois que l’utilisateur donald soit ajouté à la liste des sudoers avec la commande visudo.


Bannir les attaquants

De ma précédente expérience, les attaques pour tenter de pénétrer le serveur étaient systématiques: 1 par minute.

fail2ban est un logiciel qui analyse les logs pour repérer les erreurs d’authentification et bannir les adresses IP  concernées.

Par défaut, la prison ssh est activée et le bannissement se fait au bout de 3 erreurs d’authentification et pour une durée de 600 secondes, soit 10 minutes.

En modifiant le fichier /etc/fail2ban/jail.conf, je peux ajouter des prisons supplémentaires pour des erreurs d’authentification sur apache par exemple.

apt-get install fail2ban apporte donc une sécurité supplémentaire au serveur.

Installation d’un pare-feu

Mon serveur a 30 minutes d’existence et son espérance de vie est courte sur Internet.

Il est donc urgent de commencer à filtrer les paquets entrants, voire les paquets sortants.

J’ai donc créé un fichier /etc/init.d/iptables avec les lignes suivantes


#!/bin/bash
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport ssh -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 80 -j ACCEPT
iptables -P INPUT DROP
iptables -I INPUT 2 -i lo -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT


Dans l’ordre ces lignes me permettent:

  1. de recevoir du trafic sur une connexion déjà établie
  2. de recevoir le trafic entrant sur le port ssh
  3. de recevoir le trafic entrant sur le web
  4. de bloquer le reste du trafic
  5. d’autoriser le trafic local
  6. d’autoriser les réponses au ping entrant

J’ai rendu le script exécutable (sudo chmod +x /etc/init.d/iptables) et  je l’ai ajouté aux scripts exécutés au démarrage (sudo update-rc.d iptables defaults)

sudo chmod +x /etc/init.d/iptables
sudo update-rc.d iptables defaults

J’ai maintenant plus de temps pour affiner les règles de filtrage et notamment créer des règles pour le trafic sortant.

Installation d’un serveur LAMP

LAMP est un acronyme pour désigner un serveur web Apache hébergé sur un système d’exploitation Linux avec le moteur de scripts PHP et les bases de données MySQL.

J’installe donc les paquets suivants: apache2, mysql-server, php5, php5-mysql.


apt-get install apache2 mysql-server php5 php5-mysql


Avec les dépendance, j’obtiens 21 nouveaux paquets:

Les NOUVEAUX paquets suivants seront installés :
apache2 apache2-mpm-prefork apache2-utils apache2.2-common libapache2-mod-php5 libapr1 libaprutil1 libdbd-mysql-perl libdbi-perl libmysqlclient15off libnet-daemon-perl libplrpc-perl libpq5 libxml2 mysql-client-5.0 mysql-common mysql-server mysql-server-5.0 php5 php5-common php5-mysql

Je suis invité à fournir sans délai un mot de passe pour l’utilisateur root de MySQL.

Un serveur apache opérationnel renvoie la chaine « It Works ! » grâce au fichier index.html situé dans /var/www.

Effectivement mon serveur est opérationnel tant de l’extérieur en l’interrogeant par l’adresse IP que de l’intérieur en faisant un links 127.0.0.1.

Links est un navigateur en mode texte qui est parfois pratique pour vérifier le fonctionnement d’un serveur web.

Cela me rappelle que mon serveur est ouvert à tous vents et qu’un pare-feu s’impose.