Katello:使用Puppet模块并创建主列表

时间:2020-03-21 11:45:56  来源:igfitidea点击:

我们将安装Puppet模块,还将创建一个自定义防火墙模块,定义一些规则,配置Puppet以从自定义位置提供文件并声明站点列表。

测试环境

我们在CentOS 7服务器上安装了Katello:

katello.igi.local(10.11.1.4)

Puppet配置

在上一篇文章中,我们已经创建了一个名为“ homelab”的新环境,但尚未创建的是Puppet文件夹结构。

资料夹结构

让我们继续创建一个文件夹结构:

# mkdir -p /etc/puppetlabs/code/environments/homelab/{manifests,modules}

创建主列表并设置适当的组权限:

# touch /etc/puppetlabs/code/environments/homelab/manifests/site.pp
# chgrp puppet /etc/puppetlabs/code/environments/homelab/manifests/site.pp
# chmod 0640 /etc/puppetlabs/code/environments/homelab/manifests/site.pp

现在,我们可以开始安装Puppet模块。

Puppet模块

以下是我们已安装并将要使用的Puppet模块的列表。
乍一看可能看起来很长,但实际上并非如此。
一些模块作为依赖项安装。

我们可以看到用于SELinux,Linux安全限制,内核调整(sysctl)的模块,以及OpenLDAP和sssd,Apache,WordPress和MySQL,Corosync和NFS,Zabbix和SNMP。

Java/MongoDB/Elasticsearch有整个Graylog堆栈,还有Keepalived和HAProxy。

# puppet module list --environment homelab
/etc/puppetlabs/code/environments/homelab/modules
├── arioch-keepalived (v1.2.5)
├── camptocamp-openldap (v1.16.1)
├── camptocamp-systemd (v1.1.1)
├── derdanne-nfs (v2.0.7)
├── elastic-elasticsearch (v6.2.1)
├── graylog-graylog (v0.6.0)
├── herculesteam-augeasproviders_core (v2.1.4)
├── herculesteam-augeasproviders_shellvar (v2.2.2)
├── hunner-wordpress (v1.0.0)
├── theitroad-theitroad_firewall (v1.0.0)
├── puppet-archive (v2.3.0)
├── puppet-corosync (v6.0.0)
├── puppet-mongodb (v2.1.0)
├── puppet-selinux (v1.5.2)
├── puppet-staging (v3.1.0)
├── puppet-zabbix (v6.2.0)
├── puppetlabs-accounts (v1.3.0)
├── puppetlabs-apache (v2.3.1)
├── puppetlabs-apt (v4.5.1)
├── puppetlabs-concat (v2.2.1)
├── puppetlabs-firewall (v1.12.0)
├── puppetlabs-haproxy (v2.1.0)
├── puppetlabs-java (v2.4.0)
├── puppetlabs-mysql (v5.3.0)
├── puppetlabs-ntp (v7.1.1)
├── puppetlabs-pe_gem (v0.2.0)
├── puppetlabs-postgresql (v5.3.0)
├── puppetlabs-ruby (v1.0.0)
├── puppetlabs-stdlib (v4.24.0)
├── puppetlabs-translate (v1.1.0)
├── razorsedge-snmp (v3.9.0)
├── richardc-datacat (v0.6.2)
├── saz-limits (v3.0.2)
├── saz-rsyslog (v5.0.0)
├── saz-ssh (v3.0.1)
├── saz-sudo (v5.0.0)
├── sgnl05-sssd (v2.7.0)
└── thias-sysctl (v1.0.6)
/etc/puppetlabs/code/environments/common (no modules installed)
/etc/puppetlabs/code/modules (no modules installed)
/opt/puppetlabs/puppet/modules (no modules installed)
/usr/share/puppet/modules (no modules installed)

theitroad-theitroad_firewall模块是我们自己生成的模块。
我们将在稍后讨论。

现在,我们如何实际将模块安装到我们的homelab环境中?
默认的Puppet环境是生产环境(请参见上一篇文章),默认情况下所有模块都将其中运行。
为了将它们安装到homelab环境中,我们可以使用指定的homelab环境定义安装命令:

# MY_CMD="puppet module install --environment homelab"

要安装模块,我们现在可以使用如下代码:

