Esta web utiliza cookies, puedes ver nuestra política de cookies, aquí Si continuas navegando estás aceptándola

Puppet-Foreman-ENC bajo Gentoo


El manual se dividirá en diferentes partes claramente separadas:


Componentes de la infraestructura:

Puppet se compone de cinco componentes:

  • puppet-master: Encargado de las clases
  • puppet-agent: Cliente que aplica las clases
  • smart-proxy: Ayuda en el displiegue automágico de servidores
  • ENC: External Node Classifier, script encargado de asignar clases a los agentes.
  • foreman: Interfaz web de gestión de todo el entorno, smart-proxys, localizaciones, empresas...

 

Puppet no se limita simplemente a aplicar las clases definidas, también puede servir como entorno de despliegue completo de servidores, ya sean virtuales o físicos, puppet es capaz de configurar registros DNS, DHCP, servir imágenes de arranque por TFTP...

 

En este manual se han instalado las siguientes versiones, hay mucha incompatibilidad entre versiones de puppet, gemas de ruby, versiones de foreman y smart-proxy. Siempre se ha utilizado la ultima versión estable ya sea del portage o desde las fuentes.

app-admin/puppet 3.7.3
dev-lang/ruby
1.9.3_p551-r1
2.0.0_p645
dev-ruby/rubygems 2.2.2
eselect ruby list
  [2]   ruby20 (with Rubygems) *
gem -v
2.2.2
www-servers/apache 2.2.29
passenger (5.0.11)
bundler 1.10.5
foreman 1.8
smart-proxy 1.9

Un dato importante es no mezclar versiones distintas de puppet-master puppet-agent, los cambios major podrían provocar comportamientos impredecibles.

2.7.2 - 2.7.9 -> OK
2.6.1 - 2.7.0 -> KO

Los equipos utilizados en este manual siguen el siguiente direccionamiento:

192.168.40.170    puppetmaster.alfaexploit.com
192.168.40.174    foreman.alfaexploit.com
192.168.40.176    puppetnode00.alfaexploit.com

Instalación de puppetmaster:

Comenzamos con la instalación del puppet-master:

emerge -av app-admin/puppet

Seleccionamos ruby2.0:

eselect ruby list
Available Ruby profiles:
  [1]   ruby19 (with Rubygems) *
  [2]   ruby20 (with Rubygems)

eselect ruby set 2
gem -v
2.2.2

Vamos a comenzar con algo sencillo, una clase que cambie el motd del sistema:

vi /etc/puppet/puppet.conf
[main]
        vardir = /var/lib/puppet
        logdir = /var/log/puppet
        rundir = /var/run/puppet
        confdir = /etc/puppet
        ssldir = /var/lib/puppet/ssl
    
[master]
        fileserverconfig = /etc/puppet/fileserver.conf
vi /etc/puppet/fileserver.conf
[extra-files]
    path /etc/puppet/extra-files
    allow *

El allow * es para permitirle el acceso a todos, en principio se pueden definir rangos de ips pero al menos en la versión 3.7.3 NO funciona correctamente y mediante auth.conf no hay manera, así que firewall a machete!!

NOTA: Los agentes deben alcanzar el servidor puppet-master utilizando su FQDN, así que ejecutamos el siguiente comando en el puppet-master para obtenerlo:

facter fqdn

Creamos el fichero para la clase de prueba:

mkdir /etc/puppet/extra-files
vi /etc/puppet/extra-files/motd
Welcome to AlfaExploit!!

En site.pp se definen que clases aplicar a que hosts, se puede combinar o ser sustituido por ENC: External Node Classifier.

vi /etc/puppet/manifests/site.pp
node default {
  file { '/etc/motd':
    source => 'puppet:///extra-files/motd'
  }
}
/etc/init.d/puppetmaster start

NOTA: node default indica que se aplicará a todos los agentes


Instalación de puppetagent:

emerge -av app-admin/puppet

eselect ruby list
Available Ruby profiles:
  [1]   ruby19 (with Rubygems) *
  [2]   ruby20 (with Rubygems)

eselect ruby set 2
gem -v
2.2.2

gem install msgpack
vi /etc/puppet/puppet.conf
[main]
        vardir = /var/lib/puppet
        logdir = /var/log/puppet
        rundir = /var/run/puppet
        ssldir = /var/lib/puppet/ssl

[agent]
        server = puppetmaster.alfaexploit.com
        environment = production
   

