Category Archives: Puppet

Générer avec Puppet des certificat SSL avec des « Alternative Name »

J’avais besoins de cette fonctionnalité pour mettre en place la communication SSL entre mes deux serveurs Foreman et ses proxies.
Mon problème étant que mes serveurs Foreman sont utilisé en faillover (avec une VIP) avec un DNS généric et non pas en utilisant leur FQDN.
Ceci provoquait un problème avec le certificat puppet utilisé car l’adresse ne correspondait pas au CN exposé.
J’ai donc mis en place un certificat puppet dont le CN est le FQDN (ex:foreman1.example.com) de la machine et qui comprend en plus comme
‘Subject Alternative Name’ le nom du faillover utilisé (ex:foreman.example.com).

C’est très simple à réaliser mais l’info est pas très documentée sur le net.
Il faut commencer par révoquer et supprimer tous les certificats existants pour cette machine :
Sur le client (sur Debian) :

# rm -rf /var/lib/puppet/ssl

Sur le puppet master :

# puppet cert clean foreman1.example.com

Modifier le puppet.conf du client et lui ajouter la directive :

dns_alt_names = foreman.example.com

Puis lancer puppet sur le client pour forcer la création du nouveau certificat et envoyer la demande de signature au master :

# puppet agent -t --report --pluginsync

Sur le master vous pouvez voir une nouvelle demande de certificat et vous pouvez le signer :

# puppet cert list
  "foreman1.example.com" (SHA256) 2C:76:5B:85:67:28:1C:92:48:AA:10:22:44:C7:9B:A7:0D:9B:E2:A5:5F:10:71:87:B9:3F:46:E4:70:4B:43:6C (alt names: "DNS:foreman.example.com", "DNS:foreman1.example.com")
# puppet cert sign devshinken4.yzserv.com --allow-dns-alt-names

Vous avez donc maintenant un certificat signé par votre Puppet CA qui comprend un DNS Alt Name.

Share

Auto validation et supervision de la configuration de Nagios par lui même

Attention c’est un nom bien compliqué pour les trois lignes de bash qui vont suivre.

Ma problématique était la suivante : j’utilise Puppet et son module Naginator pour écrire l’ensemble de ma configuration Nagios. En cas de création d’un nouveau serveur avec Foreman, Puppet vient m’écrire dynamiquement la conf de Nagios avec tous les checks nécessaires en fonctions des classes puppet associées à ce serveur (supervision système, applicative, etc…). Quand puppet écris des changements dans la configuration de nagios,  il notifie automatiquement nagios du changement dans sa conf pour que celui-ci fasse un reload.

Cependant mon module nagios de Puppet n’étant pas parfait, j’arrive en cas d’erreur humaine à créer une configuration Nagios qui n’est malheureusement pas valide (un host nagios est créé et affecté dans un hostgroup qui n’existe pas). Par bonheur lorsqu’une erreur se produit,  nagios vérifie toujours la validité de la configuration avant de faire son reload. Je ne perds donc pas ma supervision mais bien que puppet continue a m’écrire les changements de conf, Nagios ne se met plus à jour.

C’est pourquoi j’ai décidé d’écrire un check de trois lignes de bash qui va vérifier que la configuration de Nagios est bien valide. J’utilise pour cela le le binaire de nagios avec l’option ‘-v’. Vous pouvez retrouver ce script sur Github.

Comme cela, je suis assuré que Nagios a toujours une configuration valide et que ma supervision évolue bien au rythme de mon SI.

J’écrirais surement bientôt un petit article pour expliquer en détail comment j’utilise Foreman / Puppet et Nagios dans mon SI.

Share

Vérifiez le run de vos Puppet avec Foreman et Nagios

J’avais besoin de m’assurer de la fiabilité des runs de Puppet sur l’ensemble de ma production. Pour cela il faut m’assurer de 2 choses :

