Mémo serveur web (LAMP linux Apache PHP MySql) multi-sites complet + webdav pour les nuls

16/8/2009: correction d'un petit oubli dans le fichier de configuration du VHOST

Intro

indien J'avais écrit différents mémos lors de la configuration de la dédibox qui héberge entre autres ce blog. Je m'aperçois que j'ai affiné depuis la configuration. L'originalité[1] de ce tuto est de remplacer le FTP par Webdav.

Prérequis

  • Un serveur Débian 5.0 dans mon cas, mais ça marchera de la même façon pour toutes les distributions basées sur débian. (ubuntu par exemple).
  • Si le serveur est derrière une passerelle, faire une redirection du port 80 et du port 443 . pour qu'on puisse y accéder depuis internet.
  • Un nom de domaine et au moins un enregistrement de type A ou CNAME pointant vers l'IP publique de votre serveur.

Appache PHP MySQL

Installer les paquets:

apt-get install apache2 apache2-doc mysql-server php5 libapache2-mod-php5 php5-mysql libapache2-mod-auth-mysql

Redémarrez apache (pour qu'il prenne en compte PHP):

/etc/init.d/apache2 restart

Il demande de choisir le mot de passe root de MySql puis de le confirmer. Pour apache ,ouvrir dans un navigateur l’URL http://XXX.XXX.XXX.XXX/ pour tester apache. Une page "It Works !" s’affiche, c’est bon ! Pour vérifier le fonctionnement de php, éditer un fichier de test. vi /var/www/phpinfo.php.dedans on y met :

<?php
  phpinfo();
?>

On teste http://XXX.XXX.XXX.XXX/phpinfo.php. Si au moment d'ouvrir la page il propose de télécharger le fichier, c'est que c'est raté.

Les sites virtuels d’apache

MAJ 6/12/2010: j'ai rédigé là un exemple (les sites tinad.fr) de gestion DNS et des VHOST multi-site.

Dans la configuration par défaut , quelque soit la manière d'atteindre le serveur web, on tombe sur le site qui se trouve dans le repertoire /var/www Si on souhaite héberger plusieurs sites, on utilise les virtualhosts.

Je fais l'impasse sur la configuration des DNS. Une configuration de bind dans un réseau local est un exercice que je conseille pour comprendre le fonctionnement des DNS. Pour le fonctionnement normal, je conseille d'utiliser l'interface du registar, c'est moins galère.

L'idée est d'avoir plusieurs enregistrements de type A (ou CNAME) qui pointent vers l'IP publique de votre machine.

En fonction que l'utilisateur ait entré http://serveur.domaine1.fr ou http://serveur.domaine2.fr, Appache est capable de le détecter et de l'orienter vers un repertoire différent. Pour faire un Vhost: Pour ce site (blog-du-grouik.tinad.fr)

je créé un fichier /etc/apache2/sites-available/blog-du-grouik.tinad.fr tel que ceci:

NameVirtualHost *:80

<VirtualHost *:80>
ServerName blog-du-grouik.tinad.fr
DocumentRoot /var/www/blog-du-grouik.tinad.fr
</VirtualHost>

Je crée le dossier, J'active le Vhost et redémarre apache:

#Créer le dossier où sera le site virtual
mkdir /var/www/blog-du-grouik.tinad.fr
#Changer le propriétaire
chown www-data:www-data /var/www/blog-du-grouik.tinad.fr
#activer le Vhost:
a2ensite blog-du-grouik.tinad.fr
#Redémarrer Apache:
/etc/init.d/apache2 restart

On teste simplement en créant un fichier HTM dans le repertoire et en l'ouvrant dans un navigateur.

Webdav en HTTPS sur le repertoire web.

Webdav et pas FTP: parceque, ça me permet de faire l'original par rapport aux autres tutos, que c'est plus sécurisé (en https) que le ftp, et que comme je ne l'ai pas mis en place, ça me permet de découvrir un truc.

J'ai principalement utilisé cette documentation

Création de la base de données qui servira pour l'authentification

mysqladmin -u root -p create webdav

se connecter à la base de bonnées:

mysql -u root -p

Créer l'utilisateur webdav_admin. Remplacez webdav_admin_password par votre mot de passe.

GRANT SELECT, INSERT, UPDATE, DELETE ON webdav.* TO 'webdav_admin'@'localhost' IDENTIFIED BY 'webdav_admin_password';
FLUSH PRIVILEGES;

Créer la table:

USE webdav;
create table mysql_auth (
username char(25) not null,
passwd char(32),
groups char(25),
primary key (username)
);

On ajoute l'utilisateur Gnieark dans le groupe blog-du-grouik.tinad.fr; Remplacez Gnieark par votre utilisateur et gniearkpwd par le mot de passe de votre choix:

INSERT INTO `mysql_auth` (`username`, `passwd`, `groups`) VALUES('gnieark', MD5('gniearkpwd'), 'blog-du-grouik.tinad.fr');
quit;

On rajoute aussi l'user gnieark@blog-du-grouik.tinad.fr Utilisé dans certaines conditions, ce sera ça l'user.

INSERT INTO `mysql_auth` (`username`, `passwd`, `groups`) VALUES('gnieark@blog-du-grouik.tinad.fr', MD5('gniearkpwd'), 'blog-du-grouik.tinad.fr');
quit;

Création d'un certificat: On va faire un certificat auto-signé. Pour un serveur en production il est conseillé d'acheter un certificat. Il est possible d'en avoir là des clés ssl certifiées gratuites. Cependant ils ne sont pas reconnus comme autorité de certification par tous les navigateur (Pas IE). Création du certificat racine :

cd ~
/usr/lib/ssl/misc/CA.pl -newca

Répondre aux questions de cette façon quand j'ai laissé vide c'est qu'il n'y a rien (ou facultif), appuyez simplement sur entree. Le champs le plus important est Le "common name" correspond au nom du VHOST (blog-du-grouik.tinad.fr dans mon cas) Je ne met pas de challenge password!

  • CA certificate filename (or enter to create)
  • Enter PEM pass phrase: (Votre mot de passe)
  • Country Name (2 letter code) [AU]: FR
  • State or Province Name (full name) [Some-State]: France
  • Locality Name (eg, city) : Rouen
  • Organization Name (eg, company) []:tinad.fr
  • Organizational Unit Name (eg, section) []:
  • Common Name (eg, YOUR name) []: blog-du-grouik.tinad.fr
  • Email Address []:unmail@tinad.fr
  • A challenge password []:
  • An optional company name []:

Using configuration from /usr/lib/ssl/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem:"(le mot de passe que vous avez mis au dessus (en second))" il doit faire ce genre de sortie:

Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            b8:99:39:e0:c0:b0:0e:04
        Validity
            Not Before: Jun  8 18:52:17 2010 GMT
            Not After : Jun  7 18:52:17 2013 GMT
        Subject:
            countryName               = FR
            stateOrProvinceName       = France
            organizationName          = tinad.fr
            commonName                = blog-du-grouik.tinad.fr
            emailAddress              = unmail@tinad.fr
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                0E:D0:8D:5F:DF:8D:32:F8:D9:9B:FB:67:D7:5C:38:16:47:2E:98:CC
            X509v3 Authority Key Identifier: 
                keyid:0E:D0:8D:5F:DF:8D:32:F8:D9:9B:FB:67:D7:5C:38:16:47:2E:98:CC
                DirName:/C=FR/ST=France/O=tinad.fr/CN=blog-du-grouik.tinad.fr/emailAddress=unmail@tinad.fr
                serial:B8:99:39:E0:C0:B0:0E:04

            X509v3 Basic Constraints: 
                CA:TRUE
Certificate is to be certified until Jun  7 18:52:17 2013 GMT (1095 days)

Write out database with 1 new entries
Data Base Updated

On crée donc un certificat public non signé et une clé, puis on le signe avec le CA :

mkdir CERT
cd ~/CERT
openssl req -new -nodes -keyout blog-du-grouik.tinad.fr-key-www.pem -out blog-du-grouik.tinad.fr-req-www.pem -days 365

Je remets exactement pareil qu'au dessus:

  • Country Name (2 letter code) [AU]: FR
  • State or Province Name (full name) [Some-State]: France
  • Locality Name (eg, city) []: Rouen
  • Organization Name (eg, company) []:tinad.fr
  • Organizational Unit Name (eg, section) []:
  • Common Name (eg, YOUR name) []: blog-du-grouik.tinad.fr
  • Email Address []:unmail@tinad.fr
  • A challenge password []:
  • An optional company name []:

Exécutez les commandes suivantes:

cd ~
openssl ca -out CERT/blog-du-grouik.tinad.fr-cert-www.pem -infiles CERT/blog-du-grouik.tinad.fr-req-www.pem
chmod 400 ~/CERT/*

Il demande alors la passphrase qu'on a mis au certificat. la signature doit sortir ça:

Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            9f:f3:18:a2:e5:9b:07:30
        Validity
            Not Before: Jun  8 18:26:43 2010 GMT
            Not After : Jun  8 18:26:43 2011 GMT
        Subject:
            countryName               = FR
            stateOrProvinceName       = France
            organizationName          = Internet Widgits Pty Ltd
            commonName                = blog-du-grouik.tinad.fr
            emailAddress              = unmail@tinad.fr
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                65:0B:62:AA:7F:A0:F1:DB:00:7A:A3:0F:D6:55:0E:C0:6B:EC:B0:01
            X509v3 Authority Key Identifier: 
                keyid:28:8F:F7:BB:1E:8E:79:E0:69:2C:03:03:25:6C:80:83:50:34:0E:58

Certificate is to be certified until Jun  8 18:26:43 2011 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? \[y/n\]y
Write out database with 1 new entries
Data Base Updated
gnieark:~# 
cd CERT/
cat blog-du-grouik.tinad.fr-key-www.pem blog-du-grouik.tinad.fr-cert-www.pem > blog-du-grouik.tinad.fr-certkey-www.pem
mkdir /etc/apache2/ssl
cp blog-du-grouik.tinad.fr-certkey-www.pem /etc/apache2/ssl/
chmod 600 /etc/apache2/ssl/blog-du-grouik.tinad.fr-certkey-www.pem
chmod 400 ~/CERT/*

On active les modules webdav HTTS et auth_mysql

a2enmod dav_fs
a2enmod dav
a2enmod auth_mysql
a2enmod ssl

Créer le VHOST en HTTPS Puis on crée le virtual host : vi /etc/apache2/sites-available/blog-du-grouik.tinad.fr-https Et on colle apres avoir modifié comme il faut en fonction de vos parametres :

<VirtualHost *:443>
        ServerAdmin webmaster@tinad.fr
        ServerName /blog-du-grouik.tinad.fr
         DocumentRoot /var/www/blog-du-grouik.tinad.fr
 
           <Directory />
                Options Indexes FollowSymLinks
               #AllowOverride All
               AllowOverride AuthConfig
               Order allow,deny
                allow from all
               DAV On
               AuthBasicAuthoritative Off
               AuthUserFile /dev/null
               AuthMySQL On
               AuthName "webdav"
               AuthType Basic
               Auth_MySQL_Host localhost
               Auth_MySQL_User webdav_admin
               Auth_MySQL_Password webdav_admin_password
               AuthMySQL_DB webdav
               AuthMySQL_Password_Table mysql_auth
               Auth_MySQL_Username_Field username
               Auth_MySQL_Password_Field passwd
               Auth_MySQL_Group_Field groups
               Auth_MySQL_Empty_Passwords Off
               Auth_MySQL_Encryption_Types PHP_MD5
               Auth_MySQL_Authoritative On
               require group blog-du-grouik.tinad.fr
 
           </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

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/blog-du-grouik.tinad.fr-certkey-www.pem

SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

 
</VirtualHost> 

Vous remarquerez que j'ai mis "require group blog-du-grouik.tinad.fr", ce qui me permettra au besoin d'ajouter un second administrateur du site qui aura ses propres identifiants.

Activer le Vhost et redémarrer apache

a2ensite blog-du-grouik.tinad.fr-https
/etc/init.d/apache2 restart

Pour s'y connecter.

Raccourci > se connecter à un serveur: comme ci dessous: webdavserveur.png

webdavauth.png

Rajouter d'autres VHOSTS:

arf...comme je vais être amené à le faire plusieurs fois: tout dans un script[2]. exécutez le:

#!bin/bash
# By Gnieark  juin 2009
# http://blog-du-grouik.tinad.fr
# 
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#                    Version 2, December 2004
#
# Copyright (C) 2004 Sam Hocevar
#  14 rue de Plaisance, 75014 Paris, France
# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.
#
#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
#  0. You just DO WHAT THE FUCK YOU WANT TO. 
#
#/* This program is free software. It comes without any warranty, to
# * the extent permitted by applicable law. You can redistribute it
# * and/or modify it under the terms of the Do What The Fuck You Want
# * To Public License, Version 2, as published by Sam Hocevar. See
# * http://sam.zoy.org/wtfpl/COPYING for more details. */ 
 
 
# Fonction confirmation des paramètres entrés par l'utilisateur
confirmer() {
   echo -e "\033[1;31m Voulez-vous continuer avec cette valeur : "$1" (o/N) \033[0;39m"
   read confirmation
}
 
# Fonction permettant de demander confirmation pour continuer à 
faire_une_pause() {
   echo -n "Continuer [O/n] ? "
   read lettre
   case $lettre in
      "n" | "N") exit 1;;
      *);;
   esac
}
##############################   Variables   #####################
 