Pedimos a puppetmaster que nos acepte el certificado y corremos puppet por primera vez, cada 10s se comprobará si el cert ha sido confirmado:

puppet agent --test --waitforcert 10

En puppetmaster aceptamos el certificado del agente:

puppet cert --list
puppet cert --sign "SERVERNAME"

Comprobamos como puppet nos ha modificado el MOTD en el agente:

cat /etc/motd
Welcome to AlfaExploit!!

Puppet por defecto correrá cada 30min, arrancamos el servicio y lo añadimos al arranque:

/etc/init.d/puppet start
rc-update add puppet default 

Puppetmaster mediante Passenger:

Por defecto puppet utiliza Ruby’s WEBrick como servidor web, este está bien para hacer algunas pruebas iniciales pero está muy limitado, cuando haya un número considerable de hosts haciendo peticiones no aguantará y tendremos que pasar a algo mas escalable.
Yo he optado por instalar Apache con soporte para Rails/Rack(passenger), se podría instalar con el servidor web de nuestra elección pero yo he optado por Apache por ser con el que mas familiarizado estoy.

Paramos puppetmaster, a partir de ahora Apache tomará el control:

/etc/init.d/puppetmaster stop

Instalamos Apache y RubyGems:

emerge -av www-servers/apache virtual/rubygems

gem install rack passenger
passenger-install-apache2-module
-> Ruby

Please edit your Apache configuration file, and add these lines:

LoadModule passenger_module /usr/local/lib64/ruby/gems/2.0.0/gems/passenger-5.0.11/buildout/apache2/mod_passenger.so
   <IfModule mod_passenger.c>
     PassengerRoot /usr/local/lib64/ruby/gems/2.0.0/gems/passenger-5.0.11
     PassengerDefaultRuby /usr/bin/ruby20
   </IfModule>

Retocamos la config por defecto de Apache, cargando el módulo SSL, asignando un Timeout de 5s y definimos el ServerName:

vi /etc/apache2/httpd.conf
LoadModule ssl_module modules/mod_ssl.so
KeepAliveTimeout 5
ServerName puppetmaster.alfaexploit.com

Borramos los vhosts por defecto y generamos el nuestro:

rm /etc/apache2/vhosts.d/*
vi /etc/apache2/vhosts.d/00_puppet_passenger.conf
# Ruby locations:
LoadModule passenger_module /usr/local/lib64/ruby/gems/2.0.0/gems/passenger-5.0.11/buildout/apache2/mod_passenger.so
PassengerRoot /usr/local/lib64/ruby/gems/2.0.0/gems/passenger-5.0.11
PassengerDefaultRuby /usr/bin/ruby20

# And the passenger performance tuning settings:
# Set this to about 1.5 times the number of CPU cores in your master:
PassengerMaxPoolSize 6
# Recycle master processes after they service 1000 requests
PassengerMaxRequests 1000
# Stop processes if they sit idle for 10 minutes
PassengerPoolIdleTime 600

PassengerAppRoot /var/www/puppetmasterd

Listen 8140
<VirtualHost *:8140>
    # Make Apache hand off HTTP requests to Puppet earlier, at the cost of
    # interfering with mod_proxy, mod_rewrite, etc. See note below.
    PassengerHighPerformance On

    SSLEngine On

    # Only allow high security cryptography. Alter if needed for compatibility.
    SSLProtocol ALL -SSLv2 -SSLv3
    SSLCipherSuite EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
    SSLHonorCipherOrder     on

    SSLCertificateFile      /var/lib/puppet/ssl/certs/puppetmaster.alfaexploit.com.pem
    SSLCertificateKeyFile   /var/lib/puppet/ssl/private_keys/puppetmaster.alfaexploit.com.pem
    SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem
    SSLCACertificateFile    /var/lib/puppet/ssl/ca/ca_crt.pem
    SSLCARevocationFile     /var/lib/puppet/ssl/ca/ca_crl.pem

    SSLVerifyClient         optional
    SSLVerifyDepth          1
    SSLOptions              +StdEnvVars +ExportCertData

    # These request headers are used to pass the client certificate
    # authentication information on to the puppet master process
    RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
    RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
    RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e

    DocumentRoot /var/www/puppetmasterd/public

    <Directory /var/www/puppetmasterd/>
      Options None
      AllowOverride None
      # Apply the right behavior depending on Apache version.
      Order allow,deny
      Allow from all
    </Directory>

    ErrorLog /var/log/apache2/puppet_passenger_ssl_error.log
    CustomLog /var/log/apache2/puppet_passenger_access.log combined
</VirtualHost>

Generamos los directorios necesarios para la aplicación:

mkdir -p /var/www/puppetmasterd
mkdir -p /var/www/puppetmasterd/public/
mkdir -p /var/www/puppetmasterd/tmp

Reiniciamos Apache y lo añadimos al arranque:

/etc/init.d/apache2 restart
rc-update add apache2 default

Indicamos en la config del puppet que tenga en cuenta SSL:

vi /etc/puppet/puppet.conf
[main]
        vardir = /var/lib/puppet
        logdir = /var/log/puppet
        rundir = /var/run/puppet
        confdir = /etc/puppet
        ssldir = /var/lib/puppet/ssl

[master]
        always_cache_fetures = true
        ssl_client_header               = SSL_CLIENT_S_DN
        ssl_client_verify_header        = SSL_CLIENT_VERIFY
        fileserverconfig = /etc/puppet/fileserver.conf

Configuramos la aplicación web:

cd /var/www/puppetmasterd
vi config.ru
# a config.ru, for use with every rack-compatible webserver.
# SSL needs to be handled outside this, though.

# if puppet is not in your RUBYLIB:
# $LOAD_PATH.unshift('/opt/puppet/lib')

$0 = "master"

# if you want debugging:
# ARGV << "--debug"

ARGV << "--rack"

# Rack applications typically don't start as root.  Set --confdir, --vardir,
# --logdir, --rundir to prevent reading configuration from
# ~/ based pathing.
ARGV << "--confdir" << "/etc/puppet"
ARGV << "--vardir"  << "/var/lib/puppet"
ARGV << "--logdir"  << "/var/log/puppet"
ARGV << "--rundir"  << "/var/run/puppet"

# always_cache_features is a performance improvement and safe for a master to
# apply. This is intended to allow agents to recognize new features that may be
# delivered during catalog compilation.
ARGV << "--always_cache_features"

# NOTE: it's unfortunate that we have to use the "CommandLine" class
#  here to launch the app, but it contains some initialization logic
#  (such as triggering the parsing of the config file) that is very
#  important.  We should do something less nasty here when we've
#  gotten our API and settings initialization logic cleaned up.
#
# Also note that the "$0 = master" line up near the top here is
#  the magic that allows the CommandLine class to know that it's
#  supposed to be running master.
#
# --cprice 2012-05-22

require 'puppet/util/command_line'
# we're usually running inside a Rack::Builder.new {} block,
# therefore we need to call run *here*.
run Puppet::Util::CommandLine.new.execute

Asignamos los permisos necesarios:

chown puppet:puppet /var/www/puppetmasterd/config.ru
cd /var/www/puppetmasterd/
chown root:apache tmp/
chown -R root:apache public
chmod 770 tmp/
chmod 750 public/

Generamos los directorios iniciales de la app:

/etc/init.d/apache2 stop
puppet master --verbose --no-daemonize
Ctrl+C

Arrancamos Apache:

/etc/init.d/apache2 start

Comprobamos que se mantiene a la escucha en el puerto 8140:

netstat -nputa|grep 8140
tcp        0      0 0.0.0.0:8140            0.0.0.0:*               LISTEN      13236/apache2   

Hacemos un cambio para comprobar que el cliente lo aplica correctamente:

vi /etc/puppet/extra-files/motd
Welcome to AlfaExploit!!
Test2

Monitorizamos posibles errores:

tail -f /var/log/apache2/puppet_passenger_ssl_error.log

Aplicamos los cambios en el agente:

puppet agent -t
cat /etc/motd 
Welcome to AlfaExploit!!
Test2

Todo un éxito, podemos ver mediante passenger-status que nuestra aplicación está activa:

passenger-status
Version : 5.0.11
Date    : 2015-06-30 10:15:58 +0200
Instance: ha6pDdeg (Apache/2.2.29 (Unix) mod_ssl/2.2.29 OpenSSL/1.0.1m Phusion_Passenger/5.0.11)

----------- General information -----------
Max pool size : 6
App groups    : 1
Processes     : 1
Requests in top-level queue : 0

----------- Application groups -----------
/var/www/puppetmasterd:
  App root: /var/www/puppetmasterd
  Requests in queue: 0
  * PID: 21103   Sessions: 0       Processed: 8       Uptime: 14s
    CPU: 2%      Memory  : 34M     Last used: 11s ago

Foreman:

Foreman nos permitirá administrar de forma fácil y rápida todos los recursos necesarios por un equipo desde su instalación hasta su configuración final.

Instalamos Apache y RubyGems:

emerge -av www-servers/apache virtual/rubygems

No hay ebuild de Foreman para Gentoo por lo tanto debemos instalar desde las fuentes:

cd /var/www
git clone https://github.com/theforeman/foreman.git -b 1.8-stable
cd foreman
cp config/settings.yaml.example config/settings.yaml
vi config/settings.yaml
---
:unattended: true
:login: true
:require_ssl: false
:locations_enabled: false
:organizations_enabled: false
:support_jsonp: false
:mark_translated: false
:domain: 'alfaexploit.com'
:fqdn: 'foreman.alfaexploit.com'
:colorize_logging: false

Instalamos los backends de bases de datos necesarios:

emerge dev-db/sqlite dev-db/mysql++ dev-db/mysql

Mientras configuramos mysql en otro terminal vamos instalando libvirt:

emerge app-emulation/libvirt

Configuramos MySQL:

emerge --config =dev-db/mysql-5.6.24
/etc/init.d/mysql start
rc-update add mysql default
mysql_secure_installation

Creamos la base de datos de Foreman y aplicamos ACLs de acceso:

mysql> CREATE DATABASE foreman DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
mysql> USE mysql
mysql> GRANT ALL PRIVILEGES ON foreman.* TO [email protected]'192.168.40.174' IDENTIFIED BY 'Iwn1tGeZnaw7UuSA5pJ2KL5eZ4f3Pc';
mysql> GRANT ALL PRIVILEGES ON foreman.* TO [email protected]'127.0.0.1' IDENTIFIED BY 'Iwn1tGeZnaw7UuSA5pJ2KL5eZ4f3Pc';
mysql> FLUSH PRIVILEGES;
mysql> exit

Instalamos las gemas necesarias:

gem install activerecord-mysql2-adapter
gem install jquery-ui-rails
gem install bundler

Como vamos a utilizar MySQL, deshablitamos postgres:

bundle install --without postgresql test --path mysql2

Procedemos con la config de la DB:

cd /var/www/foreman/config
cp database.yml.example database.yml
vi database.yml
production:
  adapter: mysql2
  database: foreman
  username: foreman
  password: Iwn1tGeZnaw7UuSA5pJ2KL5eZ4f3Pc
  host: 127.0.0.1
  socket: "/var/run/mysqld/mysqld.sock"

Inicializamos la base de datos:

cd ..
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production bundle exec rake assets:precompile
RAILS_ENV=production bundle exec rake db:seed
Login credentials: admin / XXXXXXXXX
RAILS_ENV=production bundle exec rake apipie:cache
gpasswd -a nobody puppet
gpasswd -a apache puppet
gpasswd -a puppet apache
gpasswd -a root puppet
cd /var/lib/puppet/ssl/private_keys/
chmod 660 foreman.alfaexploit.com.pem

Arrancamos Foreman:

cd /var/www/foreman/
./script/rails s -e production

Accedemos a él:

http://foreman.alfaexploit.com:3000
admin / XXXXXXXXXXXX

Foreman con Passenger:

Instalamos las gemas necesarias:

gem install rack passenger

passenger-install-apache2-module
-> Ruby

   LoadModule passenger_module /usr/local/lib64/ruby/gems/2.0.0/gems/passenger-5.0.11/buildout/apache2/mod_passenger.so
   <IfModule mod_passenger.c>
     PassengerRoot /usr/local/lib64/ruby/gems/2.0.0/gems/passenger-5.0.11
     PassengerDefaultRuby /usr/bin/ruby20
   </IfModule>

Configuramos Apache para que cargue el módulo SSL con un timeout de 5s y como ServerName foreman.alfaexploit.com:

vi /etc/apache2/httpd.conf
LoadModule ssl_module modules/mod_ssl.so
KeepAliveTimeout 5
ServerName foreman.alfaexploit.com

Borramos todos los vhosts y creamos el nuestro:

rm /etc/apache2/vhosts.d/*
vi /etc/apache2/vhosts.d/00_foreman_passenger.conf
# Ruby locations:
LoadModule passenger_module /usr/local/lib64/ruby/gems/2.0.0/gems/passenger-5.0.11/buildout/apache2/mod_passenger.so
PassengerRoot /usr/local/lib64/ruby/gems/2.0.0/gems/passenger-5.0.11
PassengerDefaultRuby /usr/bin/ruby20

# And the passenger performance tuning settings:
# Set this to about 1.5 times the number of CPU cores in your master:
PassengerMaxPoolSize 6
# Recycle master processes after they service 1000 requests
PassengerMaxRequests 1000
# Stop processes if they sit idle for 10 minutes
PassengerPoolIdleTime 600

Listen 443
<VirtualHost *:443>
  ServerName foreman.alfaexploit.com

  DocumentRoot /var/www/foreman/public
  PassengerAppRoot /var/www/foreman

  # Use puppet certificates for SSL

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

  <Directory /var/www/foreman/>
    Options None
    AllowOverride None
    # Apply the right behavior depending on Apache version.
    Order allow,deny
    Allow from all
  </Directory>

  ErrorLog /var/log/apache2/foreman_passenger_ssl_error.log
  CustomLog /var/log/apache2/foreman_passenger_access.log combined

</VirtualHost>

Asignamos los permisos necesarios:

cd  /var/www/foreman
chmod 775 -R tmp
chown -R root:nobody tmp
chmod 0666 /var/www/foreman/log/production.log

Arrancamos Apache y lo añadimos al arranque:

/etc/init.d/apache2 restart
rc-update add apache2 default

Dejamos un tail en los logs por si apareciese algún error:

tail -f /var/log/apache2/foreman_passenger_ssl_error.log
tail -f /var/www/foreman/log/production.log

NOTA: Si se queja de ficheros de cache:

cd /var/www/foreman/
RAILS_ENV=production bundle exec rake apipie:cache

Accedemos al foreman:

https://foreman.alfaexploit.com
admin / XXXXXXXXXXXXXXXX

Podemos ver que apache tiene constancia de nuestra app en ruby:

passenger-status 
Version : 5.0.11
Date    : 2015-06-30 17:15:31 +0200
Instance: gog1gIeX (Apache/2.2.29 (Unix) mod_ssl/2.2.29 OpenSSL/1.0.1m Phusion_Passenger/5.0.11)

----------- General information -----------
Max pool size : 6
App groups    : 1
Processes     : 1
Requests in top-level queue : 0

----------- Application groups -----------
/var/www/foreman:
  App root: /var/www/foreman
  Requests in queue: 0
  * PID: 17718   Sessions: 0       Processed: 4       Uptime: 1m 9s
    CPU: 1%      Memory  : 63M     Last used: 8s ago

La mayoría de parámetros se pueden configurar desde la interfaz web pero hay algunos que solo se pueden tocar desde el fichero de config.

vi /var/www/foreman/config/settings.yaml
---
:unattended: true
:login: true
:require_ssl: true
:locations_enabled: false
:organizations_enabled: false
:support_jsonp: false
:mark_translated: false
:domain: 'alfaexploit.com'
:fqdn: 'foreman.alfaexploit.com'
:colorize_logging: false
:puppet_server: puppetmaster.alfaexploit.com
:create_new_host_when_facts_are_uploaded: true

Se puede habilitar el debug:

:logging:
  :level: debug

Reiniciamos Apache y Puppet:

/etc/init.d/apache2 restart
/etc/init.d/puppet restart

Si queremos recibir notificaciones via email debemos configurarlo:

cp email.yaml.example email.yaml
vi email.yaml
production:
  delivery_method: :smtp
  smtp_settings:
    address: localhost
    port: 25
    domain: alfaexploit.com
    authentication: :none

SmartProxy:

Para que puppet pueda exportar las clases a foreman es necesario el smart-proxy, lo instalaremos en puppet-master, esta es la parte mas peliaguda sin duda alguna ya que existen varias incompatibilidades entre versiones.

Añadimos en la sección master:

vi /etc/puppet/puppet.conf
[master]
        basemodulepath = /etc/puppet/modules

Nos bajamos el código fuente de la versión estable:

cd /usr/src
wget https://github.com/theforeman/smart-proxy/archive/1.9-stable.zip
unzip 1.9-stable.zip
cd smart-proxy-1.9-stable/config
cp settings.yml.example settings.yml

Configuramos los servicios a ofrecer a través de smart-proxy:

vi settings.yml
---
:ssl_certificate: /var/lib/puppet/ssl/certs/puppetmaster.alfaexploit.com.pem
:ssl_ca_file: /var/lib/puppet/ssl/certs/ca.pem
:ssl_private_key: /var/lib/puppet/ssl/private_keys/puppetmaster.alfaexploit.com.pem
:daemon: true
:daemon_pid: /var/run/foreman-proxy/foreman-proxy.pid
:port: 8443
:trusted_hosts:
- foreman.alfaexploit.com
:tftp: false
:tftproot: /var/lib/tftpboot
:dns: false
:dns_provider: nsupdate
:dhcp: false
:dhcp_vendor: isc
:virsh_network: default
:puppetca: true
:puppet: true
:puppet_provider: puppetrun
:customrun_cmd: /bin/false
:customrun_args: -ay -f -s
:puppet_conf: /etc/puppet/puppet.conf
:puppetssh_sudo: false
:puppetssh_command: /usr/bin/puppet agent --onetime --no-usecacheonfailure
:chefproxy: false
:bmc: false
:realm: false
:realm_provider: freeipa
:realm_keytab: /etc/foreman-proxy/freeipa.keytab
:realm_principal: [email protected]
:freeipa_remove_dns: true
:log_file: /var/log/foreman-proxy/proxy.log
:log_level: ERROR

Habilitamos y configuramos los servicios de puppet y puppetCA:

cd /usr/src/smart-proxy-1.9-stable/config/settings.d/
cp puppet.yml.example puppet.yml
vi puppet.yml
---
:enabled: true
:customrun_cmd: /bin/false
:customrun_args: -ay -f -s
:puppet_conf: /etc/puppet/puppet.conf
:puppetssh_sudo: false
:puppetssh_command: /usr/bin/puppet agent --onetime --no-usecacheonfailure
:puppetssh_wait: false
cp puppetca.yml.example puppetca.yml
vi puppetca.yml
---
:enabled: true

NOTA: Existe un bug que debemos tener en cuenta, nos  aseguramos de que NO se instala una versión de puppet por gem distinta a la instalada por portage o la importación de datos desde foreman-smartproxy no funcioanará:

ERF12-2749 [ProxyAPI::ProxyException]: Unable to get environments from Puppet ([RestClient::NotAcceptable]: 406 Not Acceptable) for proxy https://puppetmaster.alfaexploit.com:8443/puppet

Para ver lo que hay instalado(en este caso eliminamos la versión 4.1.0):

eix puppet
Installed versions:  3.7.3

gem list
puppet (4.1.0, 3.7.3)

gem uninstall puppet
gem install puppet -v '3.7.3'
gem list
puppet (3.7.3)

También hay un problema con facter.

Sección: cannot load such file -- facter / puppet (LoadError)

Para solventarlo añadimos puppet con la versión correcta y facter:

vi /usr/src/smart-proxy-1.9-stable/bundler.d/puppet.rb
group :puppet, :puppetca do
  gem 'puppet', '=3.7.3'
  gem 'facter'
  gem 'ruby-augeas', :require => 'augeas'
end

Tener varias versiones de una misma gema puede causar problemas, así que lo comprobamos y en caso de ser necesario desintalamos las mas antiguas:

gem list

Instalamos las gemas restantes:

gem install bundle
gem install sinatra
gem install single_test
gem install webmock
gem install rubocop-checkstyle_formatter
gem install rubyipmi
emerge dev-ruby/ruby-augeas
gem install augeas
gem list
*** LOCAL GEMS ***
addressable (2.3.8)
ast (2.0.0)
astrolabe (1.3.0)
augeas (0.6.3)
bundle (0.0.1)
bundler (1.10.5)
crack (0.4.2)
facter (2.4.1)
hiera (1.3.4)
json (1.8.0)
parser (2.3.0.pre.2)
passenger (5.0.11)
powerpack (0.1.1)
puppet (3.7.3)
racc (1.4.9)
rack (1.6.4)
rack-protection (1.5.3)
rainbow (2.0.0)
rake (0.9.6)
rdoc (4.0.1)
rgen (0.6.6)
rubocop (0.32.1)
rubocop-checkstyle_formatter (0.2.0)
ruby-augeas (0.5.0)
ruby-progressbar (1.7.5)
safe_yaml (1.0.4)
sinatra (1.4.6)
single_test (0.6.0)
tilt (2.0.1)
webmock (1.21.0)

Kerberos necesita una versión de las librerias kerberos que no está en los repos(http://projects.theforeman.org/issues/8042) y como no lo vamos a utilizar instalamos sin soporte para Kerberos:

cd /usr/src/smart-proxy-1.9-stable/
bundle install --without krb5
mkdir /var/log/foreman-proxy

Generamos el script de arranque:

vi /etc/local.d/smart-proxy.start
#! /bin/bash
cd /usr/src/smart-proxy-1.9-stable/
export RACK_ENV='production'
bin/smart-proxy

Asignamos permisos de ejecución y arrancamos el proxy:

chmod 700 /etc/local.d/smart-proxy.start
/etc/local.d/smart-proxy.start
ps aux|grep smart
root      3415  0.4  1.3 170540 27456 ?        Sl   21:11   0:00 ruby bin/smart-proxy

Podemos habilitar el DEBUG:

vi settings.yml
:log_level: DEBUG

También podemos dejar en foreground y arrancar el proxy manualmente:

vi settings.yml
:daemon: false
cd /usr/src/smart-proxy-1.9-stable/
export RACK_ENV='production'
bin/smart-proxy

tail -f /var/log/foreman-proxy/proxy.log

Añadimos en Foreman el smart-proxy:

Infraestructura -> Proxies inteligentes: puppetmaster.alfaexploit.com https://puppetmaster.alfaexploit.com:8443

Podemos comprobar los servicios prestados por el proxy desde Foreman:

curl -k https://puppetmaster.alfaexploit.com:8443/features
["puppet","puppetca"]

Podemos comprobar que se ha cargado la config correcta desde puppetmaster:

puppet config print modulepath --environment production

External Node Classifier:

En puppetmaster debemos instalar el script encargado de aplicar las clases entre los hosts:

cd /etc/puppet
wget https://raw.githubusercontent.com/theforeman/puppet-foreman/2.2.3/files/external_node_v2.rb
mv external_node_v2.rb node.rb
chmod +x /etc/puppet/node.rb

Configuramos la parte de Foreman:

vi /etc/puppet/foreman.yaml
---
# Update for your Foreman and Puppet master hostname(s)
:url: "https://foreman.alfaexploit.com"
:ssl_ca: "/var/lib/puppet/ssl/certs/ca.pem"
:ssl_cert: "/var/lib/puppet/ssl/certs/puppetmaster.alfaexploit.com.pem"
:ssl_key: "/var/lib/puppet/ssl/private_keys/puppetmaster.alfaexploit.com.pem"

# Advanced settings
:puppetdir: "/var/lib/puppet"
:puppetuser: "root"
:facts: true
:timeout: 10
:threads: null

Añadimos la config del ENC en puppet:

vi /etc/puppet/puppet.conf
[master]
  external_nodes = /etc/puppet/node.rb
  node_terminus  = exec

Comprobamos que funciona preguntando por las clases a aplicar a un determinado host:

/etc/puppet/node.rb foreman.alfaexploit.com
---
classes: {}
parameters:
  puppetmaster: puppetmaster.alfaexploit.com
  root_pw: 
  foreman_env: production
  foreman_subnets: []
  foreman_interfaces:
  - mac: ca:fe:00:01:ca:fe
    ip: 192.168.40.174
    type: Interface
    name: foreman.alfaexploit.com
    attrs:
      network: 192.168.40.0
      netmask: 255.255.255.0
      mtu: '1500'
    virtual: false
    link: true
    identifier: eth0
    managed: true
    primary: true
    provision: true
    subnet: 
  - mac: 
    ip: 
    type: Interface
    name: 
    attrs:
      mtu: '1480'
    virtual: false
    link: true
    identifier: tunl0
    managed: false
    primary: false
    provision: false
    subnet: 
environment: production

Damos permisos a los diferentes directorios desde puppet:

vi /etc/puppet/auth.conf
# allow nodes to retrieve their own catalog
path ~ ^/catalog/([^/]+)$
method find
allow $1

# allow nodes to retrieve their own node definition
path ~ ^/node/([^/]+)$
method find
allow $1

# allow all nodes to access the certificates services
path /certificate_revocation_list/ca
method find
allow *

# allow all nodes to store their own reports
path ~ ^/report/([^/]+)$
method save
allow $1

# Allow all nodes to access all file services; this is necessary for
# pluginsync, file serving from modules, and file serving from custom
# mount points (see fileserver.conf). Note that the `/file` prefix matches
# requests to both the file_metadata and file_content paths. See "Examples"
# above if you need more granular access control for custom mount points.
path /file
allow *

### Unauthenticated ACLs, for clients without valid certificates; authenticated
### clients can also access these paths, though they rarely need to.

# allow access to the CA certificate; unauthenticated nodes need this
# in order to validate the puppet master's certificate
path /certificate/ca
auth any
method find
allow *

# allow nodes to retrieve the certificate they requested earlier
path /certificate/
auth any
method find
allow *

# allow nodes to request a new certificate
path /certificate_request
auth any
method find, save
allow *

path /v2.0/environments
method find
allow *

# deny everything else; this ACL is not strictly necessary, but
# illustrates the default policy.
path /
auth any

Creamos una clase de prueba que nos instale el cliente ntp:

cd /etc/puppet/modules
mkdir -p test/manifests
vi test/manifests/init.pp
class test {
        package {"ntpclient":
                name            =>      'ntpclient',
                category        =>      'net-misc',
                ensure          =>      installed,
        }
}

Reiniciamos todos los servicios, Puppet, Apache y Proxy:

/etc/init.d/puppet restart
/etc/init.d/apache2 restart

ps aux|grep smart
kill PID
/etc/local.d/smart-proxy.start

Importamos la clase y la aplicamos al host desde Foreman:

Configure -> Puppet Classes
Import from puppetmaster

Hosts -> All hosts
foreman.alfaexploit.com -> Edit
Puppet Classes -> test

Comprobamos que ahora SI aparece la clase ntp como aplicada:

/etc/puppet/node.rb foreman.alfaexploit.com
classes:
  test:

Corremos Puppet en el server de foreman:

puppet agent -t

NOTA: Si aparece:

Warning: Unable to fetch my node definition, but the agent run will continue:
Warning: Error 400 on SERVER: Failed to find foreman.alfaexploit.com via exec: Execution of '/etc/puppet/node.rb foreman.alfaexploit.com' returned 1:

Ejecutaremos en puppetmaster:

chown -R puppet:puppet /var/lib/puppet/yaml/

Ejecutamos puppet en Foreman y comprobamos que efectivamente el ebuild ntpclient ha sido instalado:

puppet agent -t
eix ntpclient
Installed versions: 2010.365

Para añadir mas agentes es tan sencillo como:

emerge -av app-admin/puppet
vi /etc/puppet/puppet.conf
[main]
        vardir = /var/lib/puppet
        logdir = /var/log/puppet
        rundir = /var/run/puppet
        ssldir = /var/lib/puppet/ssl
    
[agent]
        server = puppetmaster.alfaexploit.com
        environment = production
puppet agent --test --waitforcert 10

Aceptamos el nuevo agente en puppetmaster:

puppet cert --list
puppet cert --sign "SERVERNAME"

En el agente aplicariamos las clases pertinentes y correriamos puppet:

puppet agent -t

Troubleshooting:

Smart-Proxy:

Lo primero que debemos revisar si tenemos problemas con el proxy son las reglas de firewall, los puertos utilizados son:

Port     Protocol     Required For
53     TCP & UDP     DNS Server
67, 68     UDP     DHCP Server
69     UDP     * TFTP Server
80, 443     TCP     * HTTP & HTTPS access to Foreman web UI - using Apache + Passenger
3000     TCP     HTTP access to Foreman web UI - using standalone WEBrick service
3306     TCP     Separate MySQL database
5910 - 5930     TCP     Server VNC Consoles
5432     TCP     Separate PostgreSQL database
8140     TCP     * Puppet Master
8443     TCP     Smart Proxy, open only to Foreman

En smart-proxy se puede habilitar la salida en modo DEBUG:

vi settings.yml
:log_level: DEBUG
tail -f /var/log/foreman-proxy/proxy.log

Foreman:

Para depurar problemas en Foreman:

tail -f /var/log/apache2/foreman_passenger_ssl_error.log
tail -f /var/www/foreman/log/production.log
vi config/settings.yaml
:logging:
  :level: debug
  

PuppetMaster:

Podemos comprobar la sintaxis de las clases con el siguiente comando:

puppet parser validate CLASE

Podemos mostrar la config completa con el comando:

puppet config print all

Los problemas se pueden detectar en los logs de Apache si se utiliza Passenger:

tail -f /var/log/apache2/puppet_passenger_ssl_error.log

Podemos comprobar que ha cargado la config correcta:

puppet config print modulepath --environment production

Agente:

Salida verbose de puppet agent:

puppet agent -t --debug

Browser:

Si hacemos varias pruebas el navegador se quedará con el certificado anterior dando problemas:

(Código de error: sec_error_reused_issuer_and_serial)
Firefox -> Config -> Certificates -> View certificates -> Servers -> foreman.alfaexploit.com -> Delete

Os dejo un par de capturas para que veais Foreman en todo su esplendor:

 


Autor: Kr0m -- 03/07/2015 20:07:24