# $MY_CMD puppetlabs-firewall ;\
  $MY_CMD puppetlabs-accounts ;\
  $MY_CMD puppetlabs-ntp ;\
  $MY_CMD puppet-selinux ;\
  $MY_CMD saz-ssh ;\
  $MY_CMD saz-sudo ;\
  $MY_CMD saz-limits ;\
  $MY_CMD thias-sysctl

这不是模块的完整列表,而是我们的主要列表所需的模块(请参见下面的主要列表段落)。
如果我们想一次性安装所有组件,也可以循环访问模块列表。

让我们回到防火墙模块。
我们希望能够使用智能类参数通过Katello WeUI传递自定义防火墙数据。
创建一个新的防火墙模块:

# cd /etc/puppetlabs/code/environments/homelab/modules
# puppet module generate theitroad-theitroad_firewall

创建列表:

# touch ./theitroad_firewall/manifests/{init.pp,pre.pp,post.pp}

好的,让我们创建规则。
这是文件“ pre.pp”的内容(默认情况下仅允许ICMP和SSH):

class theitroad_firewall::pre {
  Firewall {

require => undef,
  }
  firewall { '000 drop all IPv6':

proto    => 'all',

action   => 'drop',

provider => 'ip6tables',
  }->
  firewall { '001 allow all to lo interface':

proto   => 'all',

iniface => 'lo',

action  => 'accept',
  }->
  firewall { '002 reject local traffic not on loopback interface':

iniface     => '! lo',

proto

=> 'all',

destination => '127.0.0.1/8',

action

=> 'reject',
  }->
  firewall { '003 allow all ICMP':

proto  => 'icmp',

action => 'accept',
  }->
  firewall { '004 allow related established rules':

proto  => 'all',

state  => ['RELATED', 'ESTABLISHED'],

action => 'accept',
  }->
  firewall { '005 allow SSH':

proto  => 'tcp',

source => '10.0.0.0/8',

state  => [ "NEW" ],

dport  => '22',

action => 'accept',
  }
}

这是文件'post.pp'的内容:

class theitroad_firewall::post {
   firewall {'999 drop all':

proto   => 'all',

action  => 'drop',

before  => undef,
  }
}

主模块列表“ init.pp”:

class theitroad_firewall($firewall_data = false) {
  include theitroad_firewall::pre
  include theitroad_firewall::post
  resources { "firewall":

purge => true
  }
  Firewall {

before  => Class['theitroad_firewall::post'],

require => Class['theitroad_firewall::pre'],
  }
  if $firewall_data != false {

create_resources('firewall', $firewall_data)
  }
}

安装模块后,我们还要注意的另一件事是SELinux上下文:

# restorecon -Rv /etc/puppetlabs/code/environments/homelab/

在这一阶段,Katello不了解我们新安装的Puppet模块。
我们必须转到Katello WebUI,导航至:

'配置>Puppet环境>从katello.igi.local导入环境'

这会将模块导入到homelab环境中。
对Puppet类执行相同的操作:

'配置>Puppet类>从katello.igi.local导入环境'

这将导入theitroad_firewall类。

奇怪的是,我找不到执行上述导入操作的Hammer命令,可能是我忽略了某些东西。
如果我们知道如何使用Hammer进行操作,请在注释部分让我知道。

配置theitroad_firewall智能类参数

打开Katello WebUI,导航至:

'配置>Puppet类'

找到类theitroad_firewall,编辑“智能类参数”,并将$firewall_data密钥参数类型设置为yaml。
这将允许通过yaml传递任何其他防火墙规则,例如:

"007 accept TCP Apache requests": 
  dport:

- "80"

- "443"
  proto: tcp
  source: "10.0.0.0/8"
  action: accept

请参阅下面的图片以了解主意。

下一步是将theitroad_firewall类分配给我们先前创建的主机组,然后将应用列表“ pre.pp”和“ post.pp”中定义的默认防火墙规则,并允许我们执行以下操作:通过yaml将新的防火墙规则直接添加到任何主机(该组的成员)。

我们可以查看主机列表以获取主机ID:

# hammer host list

然后验证是否已应用参数,例如:

# hammer host sc-params --host-id "32"
---|---------------|---------------|----------|----------------
ID | PARAMETER     | DEFAULT VALUE | OVERRIDE | PUPPET CLASS

---|---------------|---------------|----------|----------------
58 | firewall_data |

| true     | theitroad_firewall
---|---------------|---------------|----------|----------------

