Projet

Général

Profil

StageVidal » Historique » Version 41

Version 40 (Maurice Vidal, 21/05/2012 20:53) → Version 41/83 (Maurice Vidal, 21/05/2012 22:44)

h1. StageVidal

Références : http://chiliproject.tetaneutral.net/projects/tetaneutral/wiki/Stages2012

NickName sur l'IRC de l'association :
*<pre>
_Mvidal_
</pre>*

h2. TODO

outils de communication de fichier IRC

http://paste.debian.net/164858/
http://pastebin.com

h1. Tutoriel SSH :

L'objectif présenté ici est de mettre en place une connexion sécurisée entre un client et un serveur à travers une zone non fiable (Internet) grâce à un tunnel crypté. Nous nous serviront d'un système de clé SSH qui servira à nous authentifier : une clé privée que nous garderons sur le poste local, et une clé publique que nous mettrons dans le serveur.

Nous allons prendre comme exemple, le poste distant de l'association pvm3.tetaneutral.net (qui jouera le rôle du serveur), et comme poste local, pc_local.

Sur le poste distant il faut installer le package openssh-server :
*aptitude install openssh-server*

Et sur le poste local il faut installer le package openssh-client :
*aptitude install openssh-client*

h3. Configuration du poste local :

Nous allons commencer par générer une clé SSH.

*ssh-keygen*
(/root/.ssh/id_rsa) :
enter passphrase :
enter same passphrase :

Par défaut la clé publique sera créée au nom de /root/.ssh/id_rsa.pub et la clé privée au nom de /root/.ssh/id_rsa.

En laissant chacun de ces champs vides, le chemin sera celui utilisé par défaut et aucune passphrase ne sera nécessaire. La passphrase sert uniquement à protéger la clé privé si on craint de ne pas la garder en sûreté sur son poste local.

On vérifie que les clés soient bien créées (exemple type) :

*ls /root/.ssh/*
id_rsa id_rsa.pub know_hosts

h3. Configuration du poste distant :

Nous allons modifier le fichier de configuration se trouvant dans /root/.shh/authorized_keys pour venir y ajouter la clé publique (id_rsa.pub) du poste local, ce lui permettra de venir se connecter au serveur

Si nous avons récupéré la clé publique sur le serveur, nous pouvons l'insérer dans le fichier des clés autorisées :
*cat id_rsa.pub >> ~/.ssh/authorized_keys*

Le fichier de configuration pour le démon SSHD se situe à /etc/ssh/sshd_config, on le modifie pour améliorer la sécurité. Quelques options importantes :

* ListenAddress X.X.X.X:X Change le port d’écoute, ainsi l’intrus ne peut être complètement sûr de l’exécution d’un démon SSHD (c’est de la sécurité par l’obscurité).
* Protocole 2 Désactiver le protocole version 1, car il a des défauts de conception qui facilite le crack de mots de passe.
* PermitRootLogin no Cette option permet de ne pas autoriser la connexion en root sur la machine.
* PermitEmptyPasswords no Les mots de passe vides sont un affront au système de sécurité.
* PasswordAuthentication yes Il est plus sûr d’autoriser l’accès à la machine uniquement aux utilisateurs avec des clés SSH placées dans le fichier /root/.ssh/authorized_keys, il faut donc placer cette option à "no".
* SyslogFacility AUTH Fichiers journaux.
* LogLevel INF Fichiers journaux.
*

Une fois le fichier de configuration prêt, il ne reste plus qu'à relancer le service :
*/etc/init.d/ssh reload*

h3. Commandes utiles :

Se connecter en SSH sur le port 443 de la machine pvm3 de tetaneutral.net :
*ssh -p 443 root@pvm3.tetaneutral.net*