- Premièrement que puppet s’exécute correctement toute les demi-heure (j’utilise un cron et non pas le daemon puppet) . Pour cela, c’est assez simple, j’utilise un check nagios de base « check_file_age » et je vérifie l’âge du fichier « state.yaml ». Voici donc à quoi ressemble ma commande sur un serveur Debian:

/usr/lib/nagios/plugins/check_file_age -w 3780 -c 43200 -f /var/lib/puppet/state/state.yaml

- La première commande me permet de savoir que Puppet tourne bien régulièrement. Cependant je suis incapable de dire si les runs s’effectuent correctement ou non. C’est pourquoi  j’ai décidé d’utiliser la fonction de Reports de Foreman (voir ces 3 billets 1 2 3 pour l’installation de Foreman).

Vous pouvez trouver mon script içi sur Github. Pour l’utiliser sur un serveur Debian, il faut installer les dépendances (dont une qui n’est pas packagée en deb) :

# apt-get install libhttp-server-simple-perl libjson-perl
# wget http://search.cpan.org/CPAN/authors/id/M/MC/MCRAWFOR/REST-Client-243.tar.gz
# tar xvf REST-Client-243.tar.gz
# cd REST-Client-243
# make
# make install

Ensuite pour l’utiliser c’est très simple :

$ /usr/lib/nagios/plugins/check_foreman_puppet_failure.pl -H webserver.example.com -F http://foreman.example.com -w 3 -c 5 -u username -p password

Cette commande va vérifier les derniers rapports d’exécution de Puppet. Si le nombre de run en erreur est supérieur à warning ou critical alors le check retournera une erreur.

Voila, vous pouvez superviser correctement vos runs de Puppet grâce à Foreman et Nagios

Share

Intégration de PuppetDoc avec Foreman

Nous allons voir dans cet article comment intégrer la documentation de puppet à Foreman. L’objectif est de donner accès aux utilisateurs à cette documentation pour qu’ils sachent quelles règles sont appliquées dans les classes.

Patcher Puppetdoc de Debian 6

Pour les utilisateurs de Debian 6, la première chose à faire est de patcher puppetdoc (voir bug). Pour cela, vous pouvez utiliser le backport du patch que je met à disposition :

# curl http://www.fitzdsl.net/wp-content/uploads/2011/05/puppet_generator.rb_.patch | patch /usr/lib/ruby/1.8/puppet/util/rdoc/generators/puppet_generator.rb

Générer la documentation

Vous pouvez en premier lieu définir le « document root » de votre documentation. J’ai décidé pour ma part de laisser la doc dans le dossier par défaut : RAILS_ROOT/public. Pour générer la documentation, nous allons utiliser une commande rake prévue pour cela. Dans /usr/share/foreman :

# rake puppet:rdoc:generate

Pensez à mettre cette commande en Cron pour mettre à jour votre documentation au fur et à mesure.La documentation est maintenant accessible en allant dans Additional Settings, Puppet Classes, et en cliquant dans la colonne Environements de la classe.

Share

Installation d’une infrastructure de management de serveurs : Puppet / Foreman – part 3

Cet article va principalement s’intéresser aux quatres principales briques que Foreman va manager à votre place : DNS, DHCP, TFTP et bien sûr Puppet / PuppetCA.

Ajout d’un smart-proxy dans Foreman

Lancez votre service foreman-proxy :

# service foreman-proxy start