从自定义位置提供文件

Puppet自动提供每个模块的“文件”目录中的文件。
这在很大程度上完成了这项工作,但是,在homelab环境中工作时,我们更喜欢有一个自定义安装点,可以其中存储所有文件。

文件“ fileserver.conf”为Puppet的文件服务器配置自定义静态安装点。
如果存在自定义安装点,则文件资源可以使用其源属性来访问它们。

创建一个自定义目录来提供以下文件的服务:

# mkdir /etc/puppetlabs/code/environments/homelab/homelab_files

要创建自定义安装点,请打开文件'/etc/puppetlabs/puppet/fileserver.conf'并添加以下内容:

[homelab_files]
  path /etc/puppetlabs/code/environments/homelab/homelab_files
  allow *

结果,路径目录中的文件将在'puppet:///homelab_files /'中提供。

我们要立即创建几个文件并将其放置在目录中,因为这些文件将由主列表使用。

我们将努力尽可能地使用加密,因此我们需要拥有TLS/SSL证书。
让我们继续前进,并生成一个自签名的签名。
我们想要创建一个通配符证书,以便我们可以将其与任何homelab服务一起使用,因此,当要求输入通用名时,键入* .igi.local。

# cd /etc/puppetlabs/code/environments/homelab/homelab_files
# DOMAIN=hl
# openssl genrsa -out "$DOMAIN".key 2048 && chmod 0600 "$DOMAIN".key
# openssl req -new -sha256 -key "$DOMAIN".key -out "$DOMAIN".csr
# openssl x509 -req -days 1825 -sha256 -in "$DOMAIN".csr \
  -signkey "$DOMAIN".key -out "$DOMAIN".crt
# openssl pkcs8 -topk8 -inform pem -in "$DOMAIN".key \
-outform pem -nocrypt -out "$DOMAIN".pem

确保已创建文件:

# ls
hl.crt  hl.csr  hl.key  hl.pem

验证证书:

# openssl x509 -in hl.crt -text -noout|grep CN
   Issuer: C=GB, L=Birmingham, O=HomeLab, CN=*.igi.local
   Subject: C=GB, L=Birmingham, O=HomeLab, CN=*.igi.local

一切看起来不错,我们可以继续进行并声明主要列表。

定义Homelab环境的主要列表

编辑主列表文件“ /etc/puppetlabs/code/environments/homelab/manifests/site.pp”,并定义homelab环境的所有全局替代。

请注意,我们先前创建的TLS证书是如何配置为在所有服务器上部署的。