confirmation="n"
while [ "$confirmation" != "o" ]
do
  echo "Entrez le nom du Vhost (sous la forme www.exemple.com) :"
  read VHOST
  confirmer $VHOST
done
confirmation="n"
while [ "$confirmation" != "o" ]
do
  echo "Entrez l'adresse mail du webmaster :"
  read WEBMESTRE
  confirmer $WEBMESTRE
done
 
confirmation="n"
while [ "$confirmation" != "o" ]
do
  echo "Entrez le nom de l'utilisateur:"
  read USERID
  confirmer $USERID
done
 
confirmation="n"
while [ "$confirmation" != "o" ]
do
  echo "Entrez le mot de passe de l'utilisateur"
  read USERPWD
  confirmer $USERPWD
done
 
confirmation="n"
while [ "$confirmation" != "o" ]
do
  echo "Entrez l'identifiant MysQl de l'administrateur webdav:"
  read WEBDAVID
  confirmer $WEBDAVID
done
 
confirmation="n"
while [ "$confirmation" != "o" ]
do
  echo "Entrez le mot de passe MysQl de $WEBDAVID"
  read WEBDAVPWD
  confirmer $WEBDAVPWD
done
 
######### Le Vhost apache  #####
 
echo "
<VirtualHost *:80>
ServerName $VHOST
DocumentRoot /var/$VHOST
</VirtualHost>
" > /etc/apache2/sites-available/$VHOST
 
