doc mai 2005 reprise dans dokuwiki.
Ce document décrit pas à pas la mise en place de cfengine. Il s'attache simplement à installer et configurer un serveur de strategie cfengine et de lui associer un client sur lequel sera installé et deployé cfengine. Enfin appliquera de façon réguliere les choix de strategie centrale de configurations.
Le site de référence est www.cfengine.org, on y trouvera les sources du programmes et de la documentation (Tutorial, reference …). Une tres bonnes documentation de mise en oeuvre pratique est disponible sur http://thierrylhomme.developpez.com/cfengine.html. La suite de ce document est un relevé pas à pas de la mise en oeuvre d'un serveur cfengine et d'un simple client. Ce document à été écrit sous forme de prise de notes des fins didactiques, avec prise en compte des problemes rencontrés au fur et à mesure du deploiement. Le tout se base sur une simple plate-forme mono systeme (Fedora Core 3) , entre un serveur (calaz.int-evry.fr) et un client (arvouin.int-evry.fr) . Dans ces conditions, on ne révellera pas toute la puissance de cfengine, et encore moins ses capacités multi systeme, voir la présentaion évoquée ci-dessus et la doc de référence pour aller plus loin .
Nous avons packagé la distribution cfengine afin d'automatiser son deploiement et ses mises à jour, cela permet aussi dès l'installation sur les clients de distribuer et personnaliser certains fichiers de configuration. voire le chapitre package RPM cfengine plus loin pour les détails du package. Néanmoins, on peux se passer du format RPM et utiliser le tar.gz de base .
[root@calaz /usr/src/redhat/SPECS] $ rpm -Uvh /usr/src/redhat/RPMS/i386/cfengine-2.1.14-1_int.i386.rpm Préparation... ########################################### [100%] 1:cfengine ########################################### [100%]
Outre les scripts de demarrage ajoutés par notre package /etc/cron.d/cfengine , /etc/init.d/cfengine , /etc/init.d/cfinit et les binaires disponibles dans /var/cfengine/sbin/cf* , le répertoire principal est /var/cfengine
[root@calaz /var/cfengine] $ ls -R .: bin inputs outputs plugins ppkeys sbin share ./bin: cfagent ./inputs: ./outputs: ./plugins: ./ppkeys: root-157.159.50.197.pub ./sbin: cfagent cfenvd cfexecd cfrun cfshow cfdoc cfenvgraph cfkey cfservd vicf ./share: cfengine ./share/cfengine: cfagent.conf-advanced.example cf.main.example cf.solaris.example cfagent.conf.example cf.motd.example cf.sun4.example cf.chflags.example cf.preconf.example cf.users.example cfengine.el cfrc.example ChangeLog cf.freebsd.example cfrun.hosts.example INSTALL cf.ftp.example cfservd.conf.example NEWS cf.groups.example cf.services.example README cf.linux.example cf.site.example update.conf.example
Le répertoire sbin contien un certain nombre de binaires décrits ici http://thierrylhomme.developpez.com/cfengine.html#executables. Dans cette mise en oeuvre simplifiée , nous nous contenterons d'utiliser le serveur de fichier cfservd et le client de configuration cfagent . On utilisra aussi cfkey afin de générér les clés d'authentification . Plus aller plus loin voir la documentation de référence.
Le serveur va distribuer sur les clients les stratégies de configuration. Le serveur de fichiers (de strategie et de configurations) cfservf lira son fihcier de configuration cfservd.conf. Celui ci devra entre autre distribuer le fichier de configuration du service client (cfagent), fichier cfagent.conf
Le principe est de modifier les stratégies de configuration dans le fichier centralisés cfagent.conf qui se trouve sur le serveur cfengine. Ensuite il s'agit de distribuer ce fichier sur les clients au travers d'une strategie simple et quasi immuable deployée dès l'initialisation d'un client par le fichier update.conf. C'est donc dans ce fichier update.conf qui comme son nom l'indique, va nous permettre avant que le client execute son fichier local de configuration /var/cfengine/inputs/cfagent.conf de mettre à jour ce meme fichier cfagent.conf en fonction des modifications apportées à sa copie centralisée sur le serveur cfengine.
Afin d'eviter de scier la branche sur laquelle on est assis !, bref d'eviter par une erreure de syntaxe de casser le bon fonctionnement de cfengine et ainsi rendre incapables toutes les machines du parc de s'autocorriger, on va ditribuer les fichiers de configuration à partir d'une configuration cfengine tres simple et quasi immuable . C'est pour cela que le client cfagent lit et execute le fichier update.conf avant de se lancer sur (le vif du sujet !) cfagent.conf . De plus , pour rendre plus lisible et plus modulaire le fichiers de configuration cfagent.conf, ce dernier sera eclaté en sous fichiers spécifiques, le fichier cfagent.conf se chargant de faire un include (import) des sous fichiers. Sur le serveur, on créera un répertoire /var/cfengine/masterinputs qui contiendra le cfagent.conf et ses inclusions.
[root@calaz /var/cfengine/inputs] $ cat update.conf ####### # # BEGIN update.conf # # This script distributes the configuration, a simple file so that, # if there are syntax errors in the main config, we can still # distribute a correct configuration to the machines afterwards, even # though the main config won't parse. It is read and run just before the # main configuration is parsed. # ####### control: actionsequence = ( copy tidy ) # Keep this simple and constant domain = ( int-evry.fr ) # Needed for remote copy # # Which host/dir is the master for configuration roll-outs? # policyhost = ( calaz.int-evry.fr ) # le répertoire masterinputs contient entre autre le cfagent.conf et toute ses inclusions masterinputs = ( /var/cfengine/masterinputs ) # # Some convenient variables # workdir = ( /var/cfengine ) cf_install_dir = ( /var/cfengine/sbin ) # Avoid server contention SplayTime = ( 5 ) ############################################################################ # # Make sure there is a local copy of the configuration and # the most important binaries in case we have no connectivity # e.g. for mobile stations or during DOS attacks # copy: # Tout le contenu du masterinputs ira dans $(workdir)/inputs $(masterinputs) dest=$(workdir)/inputs r=inf mode=700 type=binary exclude=*.lst exclude=*~ exclude=#* server=$(policyhost) ##################################################################### tidy: # # Cfexecd stores output in this directory. # Make sure we don't build up files and choke on our own words! # $(workdir)/outputs pattern=* age=7
L'objectif principal de ce fichier est donc qu'a chaque lancement du client cfagent l'ensemble des fichiers se trouvant dans le répertoire /var/cfengine/masterinputs du serveur soient copiés dans le répertoire /var/cfengine/inputs sur le client. Pour information voici le contenu de masterinputs que nous distriburons.
[root@calaz /var/cfengine/masterinputs] $ ls cfagent.conf cf.groups cf.linux cf.main cfservd.conf update.conf
Afin d'authentifier le serveur et les clients lors des echanges, les services cfservd et cfagent s'accordent sur un echange de clé. Il s'agit de créer la paire de clé pour chaque machine. Pour démonstration, sur le serveur on lance la commande cfkey ci-dessous. Les clients peuvent en faire autant. Ici notre package rpm cfengine contient un script /var/init.d/cfinit qui lance au premier boot d'une station fraichement installée cette commande cfkey.
[root@calaz /var/cfengine] $ /var/cfengine/sbin/cfkey Making a key pair for cfengine, please wait, this could take a minute... Writing private key to /var/cfengine/ppkeys/localhost.priv Writing public key to /var/cfengine/ppkeys/localhost.pub
Lancement du serveur de fichier cfservd sur le serveur cfengine.
[root@calaz /var/cfengine] $ /var/cfengine/sbin/cfservd -F -d 2 cfservd: Debug mode: running in foreground AddClassToHeap(any) .... Loaded /var/cfengine/ppkeys/localhost.priv Loaded /var/cfengine/ppkeys/localhost.pub New Parser Object::(BEGIN PARSING /var/cfengine/inputs/cfservd.conf) Looking for an input file /var/cfengine/inputs/cfservd.conf (No file /var/cfengine/inputs/cfservd.conf) (END OF PARSING /var/cfengine/inputs/cfservd.conf) Finished with /var/cfengine/inputs/cfservd.conf
On voit clairement qu'il manque le fichier de configuration cfservd.conf .
[root@calaz /var/cfengine/inputs] $ cat cfservd.conf ######################################################### # # This is a cfd config file # control: domain = ( int-evry.fr ) # Autorisation de connexion depuis 2 reseaux IP AllowConnectionsFrom = ( 157.159.27.0/24 157.159.50.0/24 ) # Autorisation de connexion depuis un service cfengent lancé par root sur le client AllowUsers = ( root ) any:: ChecksumDatabase = ( /tmp/testDATABASEcache ) IfElapsed = ( 1 ) MaxConnections = ( 100 ) ######################################################### admit: # or grant: # Autorisation de transferts de fichiers du serveur vers les clients sur les reseaux ip suivants: /var/cfengine/masterinputs 157.159.27.* /var/cfengine/masterinputs 157.159.50.* /var/cfengine/data 157.159.27.* /var/cfengine/data 157.159.50.*
[root@calaz /var/cfengine/inputs] $ /var/cfengine/sbin/cfservd -F -d 2 Loaded /var/cfengine/ppkeys/localhost.priv Loaded /var/cfengine/ppkeys/localhost.pub New Parser Object::(BEGIN PARSING /var/cfengine/inputs/cfservd.conf) Looking for an input file /var/cfengine/inputs/cfservd.conf # BEGIN PARSING /var/cfengine/inputs/cfservd.conf Path: /var/cfengine/masterinputs (encrypt=0) Admit: 157.159.50.* root= Admit: 157.159.27.* root= Path: /var/cfengine/data (encrypt=0) Admit: 157.159.50.* root= Admit: 157.159.27.* root= ACCESS DENIAL ------------------------ : Host IPs allowed connection access : IP: 157.159.27.0/24 IP: 157.159.50.0/24 Bound to address :: on linux=6 Listening for connections ... Checking file updates on /var/cfengine/inputs/cfservd.conf (4284bfe4/4284c008)
Effectivement le serveur c'est bindé en ipv6 ! sur le port cfengine (tcp:5308)
[root@calaz /var/cfengine/inputs] $ lsof -i tcp | grep cfser cfservd 14660 root 4u IPv6 279008 TCP *:cfengine (LISTEN)
Le serveur cfengine est maintenant opérationnel, il écoute sur le port 5308 et s'apprete a recevoir des connexions depuis les reseaux ip 157.159.27.0/24 et 50.0/24 tels que demandé dans le fichier de configuration cfservd.conf
On viens de le voir, le serveur écoute sur le port 5308, il faut donc prévoir d'ouvrir son firewall en conséquance. Pour preuve, voici l'exemple de lancement d'un client (arvouin) sans ouverture du port en question:
[root@arvouin /var/cfengine/inputs] $/var/cfengine/sbin/cfagent -q -v .... Connect to calaz.int-evry.fr = 157.159.50.197 on port cfengine cfengine:: Time out
Ouverture du port.
[root@calaz /var/cfengine] $ grep 5308 /etc/sysconfig/iptables -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5308 -j ACCEPT [root@calaz /var/cfengine] $ /etc/init.d/iptables restart
[root@arvouin /var] $rpm -Uvh /root/cfengine-2.1.14-1_int_sample.i386.rpm Préparation... ########################################### [100%] 1:cfengine ########################################### [100%]
La clé du serveur a bien été intégrée par le package:
[root@arvouin /var/cfengine] $ls ppkeys/ root-157.159.50.197.pub
Pour le momment il n'y a rien, c'est au premier lancement de cfagent que l'update.conf assurera le transfert des fichiers de configuration depuis le serveur central.
[root@arvouin /var/cfengine/inputs] $ls
Voici le contenu du répertoire principal apres l'installation du package RPM.
[root@arvouin /var/cfengine] $ls -R .: bin inputs outputs plugins ppkeys sbin share ./bin: cfagent ./inputs: ./outputs: ./plugins: ./ppkeys: root-157.159.50.197.pub ./sbin: cfagent cfenvd cfexecd cfrun cfshow cfdoc cfenvgraph cfkey cfservd vicf ./share: cfengine ./share/cfengine: cfagent.conf-advanced.example cf.main.example cf.solaris.example cfagent.conf.example cf.motd.example cf.sun4.example cf.chflags.example cf.preconf.example cf.users.example cfengine.el cfrc.example ChangeLog cf.freebsd.example cfrun.hosts.example INSTALL cf.ftp.example cfservd.conf.example NEWS cf.groups.example cf.services.example README cf.linux.example cf.site.example update.conf.example
Afin que les fichiers de strategies soient deployés sur le client, il faut que ce dernier dispose d'une copie du fichier de distribution de ces fichiers → le fichier update.conf evoqué auparavant lors de sa conception sur le serveur central de configuration cfengine. Exemple de ditribution par simple copie manuelle, l'idéal étant d'integrer ce fichier dans le package RPM cfengine qui sera installé sur les clients.
[root@arvouin /var/cfengine] $scp root@calaz:/var/cfengine/masterinputs/update.conf ./inputs/
Si on lance tout de suite un cfagent (-parse et -verbose ) on constate ceci:
[root@arvouin /var/cfengine/inputs] $/var/cfengine/sbin/cfagent -p -v Unable to detect environment from cfenvd cfengine:: No preconfiguration file * (Changing context state to: update) * Looking for an input file /var/cfengine/inputs/update.conf Finished with update.conf LogDirectory = /var/cfengine cfengine:: Couldn't find a private key (/var/cfengine/ppkeys/localhost.priv) - use cfkey to get one cfengine:: open: No such file or directory
En effet il manque la paire de clé sur le client. Pour la démonstration nous la générons ici manuellement. Dans le cadre d'un deploiement industriel on assurera la création automatique de cette clé par un script (dans notre RPM; cfinit) qui se chargera au premier boot de la station fraichement installée de lancer le cfkey).
[root@arvouin /var/cfengine/inputs] $/var/cfengine/sbin/cfkey Making a key pair for cfengine, please wait, this could take a minute... Writing private key to /var/cfengine/ppkeys/localhost.priv Writing public key to /var/cfengine/ppkeys/localhost.pub
Pour que la communication entre le client et le serveur cfengine se fasse, les deux machines s'authentifient mutuellement. Le client dispose de la clé publique du serveur avec laquelle il signe l'echange, ce sera au serveur cfengine de verifier cette signature avec sa clé privé. De meme le serveur doit disposer de la clé publique du client afin de proceder à la même verification en sens inverse . Ici le client dispose bien de la clé publique du serveur root-157.159.50.197.pub (distribuée par notre package RPM, sinon il faut faire un scp vers chaque clients ..)
[root@arvouin /var/cfengine/ppkeys] $/var/cfengine/sbin/cfagent -q -v Checking copy from calaz.int-evry.fr:/var/cfengine/masterinputs to /var/cfengine/inputs Connect to calaz.int-evry.fr = 157.159.50.197 on port cfengine Updating last-seen time for calaz.int-evry.fr Loaded /var/cfengine/ppkeys/root-157.159.50.197.pub cfengine:: BAD: key could not be accepted on trust cfengine:: Authentication dialogue with calaz.int-evry.fr failed cfengine:: Unable to establish connection with calaz.int-evry.fr (failover)
En revanche, le serveur ne dispose pas encore de la clé publique de ce client !.
Nous pouvons proceder à un transfert manuelle de la clé du client vers le serveur :
[root@arvouin /var/cfengine/ppkeys] $scp localhost.pub root@calaz:/var/cfengine/ppkeys/root-157.159.27.199.pub root@calaz's password: localhost.pub 100% 426 1.1MB/s 00:00
Mais cela n'est pas tres industrialisable !
On peux autrement déclarer dans le fichier de configuration du serveur cfservd que l'on accepte de recevoir des clé publiques des machines que nous allons gerer (exemple ici le sous reseau 157.159.50.27.0/24 )
$ grep Trust /var/cfengine/inputs/cfservd.conf TrustKeysFrom = ( 157.159.27.0/24 ) Relancer cfservd : [root@calaz /var/cfengine/outputs] $ /var/cfengine/sbin/cfservd -F -d 2 Host IPs from whom we shall accept public keys on trust : IP: 157.159.27.0/24
Répertoire des cles sur le serveur avant le lancement du client:
[root@calaz /var/cfengine/ppkeys] $ ls localhost.priv localhost.pub root-157.159.50.197.pub
Lancement du client
[root@arvouin /var/cfengine/inputs] $/var/cfengine/sbin/cfagent -q -v cfservd -F -d 2 sur calaz signal: Received: [CAUTH 157.159.27.199 arvouin.int-evry.fr root 0] on socket 5 Connecting host identifies itself as 157.159.27.199 arvouin.int-evry.fr root 0 (ipstring=[157.159.27.199],fqname=[arvouin.int-evry.fr],username=[root],socket=[::ffff:157.159.27.199]) cfservd: Allowing 157.159.27.199 to connect without (re)checking ID Non-verified Host ID is arvouin.int-evry.fr (Using skipverify) Non-verified User ID seems to be root (Using skipverify) Havekey(root-157.159.27.199) Did not have key root-157.159.27.199 cfservd: Weak authentication of trusted client arvouin.int-evry.fr/::ffff:157.159.27.199 (key accepted on trust).
Répertoire de clés sur le serveur apres le lancement du client:
[root@calaz /var/cfengine/ppkeys] $ ls localhost.priv localhost.pub root-157.159.27.199.pub root-157.159.50.197.pub
On y retrouve bien le clé du client root-157.159.27.199.pub .
Maintenant que tout est correctement configuré, nous pouvons relancer l'agent avec succes:
[root@arvouin /var/cfengine/ppkeys] $/var/cfengine/sbin/cfagent -q -v Setting cfengine new port to 5308 Setting cfengine old port to 5308 Reference time set to Fri May 13 17:06:24 2005 GNU Configuration Engine - 2.1.14 Loaded /var/cfengine/ppkeys/localhost.priv Loaded /var/cfengine/ppkeys/localhost.pub Checksum database is /var/cfengine/checksum.db Checking copy from calaz.int-evry.fr:/var/cfengine/masterinputs to /var/cfengine/inputs Connect to calaz.int-evry.fr = 157.159.50.197 on port cfengine Updating last-seen time for calaz.int-evry.fr Loaded /var/cfengine/ppkeys/root-157.159.50.197.pub cfengine:: Strong authentication of server=calaz.int-evry.fr connection confirmed cfengine:: /var/cfengine/inputs/cf.main wasn't at destination (copying) cfengine:: Copying from calaz.int-evry.fr:/var/cfengine/masterinputs/cf.main cfengine:: Object /var/cfengine/inputs/cf.main had permission 600, changed it to 700 cfengine:: /var/cfengine/inputs/cf.linux wasn't at destination (copying) cfengine:: Copying from calaz.int-evry.fr:/var/cfengine/masterinputs/cf.linux cfengine:: Object /var/cfengine/inputs/cf.linux had permission 600, changed it to 700 cfengine:: /var/cfengine/inputs/cfagent.conf wasn't at destination (copying) cfengine:: Copying from calaz.int-evry.fr:/var/cfengine/masterinputs/cfagent.conf cfengine:: Object /var/cfengine/inputs/cfagent.conf had permission 600, changed it to 700 cfengine:: /var/cfengine/inputs/cf.groups wasn't at destination (copying) cfengine:: Copying from calaz.int-evry.fr:/var/cfengine/masterinputs/cf.groups cfengine:: Object /var/cfengine/inputs/cf.groups had permission 600, changed it to 700 cfengine:: /var/cfengine/inputs/cfservd.conf wasn't at destination (copying) cfengine:: Copying from calaz.int-evry.fr:/var/cfengine/masterinputs/cfservd.conf cfengine:: Object /var/cfengine/inputs/cfservd.conf had permission 600, changed it to 700 cfengine:: Update of image /var/cfengine/inputs/update.conf from master /var/cfengine/masterinputs/update.conf on calaz.int-evry.fr cfengine:: Object /var/cfengine/inputs/update.conf had permission 600, changed it to 700 Checking copy from calaz.int-evry.fr:/var/cfengine/masterinputs/cfservd.conf to /var/cfengine/inputs cfengine:: image exists but destination type is silly (file/dir/link doesn't match) cfengine:: source=/var/cfengine/masterinputs/cfservd.conf, dest=/var/cfengine/inputs Saving the setuid log in /var/cfengine/cfagent.arvouin.int-evry.fr.log
La copie des fichiers réalisés par update.conf a bien eu lieu . Cfagent poursuis sur le vif du sujet , l'excution du cfagent.conf local fraichement mis à jour par l'update.conf !:
* (Changing context state to: main) * #Execution du cfagent.conf ... Looking for an input file /var/cfengine/inputs/cfagent.conf Looking for an input file cf.groups Looking for an input file cf.main Looking for an input file cf.linux Finished with cfagent.conf Main Tree Sched: copy pass 1 @ Fri May 13 17:06:27 2005 ********************************************************************* Checking file(s) in /etc/passwd cfengine:arvouin: File /etc/passwd was not in database - new file found Checking file(s) in /etc/shadow cfengine:arvouin: File /etc/shadow was not in database - new file found Main Tree Sched: editfiles pass 1 @ Fri May 13 17:06:28 2005 ********************************************************************* Begin editing /etc/inittab End editing /etc/inittab Main Tree Sched: shellcommands pass 1 @ Fri May 13 17:06:28 2005 ********************************************************************* cfengine:arvouin: Executing script /bin/echo shellcommands de cf.main !...(timeout=0,uid=-1,gid=-1) (Setting umask to 77) cfengine:arvouin:/bin/echo shell: shellcommands de cf.main ! cfengine:arvouin: Finished script /bin/echo shellcommands de cf.main ! Main Tree Sched: links pass 1 @ Fri May 13 17:06:28 2005 ********************************************************************* cfengine:arvouin: Linking files /usr/local/bin/tcsh -> /bin/tcsh cfengine:arvouin: Linking files /usr/local/bin/bash -> /bin/bash
La strategie de configuration cliente c'est donc executée dans la foulée … nous y reviendrons apres .
Verification de la présence des fichiers de source masterinputs du serveur sur la destination inputs sur le client:
[root@arvouin /var/cfengine/ppkeys] $ls ../inputs/ cfagent.conf cf.linux cfservd.conf update.conf.cfsaved cf.groups cf.main update.conf
Remarque; la version anterieur d'un fichier déjà présent et renomée en .cfsaved
Nous montrons ici le début d'un configuration plus industrielle avec quelques exemples stratégiques.
Nous éclatons le fichier cfagent.conf en sous éléments par le biais le l'import des sous fichiers.
$ cat cfagent.conf ################################################## # cfagent.conf ################################################## import: # split things up to keep things tidy any:: cf.groups cf.main linux:: cf.linux
Le premier fichier importé est cf.goups qui comprend la liste des classes de machines:
[root@calaz /var/cfengine/masterinputs] $ cat cf.groups #Fichier de definition des groupes/class groups: # machines unix du service s2ia s2iaunix = ( calaz arvouin ) # machines windows du service s2ia s2iawindows = ( pat4784 ) #classe s2ia -> toutes les machines du service s2ia s2ia = ( s2iaunix s2iawindows ) # strategie de site linux autoconfigMozilla = ( arvouin ) logoint = ( arvouin )
Le fichier cf.main contient les définitions et taches (strategies) générales valables pour toutes les machines présentes et futures du parc à gerer. Seules les actions à mener propres à cet exemple sont commentées dans le fichier, pour les directives et variables cfengine, voir la documentation de référence.
[root@calaz /var/cfengine/masterinputs] $ cat cf.main ################################################## # cf.main ################################################## ############# Control control: EditfileSize = ( 70000 ) moduledirectory = ( /var/cfengine/plugins ) AddInstallable = ( restartgdm ) addclasses = ( noboot ) actionsequence = ( files directories copy editfiles shellcommands links tidy processes ) domain = ( int-evry.fr ) timezone = ( MET ) smtpserver = ( smtp-int.int-evry.fr ) # used by cfexecd sysadm = ( root@calaz.int-evry.fr ) # where to mail output # nous modifierons le fichier inittab, une veriable contient son chemin absolu inittab = ( /etc/inittab ) # nous allons copier un fichier d'autoconfiguration de mozilla dans $MOZILA_HOME, ce chemin depend de la version mozilla installée, le nom du package sur le client permet de definir ce chemin qui sera /usr/lib/$mozilladir/ mozilladir = ( ExecResult(/bin/rpm -q --queryformat "%{VERSION}" mozilla) ) # Definition de chemin absolue pour les machines linux linux:: grubconfigfile = ( /etc/grub.conf ) gdmconffile = ( /etc/X11/gdm/gdm.conf ) ###################################################################### resolve: # Add these name servers to the /etc/resolv.conf file 157.159.10.12 # local nameserver 157.159.10.13 # backup nameserver ###################################################################### copy: # modification du prompt ($PS1=''[\u@\h \w]\n$'') par la copie du fichier system bashrc any:: /var/cfengine/data/bashrc dest=/etc/bashrc mode=0644 server=calaz ###################################################################### shellcommands: # un simpe test de commande shell -> envoie d'un echo any:: "/bin/echo shellcommands de cf.main !" ###################################################################### links: # Création de liens s2iaunix:: /usr/local/bin/tcsh -> /bin/tcsh /usr/local/bin/bash -> /bin/bash ###################################################################### processes: # action a mener sur des processus restartgdm:: "gdm" signal=hup any:: "nscd" restart "/sbin/chkconfig --level 345 nscd on ; /etc/init.d/nscd restart" ##########################EDITFILES editfiles: any:: # Edition du inittab -> desactivation des consoles text sur CRTL+ALT+F[3-6] { $(inittab) DeleteLinesMatching "[3-6]:2345:respawn:/sbin/mingetty tty[3-6]" } ################## Files files: # verifications sur le fichier password /etc/passwd mode=644 # make sure the file permissions are right owner=root # make sure it's owned by root action=fixall # if anything is wrong, fix it immediately! checksum=md5 # keep a "tripwire" checksum to tell us # if any changes occur here /etc/shadow mode=600 owner=root action=fixall checksum=md5 /var/cfengine/checksum.db mode=600 owner=root action=fixall
Exemple de fichier de configuration propre aux machines linux:
[root@calaz /var/cfengine/masterinputs] $ cat cf.linux # cfagent file for linux stations copy: # copie du fichier d'autoconfiguration mozilla dans $MOZILLA_HOME = variable $mozilladir du cf.main
autoconfigMozilla:: /var/cfengine/data/mozilla.cfg dest=/usr/lib/mozilla-$(mozilladir)/mozilla.cfg mod=644 server=calaz
# gestion d'un logo perso à la connexion GDM, copie récursive de l'arborescence INT_theme
logoint:: /var/cfengine/data/fedora-3/INT_theme dest=/usr/share/gdm/themes/INT_theme server=calaz recurse=inf
################################## editfiles:
# edition du gdm.conf afin d'y integrer notre logo copié ci-dessus
logoint:: { $(gdmconffile) BeginGroupIfNoSuchLine "GraphicalTheme=INT_theme" LocateLineMatching "GraphicalTheme=Bluecurve" ReplaceLineWith "GraphicalTheme=INT_theme" EndGroup DefineClasses "restartgdm" }
################## shellcommands:
# a minuit et 20H , on lance une mise a jour systeme (yum update)
Hr0|Hr20:: "/bin/nice -n 20 /usr/bin/yum -y -d 2 update > /tmp/yum 2>&1"
Les differents fichiers et dossiers évoqués dans les stratégies ci-dessus sont stockés sur le serveur cfengine /var/cfengine/data :
$ mkdir /var/cfengine/data $ mkdir /var/cfengine/data/fedora-3/ [root@calaz /var/cfengine/data] $ cp /etc/bashrc [root@calaz /var/cfengine/data] $ vi mozilla.cfg [root@crotale /var/cfengine/data/fedora-3] $ scp -r INT_theme root@calaz:/var/cfengine/data/fedora-3 [root@calaz /var/cfengine/data] $ ls bashrc fedora-3 mozilla.cfg
[root@arvouin /var/cfengine/ppkeys] $/var/cfengine/sbin/cfagent -q -v $/var/cfengine/sbin/cfagent -q -v Setting cfengine new port to 5308 Setting cfengine old port to 5308 Reference time set to Fri May 13 18:40:26 2005 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ * (Changing context state to: update) * $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Looking for an input file /var/cfengine/inputs/update.conf Finished with update.conf ********************************************************************* Update Sched: copy pass 1 @ Fri May 13 18:40:26 2005 ********************************************************************* Checking copy from calaz.int-evry.fr:/var/cfengine/masterinputs to /var/cfengine/inputs Connect to calaz.int-evry.fr = 157.159.50.197 on port cfengine Updating last-seen time for calaz.int-evry.fr Loaded /var/cfengine/ppkeys/root-157.159.50.197.pub $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ * (Changing context state to: main) * $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Looking for an input file /var/cfengine/inputs/cfagent.conf Looking for an input file cf.groups Looking for an input file cf.main Looking for an input file cf.linux Finished with cfagent.conf ********************************************************************* Main Tree Sched: files pass 1 @ Fri May 13 18:40:28 2005 ********************************************************************* Checking file(s) in /etc/passwd Checking file(s) in /etc/shadow Checking file(s) in /var/cfengine/checksum.db Saving the setuid log in /var/cfengine/cfagent.arvouin.int-evry.fr.log ********************************************************************* Main Tree Sched: copy pass 1 @ Fri May 13 18:40:29 2005 ********************************************************************* Checking copy from calaz:/var/cfengine/data/bashrc to /etc/bashrc Connect to calaz = 157.159.50.197 on port cfengine Updating last-seen time for calaz Loaded /var/cfengine/ppkeys/root-157.159.50.197.pub cfengine:arvouin: Strong authentication of server=calaz connection confirmed Checking copy from calaz:/var/cfengine/data/mozilla.cfg to /usr/lib/mozilla-1.7.6/mozilla.cfg cfengine:arvouin: /usr/lib/mozilla-1.7.6/mozilla.cfg wasn't at destination (copying) cfengine:arvouin: Copying from calaz:/var/cfengine/data/mozilla.cfg cfengine:arvouin: Object /usr/lib/mozilla-1.7.6/mozilla.cfg had permission 600, changed it to 644 Checking copy from calaz:/var/cfengine/data/fedora-3/INT_theme to /usr/share/gdm/themes/INT_theme Saving the setuid log in /var/cfengine/cfagent.arvouin.int-evry.fr.log ********************************************************************* Main Tree Sched: editfiles pass 1 @ Fri May 13 18:40:30 2005 ********************************************************************* Begin editing /etc/inittab Deleted item 3:2345:respawn:/sbin/mingetty tty3 Deleted item 4:2345:respawn:/sbin/mingetty tty4 Deleted item 5:2345:respawn:/sbin/mingetty tty5 Deleted item 6:2345:respawn:/sbin/mingetty tty6 End editing /etc/inittab ..................................................................... cfengine:arvouin: Saving edit changes to file /etc/inittab Begin editing /etc/X11/gdm/gdm.conf (Begin Group - skipping, line exists) End editing /etc/X11/gdm/gdm.conf ..................................................................... ********************************************************************* Main Tree Sched: shellcommands pass 1 @ Fri May 13 18:40:30 2005 ********************************************************************* cfengine:arvouin: Executing script /bin/echo shellcommands de cf.main !...(timeout=0,uid=-1,gid=-1) (Setting umask to 77) cfengine:arvouin:/bin/echo shell: shellcommands de cf.main ! cfengine:arvouin: Finished script /bin/echo shellcommands de cf.main ! ********************************************************************* Main Tree Sched: links pass 1 @ Fri May 13 18:40:30 2005 ********************************************************************* cfengine:arvouin: Linking files /usr/local/bin/tcsh -> /bin/tcsh cfengine:arvouin: Linking files /usr/local/bin/bash -> /bin/bash ********************************************************************* Main Tree Sched: processes pass 1 @ Fri May 13 18:40:30 2005 ********************************************************************* cfengine:arvouin: Running process command /bin/ps auxw Defining classes DoSignals(nscd) Existing restart sequence found (/sbin/chkconfig --level 345 nscd on ; /etc/init.d/nscd restart) cfengine:arvouin: Matches found for nscd - no restart sequence
Toutes les opérations se sont réalisées comme prevu .
Voici un exemple de fichier de spec de construction du package cfengine, à partir du tar.gz, il apporte en valeur ajoutée la clé du serveur, les scripts de demarrage (cfengine, cfinit, cron cfengine), la construction de l'aborescence (faite aussi par cfexec ..) l'update.conf initial, eventuellement des pluggins etc …. Cela permet d'industrialiser le deploiement cfengine sur les clients dès leur installation par kickstart. Pour les details de contruction de packages RPM voir: http://www.freenix.fr/unix/linux/HOWTO/RPM-HOWTO-6.html http://www.rpm.org/RPM-HOWTO/build.html
[root@calaz /usr/src/redhat/SPECS] $ cat cfengine.spec Summary: cfengine helps set up and maintain BSD and System-5-like systems Name: cfengine Version: 2.1.14 Release: 1_int_sample Copyright: GPL Group: Utilities/System Source0: ftp://ftp.iu.hioslo.no/pub/%{name}-%{version}.tar.gz Source1: %{name}.rc.init Source2: localhost.pub Source7: cfengine.cron Source4: cfinit BuildRoot: /tmp/%{name}-%{version} Requires: dialog %define ipserver 157.159.50.197 %description Cfengine is a tool for setting up and maintaining BSD and System-5-like operating systems optionally attached to a TCP/IP network. You can think of cfengine as a very high level language---much higher level than Perl or shell: a single statement can result in many hundreds of operations being performed on multiple hosts. Cfengine is good at performing a lot of common system administration tasks, and allows you to build on its strengths with your own scripts. You can also use it as a netwide front-end for cron. Once you have set up cfengine, you'll be free to use your time being like a human being, instead of playing R2-D2 with the system. %prep %setup cp -p $RPM_SOURCE_DIR/%{name}.rc.init . %build ./configure --with-berkeleydb=/usr make %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/usr/info mkdir -p $RPM_BUILD_ROOT/etc/init.d mkdir -p $RPM_BUILD_ROOT/etc/cron.d mkdir -p $RPM_BUILD_ROOT/var/cfengine/inputs mkdir -p $RPM_BUILD_ROOT/var/cfengine/outputs mkdir -p -m 700 $RPM_BUILD_ROOT/var/cfengine/ppkeys mkdir -p $RPM_BUILD_ROOT/var/cfengine/plugins mkdir -p $RPM_BUILD_ROOT/var/cfengine/bin make prefix=$RPM_BUILD_ROOT/var/cfengine install cd doc make prefix=$RPM_BUILD_ROOT/usr/share install-man cd .. #Copie de la clée public du serveur cp $RPM_SOURCE_DIR/localhost.pub $RPM_BUILD_ROOT/var/cfengine/ppkeys/root-%{ipserver}.pub #Copie des scripts de lancement. cp $RPM_SOURCE_DIR/cfengine.cron $RPM_BUILD_ROOT/etc/cron.d/cfengine install -m 755 $RPM_SOURCE_DIR/cfinit $RPM_BUILD_ROOT/etc/init.d install -m 755 $RPM_SOURCE_DIR/%{name}.rc.init $RPM_BUILD_ROOT/etc/init.d/cfengine cd $RPM_BUILD_ROOT/var/cfengine/bin/ ln -s ../sbin/cfagent cfagent %post /sbin/chkconfig --add cfinit /sbin/chkconfig --add cfengine %clean #rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) /usr/share/man/man8/cfengine.8.gz /usr/share/man/man8/cfagent.8.gz /usr/share/man/man8/cfenvd.8.gz /usr/share/man/man8/cfshow.8.gz /usr/share/man/man8/cfenvgraph.8.gz /usr/share/man/man8/cfexecd.8.gz /usr/share/man/man8/cfrun.8.gz /usr/share/man/man8/cfkey.8.gz /usr/share/man/man8/cfservd.8.gz /var/cfengine /etc/init.d/cfinit /etc/init.d/cfengine /etc/cron.d/cfengine %doc AUTHORS ChangeLog COPYING INSTALL README NEWS TODO %doc doc/ contrib/ %changelog * Wed May 11 2005 Jehan Procaccia <jehan.procaccia@int-evry.fr> 2.1.14-1_int_sample - test de conf cfengine initiale pour doc * Fri Apr 29 2005 Jehan Procaccia <jehan.procaccia@int-evry.fr> 2.1.14-1 - update to 2.1.14 * Fri Feb 11 2005 Eric Doutreleau <Eric.Doutreleau@int-evry.fr> 2.1.13-1 - update to 2.1.13 - Ajout du module kernelclean * Mon Feb 16 2004 Jehan Procaccia <jehan.procaccia@int-evry.fr> 2.1.3-5 - changed cfinit to wait 1mn for autorpm pb - addapted module:hardware for another nvidia chipset * Thu Feb 12 2004 Jehan Procaccia <jehan.procaccia@int-evry.fr> 2.1.3-4 - upgraded to 2.1.3 - added module:hardware * Thu Oct 30 2003 Eric Doutreleau <Eric.Doutreleau@int-evry.fr> 2.0.8p1-3 - Added dialog message on cfinit * Wed Sep 24 2003 Jehan Procaccia <jehan.procaccia@int-evry.fr> 2.0.8p1-1 - chmod 700 on ppkeys directory * Wed Sep 24 2003 Jehan Procaccia <jehan.procaccia@int-evry.fr> 2.0.8p1-1 - upgraded to 2.0.8p1 * Thu Aug 3 2000 Ian Macdonald <ian@caliban.org> - strip binaries * Sat Jul 27 2000 Ian Macdonald <ian@caliban.org> - 1.5.4 packaged as RPM
Exemple de configurations évoluée (en cours d'écriture ….)
Plutot que de faire une installation de logiciels à partir de shellcommands lançants rpm ou yum etc … depuis la version 2.1 de cfengine il est possible d'utiliser la directive package:
http://www.cfengine.org/docs/cfengine-Reference.html#packages
Exemple d'utilisation.
control: fedora:: actionsequence = ( files directories copy editfiles packages shellcommands links tidy processes ) RPMInstallCommand = ( "/usr/bin/yum -y install %s" ) groups: logcommun2 = ( s2iaunix ) packages: logcommun2:: RealPlayer pkgmgr=rpm action=install scilab pkgmgr=rpm action=install
… à continuer …