Description

Le ResEl fournit un espace d'hébergement pour que les clubs qui le souhaitent puissent héberger un site web, en utilisant des technologies modernes (PHP, Python, ...), avec une base de donnée, ainsi qu'un sous nom de domaine en nom.club.resel.fr ou en nom.asso.resel.fr. Les sites sont disponibles depuis internet.

Utilisation

Côté utilisateur

On peut avoir la liste des clubs disponibles sur le site https://clubs.resel.fr.

Pour créer son site, il faut demander à un administrateur ResEl. Celui ci valide la création du site selon la politique du ResEl.

La politique d'hébergement de site au ResEl veut que seuls les sites de club ou d'association du BDE de Télécom Bretagne puisse être hébergés. Le club doit être immédiatement reconnue comme d'intérêt pour le campus et l'aspect social de TB. Il découle que le ResEl refuse d'héberger les projets scolaires ou personnel, sauf autorisation spéciale du CA.

Une fois le site créé, un membre en devient webmaster, il peut dès lors aller sur une page d'administration de son site (https://clubs.resel.fr aller vers le lien du site en question) et pourra désigner de nouveaux webmaster pour son site.

Un webmaster a accès à deux choses :

  • L'accès FTP où est hébergé son site : Connexion en SFTP sur sftp://clubs.resel.fr, authentification avec son compte ResEl.
  • L'accès PHPMyAdmin, où il peut gérer la base de données SQL si existante, pour le site : Connexion sur https://phpmyadmin.clubs.resel.fr, authentification avec son compte ResEl.

Côté Admin

Pour créer un site non associé à un club, voici comment faire :

# create_site.py <uidadmin> <site_id> <pathtosite> <nomvhost> <nomsite>
create_site.py tjacquin assos-tb /srv/www/oters/assos-tb/ assos-tb.fr Assos-Tb

Sinon, voici la démarche pour un site associé à un club :

  1. La première chose à faire, si elle n'existe pas, est de créer l'organisation correspondante dans le LDAP. Une organisation ressemble par exemple à ça :
    cn=rlb,ou=organisations,dc=maisel,dc=enst-bretagne,dc=fr
    objectClass: tbClub
    cn: rlb
    mlInfos: FALSE
    orgaName: Rencontres Ludiques de Bretagne (RLB)
    Copier un modèle existant sans le gidNumber ou voir le schéma Organisation pour plus de détails.
  2. Lancer create_site_from_orga.py, qui se trouve dans /srv/scripts sur Golf, avec en paramètres votre uid et le nom de l'organisation :
    # /srv/scripts/create_site_from_orga.py <uid_admin> <nom_orga> <site_id>
    /srv/scripts/create_site_from_orga.py tjacquin rlb rlb
  3. Relancer Apache.
    service apache2 restart
  4. Ajouter l'admin dans la branche des webmestres, ça ressemble à ça :
    uid=pchapuis,ou=webmasters,dc=maisel,dc=enst-bretagne,dc=fr
    objectClass: alias
    objectClass: uidObject
    aliasedObjectName: uid=pchapuis,ou=people,dc=maisel,dc=enst-bretagne,dc=fr
    uid: pchapuis
    warning Attention, il ya un bug sur phpLDAPadmin qui vous interdira de faire ça en vous donnant l'erreur :
    This update has been or will be cancelled, it would result in an attribute value not being unique. You might like to search the LDAP server for the offending entry.
    Pour contourner ce bug, créer l'alias en donnant à l'alias un uid différent, par exemple <uid_user>-webmaster, validez, puis renommez l'alias.
  5. Sur la branche site, dans le champ memberUid ajoutez l'UID correspondant.

Plus de détails sur les scripts automatisés.

Créer une base MySQL

Si le site nécessite l'utilisation d'une base de données MySQL il faut utiliser le script /root/old_scripts/create_base.py avec en argument le nom du site. Attention, le nom de l'organisation ne doit pas excéder 16 caractères, sinon il va falloir entrer l'user à la main :

#/root/old_scripts/create_base.py <site_id>
/root/old_scripts/create_base.py sitedeouf

Attention, phpMyAdmin ne gère pas les comptes des webmestres, il y a donc un compte dont l'identifiant est l'id du site, et le mot de passe est celui choisi au lancement de cette commande.

Fonctionnement

Vue d'ensemble générale

