diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2015-06-10 15:35:13 +0200 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2015-06-10 18:37:19 +0200 |
commit | b408390ae9311b7d703ce57c25a78dce23c31b16 (patch) | |
tree | d9b1c795c0ef8b75dbaef709aa8622863d636942 /roles/common | |
parent | a82e3759627a0612592d853796f2a1137f9189f5 (diff) |
Configure munin nodes & master.
Interhost communications are protected by stunnel4. The graphs are only
visible on the master itself, and content is generated by Fast CGI.
Diffstat (limited to 'roles/common')
15 files changed, 1056 insertions, 5 deletions
diff --git a/roles/common/files/etc/logcheck/ignore.d.server/common-local b/roles/common/files/etc/logcheck/ignore.d.server/common-local index 887688a..67e9335 100644 --- a/roles/common/files/etc/logcheck/ignore.d.server/common-local +++ b/roles/common/files/etc/logcheck/ignore.d.server/common-local @@ -31,3 +31,5 @@ ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ansible-([_a-z]+|<stdin>): Invoked with ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ (sympa\((command|distribute)\)|wwsympa|archived|bounced|bulk|task_manager)\[[[:digit:]]+\]: (info|notice)\s ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ wwsympa\[[[:digit:]]+\]: err .* main::check_action_parameters\(\) user not logged in$ +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: (flushing old values|rotating journals|started new journal /\S+$|removing old journal /\S+$) +^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ rrdcached\[[[:digit:]]+\]: queue_thread_main: rrd_update_r \(([^)]+)\) failed with status -1. \(opening '\1': No such file or directory\) diff --git a/roles/common/files/usr/local/share/munin/plugins/dovecot_logins b/roles/common/files/usr/local/share/munin/plugins/dovecot_logins new file mode 100755 index 0000000..09b79d9 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/dovecot_logins @@ -0,0 +1,119 @@ +#!/bin/sh + +# Munin plugin for monitoring Dovecot logins and IMAP throughput. +# Copyright © 2015 Guilhem Moulin <guilhem@fripost.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +PATH=/usr/bin:/bin:/usr/sbin:/sbin + +LOGFILE="/var/log/${logfile:-mail.log}" +STATEFILE="$MUNIN_PLUGSTATE/${0##*/}.offset" + +. $MUNIN_LIBDIR/plugins/plugin.sh +is_multigraph + +case "${1:-}" in + config) cat <<- EOF + multigraph dovecot_login_status + graph_title Dovecot login status + graph_vlabel logins per \${graph_period} + graph_args --base 1000 -l 0 + graph_scale no + graph_period minute + graph_category dovecot + successful.label auth successful + successful.type DERIVE + successful.draw AREA + successful.min 0 + failed.label auth failed + failed.type DERIVE + failed.draw STACK + failed.min 0 + noauth.label no auth attempt + noauth.type DERIVE + noauth.draw STACK + noauth.min 0 + + multigraph dovecot_login_types + graph_title Dovecot login types + graph_vlabel logins per \${graph_period} + graph_args --base 1000 -l 0 + graph_scale no + graph_period minute + graph_category dovecot + imap.label IMAP + imap.type DERIVE + imap.draw AREA + imap.min 0 + pop3.label POP3 + pop3.type DERIVE + pop3.draw STACK + pop3.min 0 + managesieve.label managesieve + managesieve.type DERIVE + managesieve.draw STACK + managesieve.min 0 + + multigraph dovecot_imap_throughput + graph_title Dovecot IMAP throughput + graph_vlabel bytes per \${graph_period} + graph_args --base 1024 -l 0 + graph_scale yes + graph_period minute + graph_category dovecot + read.label read + read.type DERIVE + read.min 0 + written.label written + written.type DERIVE + written.min 0 + EOF + exit 0 + ;; +esac + +if [ ! -f "$LOGFILE" ]; then + for field in successful failed noauth imap pop3 managesieve read written; do + echo $field.value U + done + exit 0; +fi + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +logtail -f"$LOGFILE" -o"$STATEFILE" | sed -nr "s#^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ dovecot: ##p" >"$tmpfile" + +sum() { + awk 'BEGIN{x=0} {x+=$0} END{print x}' +} + +prefix="^(pop3|imap|managesieve)-login" +echo multigraph dovecot_login_status +echo successful.value $(grep -Ec "$prefix: Login: user=<[^>]+>,\s" "$tmpfile") +echo failed.value $(sed -nr "s#$prefix: Aborted login \(auth failed, ([[:digit:]]+) attempts in [[:digit:]]+ secs\): user=<[^>]*>, .*#\2#p" "$tmpfile" | sum) +echo noauth.value $(grep -Ec "$prefix: Aborted login \(no auth attempts in [[:digit:]]+ secs\): user=<>,\s" "$tmpfile") + + +echo multigraph dovecot_login_types +for type in imap pop3 managesieve; do + echo $type.value $(grep -Ec "^$type-login:\s" "$tmpfile") +done + + +regexp="^imap\([-_.@[:alnum:]]+\): .* in=([[:digit:]]+) out=([[:digit:]]+)$" +echo multigraph dovecot_imap_throughput +echo read.value $(sed -nr "s#$regexp#\1#p" "$tmpfile" | sum) +echo written.value $(sed -nr "s#$regexp#\2#p" "$tmpfile" | sum) diff --git a/roles/common/files/usr/local/share/munin/plugins/dovecot_stats_ b/roles/common/files/usr/local/share/munin/plugins/dovecot_stats_ new file mode 100755 index 0000000..7f0f51a --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/dovecot_stats_ @@ -0,0 +1,135 @@ +#!/bin/bash +: <<=cut + +=head1 NAME + +dovecot_stats_ - Munin plugin to display statistics for the dovecot mail server + +=head1 CONFIGURATION + +This plugin must be run with permissions to run "doveadm". That usually means root, but to test, run the following as any user: + + doveadm who + +If you get a permission denied message, check the permissions on the socket mentioned in the error line. + +=head1 MAGIC MARKERS + + #%# family=contrib + #%# capability=autoconf suggest + +=head1 AUTHOR + +Paul Saunders <darac+munin@darac.org.uk> + +=cut + +. $MUNIN_LIBDIR/plugins/plugin.sh +is_multigraph + +if [[ "$1" == "autoconf" ]]; then + if [[ -x /usr/bin/doveadm ]]; then + echo yes + else + echo no + fi + exit 0 +fi + +if [[ "$1" == "suggest" ]]; then + doveadm stats dump domain|awk 'NR!=1 {print $1}' + exit 0 +fi + +domain=$(basename $0) +domain=${domain#dovecot_stats_} + +if [[ -z $domain ]]; then + exit 1 +fi + +if [[ "$1" == "config" ]]; then + cat <<EOF +multigraph dovecot_cpu_${domain//\./_} +graph_title Dovecot CPU Usage for $domain +graph_vlabel Seconds +graph_category dovecot +user_cpu.label User CPU +user_cpu.type DERIVE +user_cpu.min 0 +user_cpu.cdef user_cpu,1000000,/ +sys_cpu.label System CPU +sys_cpu.type DERIVE +sys_cpu.min 0 +sys_cpu.cdef sys_cpu,1000000,/ + +multigraph dovecot_system_${domain//\./_} +graph_title Dovecot System Usage for $domain +graph_category dovecot +min_faults.label Minor page faults +min_faults.type DERIVE +min_faults.min 0 +maj_faults.label Major page faults +maj_faults.type DERIVE +maj_faults.min 0 +vol_cs.label Voluntary context switches +vol_cs.type DERIVE +vol_cs.min 0 +invol_cs.label Involuntary context switches +invol_cs.type DERIVE +invol_cs.min 0 +read_count.label read() syscalls +read_count.type DERIVE +read_count.min 0 +write_count.label write() syscalls +write_count.type DERIVE +write_count.min 0 + +multigraph dovecot_mail_${domain//\./_} +graph_title Dovecot Mail Access for $domain +graph_category dovecot +num_logins.label Logins +num_logins.type DERIVE +num_logins.min 0 +num_cmds.label Commands +num_cmds.type DERIVE +num_cmds.min 0 +mail_lookup_path.label Path Lookups +mail_lookup_path.type DERIVE +mail_lookup_path.min 0 +mail_lookup_attr.label Attr lookups +mail_lookup_attr.type DERIVE +mail_lookup_attr.min 0 +mail_read_count.label Messages read +mail_read_count.type DERIVE +mail_read_count.min 0 +mail_cache_hits.label Cache hits +mail_cache_hits.type DERIVE +mail_cache_hits.min 0 +EOF + exit 0 +fi + +# Fetch data +# Gawk script cadged from http://awk.info/?JanisP +doveadm stats dump domain domain=$domain | gawk -F\\t -v cols="user_cpu sys_cpu min_faults maj_faults vol_cs invol_cs read_count write_count num_logins num_cmds mail_lookup_path mail_lookup_attr mail_read_count mail_cache_hits " -v domain=${domain//\./_} ' + BEGIN { + n=split(cols,col," ") + for (i=1; i<=n; i++) s[col[i]]=i + } + NR==1 { + for (f=1;f<=NF; f++) + if ($f in s) c[s[$f]]=f + next + } + { for (f=1; f<=n; f++) { + if (col[f] == "user_cpu") printf ("\nmultigraph dovecot_cpu_%s\n", domain) + if (col[f] == "min_faults") printf ("\nmultigraph dovecot_system_%s\n", domain) + if (col[f] == "num_logins") printf ("\nmultigraph dovecot_mail_%s\n", domain) + if (col[f] == "user_cpu" || col[f] == "sys_cpu") + printf("%s.value %d\n",col[f],$c[f] * 1000000) + else + printf("%s.value %d\n",col[f],$c[f]) + } + } +' diff --git a/roles/common/files/usr/local/share/munin/plugins/dovecot_who b/roles/common/files/usr/local/share/munin/plugins/dovecot_who new file mode 100755 index 0000000..fe3c743 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/dovecot_who @@ -0,0 +1,43 @@ +#!/bin/sh + +# Munin plugin for monitoring Dovecot IMAP connections and unique users. +# Copyright © 2015 Guilhem Moulin <guilhem@fripost.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +PATH=/usr/bin:/bin:/usr/sbin:/sbin +set -u + +case "${1:-}" in + config) cat <<- EOF + graph_title Dovecot concurrent IMAP usage + graph_args --base 1000 -l 0 + graph_scale no + graph_category dovecot + connections.label connections + connections.min 0 + users.label unique users + users.min 0 + EOF + exit 0 + ;; +esac + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +doveadm -f flow who -1 | sed -nr 's/^username=(\S+)\s+proto=imap\s.*/\1/p' >"$tmpfile" + +echo connections.value $(wc -l <"$tmpfile") +echo users.value $(sort -u "$tmpfile" | wc -l) diff --git a/roles/common/files/usr/local/share/munin/plugins/postfix_mailqueue_ b/roles/common/files/usr/local/share/munin/plugins/postfix_mailqueue_ new file mode 100755 index 0000000..31b6269 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/postfix_mailqueue_ @@ -0,0 +1,57 @@ +#!/bin/sh + +# Munin plugin for monitoring the Postfix mail queue in multi-instance +# systems. Symlink/rename to 'postfix_mailqueue_$SPOOLDIR'. +# Copyright © 2015 Guilhem Moulin <guilhem@fripost.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +PATH=/usr/bin:/bin:/usr/sbin:/sbin + +name="${0##*/}" +[ "${name#postfix_mailqueue_}" != "$name" ] && postfix="${name#postfix_mailqueue_}" || postfix= +SPOOLDIR="/var/spool/${postfix:-postfix}" + +. $MUNIN_LIBDIR/plugins/plugin.sh + +case "${1:-}" in + config) cat <<- EOF + graph_title Postfix mailqueue ($([ -n "$postfix" -a "$postfix" != postfix ] && echo "'${postfix#postfix-}'" || echo default) instance) + graph_vlabel Mails in queue + graph_args --base 1000 -l 0 + graph_scale no + graph_category postfix + graph_total Total + active.label active + deferred.label deferred + maildrop.label maildrop + incoming.label incoming + corrupt.label corrupt + hold.label held + EOF + for field in active deferred maildrop incoming corrupt hold; do + print_warning "$field" + print_critical "$field" + done + exit 0 + ;; +esac + +for field in active deferred maildrop incoming corrupt hold; do + if [ -d "$SPOOLDIR/$field" ]; then + echo $field.value $(find "$SPOOLDIR/$field" -type f | wc -l) + else + echo $field.value U + fi +done diff --git a/roles/common/files/usr/local/share/munin/plugins/postfix_mailvolume2 b/roles/common/files/usr/local/share/munin/plugins/postfix_mailvolume2 new file mode 100755 index 0000000..d16d88e --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/postfix_mailvolume2 @@ -0,0 +1,62 @@ +#!/bin/sh + +# Munin plugin for monitoring Postfix per-instance mail throughput. +# Copyright © 2015 Guilhem Moulin <guilhem@fripost.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +PATH=/usr/bin:/bin:/usr/sbin:/sbin +set -u + +LOGFILE="/var/log/${logfile:-mail.log}" +STATEFILE="$MUNIN_PLUGSTATE/${0##*/}.offset" + +case "${1:-}" in + config) cat <<- EOF + graph_title Postfix per-instance bytes throughput + graph_vlabel bytes per \${graph_period} + graph_args --base 1024 -l 0 + graph_scale yes + graph_period minute + graph_category postfix + EOF + if [ $(echo "${postmulti:-postfix}" | wc -w) -gt 1 ]; then + echo graph_total total throughput + fi + for postfix in ${postmulti:-postfix}; do + echo "${postfix}_volume.label" "$postfix throughput" + echo "${postfix}_volume.type" DERIVE + echo "${postfix}_volume.min" 0 + done + exit 0 + ;; +esac + +if [ ! -f "$LOGFILE" ]; then + for postfix in ${postmulti:-postfix}; do + echo "${postfix}_volume.value U" + done + exit 0; +fi + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +logtail -f"$LOGFILE" -o"$STATEFILE" >"$tmpfile" + +for postfix in ${postmulti:-postfix}; do + echo -n "${postfix}_volume.value " + sed -nr "s#^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ $postfix/qmgr\[[[:digit:]]+\]: [[:xdigit:]]+: from=<[^>]*>, size=([[:digit:]]+), nrcpt=[[:digit:]]+ \(queue active\)\$#\1#p" "$tmpfile" \ + | awk 'BEGIN{x=0} {x+=$0} END{print x}' +done diff --git a/roles/common/files/usr/local/share/munin/plugins/postfix_sasl_ b/roles/common/files/usr/local/share/munin/plugins/postfix_sasl_ new file mode 100755 index 0000000..8dc1219 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/postfix_sasl_ @@ -0,0 +1,63 @@ +#!/bin/sh + +# Munin plugin for monitoring Postfix SASL logins. Symlink/rename to +# 'postfix_sasl_$SYSLOGNAME'. +# Copyright © 2015 Guilhem Moulin <guilhem@fripost.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +PATH=/usr/bin:/bin:/usr/sbin:/sbin +set -u + +LOGFILE="/var/log/${logfile:-mail.log}" +STATEFILE="$MUNIN_PLUGSTATE/${0##*/}.offset" + +name="${0##*/}" +[ "${name#postfix_sasl_}" != "$name" ] && postfix="${name#postfix_sasl_}" || postfix= + +case "${1:-}" in + config) cat <<- EOF + graph_title Postfix SASL ($([ -n "$postfix" -a "$postfix" != postfix ] && echo "'${postfix#postfix-}'" || echo default) instance) + graph_vlabel logins per \${graph_period} + graph_args --base 1000 -l 0 + graph_scale no + graph_period minute + graph_category postfix + successful.label successful + successful.type DERIVE + successful.draw AREA + successful.min 0 + failed.label failed + failed.type DERIVE + failed.draw STACK + failed.min 0 + EOF + exit 0 + ;; +esac + +if [ ! -f "$LOGFILE" ]; then + for postfix in ${postmulti:-postfix}; do + echo "${postfix}_volume.value U" + done + exit 0; +fi + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +logtail -f"$LOGFILE" -o"$STATEFILE" | sed -nr "s#^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ $postfix/smtpd\[[[:digit:]]+\]: ##p" >"$tmpfile" + +echo successful.value $(grep -Ec "^warning: [-._[:alnum:]]+\[[.[:digit:]]+\]: SASL \S+ authentication failed(:.*)?$" "$tmpfile") +echo failed.value $(grep -Ec "^[[:xdigit:]]{10}: client=\S+, sasl_method=\S+, sasl_username=" "$tmpfile") diff --git a/roles/common/files/usr/local/share/munin/plugins/postfix_stats_ b/roles/common/files/usr/local/share/munin/plugins/postfix_stats_ new file mode 100755 index 0000000..5678870 --- /dev/null +++ b/roles/common/files/usr/local/share/munin/plugins/postfix_stats_ @@ -0,0 +1,113 @@ +#!/bin/sh + +# Munin plugin for monitoring Postfix per-service and per-instance +# usage. Symlink/rename to 'postfix_sasl_$SERVICE_$SYSLOGNAME'. +# Copyright © 2015 Guilhem Moulin <guilhem@fripost.org> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +PATH=/usr/bin:/bin:/usr/sbin:/sbin +set -u + +LOGFILE="/var/log/${logfile:-mail.log}" +STATEFILE="$MUNIN_PLUGSTATE/${0##*/}.offset" + +name="${0##*/}" +name="${name#postfix_stats_}" + +if [ "${name#postscreen_}" != "$name" ]; then + postfix="${name#postscreen_}" + service=postscreen + fields='connected accepted passed' +elif [ "${name#smtpd_}" != "$name" ]; then + postfix="${name#smtpd_}" + service=smtpd + fields='connected accepted queued' +elif [ "${name#qmgr_}" != "$name" ]; then + postfix="${name#qmgr_}" + service=qmgr + fields='queued' +elif [ "${name#smtp_}" != "$name" ]; then + postfix="${name#smtp_}" + service=smtp + fields='sent deliverable deferred undeliverable bounced' +elif [ "${name#lmtp_}" != "$name" ]; then + postfix="${name#lmtp_}" + service=lmtp + fields='sent deliverable deferred undeliverable bounced' +elif [ "${name#pipe_}" != "$name" ]; then + postfix="${name#pipe_}" + service=pipe + fields='sent deliverable deferred undeliverable bounced' +fi + +case "${1:-}" in + config) cat <<- EOF + graph_title Postfix $service message throughput ($([ -n "$postfix" -a "$postfix" != postfix ] && echo "'${postfix#postfix-}'" || echo default) instance) + graph_vlabel mails per \${graph_period} + graph_args --base 1000 -l 0 + graph_scale no + graph_period minute + graph_category postfix + EOF + for field in $fields; do + echo "$field.label $field" + echo "$field.type DERIVE" + echo "$field.draw AREA" + echo "$field.min 0" + done + exit 0 + ;; +esac + +if [ ! -f "$LOGFILE" ]; then + for field in $fields; do + echo "$field.value U" + done + exit 0; +fi + +tmpfile="$(mktemp --tmpdir)" +trap 'rm -f "$tmpfile"' EXIT + +logtail -f"$LOGFILE" -o"$STATEFILE" | sed -nr "s#^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ $postfix/$service\[[[:digit:]]+\]: ##p" >"$tmpfile" + +case "$service" in + postscreen) + connected=$(grep -Ec "^CONNECT from\s" "$tmpfile") + rejected=$( grep -Ec "^NOQUEUE: reject:\s" "$tmpfile") + passed=$( grep -Ec "^(PASS (OLD|NEW)|WHITELISTED)\s" "$tmpfile") + echo connected.value $connected + echo accepted.value $(($rejected + $passed)) + echo passed.value $passed + ;; + smtpd) + connected=$(grep -Ec "^connect from\s" "$tmpfile") + rejected=$( grep -Ec "^NOQUEUE: reject:\s" "$tmpfile") + queued=$( grep -Ec "^[[:xdigit:]]+: client=" "$tmpfile") + echo connected.value $connected + echo accepted.value $(($rejected + $queued)) + echo queued.value $queued + ;; + qmgr) + queued=$(grep -Ec "^[[:xdigit:]]+: from=<\S+>, .*\(queue active\)$" "$tmpfile") + echo queued.value $queued + ;; + smtp|lmtp|pipe) + for field in $fields; do + v=$(grep -Ec "^[[:xdigit:]]+:( [^ =]+=\S+,)+ status=$field(\s.*)?$" "$tmpfile") + echo $field.value $v + done + ;; +esac diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml index b7ecaab..3dbbf90 100644 --- a/roles/common/handlers/main.yml +++ b/roles/common/handlers/main.yml @@ -46,3 +46,6 @@ - name: Update certificate command: update-ca-certificates + +- name: Restart munin-node + service: name=munin-node state=restarted diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 477bd34..df609d3 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -27,10 +27,11 @@ - name: Generate DH parameters command: gendhparam.sh /etc/ssl/private/dhparams.pem creates=/etc/ssl/private/dhparams.pem tags: genkey -- include: logging.yml tags=logging -- include: ntp.yml tags=ntp -- include: mail.yml tags=mail,postfix -- include: bacula.yml tags=bacula-fd,bacula +- include: logging.yml tags=logging +- include: ntp.yml tags=ntp +- include: mail.yml tags=mail,postfix +- include: bacula.yml tags=bacula-fd,bacula +- include: munin-node.yml tags=munin-node,munin - name: Install common packages apt: pkg={{ item }} diff --git a/roles/common/tasks/munin-node.yml b/roles/common/tasks/munin-node.yml new file mode 100644 index 0000000..9e5d8f4 --- /dev/null +++ b/roles/common/tasks/munin-node.yml @@ -0,0 +1,207 @@ +- name: Install munin-node + apt: pkg={{ item }} + with_items: + - munin-node + - munin-plugins-extra + ### + - acpi + - lm-sensors + - ethtool + - hdparm + - libwww-perl + - libxml-simple-perl + - logtail + +- name: Create directory /usr/local/share/munin/plugins + file: path=/usr/local/share/munin/plugins + state=directory + owner=root group=root + mode=0755 + +- name: Copy our own Munin plugins + copy: src={{ item }} + dest=/usr/local/share/munin/plugins/ + owner=root group=root + mode=0755 + with_fileglob: + - usr/local/share/munin/plugins/* + +- name: Configure munin-node + template: src=etc/munin/{{ item }}.j2 + dest=/etc/munin/{{ item }} + owner=root group=root + mode=0644 + register: r1 + with_items: + - munin-node.conf + - plugin-conf.d/munin-node + notify: + - Restart munin-node + +- name: Install Munin plugins + file: src=/usr/share/munin/plugins/{{ item }} + dest=/etc/munin/plugins/{{ item }} + owner=root group=root + state=link force=yes + register: r2 + with_items: + - cpu + - df + - df_inode + - diskstats + - entropy + - fail2ban + - forks + - fw_conntrack + - fw_forwarded_local + - fw_packets + - hddtemp_smartctl + - interrupts + - irqstats + - load + - memory + - netstat + - ntp_kernel_err + - ntp_kernel_pll_freq + - ntp_kernel_pll_off + - ntp_offset + - open_files + - open_inodes + - processes + - proc_pri + - swap + - threads + - uptime + - users + - vmstat + notify: + - Restart munin-node + +- name: Delete Munin plugins + file: path=/etc/munin/plugins/{{ item }} + state=absent + register: r3 + with_items: + - http_loadtime + - ip_255.255.255.255 + - postfix_mailqueue + - postfix_mailvolume + notify: + - Restart munin-node + +- name: Install 'if_' Munin wildcard plugin + file: src=/usr/share/munin/plugins/{{ item.0 }}_ + dest=/etc/munin/plugins/{{ item.0 }}_{{ item.1 }} + owner=root group=root + state=link force=yes + register: r4 + with_nested: + - [ if, if_err ] + - [ lo, "{{ ansible_default_ipv4.interface }}" ] + notify: + - Restart munin-node + +- name: Install 'postfix_mailvolume2' Munin plugin + file: src=/usr/local/share/munin/plugins/postfix_mailvolume2 + dest=/etc/munin/plugins/postfix_mailvolume2 + owner=root group=root + state=link force=yes + register: r5 + notify: + - Restart munin-node + +- name: Install 'postfix_mailqueue_' Munin wildcard plugin + file: src=/usr/local/share/munin/plugins/postfix_mailqueue_ + dest=/etc/munin/plugins/postfix_mailqueue_postfix + owner=root group=root + state=link force=yes + register: r6 + notify: + - Restart munin-node + +- name: Install 'postfix_stats_' Munin wildcard plugin + file: src=/usr/local/share/munin/plugins/postfix_stats_ + dest=/etc/munin/plugins/postfix_stats_{{ item }}_postfix + owner=root group=root + state=link force=yes + register: r7 + with_items: + - smtpd + - qmgr + - smtp + notify: + - Restart munin-node + +- name: Start munin-node + service: name=munin-node state=started + when: not (r1.changed or r2.changed or r3.changed or r4.changed or r5.changed or r6.changed or r7.changed) + +- meta: flush_handlers + + + +- name: Install stunnel + apt: pkg=stunnel4 + +- name: Auto-enable stunnel + lineinfile: dest=/etc/default/stunnel4 + regexp='^(\s*#)?\s*ENABLED=' + line='ENABLED=1' + owner=root group=root + mode=0644 + +- name: Create /etc/stunnel/certs + file: path=/etc/stunnel/certs + state=directory + owner=root group=root + mode=0755 + +- name: Generate a private key and a X.509 certificate for munin-node + command: genkeypair.sh x509 + --pubkey=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.pem + --privkey=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.key + --ou=Munin --cn={{ inventory_hostname }} --dns={{ inventory_hostname }} + -t rsa -b 4096 -h sha512 + register: r1 + changed_when: r1.rc == 0 + failed_when: r1.rc > 1 + notify: + - Restart stunnel + tags: + - genkey + +- name: Fetch Munin X.509 certificate + # Ensure we don't fetch private data + sudo: False + fetch: src=/etc/stunnel/certs/munin-{{ inventory_hostname_short }}.pem + dest=certs/munin/{{ inventory_hostname }}.pem + fail_on_missing=yes + flat=yes + tags: + - genkey + +- name: Copy munin-master X.509 certificates + assemble: src=certs/munin regexp="{{ groups['munin-master'] | join('|') }}\.pem$" remote_src=no + dest=/etc/stunnel/certs/munin-master.pem + owner=root group=root + mode=0644 + register: r2 + when: "'munin-master' not in group_names" + notify: + - Restart stunnel + +- name: Configure stunnel + template: src=etc/stunnel/munin-node.conf.j2 + dest=/etc/stunnel/munin-node.conf + owner=root group=root + mode=0644 + register: r3 + when: "'munin-master' not in group_names" + notify: + - Restart stunnel + +- name: Start stunnel + service: name=stunnel4 pattern=/usr/bin/stunnel4 state=started + when: not (r1.changed or r2.changed or r3.changed) + +- meta: flush_handlers diff --git a/roles/common/templates/etc/iptables/services.j2 b/roles/common/templates/etc/iptables/services.j2 index a0bb714..8792771 100644 --- a/roles/common/templates/etc/iptables/services.j2 +++ b/roles/common/templates/etc/iptables/services.j2 @@ -69,7 +69,12 @@ in tcp 9103 # BACULA-SD {% elif groups['bacula-sd'] | difference([inventory_hostname]) %} out tcp 9103 # BACULA-SD {% endif %} - +{% if 'munin-master' in group_names and groups.all | difference([inventory_hostname]) %} +out tcp 4949 # MUNIN +{% endif %} +{% if groups['munin-master'] | difference([inventory_hostname]) %} +in tcp 4949 # MUNIN +{% endif %} {% if 'LDAP-provider' in group_names %} out tcp 11371 # HKP out tcp 43 # WHOIS diff --git a/roles/common/templates/etc/munin/munin-node.conf.j2 b/roles/common/templates/etc/munin/munin-node.conf.j2 new file mode 100644 index 0000000..de4098a --- /dev/null +++ b/roles/common/templates/etc/munin/munin-node.conf.j2 @@ -0,0 +1,51 @@ +# +# Example config-file for munin-node +# + +log_level 4 +log_file /var/log/munin/munin-node.log +pid_file /var/run/munin/munin-node.pid + +background 1 +setsid 1 + +user root +group root + +# This is the timeout for the whole transaction. +# Units are in sec. Default is 15 min +# +# global_timeout 900 + +# This is the timeout for each plugin. +# Units are in sec. Default is 1 min +# +# timeout 60 + +# Regexps for files to ignore +ignore_file [\#~]$ +ignore_file DEADJOE$ +ignore_file \.bak$ +ignore_file %$ +ignore_file \.dpkg-(tmp|new|old|dist)$ +ignore_file \.rpm(save|new)$ +ignore_file \.pod$ + +# Set this if the client doesn't report the correct hostname when +# telnetting to localhost, port 4949 +# +host_name {{ inventory_hostname_short }} + +# A list of addresses that are allowed to connect. This must be a +# regular expression, since Net::Server does not understand CIDR-style +# network notation unless the perl module Net::CIDR is installed. You +# may repeat the allow line as many times as you'd like + +allow ^127\.0\.0\.1$ +allow ^::1$ + +# Which address to bind to; +host 127.0.0.1 + +# And which port +port 4994 diff --git a/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2 b/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2 new file mode 100644 index 0000000..fa05327 --- /dev/null +++ b/roles/common/templates/etc/munin/plugin-conf.d/munin-node.j2 @@ -0,0 +1,137 @@ +# This file is used to configure how the plugins are invoked. +# Place in /etc/munin/plugin-conf.d/ or corresponding directory. +# +# PLEASE NOTE: Changes in the plugin-conf.d directory are only +# read at munin-node startup, so restart at any changes. +# +# user <user> # Set the user to run the plugin as. +# group <group> # Set the group to run the plugin as. +# command <command> # Run <command> instead of the plugin. %c expands to +# what would normally be run. +# env.<variable> <value> # Sets <variable> in the plugin's environment, see the +# individual plugins to find out which variables they +# care about. + + +[amavis] +group adm +env.MUNIN_MKTEMP /bin/mktemp -p /tmp/ $1 +env.amavislog /var/log/mail.info + +[apt] +user root + +[courier_mta_mailqueue] +group daemon + +[courier_mta_mailstats] +group adm + +[courier_mta_mailvolume] +group adm + +[cps*] +user root + +[df*] +env.warning 92 +env.critical 98 + +[exim_mailqueue] +group adm, (Debian-exim) + +[exim_mailstats] +group adm, (Debian-exim) +env.logdir /var/log/exim4/ +env.logname mainlog + +[fw_conntrack] +user root + +[fw_forwarded_local] +user root + +[hddtemp_smartctl] +user root + +[hddtemp2] +user root + +[if_*] +user root + +[if_err_*] +user nobody + +[ip_*] +user root + +[ipmi_*] +user root + +[mysql*] +user root +env.mysqlopts --defaults-file=/etc/mysql/debian.cnf +env.mysqluser debian-sys-maint +env.mysqlconnection DBI:mysql:mysql;mysql_read_default_file=/etc/mysql/debian.cnf + +[postfix_mailqueue_*] +user postfix + +[postfix_stats_*] +group adm + +[postfix_sasl_*] +group adm + +[postfix_mailvolume2] +group adm +env.postmulti postfix{% for g in postfix_instance.keys() | sort %}{% if g in group_names %} postfix-{{ postfix_instance[g].name }}{% endif %}{% endfor %} + + +[dovecot_logins] +group adm + +[dovecot_stats_*] +user root + +[dovecot_who] +user root + +[sendmail_*] +user smmta + +[smart_*] +user root + +[vlan*] +user root + +[ejabberd*] +user ejabberd +env.statuses available away chat xa +env.days 1 7 30 + +[dhcpd3] +user root +env.leasefile /var/lib/dhcp3/dhcpd.leases +env.configfile /etc/dhcp3/dhcpd.conf + +[jmx_*] +env.ip 127.0.0.1 +env.port 5400 + +[samba] +user root + +[munin_stats] +user munin +group munin + +[postgres_*] +user postgres +env.PGUSER postgres +env.PGPORT 5432 + +[fail2ban] +user root diff --git a/roles/common/templates/etc/stunnel/munin-node.conf.j2 b/roles/common/templates/etc/stunnel/munin-node.conf.j2 new file mode 100644 index 0000000..de6c156 --- /dev/null +++ b/roles/common/templates/etc/stunnel/munin-node.conf.j2 @@ -0,0 +1,53 @@ +; ************************************************************************** +; * Global options * +; ************************************************************************** + +; setuid()/setgid() to the specified user/group in daemon mode +setuid = stunnel4 +setgid = stunnel4 + +; PID is created inside the chroot jail +pid = /var/run/stunnel4/munin-node.pid + +; Only log messages at severity warning (4) and higher +debug = 4 + +; ************************************************************************** +; * Service defaults may also be specified in individual service sections * +; ************************************************************************** + +; Certificate/key is needed in server mode and optional in client mode +cert = /etc/stunnel/certs/munin-{{ inventory_hostname_short }}.pem +key = /etc/stunnel/certs/munin-{{ inventory_hostname_short }}.key + +; Some performance tunings +socket = l:TCP_NODELAY=1 +socket = r:TCP_NODELAY=1 + +; Prevent MITM attacks +verify = 4 + +; Disable support for insecure protocols +options = NO_SSLv2 +options = NO_SSLv3 +options = NO_TLSv1 +options = NO_TLSv1.1 + +; These options provide additional security at some performance degradation +options = SINGLE_ECDH_USE +options = SINGLE_DH_USE + +; Select permitted SSL ciphers +ciphers = EECDH+AES:EDH+AES:!MEDIUM:!LOW:!EXP:!aNULL:!eNULL:!SSLv2:!SSLv3:!TLSv1:!TLSv1.1 + +; ************************************************************************** +; * Service definitions (remove all services for inetd mode) * +; ************************************************************************** + +[munin-node] +client = no +accept = 4949 +connect = 127.0.0.1:4994 +CAfile = /etc/stunnel/certs/munin-master.pem + +; vim:ft=dosini |