Utiliser Gitlab Pages comme repository Debian

Les Gitlab Pages (et Github Pages) permettent via un processus de construction d'artefact de publier un site web au travers d'un pipeline.

Un repository Debian étant simplement constitué de fichiers statiques, nous pouvons donc faire un rapprochement entre les pipelines de build et un repository Debian.

Pour réaliser notre repository Debian hébergé sur des gitlab pages nous aurons besoin:

  • Du conteneur docker debian:stretch
  • De GPG pour la signature du repository
  • De reprepro pour créer notre repository
  • D'un repository git hébergé sur un Gitlab

Initialisation du repository

Créer un répertoire sur votre machine et initialisez le lien avec Gitlab:

mkdir debianrepo
cd debianrepo
git init
git remote add origin git@gitlab.com:nerzhul/debianrepo.git

Génération de la clef GPG

Dans un premier temps nous aurons besoin d'une clef GPG pour notre repository. Générez une clef:

gpg --gen-key

On va ensuite exporter la clef publique et la clef privée dans notre repository local:

mkdir repo_meta
gpg --armor --output repo_meta/gpg-public.key --export BDB31B849949AD389C76573EF02015F1E3A69CF2
gpg --export-secret-keys -a BDB31B849949AD389C76573EF02015F1E3A69CF2 > repo_meta/gpg-private.key

Note: exposer la clef privée dans le repository n'est pas recommandé, il est plus judicieux d'utiliser les secret variables de Gitlab pour stocker le contenu de la clef privée. Il s'agit juste de simplifier l'exercice ici

Création du fichier de définition du repository

Créez un fichier repo_distributions dans le répertoire repo_meta. Celui-ci nous servira plus tard, lors de la création du repository. Notez bien que la ligne SignWith contient le fingerprint de la clef GPG précédemment créée

Origin: Debian
Label: Debian
Codename: stretch
Architectures: amd64
Components: main
Description: Apt repository for the posterity
SignWith: BDB31B849949AD389C76573EF02015F1E3A69CF2

Création du pipeline de construction du repository

Le pipeline de repository s'appuie sur le fichier .gitlab-ci.yml de Gitlab. Voici le fichier que nous allons utiliser, nous le détaillerons juste après:

---
image: debian:stretch

stages:
  - package
  - deploy

variables:
  DEBIAN_VERSION: "stretch"
  ETCD_VERSION: 3.2.7
  RUNDECK_VERSION: 2.9.3-1

