| 50 | == Some helper modules for work with text files == |
| 51 | What follows are some helper functions for working with text files. If native puppet resource type or augeas lens exists for the file type you want to manage please use that instead of these hacks. |
| 52 | {{{ |
| 53 | # Josko Plazonic 20110314 |
| 54 | |
| 55 | # should be self explanatory |
| 56 | define append_if_no_such_line($file, $line, $refreshonly = 'false') { |
| 57 | exec { "/bin/echo '$line' >> '$file'": |
| 58 | unless => "/bin/grep -Fxqe '$line' '$file'", |
| 59 | path => "/bin", |
| 60 | refreshonly => $refreshonly |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | # can only be used for files where the parameter already exists and will change it |
| 65 | define change_present_param_custom($file, $param, $value, $refreshonly = 'false', $separator = '=', $matchfor="") { |
| 66 | if $matchfor == "" { |
| 67 | $realmatchfor="$param$separator$value" |
| 68 | } else { |
| 69 | $realmatchfor = $matchfor |
| 70 | } |
| 71 | exec { "/usr/bin/perl -pi -e 's|^$param$separator.*|$param$separator$value|g' '$file'": |
| 72 | unless => "/bin/grep -Fxqe '$realmatchfor' '$file'", |
| 73 | path => "/bin:/usr/bin", |
| 74 | refreshonly => $refreshonly |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | # similar to above but if the param is not there it will add it |
| 79 | define change_param_custom($file, $param, $value, $refreshonly = 'false', $separator = '=', $matchfor="") { |
| 80 | if $matchfor == "" { |
| 81 | $realmatchfor="$param$separator$value" |
| 82 | } else { |
| 83 | $realmatchfor = $matchfor |
| 84 | } |
| 85 | exec { "/bin/grep -q '^$param$separator.*' '$file' && /usr/bin/perl -pi -e 's|^$param$separator.*|$param$separator$value|g' '$file' || echo '$param$separator$value' >> '$file' ": |
| 86 | unless => "/bin/grep -Fxqe '$realmatchfor' '$file'", |
| 87 | path => "/bin:/usr/bin", |
| 88 | refreshonly => $refreshonly |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | # delete a line from a text file |
| 93 | define remove_line($file, $line, $refreshonly = 'false') { |
| 94 | exec { "/usr/bin/perl -pi -e 's|^$line\$\\\\n||' '$file'": |
| 95 | onlyif => "/bin/grep -Fxqe '$line' '$file'", |
| 96 | path => "/bin", |
| 97 | refreshonly => $refreshonly |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | }}} |
| 102 | |
| 103 | Examples: |
| 104 | {{{ |
| 105 | # add a path to use for environment modules |
| 106 | append_if_no_such_line { "usr_local_modules": |
| 107 | file => "/usr/share/Modules/init/.modulespath", |
| 108 | line => "/usr/local/share/Modules/modulefiles", |
| 109 | require => Package["environment-modules"], |
| 110 | } |
| 111 | |
| 112 | # change to who mdadm sends emails |
| 113 | change_present_param_custom { mdadmReport: |
| 114 | file => "/etc/mdadm.conf", |
| 115 | param => "MAILADDR", |
| 116 | value => 'reportreceiver@mydomain.com', |
| 117 | separator => " ", |
| 118 | notify => Service["mdmonitor"], |
| 119 | require => Package["mdadm"] |
| 120 | } |
| 121 | |
| 122 | }}} |
| 123 | |
| 124 | |
| 125 | == Kernel version monitoring recipes == |
| 126 | These sample recipes should help you with ensuring your puppet clients run the latest version of kernel and with associated cleanup and security lock down. The idea is the following: |
| 127 | |
| 128 | * either via yum nightly update or with a puppet recipe ensure latest kernel(s) are installed. E.g. in emergencies (say a critical local kernel vulnerability that you want installed on next puppet client run) you could easily do |
| 129 | {{{ |
| 130 | package { "kernel-2.6.32-71.18.2.el6.x86_64": |
| 131 | ensure => "installed" |
| 132 | } |
| 133 | }}} |
| 134 | |
| 135 | * kernel version fact from [wiki:FacterTweaks facter tweaks webpage] allows access to info on currently running client kernel ($kernelrelease), newest installed kernel ($kernelnewest) and oldest installed kernel ($kerneloldest). |
| 136 | |
| 137 | * example optional security lock down - disallow remote ssh: |
| 138 | {{{ |
| 139 | # Josko Plazonic 20110314 |
| 140 | case $kernelnewest { |
| 141 | "",$kernelrelease: { |
| 142 | # either puppet does not have (yet) kernel version facts or we are currently |
| 143 | # running the latest kernel so allow ssh from our usual open networks |
| 144 | $sshallowwks = "192.168.1.1/255.255.255.0" |
| 145 | } |
| 146 | default: { |
| 147 | # if we are arriving here it is because $kernelnewest != $kernelrelease so we list |
| 148 | # trusted hosts we always allow remote logins from |
| 149 | $sshallowwks = "127.0.0.1, 192.168.1.250, 192.168.1.251" |
| 150 | } |
| 151 | |
| 152 | } |
| 153 | # Now set it in hosts.allow, it would be better to use augeas but |
| 154 | # no available lens for hosts.allow/deny forces us to use the below |
| 155 | change_param_custom { "set_ssh_hosts_allow": |
| 156 | file => "/etc/hosts.allow", |
| 157 | param => "sshd", |
| 158 | separator => ": ", |
| 159 | value => "$sshallowwks" |
| 160 | } |
| 161 | } |
| 162 | }}} |
| 163 | |
| 164 | * remove older kernels: |
| 165 | {{{ |
| 166 | # Josko Plazonic 20110314 |
| 167 | case $kerneloldest { |
| 168 | "",$kernelrelease: { |
| 169 | # do nothing, we either do not have the kernel version facts |
| 170 | # or we are running oldest kernel |
| 171 | } |
| 172 | default: { |
| 173 | package { "kernel-$kerneloldest": |
| 174 | ensure => "absent" |
| 175 | } |
| 176 | } |
| 177 | } |
| 178 | }}} |
| 179 | |
| 180 | * reboot - this one is tricky and you will have to tweak it for your environment carefully. I give an example used on Linux workstation where by using $cmdtocheck_users command - ps and a long long egrep - we exclude processes that are safe to ignore when rebooting (like ssh-agent, ntp daemon and so on) but anything left over (say firefox, or matlab or ...) will prevent reboot: |
| 181 | {{{ |
| 182 | # Josko Plazonic 20110314 |
| 183 | case $kernelnewest { |
| 184 | "",$kernelrelease: { |
| 185 | # do nothing, either kernel version facts missing or we are current |
| 186 | } |
| 187 | default: { |
| 188 | # here we go, current kernel not matching running kernel |
| 189 | # the following line excludes processes we do not care about, anything left over will prevent reboot |
| 190 | $cmdtocheck_users = "/bin/ps -auxw | /bin/egrep -v '^(USER|root|postfix|rpc|rpcuser|68|dbus|ntp|rtkit|gdm) | (ssh-agent|-bash|/usr/bin/pulseaudio|/usr/libexec/pulse/gconf-helper|/usr/bin/gnome-keyring-daemon|gnome-session|sshd:|dbus-launch|/bin/dbus-daemon|/usr/bin/seahorse-agent|/usr/libexec/gconfd-2|/usr/libexec/gnome-settings-daemon|seahorse-daemon|metacity|gnome-panel|nautilus|/usr/libexec/bonobo-activation-server|bluetooth-applet|abrt-applet|/usr/share/system-config-printer/applet.py|/usr/libexec/gvfs.*|/usr/libexec/.*notification-daemon|/usr/libexec/wnck-applet|gnome-power-manager|/usr/libexec/trashapplet|/usr/libexec/polkit-gnome-authentication-agent-1|gnome-volume-control-applet|krb5-auth-dialog|/usr/sbin/restorecond|/usr/libexec/im-settings-daemon|gnome-screensaver|/usr/bin/gnote|/usr/libexec/clock-applet|/usr/libexec/notification-area-applet|/usr/libexec/gdm-user-switch-applet|/usr/libexec/gconf-im-settings-daemon|gnome-terminal|gnome-pty-helper|bash|/usr/libexec/gam_server|/opt/google/talkplugin/GoogleTalkPlugin|/usr/libexec/evolution-data-server-2.28|gnome-help)( |$)'" |
| 191 | # Reboot and send an email about it (tweak to your preferences) if safe to do |
| 192 | exec { "ps -auxw | mail -s Auto_rebooting_$hostname root && /sbin/reboot": |
| 193 | path => [ "/sbin", "/bin", "/usr/sbin", "/usr/bin" ], |
| 194 | cwd => "/root", |
| 195 | # the following line will prevent reboot if yum is running or if $cmdtocheck_users finds processes not excluded with above |
| 196 | unless => [ "/usr/bin/pgrep yum >/dev/null", "$cmdtocheck_users > /dev/null" ] |
| 197 | } |
| 198 | # this rule is entirely optional, just reminds root that some machines continue running with old kernels and lists reasons why |
| 199 | exec { "$cmdtocheck_users | mail -s Cannot_reboot_on_$hostname root": |
| 200 | path => [ "/sbin", "/bin", "/usr/sbin", "/usr/bin" ], |
| 201 | cwd => "/root", |
| 202 | onlyif => "$cmdtocheck_users > /dev/null" |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | }}} |