Katello:使用Puppet模块并创建主列表
我们将安装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环境的任何服务器都将应用上面的配置。