Copier le fichier distant /var/log/mail.log sur son poste local (il ne faut pas être connecté en SSH) :
*scp -P 443 root@pvm3.tetaneutral.net:/var/log/mail.log /tmp/*
Inversement pour copier un fichier local vers un poste distant (ne pas être connecté en SSH)
*scp -P 443 fichier_local root@pvm1.tetaneutral.net:/home/maumau/lol.txt*

h3. Pour se déconnecter :

*CTRL + d*

h3. Voir les log de ssh :

*tailf /var/log/auth.log*

h1. PROJET PUPPET : DRBD + MX REDONDANT

h2. Roadmap

Semaine 01, 09/04 - 13/04 : Prise en main de l'existant (SSH, IRC, Machines Virtuelles)
Semaine 02, 16/04 - 20/04 : Documentation sur le gestionnaire Puppet
Semaine 03, 23/04 - 28/04 : Maîtrise et configuration de Puppet
Semaine 04, 30/04 - 04/05 : Déploiement de Bind, Unbound et de Postfix via Puppet
Semaine 05, 07/05 - 11/05 : Documentation sur DRBD
Semaine 06, 14/05 - 18/05 : Mise en place d'un MX redondant grâce à DRBD

h2. Aides Tutoriels sur Puppet

http://doc.ubuntu-fr.org/puppet
http://www.crium.univ-metz.net/docs/system/puppet.html
http://www.octopuce.net/Puppet-Administration-systeme-centralisee
http://bitfieldconsulting.com/puppet-tutorial-2
http://www.craigdunn.org/2010/08/part-2-puppet-2-6-1-configure-pvm1-and-puppetd/
http://docs.puppetlabs.com/guides/environment.html
http://projects.puppetlabs.com/projects/puppet/wiki/Simplest_Puppet_Install_Pattern
http://chiliproject.tetaneutral.net/projects/tetaneutral/wiki/PUPPET
http://finninday.net/wiki/index.php/Zero_to_puppet_in_one_day
http://madeinsyria.net/2011/06/howto-puppet-administration-et-industrialisation-de-masse/
http://jeyg.info/mise-en-place-de-puppet-un-gestionnaire-de-configuration-linuxunix/
http://www.deimos.net/blocnotesinfo/index.php?title=Puppet_:_Solution_de_gestion_de_fichier_de_configuration
http://bitfieldconsulting.com/puppet-tutorial
http://www.unixgarden.com/index.php/gnu-linux-magazine/les-sysadmins-jouent-a-la-poupee

h2. Aides Tutoriels sur DRBD

http://wapiti.telecom-lille1.eu/commun/ens/peda/options/ST/RIO/pub/exposes/exposesrio2007/legrand-playez/howto.htm
http://www.drbd.org/users-guide-emb/p-work.html
http://doc.ubuntu-fr.org/drbd
http://doc.ubuntu-fr.org/tutoriel/mirroring_sur_deux_serveurs

h2. Aides Tutoriels sur UnBound

http://www.deimos.net/blocnotesinfo/index.php?title=Fichier:Installing_And_Using_The_Unbound_Name_Server.pdf
http://unbound.net/documentation/index.html
http://www.howtoforge.com/installing-using-unbound-nameserver-on-debian-etch
http://www.bortzmeyer.org/unbound.html

h2. Aides Tutoriels sur BIND

http://fr.wikibooks.org/wiki/Le_syst%C3%A8me_d%27exploitation_GNU-Linux/Le_serveur_de_noms_Bind
http://www.deimos.net/blocnotesinfo/index.php?title=Installation_et_configuration_d%27un_serveur_Bind9_primaire_(Master)
http://www.howtoforge.com/traditional_dns_howto
http://coagul.org/drupal/article/installation-d%E2%80%99-serveur-dns-bind-9-sur-debian

h2. Aides Tutoriels sur Postfix Ldap

http://www.bizeul.net/?2005/05/27/7-serveur-de-messagerie-multi-domaines-avec-postfix-openldap-et-courier
http://www.mp-poissy.ac-versailles.net/Formations/05-06/Pdf/courrier_ldap.pdf
http://blog.wains.be/2010/01/25/postfix-virtual-usersgroupsaliases-stored-in-ldap/
http://wiki.linuxwall.info/doku.php/fr:ressources:dossiers:postfix:ldap
http://www.mp-poissy.ac-versailles.net/Formations/05-06/Pdf/courrier_ldap.pdf
http://www.404blog.net/?p=36
http://www.linux-france.org/prj/inetdoc/cours/admin.reseau.ldap.synthese/admin.reseau.ldap.srvr.html

h1. Questions

h2. A propos du DRBD + MX redondant

*j'aurais voulu savoir si il faut que l'on mette en place 1 Bind et 1 Unbound et que l'on y fasse un DRBD sur les sections /etc de chacun de ces deux serveurs ?*

Réponse : il y a trois choses séparées :

# configurer deux VM une avec bind et une avec unbound. Comme une partie des fichiers de configuration sont différents pour le moment pas de DRBD, juste bien documenter.
# configurer deux VM qui ont un bout de disque répliqué avec DRBD, bien documenter le setup DRBD
# configurer deux VM qui sont MX primaire et secondaire d'un domaine, verifier que ça marche. Ensuite essayer de rajouter DRBD pour rendre le setup totalement fiable dans le sens qu'aucune perte de mail entrant n'est possible.

A chaque fois l'objectif "documenter" est bien sur d'utiliser [[Puppet]]

La partie DRBD du MX viendra uniquement à la fin, c'est la plus complexe.

h2. PUPPET : Déploiement de BIND et UNBOUND (sur deux machines)

*Puppet est ce que l’on peut appeler un gestionnaire de configuration.
C’est un outil qui facilite le contrôle et la mise à jour de configurations tout en offrant la possibilité de faire abstraction de l’OS et de l’architecture concernée. Puppet va permettre de déployer des fichiers, des services, des packages, des commandes et même un cron au travers de clients qui deviendront des Serveurs (exemple : BIND, UNBOUND).*

Puppet est donc un outil de centralisation de l’administration de systèmes hétérogènes ou homogènes
Au travers du serveur puppet (Pvm1), chaque machine, appelée noeud (node), fait tourner Puppetd, qui :
+Applique la configuration initiale pour le noeud concerné.+
+Applique les nouveautés de configuration au fil du temps.+
+S’assure de manière régulière que la machine correspond bien à la config voulu.+

La communication est assurée via des canaux chiffrés, en utilisant le protocole HTTPS de communication de ruby, et donc SSL (une mini-pki est fournie). Pvm1 sait servir :
+des recettes de configuration+ (recipes)
+des fichiers+
+des modèles+ (qui sont des fichiers avec des variables de remplacement)
+des objets ruby+ (c’est là l’extensibilité de l’application)
Et bien évidemment : Puppet est un logiciel libre écrit en Ruby, multiplateforme : BSD (Free, MacOS ...), Linux (Redhat, Debian, Suse ...), Sun (OPENSolaris ...).

Puppet fournit un langage déclaratif simple :
+classes+ (permet de définir les configurations de chaque service)
+héritage+ (permet de regrouper les configurations communes)
+types d’objets particuliers+ (définis par puppet, ou par des modules) +fonctions utilisateur+
+abonnement d’instances à d’autres instances+ (ex : un service est abonné à son fichier de conf, la modif de l’un entraînera le redémarrage de l’autre)

h3. *Exemples de types d’objets internes :*

+File+, permet de demander qu’un fichier existe, dispose de certains droits, et corresponde éventuellement à un certain contenu, fournit statiquement, ou à travers un modèle (template) avec substitution de variables.
+Service+, permet de déclarer un service, de s’assurer qu’il fonctionne, de le redémarrer dans certaines conditions (par exemple quand la configuration est modifiée).
+Package+, permet de demander l’installation, la mise à jour ou la désinstallation d’un package, en utilisant le système de packaging natif de l’OS utilisé (ports, deb, packages MacosX etc.)
+User+, permet de gérer les utilisateurs UNIX (dans /etc/passwd) indépendemment de l’OS utilisé.

h3. *Puppet fonctionne selon le modèle client/serveur :*

!http://img15.hostingpics.net/pics/54901331cs.jpg!

*Pré-requis :*

Nous prenons l'exemple que notre serveur Puppet à pour hostname : pvm1, et nos clients portent le nom de : pvm2, pvm3.

Comme nom de domaine nous prenons un sous-domaine l'exemple de l'association l'université de Perpignan : testdomain1.tetaneutral.net

*Et les adresses IP sont donc :*

pvm1 : 91.224.149.35
pvm2 : 91.224.149.36
pvm3 : 91.224.149.37
pvm4 : 91.224.149.38
pvm5 : 91.224.149.30

h3. *Installation de Puppet*

Serveur : # apt-get install pvm1
Clients : # apt-get install puppet

Ici nous utilisons la version 2.6.2 de Puppet. Lors de l’installation, un utilisateur « puppet » sera créé.

Tout d'abord il faut que le fichier hosts de chaque client référence l'adresse IP, le hostname et le FQDN du serveur. Ainsi il faut rajouter dans /etc/hosts :

91.224.149.35 pvm1 pvm1.testdomain1.tetaneutral.net

De même sur le serveur il faut rajouter les noms des 3 machines clientes de la même façon.
A ce stade nous n'avons pas de serveurs DNS, justement nous allons le(s) déployer :)

Il est important (si l'on a un pare-feu) d'ouvrir les ports 8140 coté serveur :
*iptables -A INPUT -p tcp -m state --state NEW -s 91.224.149.0/24 --dport 8140 -j ACCEPT*

De plus il est important de pouvoir regarder les logs (tant sur le serveur que sur les clients) :
*tailf /var/log/daemon.log*

h3. *Configuration de Puppet*

DEMANDE DE CERTIFICAT

*Serveur :*
Il faut modifier le fichier /etc/puppet/puppet.conf, il doit ressembler à ceci :

<pre>
[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
templatedir=$confdir/templates

[master]
report=true
reports=log,store
modulepath=/etc/puppet/modules
</pre>

*Clients :*

Ici il faut rajouter le FQDN (ou Hostname s'il n'y a pas de domaine) du serveur, ainsi dans /etc/puppet/puppet.conf :

<pre>
[main]
...
server=pvm1.testdomain1.tetaneutral.net
</pre>

Une fois cette modification faite, il n'y pas plus qu'à demander au serveur Puppet de signer notre certificat, car rappelons que PUPPET utilise le SSL, il est donc plus sécurisé qu'un NFS.

*pvm2# puppetd --waitforcert 60 --test*
ou
*pvm2# puppet agent --waitforcert 60 --test*

Le serveur va ensuite visualiser les demandes :
*pvm1#puppetca --list*

Puis il va signer les demandes :
*pvm1#puppetca --sign pvm2*
ou
*pvm1#puppetca --sign --all* (pour tous d'un coup)

Le serveur est prêt à l'emploi, et les clients ont un certificat signé. Passons à une configuration axé sur le déploiement de Bind et d'Unbound.

Tout d'abord laissez moi vous montrer à quoi va ressembler l'arborescence de votre serveur puppet :

!http://img15.hostingpics.net/pics/481782tree.jpg!

Afin d'utiliser Puppet un minimum, nous allons lui demander de déployer UNBOUND sur une machine cliente (pvm2). Il va falloir configurer le serveur, ainsi /etc/puppet/fileserver.conf :

<pre>
[files]
path /etc/puppet/files
allow *.testdomain1.tetaneutral.net
</pre>

Nous venons d'autoriser seulement les machines provenant du domaine à pouvoir recevoir des fichiers du répertoire /etc/puppet/files/

Il faut également créer le fichier : /etc/puppet/namespaceauth.conf et y rajouter :

<pre>
[puppetrunner]
allow *
</pre>

Le daemon du client va initialement interroger le fichier /etc/puppet/manifests/site.pp du serveur, c'est pourquoi dans ce fichier nous allons importer tous les fichiers .pp (spécialement conçu pour Puppet).
/etc/puppet/manifests/site.pp :

<pre>
import "node"
import "modules.pp"
import "cron"
</pre>

Ensuite pour éviter de déployer UNBOUND sur tous les nodes, nous allons spécifier lesquels vont recevoir la classe UNBOUND que nous créerons (dans le fichier init.pp du module Unbound). Ainsi dans le fichier /etc/puppet/manifests/node.pp :

<pre>
node basenode {
include crontab
}
node 'pvm2.testdomain1.tetaneutral.net' inherits basenode {
include bind, resolv
}
node 'pvm3.testdomain1.tetaneutral.net' inherits basenode {
include unbound, resolv
}</pre>

Ici nous créons un faux node (client puppet) nommé basenode en lui incluant la classe "crontab", et les nodes puppetli1 et pvm3 héritent de basenode (autrement dit de la classe crontab). Ensuite nous leurs attribuons la classe unbound et resolv pour pvm2 puis bind et resolv pour pvm3.

Il faut également créer le fichier /etc/puppet/manifests/modules.pp qui va référencer les modules du serveur :

<pre>
import "unbound"
import "bind"
</pre>

On peut appeler un module, le nom d'un répertoire, en effet il est recommandé de créer des modules pour chaque service afin de rendre la configuration plus souple.

Pour finir sur la configuration de base, nous allons mettre en place un cron qui se déploiera sur les clients afin de lancer une synchronisation avec le serveur, ainsi quand le cron arrive à son échéance (15 minutes) il va permettre de checker toutes modifications du client puppet. Donc on va créer le fichier /etc/puppet/manifests/cron.pp :

<pre>
class crontab {
cron { "synchronisation puppet":
command => "/usr/sbin/puppetd --test --server=pvm1.testdomain1.tetaneutral.net",
minute => "*/15"
}
}
</pre>