L'hébergement de site est réalisée via un ensemble de services et scripts.

Principalement, l'hébergement est fait sur Golf, via un ensemble de scripts, ainsi que grâce à l'architecture de branches du LDAP spécifiques.

Tout les sites de clubs ont leurs sources dans le dossier /var/www/ sur Golf, un serveur Apache2 hoste les sites et leur configuration sont classiquement dans /etc/apache/sites-available/. Il y a un VirtualHost par site.

Un serveur SFTP sur Golf permet aux webmestres des sites d'accéder aux code sources des sites.

Un serveur PhpMyAdmin sur Golf permet aux webmestres de gérer leur base de données.

Pour gérer des droits corrects, sur le LDAP ont été ajoutés deux branches:

  • La branche site contient les sites et leur spécifications.
  • La branche webmasters contient des alias vers les fiches des utilisateurs dans la branche people.

Golf est configurée pour que tout les utilisateurs de la branche webmasters puisse s'authentifier via le LDAP, que touts les sites de la branche site soit définie en tout que groupe. Ainsi une gestion des droits fine est permise.

Finalement, un ensemble de scripts permet aux admins ResEl de générer plus ou moins automatiquement les sites.

Serveur web

Le serveur web est Apache2. Il est installé depuis les miroirs Debian.

Dans le soucis de séparer les fichiers accessibles par les différents sites, on fait tourner chaque vhost sous un user et groupe différent. Cela est réalisé grâce au module ipm-itk. Il est installé depuis les miroirs Debian : apache2-mpm-itk.

ipm-itk a été configuré pour réduire le nombre de processus originaux :

Sécurisation de PHP

PHP a été configuré pour augmenter la sécurité des scripts php. La configuration est dans /etc/php5/apache2/php.ini.
Notemment des fonctions potentiellement dangereuses ont été désactivées via disable_functions, puis l'open-basedir a été chrooté vers /srv/www/.
Finalement lors d'une auth avec un .htaccess auprès (par exemple) du LDAP, on récupère dans $_SERVERPHP_AUTH_USER le nom de l'utilisateur. Malheureusement, dans sa configuration par défaut, on peut aussi récupérer dans $_SERVERPHP_AUTH_PW le mot de passe entré par l'utilisateur. Pour éviter cela, on ajoute dans php.ini une option, auto_prepend_file qui permet de préciser un script exécuté avant tout script PHP. Dans son incarnation actuelle, ce script met juste dans PHP_AUTH_PW une valeur bidon. Il a fallu faire un cas spécial pour phpMyAdmin, qui récupère le mot de passe pour se connecter à la base SQL.

Reverse-Proxy

Au niveau de Cyric - l'ancien site publique, un proxy sur *.(clubs|club|assos|campagne).resel.fr redirige vers Golf. Le flag PreserveHost est mis pour ne pas altérer l'Host de la requête. Les requêtes venant de l'extérieur sont redirigées vers le port 8000 (et 8443 en SSL), et les requêtes vers le port 80 (et 443 en SSL).

Serveur SFTP

Le serveur est sftpd. Il est installé depuis les miroirs Debian.

Il sert /srv/www/ comme chroot.

L'authentification est faite via l'authentification PAM classique. Cf Authentification.

Les utilisateurs ont donc accès à l'arborescence de tout les clubs, mais autant donnée la gestion des droits faite, ils ne peuvent que toucher aux fichiers d'un site dont ils sont webmestre.

La petite subtilité

Parceque c'était trop simple sinon, pour sécuriser ça, d'abord la synchronisation des utilisateurs avec des comptes Linux fait en sorte que le home soit dans /srv/chrooted_sftp et aussi, que le shell soit le programme /usr/bin/spconlyc_umask. C'est un programme custom au ResEl défini sur Golf qui lance un client SFTP.

Organisation des droits

La gestion des droits est vue comme ceci :

Il y a un groupe global clubs.

Chaque site déclaré sur la branche site se voit créer un groupe et un utilisateur du même nom, de même pour chaque webmestre dans la branche webmasters. Cela est geré par une configuration spécifique de PAM et NSS sur Golf

Tout les utilisateurs de site ou de webmestres appartiennent à clubs.

Depuis l'interface utilisateur, un webmaster peut définir qui d'autre est webmaster du site. Cela actualise le LDAP, et ajoute le webmestre en question dans le groupe du site.