package:etcd:
  stage: package
  before_script:
    - find etcd -type d -exec chmod 755 {} \;
    - find etcd -type f -not -name postinst -exec chmod 644 {} \;
    - find etcd -type f -name postinst -exec chmod 755 {} \;
    - mkdir -p build/ dist/
    - apt-get -qy update > /dev/null
    - apt-get -qyy install wget > /dev/null
  script:
    - sed -i 's/%%ETCD_VERSION%%/'${ETCD_VERSION}'/g' etcd/DEBIAN/control
    - mkdir -p etcd/usr/bin/
    - cd build/
    - wget https://github.com/coreos/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz
    - tar xzf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz
    - cp etcd-v${ETCD_VERSION}-linux-amd64/etcd etcd-v${ETCD_VERSION}-linux-amd64/etcdctl ../etcd/usr/bin/
    - cd ..
    - dpkg-deb -b etcd/
    - mv etcd.deb dist/
  artifacts:
    when: on_success
    expire_in: 1 week
    paths:
      - dist/*

package:rundeck:
  stage: package
  before_script:
    - apt-get -qy update > /dev/null
    - apt-get -qyy install wget > /dev/null
    - mkdir dist/
  script:
    - cd dist/
    - wget http://dl.bintray.com/rundeck/rundeck-deb/rundeck-${RUNDECK_VERSION}-GA.deb
  artifacts:
    when: on_success
    expire_in: 1 week
    paths:
      - dist/*

pages:
  stage: deploy
  only:
    - master
  dependencies:
    - package:etcd
    - package:rundeck
  before_script:
    - apt-get -qy update > /dev/null
    - apt-get -qyy install reprepro > /dev/null
    - gpg --import repo_meta/gpg-private.key
  script:
    - mkdir -p public/conf
    - cp repo_meta/repo_distributions public/conf/distributions
    - cp repo_meta/gpg-public.key public/repo.key
    - cd public
    - reprepro includedeb ${DEBIAN_VERSION} ../dist/*.deb
  artifacts:
    when: on_success
    expire_in: 1 year
    paths:
      - public

Notre pipeline se décompose en 2 phases:

  • Construction des paquets du repository
  • Création et déploiement du repository

La phase de déploiement nécessite de connaître les paquets Debian construits. Par convention les paquets Debian construits seront placés dans le répertoire dist/ qui sera transféré à la phase de déploiement des Gitlab Pages.

Nous avons ici 2 paquets différents, Etcd et Rundeck qui sont 2 outils libres. Le premier ne fournit pas de paquet Debian, le second oui.

Création des paquets

Commençons par Rundeck, le plus simple.

package:rundeck:
  stage: package
  before_script:
    - apt-get -qy update > /dev/null
    - apt-get -qyy install wget > /dev/null
    - mkdir dist/
  script:
    - cd dist/
    - wget http://dl.bintray.com/rundeck/rundeck-deb/rundeck-${RUNDECK_VERSION}-GA.deb
  artifacts:
    when: on_success
    expire_in: 1 week
    paths:
      - dist/*

Dans la section __before_script__, nous mettons ce qui ne concerne pas le build, ici l'installation de wget pour télécharger le paquet.

Nous nous plaçons ensuite dans le répertoire dist et téléchargeons la version de Rundeck spécifiée dans les variables du CI, plus haut.

Les artefacts intermédiaires sont ensuite sauvegardés pour 1 semaine. Pour rappel on peut télécharger les artefacts depuis l'interface de Gitlab sur chaque pipeline.

Passons maintenant au paquet etcd:

package:etcd:
  stage: package
  before_script:
    - find etcd -type d -exec chmod 755 {} \;
    - find etcd -type f -not -name postinst -exec chmod 644 {} \;
    - find etcd -type f -name postinst -exec chmod 755 {} \;
    - mkdir -p build/ dist/
    - apt-get -qy update > /dev/null
    - apt-get -qyy install wget > /dev/null
  script:
    - sed -i 's/%%ETCD_VERSION%%/'${ETCD_VERSION}'/g' etcd/DEBIAN/control
    - mkdir -p etcd/usr/bin/
    - cd build/
    - wget https://github.com/coreos/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz
    - tar xzf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz
    - cp etcd-v${ETCD_VERSION}-linux-amd64/etcd etcd-v${ETCD_VERSION}-linux-amd64/etcdctl ../etcd/usr/bin/
    - cd ..
    - dpkg-deb -b etcd/
    - mv etcd.deb dist/
  artifacts:
    when: on_success
    expire_in: 1 week
    paths:
      - dist/*

Pour etcd nous construisons un paquet Debian depuis des binaires fournis par les développeurs. Le répertoire etcd contient l'arborescence minimale du paquet, à savoir la configuration, l'unit system et les fichiers control et postinst de Debian.

Dans l'étape __before_script__ nous avons également besoin de wget, mais également de corriger les permissions sur le répertoire etcd du repository, le Gitlab CI changeant les droits sur les fichiers. Je n'ai pas réussi à comprendre pourquoi, celles-ci sont correctes dans git.

L'étape de build se décompose ensuite de la manière suivante:

  • On modifie le fichier control du paquet afin de spécifier la version du paquet etcd
  • On télécharge l'archive etcd du release concerné, qu'on extrait
  • On copie les binaires nous intéressant dans le paquet dans /usr/bin
  • On construit le paquet avec dpkg-deb
  • On bouge le paquet dans le répertoire dist

Enfin, tout comme pour Rundeck, on archive l'artefact.

Création du repository Debian et publication

Notre dernière tâche consiste à créer le repository Debian pour l'exposer via les Gitlab Pages

pages:
  stage: deploy
  only:
    - master
  dependencies:
    - package:etcd
    - package:rundeck
  before_script:
    - apt-get -qy update > /dev/null
    - apt-get -qyy install reprepro > /dev/null
    - gpg --import repo_meta/gpg-private.key
  script:
    - mkdir -p public/conf
    - cp repo_meta/repo_distributions public/conf/distributions
    - cp repo_meta/gpg-public.key public/repo.key
    - cd public
    - reprepro includedeb ${DEBIAN_VERSION} ../dist/*.deb
  artifacts:
    when: on_success
    expire_in: 1 year
    paths:
      - public

L'étape du pipeline doit obligatoirement se nommer pages par convention de Gitlab et le livrable du repository doit se situer dans le répertoire public.

Nous ajoutons nos deux étapes de construction de paquets en dépendances, afin d'avoir les artefacts à disposition pour cette étape, puis nous installons reprepro qui va nous permettre de construire un repository Debian facilement, et nous importons la clef GPG privées dans le trousseau du conteneur de build.

La construction du repository se fait ensuite de la manière suivante:

  • Copie du fichier repo_meta/repo_distributions vers public/conf/distributions, utilisé par reprepro pour construire le repository
  • Copie de la clef GPG publique vers public/repo.key afin de la distribuer à nos clients
  • En se positionnant dans le répertoire public, inclusion de l'ensemble des fichiers deb du répertoire dist/ dans le repository

Enfin nous archivons le repository pour une durée de 1 an, afin d'assurer sa pérennité dans le temps.

Vous pouvez maintenant commiter et pousser tous les changements

Résultat

Allez maintenant sur votre repository Gitlab dans la section pipelines, vous devriez avoir un résultat similaire:

Vous savez désormais construire une repository Debian en ajoutant dynamiquement des paquets construits à partir d'un pipeline Gitlab. Je vous invite à consulter le repository ayant servi de PoC puis de référence pour cet article:

Debian: packager le JAVA Oracle

Dans un environnement de production JAVA sous Linux les mainteneurs d'applications lourdes, web ou non, seront amenés à faire le choix entre OpenJDK et Oracle-JDK

L'OpenJDK a l'avantage d'être libre et open source, il peut être recompilé pour améliorer sensiblement les performances du code java au moyen d'optimisations compilateur GCC pour l'adapter au processeur de vos machines, néanmoins on le fait rarement sous Debian.

Le JDK Oracle a le mérite d'être plus performant sur certains points et certaines structures/entreprises le préfèreront pour des raisons de confiance, de support ou encore de grapiller quelques performmances par rapport à un OpenJDK non compilé.

Sous Debian on ne retrouve pas nativement le JDK Oracle dans les repositories, il faut passer alors par le système d'installation par .tar.gz ou binaire d'Oracle, qui n'offre pas une intégration Debian suffisante.

Pour résoudre cette dernière problématique, il existe un outil dans le repository main de Debian qui s'appelle JavaPackage. Cet outil permet à partir d'un .tar.gz Oracle de créer une archive .deb et d'ajouter l'intégration Debian au sein du paquet (update-alternatives, liens symboliques...).

Pour l'installer rien de plus simple:

apt-get install java-package

Et pour l'utiliser, téléchargez l'archive sur le site d'Oracle puis tapez la commande suivante:

make-jpkg jdk-7u60-linux-x64.tar.gz

Ensuite il vous suffit de l'installer simplement avec dpkg:

dpkg -i oracle-jdk_7.0.60_amd64.deb

Si vous disposez d'un repository local avec vos propres paquets, plus qu'à l'intégrer avec par exemple reprepro.

Source

https://wiki.debian.org/JavaPackage

Créer son propre paquet Debian

Dans le cas de logiciels maisons ou propriétaires, il peut être utile d'avoir son propre repository et ses propres paquets Debian maison afin de déployer rapidement un logiciel.

Nous allons voir ici comment créer un paquet Debian.

Création de l'arborescence

Un paquet Debian s'architecture de manière simple. Il s'agit d'un répertoire contenant les fichiers tels qu'ils seraient vus à partir de la racine. A cela on rajoute un répertoire DEBIAN contenant les fichiers de configuration du paquet (options, scripts de pré-install, post-install...).

On créée ici un paquet mypackage qui devra déployer le binaire /usr/bin/mycustomsoft.

mkdir -p /tmp/mypackage /tmp/mypackage/DEBIAN /tmp/mypackage/usr/bin/

Copie des fichiers à déployer

Une fois l'arborescence créée, on copie les fichiers que l'on souhaite déployer dans notre répertoire dédié au paquet. Attention à bien conserver les droits

cp -p /usr/bin/mycustomsoft /tmp/mypackage/usr/bin/

Configuration du paquet

Pour finir on va créer un fichier dans le répertoire DEBIAN nommé control qui contiendra des informations administratives sur le paquet.

Package: mypackage
Version: 1.0
Section: base
Architecture: amd64
Depends: linux-headers libboost-dev
Conflicts: firefox
Maintainer: Gerard Toki <gtoki@unix-experience.fr>
Description: Paquet custom

Vous pourrez spécifier ici le nom du paquet, sa version, ses dépendances, éventuellement les paquets avec lequel il est en conflit, une description et un mainteneur.

La liste est non exhaustive, bien entendu.

Construction du paquet

Pour terminer on construit le paquet avec la commande dpkg-deb.

dpkg-deb --build mypackage

Conclusion

Vous savez maintenant comment créer un paquet Debian très simple. Il est possible de rajouter des options et scripts avant et après l'installation (redémarrage de service, configuration automatisée...

Sources

http://alp.developpez.com/tutoriels/debian/creer-paquet/

https://www.debian.org/doc/debian-policy/ch-relationships.html

Shibboleth (IdP): installation et retour d’expérience

Shibboleth est un système de fédération d'identités. Il permet d'authentifier des utilisateurs faisant partie d'établissements/entreprises différentes sur des applications mutualisées.

Peu présent et utile dans le secteur privé, Shibboleth est une référence en terme d'authentification dans le secteur public, au sein du ministère de l'enseignement supérieur et de la recherche. Renater, fournisseur d'accès à Internet réservé aux établissement d'enseignement supérieur et de recherche, est l'un des organismes qui l'utilise le plus.

Shibboleth est composé de plusieurs briques, notamment le Service Provider (SP, fournisseur de services) et dans notre cas le fournisseur d'identité (Identity Provider, IdP)

Installation

Pré-requis

Avant de pouvoir installer et utiliser shibboleth, il vous faudra installer JDK 6 et Tomcat 7.

Si vous utilisez Debian tapez simplement:

apt-get install openjdk-6-jdk tomcat7

Si vous utilisez FreeBSD, compilez le port www/tomcat

cd /usr/ports/www/tomcat7
make install clean

ou installez le package depuis votre repo pkgng préféré

pkg install tomcat

Installation de Shibboleth

Téléchargement de l'archive

On télécharge tout d'abord le dernier Shibboleth puis on l'extrait

wget http://shibboleth.net/downloads/identity-provider/latest/shibboleth-identityprovider-2.4.0-bin.tar.gz
tar xvzf shibboleth-identityprovider-2.4.0-bin.tar.gz

Configuration de la variable JAVA_HOME

Pour pouvoir installer Shibboleth nous allons avoir besoin de spécifier la variable d'environnement JAVA_HOME.

Pour Debian, tapez la commande suivante:

export JAVA_HOME="/usr/lib/jvm/java-6-openjdk-amd64/jre"

Pour FreeBSD:

  • si vous utilisez csh:
setenv JAVA_HOME "/usr/local/openjdk6/jre/"
  • si vous utilisez sh, bash ou encore zsh:
export JAVA_HOME="/usr/local/openjdk6/jre/"

Lancement de l'installeur

Pour finir nous lançons l'installation:

cd shibboleth-identityprovider-2.4.0
./install.sh

Lors de l'installation le chemin d'installation, le nom du serveur (adresse DNS du CAS/SSO) et un mot de passe vous seront demandés:

Where should the Shibboleth Identity Provider software be installed? [/opt/shibboleth-idp]
What is the fully qualified hostname of the Shibboleth Identity Provider server? [idp.example.org]
A keystore is about to be generated for you. Please enter a password that will be used to protect it.

Une fois l'installation terminée, on copie le fichier WAR de l'application java dans le répertoire d'applications tomcat.

Pour Debian:

cp /opt/shibboleth-idp/war/idp.war /usr/share/tomcat7/webapps/

Pour FreeBSD:

cp /opt/shibboleth-idp/war/idp.war /usr/local/apache-tomcat-7.0/webapps/

Il faut ensuite changer les droits des répertoires de logs et de méta-données.

Pour Debian:

chown -R tomcat7 /opt/shibboleth-idp/logs
chown -R tomcat7 /opt/shibboleth-idp/metadata

Pour FreeBSD:

chown -R www /opt/shibboleth-idp/logs
chown -R www /opt/shibboleth-idp/metadata

Pour finir, on va ajouter quelques librairies JAVA à tomcat afin que Shibboleth fonctionne correctement. Vous trouverez ces fichiers dans le répertoire où vous avez extrait l'installeur de Shibboleth.

Pour Debian:

cp endorsed/*.jar /usr/share/tomcat7/endorsed/

Pour FreeBSD:

cp endorsed/*.jar /usr/local/apache-tomcat-7.0/endorsed/

Lancement du service

On peut désormais lancer Tomcat.

Sous Debian:

service tomcat7 start

Sous FreeBSD:

service tomcat start

Pour vérifier que tout fonctionne, connectez vous à l'adresse http://idp.example.org:8080/idp/profile/Status. Si la page affiche ok c'est que l'application est correctement déployée.

Enfin, vérifiez que le portail SSO de Shibboleth fonctionne en allant à l'URL http://idp.example.org:8080/idp/Authn/UserPassword

Designer le SSO

Le premier axe d'amélioration est la personnalisation du design du SSO. Pour cela c'est très simple, il suffit d'aller dans le répertoire webapps/idp/ de votre tomcat et de personnaliser les fichiers login.jsp et login.css, correspondant à la page de login. Vous n'avez pas besoin de redémarrer tomcat à chaque modification, à contrario des fichiers de configuration de Shibboleth.

Conclusion

Nous avons ici fait la partie la plus simple, à savoir l'installation de Shibboleth. Le plus compliqué reste la configuration de l'IdP lui-même. Vous trouverez dans les sources ci-dessous la documentation Renater, extrêmement complète permettant de comprendre les différents éléments à configurer pour Shibboleth (partez de la partie 4)

J'ai également essayé d'installer Shibboleth avec Jetty 8 (Shibboleth ne supporte que Jetty >= 7) mais je n'ai pas réussi, ni sur Debian, ni sur FreeBSD. Jetty nécessite d'intégrer des fichiers de configuration supplémentaires et des librairies Tomcat pour faire fonctionner Shibboleth, il reste donc plus pertinent d'utiliser Tomcat 7.

Par ailleurs, j'ai fortement apprécié le déploiement sur cette version de Tomcat 7. J'utilise peu Tomcat et ma précédente expérience avec Tomcat 6 n'avait pas été convaincante.

Même si vous n'utilisez pas la fédération d'identité, Shibboleth peut très bien être utilisé en tant que serveur CAS/SSO (dans mon cas il est branché sur 2 OpenLDAP). Si vous suivez la documentation Renater vous devriez sans problème arriver à faire fonctionner cette partie et pouvoir commencer à l'intégrer sur vos services web.

Sources

https://wiki.shibboleth.net/confluence/display/SHIB2/IdPInstall https://www.switch.ch/aai/docs/shibboleth/SWITCH/latest/idp/deployment/#shibboleth-idp-configuration https://services.renater.fr/federation/docs/installation/idp_decembre2012