Passons à la configuration des modules :

h3. Création des modules :

*mkdir -p /etc/puppet/modules/unbound/{files,manifests,templates}*
*mkdir -p /etc/puppet/modules/bind/{files,manifests,templates}*

Le dossier MANIFESTS permet de répertorier le fichier init.pp qui défini le coeur du module.
Le dossier FILES contient les fichiers statiques, ceux qui ne changent pas d'un node à l'autre.
Le dossier TEMPLATES contient les fichiers de configurations variant d'un hôte à l'autre.

+Maintenant que les modules sont crées, nous plaçons le fichier de configuration d'Unbound que voici : /etc/puppet/modules/unbound/files/unbound.conf :+

Ici nous faisons la résolution du domaine : testdomain1.tetaneutral.net avec pour serveur DNS : pvm3

<pre>
### Simple recursive caching DNS
## /etc/unbound.conf
server:
verbosity: 1
outgoing-range: 60
interface: 91.224.149.37
do-ip4: yes
do-udp: yes
do-tcp: yes
access-control: 0.0.0.0/0 allow #On autorise l’ensemble d’INTERNET à interroger le DNS
chroot: "" #Pas de chroot par défaut
logfile: "/var/log/unbound.log" #On défini le fichier de log
use-syslog: no #Log par défaut dans syslog
hide-identity: yes
hide-version: yes
harden-glue: yes #On dit que le serveur fait autorité sur la zone
private-domain: "testdomain1.tetaneutral.net." #On définit le suffix dns du réseau local
local-zone: "testdomain1.tetaneutral.net." static #on définit qui s'occupe de quoi dans le domaine
local-data: "testdomain1.tetaneutral.net. IN MX 10 pvm5.testdomain1.tetaneutral.net." #serveur Postfix pvm5
local-data: "testdomain1.tetaneutral.net. IN MX 20 pvm4.testdomain1.tetaneutral.net." #serveur Postfix pvm4
local-data: "testdomain1.tetaneutral.net. IN NS pvm3.testdomain1.tetaneutral.net." #service DNS
local-data: "pvm1.testdomain1.tetaneutral.net. IN A 91.224.149.35" #résolution : nom -> adresse
local-data: "pvm2.testdomain1.tetaneutral.net. IN A 91.224.149.36"
local-data: "pvm3.testdomain1.tetaneutral.net. IN A 91.224.149.37"
local-data-ptr: "91.224.149.35 pvm1.testdomain1.tetaneutral.net." #résolution inverse : adresse -> nom
local-data-ptr: "91.224.149.36 pvm2.testdomain1.tetaneutral.net."
local-data-ptr: "91.224.149.37 pvm3.testdomain1.tetaneutral.net."
python:
remote-control:
forward-zone:
name: "."
forward-addr: 91.224.149.254 # DNS Faisant Authorité à tetaneutral.net
</pre>