echo - Enregistrement du fichier /etc/apache2/sites-available/$VHOST: [OK]
echo "
NameVirtualHost *:443
<VirtualHost *:443>
        ServerAdmin $WEBMESTRE
        ServerName $VHOST
         DocumentRoot /var/$VHOST
 
           <Directory />
                Options Indexes FollowSymLinks
               #AllowOverride All
               AllowOverride AuthConfig
               Order allow,deny
                allow from all
               DAV On
               AuthBasicAuthoritative Off
               AuthUserFile /dev/null
               AuthMySQL On
               AuthName "webdav"
               AuthType Basic
               Auth_MySQL_Host localhost
               Auth_MySQL_User $WEBDAVID
               Auth_MySQL_Password $WEBDAVPWD
               AuthMySQL_DB webdav
               AuthMySQL_Password_Table mysql_auth
               Auth_MySQL_Username_Field username
               Auth_MySQL_Password_Field passwd
               Auth_MySQL_Group_Field groups
               Auth_MySQL_Empty_Passwords Off
               Auth_MySQL_Encryption_Types PHP_MD5
               Auth_MySQL_Authoritative On
               require group $VHOST
           </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

SSLEngine On
SSLCertificateFile /etc/apache2/ssl/blog-du-grouik.tinad.fr-certkey-www.pem

SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

</VirtualHost> 
" > /etc/apache2/sites-available/$VHOST-https
 
echo - Enregistrement du fichier etc/apache2/sites-available/$VHOST-https: [OK]
 
####### Création du repertoire ########
mkdir /var/$VHOST
chown www-data:www-data /var/$VHOST
echo - Création du repertoire /var/$VHOST: [OK]
 
###########Inscription uesr Base de données authentification########
echo "INSERT INTO mysql_auth (username, passwd, groups) VALUES('$USERID', MD5('$USERPWD'), '$VHOST')" |mysql -u$WEBDAVID -p$WEBDAVPWD -Dwebdav
echo - Inscription de l user Webdav dans la base de donées: [OK]
 
########## Activation site et redémarage apache ###########
a2ensite $VHOST-https
a2ensite $VHOST
/etc/init.d/apache2 restart
echo - Redémarrage d\'apache: [OK]

Remarque: j'ai utilisé le même certificat... il y aura un problème dans les noms de certificat. bref... m'en fous.. Tuto pour gérer plusieurs en https sur un serveur

Firewall du serveur

Je m'étais basé sur cette doc là pour le script Iptables auquel j'ai rajouté la commande qui réinitialise fail2ban et quelques ouvertures de ports (rsync pour la mise à jour de l'antivirus et les ports pour le serveur mail.

Conclusion

Bon je vais changer mes mots de passe...

Notes

[1] Enfin, je ne dois pas être le seul à l'avoir fait, loin de là

[2] Le Plaisir de poser une WTFYW public license

Commentaires

1. Le mardi, juin 8 2010, 14:26 par AbroutiMaster

Salut et merci pour ce mémo.

J'ai essayé de suivre à la lettre votre tuto, mais j'ai des problèmes à l'étape "Création du certificat". Je dois vous dire que j'apprends petit à petit ce nouveau monde, et il y a surement une étape que je ne comprends pas, un ligne qui n'est pas présente dans le tuto, une création de dossier ou fichier, bref...

Si vous pouviez me donner un coup de main ce serait sympatoche!

PS; les erreur sont le plus souvent

Using configuration from /usr/lib/ssl/openssl.cnf
unable to load CA private key
4023:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:647:Expecting: ANY PRIVATE KEY

2. Le mardi, juin 8 2010, 17:42 par gnieark

Bonsoir AbroutiMaster.
Merci pour ce retour.
Le création du certificat est une étape assez galere. Déja pour la compréhension du role "certificat racine" "clé" et des champs demandés etc... Si on ne met pas des valeurs cohérentes ça marche pas.

je regarde pour détailler ce tuto sur les certificats

3. Le mercredi, juin 9 2010, 00:27 par gnieark

Il y avait quelques erreurs effectivement (un oubli de création du repertoire)

Je me suis permis de vous envoyer un mail expliquer d'ou je vous conseille de repartir

Page top