## Author: igi at www.theitroad.com
## Date: March 2016## This manifest defines services in the following order:## 1. OpenSSH server config
## 2. Packages and services
## 3. Sudo and User config
## 4. SELinux config
## 5. Sysctl config
## 6. System security limits##
## The name default (without quotes) is a special value for node names.
## If no node statement matching a given node can be found, the default 
## node will be used.node 'default' {}## Note: the theitroad_firewall class should not be assigned here,
## but rather added to Katello Host Groups. This is to allow us
## to utilise Smart Class Parameters and add additional rules
## per host by using Katello WebUI. #################################################
## OpenSSH server configuration for the env## CentOS 7 OpenSSH server configuration
if ($facts['os']['family'] == 'RedHat') and ($facts['os']['release']['major'] == '7') {
  class { 'ssh::server':

validate_sshd_file => true,

options => {

'Port'

=> '22',

'ListenAddress'

=> '0.0.0.0',

'Protocol'

=> '2',

'SyslogFacility'

=> 'AUTHPRIV',

'LogLevel'

=> 'INFO',

'MaxAuthTries'

=> '3',

'MaxSessions'

=> '5',

'AllowUsers'

=> ['root','igi'],

'PermitRootLogin'

=> 'without-password',

'HostKey'

=> ['/etc/ssh/ssh_host_ed25519_key', '/etc/ssh/ssh_host_rsa_key'],

'PasswordAuthentication' => 'yes',

'PermitEmptyPasswords'   => 'no',

'PubkeyAuthentication'   => 'yes',

'AuthorizedKeysFile'     => '.ssh/authorized_keys',

'KerberosAuthentication' => 'no',

'GSSAPIAuthentication'   => 'yes',

'GSSAPICleanupCredentials' => 'yes',

'ChallengeResponseAuthentication' => 'no',

'HostbasedAuthentication' => 'no',

'IgnoreUserKnownHosts'   => 'yes',

'PermitUserEnvironment'  => 'no',

'UsePrivilegeSeparation' => 'yes',

'StrictModes'

=> 'yes',

'UsePAM'

=> 'yes',

'LoginGraceTime'

=> '60',

'TCPKeepAlive'

=> 'yes',

'AllowAgentForwarding'   => 'no',

'AllowTcpForwarding'     => 'no',

'PermitTunnel'

=> 'no',

'X11Forwarding'

=> 'no',

'Compression'

=> 'delayed',

'UseDNS'

=> 'no',

'Banner'

=> 'none',

'PrintMotd'

=> 'no',

'PrintLastLog'

=> 'yes',

'Subsystem'

=> 'sftp /usr/libexec/openssh/sftp-server',

'Ciphers'

=> 'Hyman@theitroad,Hyman@theitroad,Hyman@theitroad,aes256-ctr,aes192-ctr,aes128-ctr',

'MACs'

=> 'Hyman@theitroad,Hyman@theitroad,Hyman@theitroad',

'KexAlgorithms'

=> 'Hyman@theitroad,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256',

'HostKeyAlgorithms'

=> 'ssh-ed25519,Hyman@theitroad,ssh-rsa,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,Hyman@theitroad,Hyman@theitroad,Hyman@theitroad,Hyman@theitroad,Hyman@theitroad',

},
  }
}## Packages/services configuration for the env  ## We want these packages installed on all servers
  $packages_to_install = [

'bzip2',

'deltarpm',

'dos2unix',

'gzip',

'htop',

'iotop',

'lsof',

'mailx',

'net-tools',

'nmap-ncat',

'postfix',

'rsync',

'screen' ,

'strace',

'sudo',

'sysstat',

'unzip',

'vim' ,

'wget',

'xz',

'yum-cron',

'yum-utils',

'zip',
  ]
  package { $packages_to_install: ensure => 'installed' }
  ## We do not want these packages on servers
  $packages_to_purge = [

'aic94xx-firmware',

'alsa-firmware',

'alsa-utils',

'ivtv-firmware',

'iw',

'iwl1000-firmware',

'iwl100-firmware',

'iwl105-firmware',

'iwl135-firmware',

'iwl2000-firmware',

'iwl2030-firmware',

'iwl3160-firmware',

'iwl3945-firmware',

'iwl4965-firmware',

'iwl5000-firmware',

'iwl5150-firmware',

'iwl6000-firmware',

'iwl6000g2a-firmware',

'iwl6000g2b-firmware',

'iwl6050-firmware',

'iwl7260-firmware',

'iwl7265-firmware',

'wireless-tools',

'wpa_supplicant',
  ]
  package { $packages_to_purge: ensure => 'purged' }
  ##
  ## Manage some specific services below
  ##
  service { 'kdump': enable => false, } 
  service { 'puppet': enable => true, }
  service { 'sysstat': enable => false, }
  service { 'yum-cron': enable => true, }
  ##
  ## Configure NTP
  ##
  class { 'ntp':

servers  => [ 'admin1.igi.local', 'admin2.igi.local' ],

restrict => ['127.0.0.1'],
  }
  ##
  ## Configure Postfix via postconf
  ## Note how we configure smtp_fallback_relay 
  ##
  service { 'postfix': enable => true, ensure => "running", }
  exec { "configure_postfix":

path     => '/usr/bin:/usr/sbin:/bin:/sbin',

provider => shell,

command  => "postconf -e 'inet_interfaces = localhost' \

'relayhost = admin1.igi.local' \

'smtp_fallback_relay = admin2.igi.local' \

'smtpd_banner = $hostname ESMTP'",

unless   => "grep ^smtp_fallback_relay /etc/postfix/main.cf",

notify   => Exec['restart_postfix']
  }
  exec {'restart_postfix':

path

=> '/usr/bin:/usr/sbin:/bin:/sbin',

provider    => shell,

## Using service rather than systemctl to make it portable

command     => "service postfix restart",

refreshonly => true,
  }
  if ($facts['os']['release']['major'] == '7') {

## Disable firewalld and install iptables-services

package { 'iptables-services': ensure => 'installed' }

service { 'firewalld': enable => "mask", ensure => "stopped", }

service { 'iptables': enable => true, ensure => "running", }

service { 'ip6tables': enable => true, ensure => "running", }

service { 'tuned': enable => true, }

package { 'chrony': ensure => 'purged' }
  }
  ## Wildcard *.igi.local TLS certificate for homelab
  file {'/etc/pki/tls/certs/hl.crt':

ensure => 'file',

source => 'puppet:///homelab_files/hl.crt',

path => '/etc/pki/tls/certs/hl.crt',

owner => '0',

group => '0',

mode  => '0644',
  }
  file {'/etc/pki/tls/private/hl.key':

ensure => 'file',

source => 'puppet:///homelab_files/hl.key',

path => '/etc/pki/tls/private/hl.key',

owner => '0',

group => '0',

mode  => '0640',
  }
}## Sudo and Users configuration for the envclass { 'sudo':
  purge