Passons à la configuration du fichier principal : /etc/puppet/modules/unbound/manifests/init.pp :

<pre>
class unbound {
package { unbound: ensure => installed }
file { "/etc/unbound/unbound.conf":
require => package["unbound"],
notify => Service["unbound"],
mode => 644,
owner => "root",
group => "root",
source => "puppet:///modules/unbound/unbound.conf"
}
service { unbound: ensure => running,
enable => true
} }
class resolv {
file { "/etc/resolv.conf":
require => Class["unbound"],
ensure => present,
content => "domain testdomain1.tetaneutral.net
search testdomain1.tetaneutral.net
nameserver $ipaddress"
}
}
</pre>
Pour la classe "unbound", nous venons de lui permettre d'installer le paquet UNBOUND, de lui déployer le fichier de configuration sur /etc/unbound/unbound.conf afin de remplacer l'existant et ensuite nous lui avons forçer le démarrage du daemon UNBOUND. Lors du déploiement d'un fichier, dans le paramètre SOURCE, remarquons qu'il n'est pas nécessaire de référencer le répertoire "files" dans le module, grâce au protocole qui est défini ici : puppet:///

Quant à la classe "resolv" est de type TEMPLATES, c'est à dire qu'elle est dynamique, elle s'adapte à l'hôte grâce à son adresse IP qui est remonté grâce aux facts (outils facter qui est compréhensible par PUPPET). En effet Facter est un outil associé à puppet, chargé d’énumérer les paramètres locaux d’un système :
*Adresse IP
Hostname
Distribution et version
Toutes autres variables locales définies par l’utilisateur.*

Il est disponible sur les noeuds utilisant Puppetd, il fournit des variables utilisables dans les templates puppet.

Configuration du module BIND

Voici le fichier de configuration /etc/puppet/modules/bind/manifests/init.pp :

<pre>
class bind {
package { bind9: ensure => installed }
file { "/etc/bind/named.conf.local":
require => package ["bind9"],
ensure => present,
mode => 644,
owner => "root",
group => "bind",
source => "puppet:///modules/bind/named.conf.local" }
file { "/etc/bind/named.conf.options":
require => package ["bind9"],
ensure => present,
mode => 644,
owner => "root",
group => "bind",
source => "puppet:///modules/bind/named.conf.options" }
file { "/var/cache/bind/db.testdomain1.tetaneutral.net":
require => package ["bind9"],
ensure => present,
mode => 644,
owner => "root",
group => "bind",
source => "puppet:///modules/bind/db.testdomain1.tetaneutral.net" }
file { "/var/cache/bind/rev.testdomain1.tetaneutral.net":
require => package ["bind9"],
ensure => present,
mode => 644,
owner => "root",
group => "bind",
source => "puppet:///modules/bind/rev.testdomain1.tetaneutral.net" }
service { bind9: ensure => running,
enable => true ,
require => package ["bind9"],
}
}
</pre>