Pour vérifier que votre service s’est bien lancé, faite pointer votre navigateur HTTP sur l’url de votre foreman-proxy sur le port 8443. (ex: http://foreman:8443/features) Vous devriez voir apparaitre une page listant les fonctionnalités activées sur votre Smart Proxy Foreman. Si cette page n’est pas accessible pensez à vérifier vos règles de firewalling.

Avant de pouvoir ajouter un smart-proxy dans Foreman il faut au moins activer une fonctionalité. Comme nous allons le voir par la suite vous pouver activer :

:tftp: true
:dns: true
:dhcp: true
:puppetca: true
:puppet: true

Pensez à redémarrer le proxy pour appliquer la nouvelle configuration. On peut maintenant ajouter un Smart Proxy dans Foreman. Pour cela allez sur l’interface de Foreman, dans le menu déroulant à droite sélectionnez « Smart Proxies », New Proxy, nommez le et indiquez son URL sans oublier le port d’écoute du serveur Webrick (8443) par défaut.
Lorsque vous sauvegardez, si tout vas bien vous devriez voir toutes les Features supportées par votre smart-proxy.

Configuration du serveur TFTP

Pour configurer votre serveur TFTP, il vous faut aller dans /tftpboot (ou votre racine TFTP si vous en avez choisi une différente) .
Il vous faut un pxelinux.0 et des fichiers permettant une netboot de debian. Vous pouvez trouver ceux-ci dans cette archive proposée par Debian (http://ftp.fr.debian.org/debian/dists/squeeze/main/installer-amd64/current/images/netboot/netboot.tar.gz).

Extrayez l’archive dans /tftpboot (ou la racine de votre serveur TFTP), supprimez le lien symbolique de pxelinux.cfg et créez les répertoires boot et pxelinux.cfg (oui, c’est un répertoire !). Donnez les droits 700 et user foreman-proxy:root à ces deux dossiers.

# tar xvf netboot.tar.gz
# rm -rf pxelinux.cfg
# mkdir boot pxelinux.cfg && chmod 700 boot pxelinux.cfg && chown foreman-proxy:root boot pxelinux.cfg
# rm netboot.tar.gz

Dans le fichier /etc/foreman-proxy/settings.yml :

  1. Décommenter la ligne :tftp: true
  2. Décommenter la ligne :tftproot et mettez /tftpboot (ou votre autre dossier)

Redémarrez votre service foreman-proxy, retournez dans la configuration des smart-proxy sur Foreman, éditez votre proxy renseigné et sauvegardez tout de suite : la feature TFTP devrait s’afficher.
On va créer un fichier de boot par défaut. Si vous ne demandez pas explicitement à Foreman de reconstruire votre machine alors ce fichier de boot par défaut demandera à votre machine de continuer son boot sur son disque local en cas de redémarrage. Pour cela on va utiliser la fonction de templating de Foreman. Allez sur l’interface Web, un template nommé « PXE Default File » devrait être présent. Vous avez juste à clicker sur « Build PXE Default button », et c’est bon, vous devriez avoir un serveur PXE fonctionnel.

Configuration du serveur DHCP

Dans le fichier de configuration du serveur DHCPd, il vous faut ajouter les lignes suivantes par rapport à une configuration « classique » :

> omapi-port 7911;
> allow booting;
> allow bootp;

subnet 192.168.1.0 netmask 255.255.255.0 {
   range 192.168.1.10 192.168.1.200;
   option domain-name-servers 192.168.1.1 8.8.8.8 8.8.4.4;
   option domain-name "mycomapny.com";
   option routers 192.168.1.1;
   filename "/pxelinux.0";
   next-server 192.168.1.1;
}

Dans le fichier /etc/foreman-proxy/settings.yml :

  1. Décommenter la ligne :dhcp: true
  2. Décommenter la ligne :dhcp_vendor: isc
  3. Ajouter les lignes
     :dhcp_config: /etc/dhcp/dhcpd.conf
     :dhcp_leases: /var/lib/dhcp/dhcpd.leases

On redémarre le service de smart-proxy :

# service foreman-proxy restart

Configuration de Bind

On va maintenant passer à la configuration du serveur DNS. Nous allons utiliser le serveur Bind9. Pour que foreman puisse modifier dynamiquement des zones via l’outils nsupdate, il va falloir lui générer une paire de clé permettant de l’authentifier.

Ces clés vont être générées via les commandes :

# dnssec-keygen -a HMAC-MD5 -b 512 -n USER foreman.mycompany.com

Je stocke personnellement ces clés dans le répertoire /etc/bind en les renomant foreman.key et foreman.private. Il faut leur donner les droits 400 et les users foreman-proxy:foreman-proxy.
Il faut ensuite indiquer à Bind que le user à qui appartient cette clé à le droit de modifier sa zone. Il faut donc dans votre déclaration de zone ajouter une directive allow-update. Vous devriez obtenir quelquechose comme ca :

zone "mycompany.com" {
        type master;
        file "/etc/bind/mycompany/db.mycompany.com";
        allow-update {key "foreman"; };
};

Pensez à faire de même pour votre zone reverse !

Création d’un domaine dans Foreman

Il vous faut maintenant indiquer à Foreman qu’il peut gérer un nouveau domaine. Dans le menu déroulant sélectionnez Domain, New Domain.

Entrez un nom qui vous servira uniquement de référence dans Foreman, le nom complet de votre domaine puis associez votre smart-proxy. Enfin sauvez !

Configuration de Puppet / PuppetCA

Il faut dans un premier temps installer le package sudo.

#apt-get install sudo

Puis il faut ajouter dans le fichier /etc/sudoers les lignes suivantes :

# visudo
> foreman ALL=(ALL) NOPASSWD:/usr/sbin/puppetca
> foreman-proxy ALL=(ALL) NOPASSWD:/usr/sbin/puppetca --clean *

Comme d’habitude on va activer ces services en dé-commentant les lignes correspondantes aux services dans /etc/foreman-proxy/settings.yml puis redémarrer le service foreman-proxy. Pour faire prendre en compte ces nouveaux services par foreman, éditez votre smart-proxy et sauvez ! Les services devraient apparaitre dans la liste des services disponibles pour ce smart-proxy !

Dans /etc/puppet, créer un fichier autosign.conf et changer son owner en foreman-proxy:puppet

# cd /etc/puppet
# touch autosign.conf
# chown foreman-proxy:puppet autosign.conf

Ajouter un sous-réseau dans Foreman

Pour ajouter un sous-réseau dans Foreman, sélectionnez Subnet dans le menu déroulant, puis New Subnet.
Remplissez son nom, son domaine associé, les informations relatives au réseau et le serveur smart-proxy que vous souhaitez associer à ce sous-réseau.

Conclusion

Voila, vous avez fini de paramétrer globalement la gestion des 4 briques principales que Foreman va pouvoir piloter pour vous. Nous verrons dans une dernière partie comment utiliser Foreman pour automatiser complètement l’installation d’une machine Debian.

Share

Installation d’une infrastructure de management de serveurs : Puppet / Foreman – part 2

Après avoir mis en place un serveur avec notre Puppetmaster, nous allons maintenant procéder à l’installation de TheForeman.
C’est grâce à Foreman que nous allons pouvoir :

  • Utiliser Puppet en External Nodes (Interface WebUI)
  • Avoir du reporting sur la dance de tous les Puppets
  • Manager un serveur TFTP, DNS, DHCP afin de provisionner de nouvelles machines complètement dynamiquement

Pour cela, de la même manière nous allons utiliser des packages debian, cependant ceux-ci ne sont pas disponibles dans les repository de Debian. Nous devons donc ajouter celui mis à disposition par la communauté s’occupant de Foreman.

# echo "deb http://deb.theforeman.org/ stable main" > /etc/apt/sources.list.d/foreman.list
# wget -q http://deb.theforeman.org/foreman.asc -O- | apt-key add -
# apt-get update
# apt-get install foreman foreman-proxy foreman-mysql isc-dhcp-server bind9 tftpd-hpa

Lors de l’installation de tftpd-hpa, debconf demande à choisir la racine du serveur TFTP. J’ai choisis personnellement /tftpboot mais vous êtes libre de choisir ce qu’il vous plaira !
Le debconf de Foreman vous propose de configurer la BD pour vous, choisissez Non pour la configuration automatique de la BD. Nous le ferons manuellement plus tard.
Nous allons utiliser pour foreman la même base mysql que celle utilisée par puppet pour ses configstore. Configurons donc la database pour foreman :

# vim /etc/foreman/database.yml
production:
adapter: mysql
database: puppet
host: localhost
port: 3306
username: puppet
password: votre_password_puppet
encoding: utf8

Cependant Foreman à besoin d’étendre la base de puppet. Pour cela rake va nous venir en aide :

# cd /usr/share/foreman
# rake db:migrate RAILS_ENV=production

On va ensuite configurer apache2/passenger afin de servir TheForeman. On utilise les certificats SSL de Puppet pour l’HTTPS

# vim /etc/apache2/sites-available/foreman
<VirtualHost *:80>
ServerName foreman.mycompany.com
DocumentRoot /usr/share/foreman/public

RailsAutoDetect On
AddDefaultCharset UTF-8
</VirtualHost>

<VirtualHost *:443>
ServerName foreman.mycompany.com

RailsAutoDetect On
RailsEnv production
DocumentRoot /usr/share/foreman/public

# Use puppet certificates for SSL

SSLEngine On
SSLCertificateFile /var/lib/puppet/ssl/certs/hostname.domain.pem
SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/hostname.domain.pem
SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem
SSLCACertificateFile /var/lib/puppet/ssl/certs/ca.pem
SSLVerifyClient optional
SSLOptions +StdEnvVars
SSLVerifyDepth 3

</VirtualHost>

Nous activons le virtualhost pour apache2. Il faut d’autre part définir sous quel user sera éxecuté passenger (nobody/nogroup) par défaut sous Debian. Il vous faut donc changer le propriétaire du fichier /usr/share/foreman/config/environment.rb :

# a2ensite foreman
# chown foreman:foreman /usr/share/foreman/config/environment.rb
# service apache2 restart

Vous devriez avoir accès l’interface de foreman en faisant pointer votre navigateur sur votre virtualhost ! Nous allons voir dans un 3ème article comment configurer l’ensemble des services pilotés par Foreman.

Share

Installation d’une infrastructure de management de serveurs : Puppet / Foreman – part 1

L’objectif de cet ensemble d’articles (voir la suite part2 et part3) est de détailler l’installation d’une infrastructure de management de serveur basée principalement sur deux outils :

  1. Puppet (Site officiel PuppetLabs )
  2. TheForeman (Site officiel TheForeman)

Puppet est relativement connu de la communauté des administrateurs Unixiens  mais TheForeman, projet beaucoup plus récent, est nettement moins répandu ! Nous verrons que ces deux logiciels utilisés conjointement forment un formidable outil permettant de déployer / manager un parc sans soucis !

Quels sont les objectifs de cette infrastructure :

  1. Utiliser la notion d’External Nodes de Puppet (Documentation External Nodes) : Cette fonctionnalité permet de binder un ensemble de modules de Puppet (les classes de configuration) à un ensemble de nodes (les machines) à travers une WebUI. Cette fonctionnalité permet ainsi d’autoriser la manipulation de puppet par des personnes n’ayant pas forcément un haute expertise sur le sujet.
  2. Avoir un ensemble de reporting associé à l’execution de Puppet sur chacun des nodes managé par le PuppetMaster
  3. Et surtout : permettre le management dynamique des services de DHCP, TFTP et DNS pour le déploiement de nouvelles machines en PXE !

 

Installation de Puppet

Ce premier article sera centré sur l’installation d’un serveur Puppet. Il sera basé sur un retour d’expérience de déploiement de ces services sur des machines Debian Squeeze 6.
Nous allons utiliser autant que possible les paquets fournis par la distribution Debian. Profitons que Debian Squeeze ne soit pas trop vieille et que ces paquets ne soient pas encore (trop) obsolètes.
Nous allons donc installer sur la machine servant de Puppetmaster les paquets :

# apt-get install puppet puppetmaster mysql-server libdbd-mysql-ruby libmysql-ruby1.8 vim-puppet

Nous allons faire tourner le puppetmaster non pas avec webrick qui est le webserver packagé avec ruby mais avec passenger qui est un module pour le serveur apache2 permettant de faire tourner une application Ruby on Rails (Site officiel de Passenger).
Il va donc nous falloir installer apache2 et passenger

# apt-get install apache2 libapache2-mod-passenger

Configuration de passenger

Nous allons donc commencer par créer le vhost pour apache2 (cette méthode est issue de cette documentation):

# cd /etc/apache2/sites-available
# vim puppet
Listen 8140
<VirtualHost *:8140>

SSLEngine on
SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP
SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/hostname.domain.pem
SSLCertificateFile /var/lib/puppet/ssl/certs/hostname.domain.pem
SSLCACertificateFile /var/lib/puppet/ssl/ca/ca_crt.pem
SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem
# If Apache complains about invalid signatures on the CRL, you can try disabling
# CRL checking by commenting the next line, but this is not recommended.
SSLCARevocationFile     /var/lib/puppet/ssl/ca/ca_crl.pem
# Set to require if this puppetmaster doesn't issue certificates
# to puppet clients.
# NB: this requires SSLCACertificateFile to include the CA cert
#     issuing puppet client certificate.
SSLVerifyClient optional
SSLVerifyDepth  1
SSLOptions +StdEnvVars
# Passenger options that can be set in a virtual host
# configuration block.
PassengerHighPerformance on
PassengerStatThrottleRate 120
PassengerUseGlobalQueue on
RackAutoDetect Off
RailsAutoDetect Off
RackBaseURI /
DocumentRoot /usr/share/puppet/rack/puppetmasterd/public 

<Directory /usr/share/puppet/rack/puppetmasterd/>
   Options None
   AllowOverride None
   Order allow,deny
   Allow from all
</Directory>
</VirtualHost>

Attention bien sur de remplacer « hostname.domain » par le nom de votre machine et de son domaine !
Ensuite il faut empecher le puppetmaster d’utiliser son serveur webrick, on va spécifier dans le fichier /etc/default/puppetmaster que le démon ne doit pas être lancé (puisque c’est apache2 qui sera utilisé !)

# sed -i "s/START=yes/START=no/" /etc/default/puppetmaster
# service puppetmaster stop

Il faut enfin activer le mode ssl d’apache, le vhost et relancer apache2

# a2enmod ssl; a2ensite puppet && service apache2 restart

Il vous faut maintenant configurer correctement votre Puppetmaster. Par soucis de simplicité j’ai décidé d’utiliser mysql comme backend pour mes storeconfig (documentation officielle). Il faut donc configurer la section [master] dans le fichier de configuration /etc/puppet/puppet.conf.
Il vous faut donc créer votre base pour puppet et granter un user :

# mysql -u root -pvotre_password
mysql> create database puppet;
mysql> grant all on puppet.* to puppet@'localhost' identified by 'votre_password_puppet';
mysql> quit;

Il vous faut ensuite ajouter à votre puppet.conf la section [master] :

[master]
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY
storeconfigs=true
dbadapter=mysql
dbuser=puppet
dbpassword=votre_password_puppet
dbserver=localhost
dbsocket=/var/run/mysqld/mysqld.sock

Toujours dans le puppet.conf, il vous faut vous assurer que votre serveur puppetmaster est configuré correctement avec la directive :

server = votre_serveur.example.com

Attention de ne pas utiliser un alias DNS, il faut que le nom du serveur pointé corresponde au nom des variables $hostname et $domain remonté par la commande `facter` ;
Puppet possède un mécanisme de protection pour autoriser seulement certaines IP à accéder au Puppetmaster. Ceci ce règle au niveau du fileserver.conf :

[files]
  path /etc/puppet/files
#  allow *.example.com
#  deny *.evil.example.com
  allow xxx.xxx.xxx.xxx/yy

[plugins]
  allow xxx.xxx.xxx.xxx/yy

[modules]
  allow xxx.xxx.xxx.xxx/yy

Vous devez ensuite positionner l’ensemble de vos modules puppet dans le répertoire /etc/puppet/module.
Une fois ceci réalisé vous devriez avoir un serveur puppet sous passenger fonctionnel !

Share