=> true,
  config_file_replace => true,
}
sudo::conf { 'wheel_group':
  content  => "%wheel ALL=(ALL) ALL",
}
## These are necessary for passwordless SSH
file {'/root/.ssh':
  ensure  => 'directory',
  owner   => '0',
  group   => '0',
  mode    => '0700',
}->
file {'/root/.ssh/authorized_keys':
  ensure  => 'file',
  owner   => '0',
  group   => '0',
  mode    => '0600',
  content => "# Managed by Puppet\n\n\nssh-rsa key-string\n",
}## SELinux configuration for the environmentclass { selinux:
  mode => 'enforcing',
  type => 'targeted',
}## Sysctl configuration for the environmentsysctl { 'fs.suid_dumpable': value => '0' }
sysctl { 'kernel.dmesg_restrict': value => '1' }
sysctl { 'kernel.kptr_restrict': value => '2' }
sysctl { 'kernel.randomize_va_space': value => '2' }
sysctl { 'kernel.sysrq': value => '0' }
sysctl { 'net.ipv4.tcp_syncookies': value => '1' }
sysctl { 'net.ipv4.tcp_timestamps': value => '1' }
sysctl { 'net.ipv4.conf.default.accept_source_route': value => '0' }
sysctl { 'net.ipv4.conf.all.accept_redirects': value => '0' }
sysctl { 'net.ipv4.conf.default.accept_redirects': value => '0' }
sysctl { 'net.ipv4.conf.all.send_redirects': value => '0' }
sysctl { 'net.ipv4.conf.default.send_redirects': value => '0' }
sysctl { 'net.ipv4.conf.all.secure_redirects': value => '0' }
sysctl { 'net.ipv4.conf.default.secure_redirects': value => '0' }
sysctl { 'net.ipv4.conf.all.rp_filter': value => '1' }
sysctl { 'net.ipv4.conf.default.rp_filter': value => '1' }
sysctl { 'net.ipv4.conf.all.log_martians': value => '1' }
sysctl { 'net.ipv4.conf.default.log_martians': value => '1' }
sysctl { 'net.ipv6.conf.lo.disable_ipv6': value => '0' }
sysctl { 'net.ipv6.conf.all.disable_ipv6': value => '0' }
sysctl { 'net.ipv6.conf.default.disable_ipv6': value => '0' }
sysctl { 'net.ipv6.conf.all.accept_redirects': value => '0' }
sysctl { 'net.ipv6.conf.default.accept_redirects': value => '0' }
sysctl { 'vm.swappiness': value => '40' }## Security limits configuration for the envlimits::limits{'*/core':   hard => 0; }
limits::limits{'*/fsize':  both => 67108864; }
limits::limits{'*/locks':  both => 65535; }
limits::limits{'*/nofile': both => 65535; }
limits::limits{'*/nproc':  both => 16384; }
limits::limits{'*/stack':  both => 32768; }
limits::limits{'root/locks':  both => 65535; }
limits::limits{'root/nofile': both => 65535; }
limits::limits{'root/nproc':  both => 16384; }
limits::limits{'root/stack':  both => 32768; }
## Module does not manage the file /etc/security/limits.conf
## We might as well warn people from editing it.
file {'/etc/security/limits.conf':
  ensure  => 'file',
  owner   => '0',
  group   => '0',
  mode    => '0644',
  content => "# Managed by Puppet\n\n",
}

使用Puppet homelab环境的任何服务器都将应用上面的配置。