Ici nous installons (si BIND n'est pas installé) le paquet, puis lui déployons les fichiers de configurations, puis le forçons à être démarré. Nous lui attribuons les droits 644 (par défaut sur Bind), puis le propriétaire root et le groupe bind.
Pareillement, ici nous remarquons que pour déployer le fichier, il n'est pas nécessaire de référencer le répertoire "files" dans le module, grâce au protocole qui est défini ici : puppet:///

Passons aux fichiers de configurations : /etc/puppet/modules/bind/files/named.conf.local :

<pre>
// La zone primaire testdomain1.tetaneutral.net
zone "testdomain1.tetaneutral.net" {
type master;
file "/var/cache/bind/db.testdomain1.tetaneutral.net"; };
// La zone inverse
zone "149.224.91.in-addr.arpa" {
type master;
file "/var/cache/bind/rev.testdomain1.tetaneutral.net";
};
</pre>

Puis le fichier : /etc/puppet/modules/bind/files/named.conf.options :

<pre>
options {
directory "/var/cache/bind";
forwarders {
91.224.149.254; 91.224.148.10; 8.8.8.8;
};
auth-nxdomain no; # conform to RFC1035
listen-on { any; };
allow-query { any ; };
};
</pre>

Le fichier de zone primaire TESTDOMAIN1.TETANEUTRAL.net : /etc/puppet/modules/bind/files/db.testdomain1.tetaneutral.net :

<pre>
;
; BIND data file for testdomain1.tetaneutral.net
;
$TTL 604800
@ IN SOA pvm2.testdomain1.tetaneutral.net. admin.testdomain1.tetaneutral.net. (
201205091 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
@ IN NS pvm2.testdomain1.tetaneutral.net.
pvm1 IN A 91.224.149.35
pvm2 IN A 91.224.149.36
pvm3 IN A 91.224.149.37
pvm4 IN MX 0 91.224.149.38
pvm5 IN MX 10 91.224.149.30
</pre>

Et pour finir le fichier de zone inverse ARPA : /etc/puppet/modules/bind/rev.testdomain1.tetaneutral.net :

<pre>
;
; BIND data file for 91.224.149
;
$TTL 604800
@ IN SOA pvm2.testdomain1.tetaneutral.net. (
201209051 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
@ IN NS pvm2.testdomain1.tetaneutral.net.
35 IN PTR pvm1.testdomain1.tetaneutral.net.
36 IN PTR pvm2.testdomain1.tetaneutral.net.
37 IN PTR pvm3.testdomain1.tetaneutral.net.
38 IN PTR pvm4.testdomain1.tetaneutral.net.
30 IN PTR pvm5.testdomain1.tetaneutral.net.

</pre>

h3. *Configuration des templates*

Variables prédéfinie:

Ici nous allons vous montrer comment on peut adapter les fichiers de configurations que nous déployons suivant le node.
Ainsi chaque node aura un paramètre différent d’un autre node, il s’agit du template. Nous allons prendre le cas du fichier de configuration d’Unbound. Sur le serveur Puppet il faut déplacer le fichier /etc/puppet/modules/unbound/files/unbound.conf dans /etc/puppet/modules/unbound/templates/unbound.conf.erb.

En effet lorsqu’on créé un template, il doit être sous l’extension "erb".
En effet nous allons nous servir de la variable "ipaddress" disponible grâce à l’outil facter, ainsi en étant sur le client, il suffit de lancer la commande : *pvm2 # facter* pour obtenir les informations des variables de la machine locale.

Nous allons renseigner la variable "ipaddress" grâce aux balises de début: <%= et aux balises de fin: %>
Ainsi :

Pvm1 *head /etc/puppet/modules/unbound/templates/unbound.conf.erb*

<pre>
server:
verbosity: 1
outgoing-range: 60
interface: <%= ipaddress %>
do-ip4: yes
do-udp: yes
do-tcp: yes
access-control: 91.224.149.0/24 allow
chroot: ""
logfile: "/var/log/unbound.log"
</pre>

A chaque fois que nous utiliserons les fichiers templates, il faudra changer le chemin source du fichier du serveur Puppet du fichier init.pp, dans cet exemple : /etc/puppet/modules/unbound/manifests/init.pp :
On remplace : source => "puppet:///modules/unbound/unbound.conf"
Par : content => template("/etc/puppet/modules/unbound/templates/unbound.conf.erb"),

h3. *Création de variables:*

Nous allons maintenant créer des variables qui s’utiliseront uniquement sur les nodes définis. Nous poursuivons sur l’exemple d’Unbound qui se déploiera sur le client : pvm2.testdomain1.tetaneutral.net. Dans un premier temps il faut créer la variable dans le fichier /etc/puppet/manifests/node.pp :

> node ‘pvm2.testdomain1.tetaneutral.net' inherits basenode {
> *$network = “91.224.149.0”*
> include bind }

Puis l’appliquer sur le fichier /etc/puppet/modules/unbound/templates/unbound.conf.erb :
Pvm1 *head /etc/puppet/modules/unbound/templates/unbound.conf.erb*

<pre>
server:
verbosity: 1
outgoing-range: 60
interface: <%= ipaddress %>
do-ip4: yes
do-udp: yes
do-tcp: yes
access-control: <%= network %>/24 allow
chroot: ""
logfile: "/var/log/unbound.log"
</pre>

La mise en place de templates permet de gagner sensiblement du temps sur la configuration des postes, c’est d’ailleurs pour cette utilisation que l’outil facter a été développé. En effet Puppet sert surtout pour les déploiements massifs, le gain de temps et d'énergie est ainsi effectif.

h2. *LANCEMENT DE LA SYNCHRONISATION :*

Sur le serveur, il faut initier la connexion :
*puppetmasterd --no-daemonize --debug*

Nous lançon le daemon en mode test, c'est à dire non-démon afin de débugger et vérifier que tout se déroule convenablement.

Si on rencontre un problème tel que :
_Could not run: Could not create PID file: /var/run/puppet/master.pid_

Il faut alors supprimer le fichier sur le serveur : # *rm /var/run/puppet/master.pid* relancer la commande :
*puppetmasterd --no-daemonize --debug*

Sur les clients on va vérifier le fichier du serveur /etc/puppet/site.pp avec la commande :
*puppetd --test --server=pvm1.testdomain1.tetaneutral.net*

A savoir qu'un cron est mis en place afin d'éviter aux clients de renouveler cette commande manuellement, il faut noter que la commande du serveur : "puppetmasterd --no-daemonize -d" ne doit pas être arrêtée.

h2. Mise en place d'un DRBD et GFS2 par Puppet

*TOUT CE QUI EST DIT A PARTIR DE MAINTENANT DOIT ETRE IDENTIQUE SUR LES DEUX MACHINES, LANCER LES COMMANDES EN MEME TEMPS :*

Nous avons besoins de deux nouvelles machines :

Hostname : pvm4 = IP : 91.224.149.38
Hosntame : pvm5 = IP : 91.224.149.30

h3. *Installation :*

Au préalable il faut un second disque dur sur chaque machines, de taille minimale de 2G. normalement il apparait tel que : /dev/vdb.
Nous le partitionnons :

*cfdisk /dev/vdb*
NEW => LOGIQUE => Taille totale (faites entré) => WRITE => yes => "q" pour sortir

A la suite de cela, nous obtenons la partition : /dev/vdb5.

h3. *Installation des outils :*

Sur le pvm1, nous allons créer deux nouveaux modules :

*mkdir -p /etc/puppet/modules/drbd/{files,manifests,templates}*
*mkdir -p /etc/puppet/modules/gfs2/{files,manifests,templates}*

Puis on rajoute nos deux modules dans le fichier /etc/puppet/manifests/modules.pp :

<pre>
import "drbd"
import "gfs2"
</pre>

Commençons par l'installation de drbd :

*vi /etc/puppet/modules/drbd/manifests/init.pp*

<pre>
class drbd::package {
package { "drbd8-utils": ensure => installed }
}
class drbd::fic {
exec { "modprobe":
require => Class["drbd::package"],
command => "/sbin/modprobe drbd"
}
file { "/etc/drbd.d/global_common.conf":
require => Class["drbd::package"],
ensure => present,
source => "puppet:///modules/drbd/global_common.conf"
}
file { "/etc/drbd.d/r0.res":
require => Class["drbd::package"],
ensure => present,
content => template("/etc/puppet/modules/drbd/templates/r0.res.erb")
}
}
class drbd::command {
exec { "create_ressource":
require => File["/etc/drbd.d/r0.res"],
command => "/sbin/drbdadm create-md r0"
}
exec { "start_drbd":
require => create_ressource"],
command => "/usr/sbin/service drbd start"
}
}
class drbd::cron1 {
file { "/root/overwrite.sh":
ensure => present,
source => "puppet:///modules/drbd/overwrite.sh"
}
file { "/root/mkfs.sh":
ensure => present,
source => "puppet:///modules/drbd/mkfs.sh"
}
}
class drbd::cron1.1 {
cron { "cron_over":
require => Class["drbd::cron1"],
command => "/root/overwrite.sh",
hour => "*/2"
}
cron { "cron_mkfs":
require => Class["drbd::cron1"],
command => "/root/mkfs.sh",
hour => "*/3",
minute => "*/10"
}
}
class drbd::cron2 {
file { "/root/primary.sh":
ensure => present,
source => "puppet:///modules/drbd/primary.sh"
}
}
class drbd::cron2.2 {
cron { "cron_primary":
require => Class["drbd::cron2"],
command => "/root/primary.sh",
hour => "*/3"
}
}
class cron_supp {
file { "/root/supp.sh":
ensure => present,
source => $hostname ? {
pvm4 => "puppet:///modules/drbd/supp.pvm4.sh",
pvm5 => "puppet:///modules/drbd/supp.pvm5.sh"
}
}
cron { "delete_cron":
require => File["/root/supp.sh"],
command => "/root/supp.sh",
hour => "*/3",
minute => "35"
}
}
</pre>

Puis nous mettons à disposition le fichier de configuration de drbd,
*vi /etc/puppet/modules/drbd/files/global_common.conf*

<pre>
global {
usage-count no;
}
common {
protocol C;
syncer {
rate 100M;
}
}</pre>

Et on utilise un template pour l'autre partie du fichier de configuration,
*vi /etc/puppet/modules/drbd/templates/r0.res.erb*

<pre>
resource r0 {
device /dev/drbd0;
disk <%= disk %>;
meta-disk internal;
startup {
wfc-timeout 120;
degr-wfc-timeout 120;
become-primary-on both;
}
disk { on-io-error detach; }
net {
allow-two-primaries;
after-sb-0pri discard-zero-changes;
after-sb-1pri discard-secondary;
after-sb-2pri disconnect;
}
on <%= node1name %> {
address <%= node1ip %>:7788;
}
on <%= node2name %> {
address <%= node2ip %>:7788;
}
}
</pre>

On va ensuite modifier sur le serveur Puppet le fichier :
/etc/puppet/manifests/node.pp :

<pre>
node 'pvm4.testdomain1.tetaneutral.net' {
$pptmasterip = "91.224.149.35"
$pptmastername = "pvm1"
$pptmasterfqdn = "pvm1.testdomain1.tetaneutral.net"
$node1ip = "91.224.149.38"
$node1name = "pvm4"
$node1fqdn = "pvm4.testdomain1.tetaneutral.net"
$node2ip = "91.224.149.30"
$node2name = "pvm5"
$node2fqdn = "pvm5.testdomain1.tetaneutral.net"
$disk = "/dev/vdb5"
include drbd::package, drbd::fic, drbd::command, drbd::cron1, drbd::cron1.1, cron_supp
}
node 'pvm5.testdomain1.tetaneutral.net' {
$pptmasterip = "91.224.149.35"
$pptmastername = "pvm1"
$pptmasterfqdn = "pvm1.testdomain1.tetaneutral.net"
$node1ip = "91.224.149.38"
$node1name = "pvm4"
$node1fqdn = "pvm4.testdomain1.tetaneutral.net"
$node2ip = "91.224.149.30"
$node2name = "pvm5"
$node2fqdn = "pvm5.testdomain1.tetaneutral.net"
$disk = "/dev/vdb5"
include drbd::package, drbd::fic, drbd::command, drbd::cron2, drbd::cron2.2, cron_supp
}
</pre>

Maintenant voyons les fichiers bash que nous utiliserons pour les différents 'cron' :
*cat /etc/puppet/modules/drbd/files/overwrite.sh*
<pre>
#!/bin/bash
drbdadm -- --overwrite-data-of-peer primary r0
</pre>

*cat /etc/puppet/modules/drbd/files/mkfs.sh*
<pre>
#!/bin/bash
mkfs.gfs2 -t cluster1:gfs2 -p lock_dlm -j 2 /dev/drbd0
</pre>

*cat /etc/puppet/modules/drbd/files/primary.sh*
<pre>
#!/bin/bash
drbdadm primary r0
</pre>

*cat /etc/puppet/modules/drbd/files/supp.pvm4.sh*
<pre>
#!/bin/bash
rm -r /root/overwrite.sh
rm -r /root/mkfs.sh
</pre>

*cat /etc/puppet/modules/drbd/files/supp.pvm5.sh*
<pre>
#!/bin/bash
rm -r /root/primary.sh
</pre>

Ne pas oublier de mettre le droit d'execution aux fichier bash avec cette commande :
<pre>
chmod 744 /etc/puppet/modules/drbd/files/*.sh
</pre>

Il y a des commandes à faire manuellement, moi j'ai préféré utiliser l'ordonnanceur cron.

Passons à la configuration de GFS2 :

*cat /etc/puppet/modules/gfs2/manifests/init.pp*
<pre>
class gfs2::package {
package { "cman": ensure => installed }
package { "gfs2-tools": ensure => installed }
package { "libopenais-dev": ensure => installed }
}
class gfs2::fic {
file { "/etc/cluster/cluster.conf":
require => Class["gfs2::package"],
ensure => present,
source => "puppet:///modules/gfs2/cluster.conf"
}
}
class gfs2::command {
exec { "stop_network_manager":
require => Class["gfs2::fic"],
command => "/usr/sbin/service network-manager stop"
}
exec { "start_cman":
require => Exec["stop_network_manager"],
command => "/usr/sbin/service cman start"
}
}
class gfs2::hosts {
file { "/etc/hosts":
require => Class["gfs2::package"],
ensure => present,
content => template("/etc/puppet/modules/gfs2/templates/hosts.erb")
}
}
</pre>

Nous voulons être sûr que nos deux machines puissent se joindre :
*cat /etc/puppet/modules/gfs2/templates/hosts.erb*
<pre>
127.0.0.1 localhost
<%= pptmasterip %> <%= pptmastername %> <%= pptmasterfqdn %>
<%= node1ip %> <%= node1name %> <%= node1fqdn %>
<%= node2ip %> <%= node2name %> <%= node2fqdn %>
</pre>

Il faut également modifier le fichier /etc/puppet/manifests/node.pp afin de rajouter les classes gfs :

> node 'pvm4.testdomain1.tetaneutral.net' {
>...
> $disk = "/dev/vdb5"
> include drbd::package, drbd::fic, drbd::command, drbd::cron1, drbd::cron1.1, cron_supp, *gfs2::package, gfs2::fic, gfs2::command, gfs2::hosts*
>}
>
> node 'pvm5.testdomain1.tetaneutral.net' {
>...
> $disk = "/dev/vdb5"
> include drbd::package, drbd::fic, drbd::command, drbd::cron2, drbd::cron2.2, cron_supp, *gfs2::package, gfs2::fic, gfs2::command, gfs2::hosts*
>}

Il ne reste plus que le fichier de configuration du cluster, cependant à cause de sa forme (composé de balises) :
Ainsi le fichier /etc/puppet/modules/gfs2/files/cluster.conf :

<pre>
<?xml version="1.0"?>
<cluster name="cluster1" config_version="3">
<cman two_node="1" expected_votes="1"/>
<clusternodes>
<clusternode name="pvm4" votes="1" nodeid="1">
<fence>
<method name="single">
<device name="manual" ipaddr="91.224.149.38"/>
</method>
</fence>
</clusternode>
<clusternode name="pvm5" votes="1" nodeid="2">
<fence>
<method name="single">
<device name="manual" ipaddr="91.224.149.30"/>
</method>
</fence>
</clusternode>
</clusternodes>
<fence_daemon clean_start="1" post_fail_delay="0" post_join_delay="3"/>
<fencedevices>
<fencedevice name="manual" agent="fence_manual"/>
</fencedevices>
</cluster>
</pre>

Ici ce qui importe c'est le nom du cluster que l'on y donne (important pour la suite) et le numéro de la version :
cluster name= *cluster1* config_version= *3* (pour connaitre le numéro de la version : *apt-cache policy gfs2-tools* )
Egalement le nom des nos noeuds : clusternode name= *pvm4* votes="1" nodeid= *1*
Et pour finir l'adresse IP : device name="manual" ipaddr= *91.224.149.38*

Puis sur le Pvm1 on lance la commande :
*puppetmasterd --no-daemonize --debug*

Et sur les clients :
*puppetd --test --server=pvm1.testdomain1.tetaneutral.net*

+On vérifie :+
Sur les machines clientes, on peut aller vérifier le raid1 :
*service drbd status*

Nous voyons que nous sommes à Primary/Primary UpToDate/UpToDate
Ici les machines sont en attentes d'un montage.

Maintenant il ne reste plus qu'à créer un répertoire, sur la pvm4 :
*mkdir -p /media/cluster/drbd*
*mount -t gfs2 /dev/drbd0 /media/cluster/drbd*

Et, sur la pvm5 :
*mkdir -p /media/clusterdata/drbd*
*mount -t gfs2 /dev/drbd0 /media/clusterdata/drbd*

h3. *Vérification :*

On vérifie :
*service drbd status*

+Il faut que l'on voie nos points de montage.+

Sur une machine, n'importe laquelle, écrivez sur votre point de montage, par exemple pvm4 :
*touch /media/cluster/drbd/pvm4.txt*
*ls /media/cluster/drbd*
On voit notre fichier : pvm4.txt

Sur l'autre node du cluster (pvm5) :
*ls /media/clusterdata/drbd*
On voit notre fichier : pvm4.txt

Pour voir les log du cluster :
*tailf /var/log/cluster/corosync.log*

Grâce à GFS2, il n'est pas nécessaire de démonter le point de montage sur le node (pvm5) puis de le remonter afin de voir les écritures, en effet l'écriture se fait mais on ne peut la visualiser tant que le umount/mount n'a pas été réalisé.

h3. A la fin de la page je met à disposition un tuto (sans puppet) de l'installation d'un Cluster DRBD GFS2.

h2. Mise en place d'un Postfix avec authentification LDAP Sans Puppet (Pas fini)

*Le projet n'est pas terminé, j'ai beaucoup travaillé mais j'ai manqué de logique, de bons tutoriels et de temps aussi, j'ai mis beaucoup du temps à comprendre Puppet =(*

Grâce au DRBD, les messages ne sont pas perdu, ils sont accessibles par les deux serveurs Postfix. Le but ici est d'avoir des utilisateurs qui peuvent envoyer des mails sur les deux serveurs de messageries (utilisation de Ldap préférable à un serveur NIS).

h3. Installer LDAP :

*apt-get install slapd ldap-utils*
*dpkg-reconfigure slapd*

Si on ne reconfigure pas ldap (à l'heure des dépôts actuels), il n'est pas possible de se connecter à l'annuaire ldap, que ce soit pour ajouter des entrées avec la commande #ldapadd (erreur : Invalid Credential (49)) car on voit qu'avec la commande #slapcat, le domaine n'est pas celui que nous avons créé dans /etc/ldap/slapd.conf, mais il s'agit du domaine : "nodomain".

A la suite de l'installation, il est nécessaire d'avoir le fichier de configuration /etc/ldap/slapd.conf. Pour cela il faut le copier :
*cp /usr/share/doc/slapd/example/slapd.conf /etc/ldap/*

Ensuite il faut modifier le fichier slapd.conf
<pre>
suffix "dc=testdomain1.tetaneutral,dc=net"
rootdn "cn=admin,dc=testdomain1.tetaneutral,dc=net"
password-hash SSHA
rootpw {SSHA}zmQHHtuIgyentPKrBw3lkNHN6JSVg/UW
access to attrs=userPassword,shadowLastChange
by dn="cn=admin,dc=testdomain1.tetaneutral,dc=net" write
by anonymous auth
by self write
by * none
access to *
by dn="cn=admin,dc=dtestdomain1.tetaneutral,dc=net" write
by * none
</pre>

h3. On peut ensuite installer les serveurs de messageries :

*apt-get install courier-ldap postfix postfix-ldap*

On peut rajouter des schema fournis par ldap :
*cp /usr/share/doc/courier-authlib-ldap/authldap.schema.gz /etc/ldap/schema*
*gunzip /etc/ldap/schema/authldap.schema.gz*

Et rajouter son chemin dans /etc/ldap/slapd.conf :
<pre>
include /etc/ldap/schema/authldap.schema
</pre>

On redémarre :
*service slapd restart*

Il faut ensuite ajouter des entrées, le mieux c'est avec *phpldapadmin* à l'adresse 127.0.0.1/phpldapadmin, mais avec l'editeur de texte -emacs- *vi et les fichiers .ldif on va plus vite =))*

*vi exemple-type.ldif*
<pre>
dn: ou=people, dc=testdomain1.tetaneutral, dc=net
objectclass: top
objectclass: organizationalUnit
ou: people

dn: cn=gp_tech, ou=people, dc=testdomain1.tetaneutral, dc=net
objectClass: top
objectClass: posixGroup
cn: gp_tech
gidNumber: 1111

dn: uid=toto1, ou=people, dc=testdomain1.tetaneutral, dc=net
objectClass: top
objectClass: posixAccount
objectClass: inetOrgPerson
uid: toto
cn: toto un
sn: toto
givenName: un
uidNumber: 2200
gidNumber: 1111
homeDirectory: /home/toto1
userPassword: mdp2toto1
mail: toto1@testdomain1.tetaneutral.net

dn: uid=toto2,ou=people,dc=testdomain1.tetaneutral,dc=net
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
uid: toto2
cn: toto deux
sn: toto
uidNumber: 2201
gidNumber: 1111
mail: toto2@testdomain1.tetaneutral.net
homeDirectory: /home/toto2
userPassword: mdp2toto2
</pre>

On applique ce changement d'arborescence :
*ldapadd -x -f exemple_type.ldif -D cn=admin,dc=testdomain1.tetaneutral,dc=net -W*

h3. *Configuration de Postfix*

Il faut modifier le fichier de conf du serveur de messagerie:
*vi /etc/postfix/main.cf*

<pre>
...
local_recipient_maps = ldap:/etc/postfix/ldap_local_recipient.cf
...
</pre>

Puis on créé le fichier ldap_local_recipient.cf :

<pre>
server_host = 91.224.149.38
server_port = 389
search_base = dc=testdomain1.tetaneutral,dc=net
# le %s signifie "adresse du destinataire telle que fourni par la commande "RCPT TO:"
query_filter = (mail=%s)
result_attribute = mail
</pre>

On peut vérifier si notre serveur de messagerie peut joindre l'annuaire ldap :
*postmap -q toto1@testdomain1.tetaneutral.net ldap:/etc/postfix/ldap_local_recipient.cf*

Le problème c'est que quand je fais un : *telnet 91.224.149.38 25* c'est que le mail est expédié, seulement il n'est pas envoyé à la boite mail, réponse des logs : status=bounced (unknown user: "toto1").