Un site peut-être relié à une organisation via le champ dans sa fiche.

Le site sera dans un répertoire qui sera soit dans dans /srv/www/(club|assos|campagnes) si il est relié à une organisation, sinon il sera dans le répertoire indiqué dans le champ mainDir de sa fiche LDAP.

Chaque fichier de ce répertoire appartient à $site:$site et les permissions sont définies à 0700.

Les répertoires ont le GUID bit d'activé (g+s).

Le VirtualHost Apache est lancé sous l'utilisateur du site, et le groupe clubs.

Schéma LDAP spécifique

Dans le schéma LDAP, la branche organisation recense les clubs et associations et listes de campagne de l'AE :

dn: ou=organisations,dc=maisel,dc=enst-bretagne,dc=fr
objectClass: organizationalUnit
ou: organisations

Les objectClass en jeux sont :

  • studentOrganisation, que possède toute organisation, définissant les champs uidPrezs, description, cn et mlInfos.
  • tbClub, définissant un club, dérivant de studentOrganisation.
  • tbAsso, définissant une asso, dérivant de studentOrganisation.
  • tbCampagne, définissant une liste BdE de campagne, dérivant de studentOrganisation et ajoutant le champ campagneYear.

Ainsi, une organisation ne possède pas forcément de sites web, mais peut posséder une machine par exemple. De plus, le champ prezUids permet de connaître les présidents des différentes associations.

Branche Sites

Une branche site dans laquelle les sites sont déclarés en tant que reselSite (qui "dérive" de posixGroup).

dn: ou=sites,dc=resel,dc=enst-bretagne,dc=fr
objectClass: organizationalUnit
ou: sites

L'objectClass principal est reselSite, avec les champs :

  • allowCGI : Autoriser au site du contenu CGI-BIN.
  • siteAccess : Accès au site depuis : "INT", "EXT", "EXT_RESEL", voir les scripts...
  • siteVisibility : ?
  • vhosts : si besoin d'un domaine name particulier pour le vhosts.
  • mainDir : chemin vers les dossier du site si pas conventionnel.
  • description
  • cnOrga : l'organisation (cf ci haut) associée. Si défini, vhosts, mainDir, siteName et description sont automatiquement définis via les infos de l'organisation associée. Sinon les champs deviennent obligatoires.
  • siteName
  • memberUid : listes des uids (attention pas les dn..) des webmestres du site.

Branche Webmasters

Une branche webmasters dans laquelle les webmasters sont déclarés en tant que alias (objectClass: alias) d'une fiche dans la branche people.

dn: ou=webmasters,dc=resel,dc=enst-bretagne,dc=fr
objectClass: organizationalUnit
ou: webmasters

Script de génération des sites

Pour simplifier la tâche, des scripts ont été créés. Ils sont dans le dossier /srv/scripts. Il ne font pas l'objet d'un versionnage, à faire !

Le script le plus simple est create_site.py

Utilisation :

# create_site.py <uidadmin> <site_id> <pathtosite> <nomvhost> <nomsite>
create_site.py tjacquin assos-tb /srv/www/oters/assos-tb/ assos-tb.fr Assos-Tb

Ce script permet de créer un site non associé à une organisation.

L'autre script est create_site_from_orga.py

Utilisation :

# create_site_form_orga.py <uidadmin> <orga_id> <site_id>
create_site_form_orga.py tjacquin mangatheque mangatheque

Ce site permet de créer un site associé à une organisation.

Il y a des scripts de gestion des sites de campagne :

  • precampagne.py
  • migre_campagne.py

Un script pour réparer les bêtises des webmestres sur les permissions fix_perms.py.

Un script pour assigner une IPv6 à un vhost de site ipv6site.pl, un grand mystère.

Un script pour rédiger la configuration Apache d'un site en fonction des infos sur la branche LDAP conf_apache.py.

Un script contenant les variables globales pour tout les scripts précédents common.py.

Et finalement, un script bash qui monitore le nombre de répertoire, parce que sinon le programme décrit dans la petite subtilité ne fonctionnera plus !

Il y a plein d'autre scripts dans le dossier /root/old_scripts, mais vu le nom, je suppose qu'il ne faut pas les utiliser.

Lien utiles

  • Golf : le serveur hébergeant les sites et les scripts.
  • LDAP : la configuration du LDAP.
  • Le site clubs.

Modifications

  • Mise en place initiale en 2007.