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
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:
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...
Commentaires
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
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
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