Update icinga2_server role

This commit is contained in:
Nemo 2020-10-03 14:19:22 +02:00
parent 36eb8aa939
commit c10b6ab95c
16 changed files with 1728 additions and 2 deletions

View File

@ -74,6 +74,7 @@ icinga2_server_api_users:
icinga2_server_icingaweb2_main_user: john
icinga2_server_icingaweb2_main_user_password: needToBeChanged
icinga2_server_icingaweb2_main_user_email: "needToBeChange@example.org"
icinga2_server_apache2_service: apache2
icinga2_server_apache2_default_index: "/var/www/html/index.html"
icinga2_server_apache2_user: "www-data"
@ -86,3 +87,7 @@ icinga2_server_apache2_modules_to_disable:
- negociation
icinga2_server_icingaweb2_main_user_password_hash_manual: needToBeChanged
icinga2_server_ticket_salt: ""
icinga2_server_custom_hostgroup: wirebrass
icinga2_server_nagios_plugins_location: "/usr/lib/nagios/plugins/"

View File

@ -0,0 +1,440 @@
#!/usr/bin/env python3
# Copyright (C) 2014-2016 Felix Geyer <debfx@fobos.de>
#
# 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 2 or (at your option)
# version 3 of the License.
#
# 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/>.
import argparse
import datetime
import dns.exception
import dns.flags
import dns.rdatatype
import dns.rdtypes.ANY.TLSA
import dns.resolver
import hashlib
import re
import socket
import struct
import ssl
import subprocess
import sys
VERSION = "1.1"
class ProtocolError(Exception):
pass
def nagios_ok(msg: str) -> None:
print("DANE OK - " + msg)
sys.exit(0)
def nagios_warning(msg: str) -> None:
print("DANE WARNING - " + msg)
sys.exit(1)
def nagios_critical(msg: str) -> None:
print("DANE CRITICAL - " + msg)
sys.exit(2)
def nagios_unknown(msg: str) -> None:
print("DANE UNKONWN - " + msg)
sys.exit(3)
def create_resolver(dnssec: bool = True,
timeout: int = None,
nameserver: str = None) -> dns.resolver.Resolver:
resolver = dns.resolver.Resolver()
if timeout and timeout != 0:
resolver.lifetime = timeout
if nameserver:
resolver.nameservers = [nameserver]
if dnssec:
resolver.edns = 0
resolver.payload = 1280
resolver.ednsflags = dns.flags.DO
return resolver
def check_dns_response_auth(response: dns.resolver.Answer) -> bool:
if response.response.flags & dns.flags.AD:
return True
else:
return False
def extract_pubkey(cert_binary: bytes) -> bytes:
# should really be done with a python 3 module that exposes this openssl api
# extract public key in pem format
pubkey_pem = subprocess.check_output(["openssl", "x509", "-pubkey", "-inform", "der", "-noout"], input=cert_binary)
# conver to binary / der format
pubkey_binary = subprocess.check_output(["openssl", "pkey", "-pubin", "-outform", "der"], input=pubkey_pem)
return pubkey_binary
def get_tlsa_records(args: argparse.Namespace) -> dns.resolver.Answer:
resolver = create_resolver(dnssec=args.dnssec, timeout=args.timeout, nameserver=args.nameserver)
tlsa_domain = "_{}._tcp.{}".format(args.port, args.host)
try:
tlsa_records = resolver.query(tlsa_domain, dns.rdatatype.TLSA)
except dns.resolver.NXDOMAIN:
nagios_critical("No DNS TLSA record found: {}".format(tlsa_domain))
except dns.exception.Timeout:
nagios_unknown("DNS query timeout: {}".format(tlsa_domain))
if args.dnssec and not check_dns_response_auth(tlsa_records):
nagios_unknown("DNS query not DNSSEC validated")
return tlsa_records
def validate_dane(cert_binary: bytes,
pkix_valid: bool,
tlsa_record: dns.rdtypes.ANY.TLSA.TLSA) -> bool:
if tlsa_record.usage == 3:
pass
elif tlsa_record.usage == 1 and pkix_valid:
pass
else:
# usage=2 unsupported
return False
if tlsa_record.selector == 0:
data = cert_binary
elif tlsa_record.selector == 1:
data = extract_pubkey(cert_binary)
else:
return False
if tlsa_record.mtype == 0:
hashed = data
elif tlsa_record.mtype == 1:
hashed = hashlib.sha256(data).digest()
elif tlsa_record.mtype == 2:
hashed = hashlib.sha512(data).digest()
else:
return False
return hashed == tlsa_record.cert
def check_cert_expiry(args: argparse.Namespace,
cert: dict,
days_warning: int,
days_critical: int = None) -> datetime.timedelta:
not_after = datetime.datetime.strptime(cert["notAfter"], "%b %d %H:%M:%S %Y %Z")
date_diff = not_after - datetime.datetime.now()
if days_critical:
if date_diff <= datetime.timedelta(days_critical):
nagios_critical("{}:{} cert expires in {} days".format(args.host, args.port, date_diff.days))
if date_diff <= datetime.timedelta(days_warning):
nagios_warning("{}:{} cert expires in {} days".format(args.host, args.port, date_diff.days))
return date_diff
def connect_to_host(connect_host: str,
connect_port: int,
args: argparse.Namespace,
check_cert: bool) -> ssl.SSLSocket:
if args.timeout == 0:
socket.setdefaulttimeout(None)
else:
socket.setdefaulttimeout(args.timeout)
context = ssl.create_default_context()
if not check_cert:
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
# TODO: use our resolver
try:
sock = socket.create_connection((connect_host, connect_port))
except OSError as e:
nagios_unknown("Can't establish a connection to {}:{}:\n{}"
.format(connect_host, connect_port, str(e)))
peername = sock.getpeername()[0]
if ":" in peername:
peername = "[{}]".format(peername)
try:
if args.starttls == "smtp":
connect_smtp(sock)
elif args.starttls == "ftp":
connect_ftp(sock)
elif args.starttls == "imap":
connect_imap(sock)
elif args.starttls == "xmpp":
connect_xmpp(sock, args.host)
elif args.starttls == "quassel":
connect_quassel(sock, args.host)
except (ProtocolError, OSError) as e:
nagios_unknown("Failed to initiate STARTTLS to {} ({}:{}):\n{}"
.format(connect_host, peername, connect_port, str(e)))
try:
return context.wrap_socket(sock, server_hostname=args.host)
except (ProtocolError, ssl.SSLError, OSError) as e:
if isinstance(e, ssl.SSLError) and e.reason == "CERTIFICATE_VERIFY_FAILED":
# pass exceptions concerning certificate validation to the caller
raise
else:
nagios_unknown("Can't establish a TLS connection to {} ({}:{}):\n{}"
.format(connect_host, peername, connect_port, str(e)))
def smtp_read_response(sock: socket.socket) -> str:
response = ""
line_end = False
while not line_end:
line = sock.recv(1024)
response += line.decode("ASCII")
if len(line) < 4 or line[3] != "-":
line_end = True
return response
def connect_smtp(sock: socket.socket) -> None:
smtp_read_response(sock)
sock.sendall(b"EHLO openssl.client.net\r\n")
response = smtp_read_response(sock)
if "STARTTLS" not in response:
raise ProtocolError("Server doesn't support STARTTLS")
sock.sendall(b"STARTTLS\r\n")
smtp_read_response(sock)
def connect_ftp(sock: socket.socket) -> None:
buf = sock.recv(1024)
sock.sendall(b"AUTH TLS\r\n")
response = sock.recv(1024).decode("ASCII").strip("\r\n\t ")
if not re.search(r"^2\d\d", response):
raise ProtocolError("Server doesn't support STARTTLS ({})".format(response))
def connect_imap(sock: socket.socket) -> None:
sock.recv(1024)
sock.sendall(b". CAPABILITY\n")
response = smtp_read_response(sock)
if "STARTTLS" not in response:
raise ProtocolError("Server doesn't support STARTTLS")
sock.sendall(b". STARTTLS\n")
smtp_read_response(sock)
def connect_xmpp(sock: socket.socket, host: str) -> None:
sock.sendall("<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
"xmlns='jabber:client' to='{}' version='1.0'>".format(host).encode("ASCII"))
buf = sock.recv(1024)
if "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'" not in buf.decode("ASCII"):
raise ProtocolError("Server doesn't support STARTTLS")
sock.sendall(b"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>")
buf = sock.recv(1024)
if "<proceed" not in buf.decode("ASCII"):
raise ProtocolError("Server doesn't support STARTTLS")
def connect_quassel(sock: socket.socket, host: str) -> None:
MAGIC = 0x42b33f00
FEATURE_ENCRYPTION = 0x1
PROTOCOL_DATAGRAM = 0x2
PROTOCOL_END = (0x1 << 31)
sock.sendall(struct.pack("!I", MAGIC | FEATURE_ENCRYPTION))
sock.sendall(struct.pack("!I", PROTOCOL_DATAGRAM | PROTOCOL_END))
try:
response = struct.unpack("!I", sock.recv(4))[0]
except struct.error:
raise ProtocolError("No valid response from server")
protocol_type = (response & 0xff)
connection_features = (response >> 24)
if not (protocol_type & PROTOCOL_DATAGRAM):
raise ProtocolError("Server doesn't support the protocol")
if not (connection_features & FEATURE_ENCRYPTION):
raise ProtocolError("Server doesn't support TLS")
def main() -> None:
parser = argparse.ArgumentParser(description=""" Nagios/Icinga plugin for checking DANE/TLSA records.
It compares the DANE/TLSA record against the TLS certificate provided
by a service.""")
parser.add_argument("--host", "-H", dest="host", required=True, help="Hostname to check.")
parser.add_argument("--port", "-p", type=int, required=True, help="TCP port to check.")
parser.add_argument("--connect-host", "--ip", "-I", dest="connect_host",
help="Connect to this host instead of --host.")
parser.add_argument("--connect-port", dest="connect_port", help="Connect to this port instead of --port.")
parser.add_argument("--starttls",
choices=["smtp", "ftp", "imap", "xmpp", "quassel"],
help="Send the protocol-specific messages to enable TLS.")
parser = argparse.ArgumentParser(description=""" Nagios/Icinga plugin for checking DANE/TLSA records.
It compares the DANE/TLSA record against the TLS certificate provided
by a service.""")
parser.add_argument("--host", "-H", dest="host", required=True, help="Hostname to check.")
parser.add_argument("--port", "-p", type=int, required=True, help="TCP port to check.")
parser.add_argument("--connect-host", "--ip", "-I", dest="connect_host",
help="Connect to this host instead of --host.")
parser.add_argument("--connect-port", dest="connect_port", help="Connect to this port instead of --port.")
parser.add_argument("--starttls",
choices=["smtp", "ftp", "imap", "xmpp", "quassel"],
help="Send the protocol-specific messages to enable TLS.")
parser.add_argument("--check-pkix", action="store_true",
help="Additionally perform traditional checks on the certificate "
"(ca trust path, hostname, expiry).")
parser.add_argument("--min-days-valid", help="Minimum number of days a certificate has to be valid. "
"Format: INTEGER[,INTEGER]. "
"1st is #days for warning, 2nd is critical.")
parser.add_argument("--no-dnssec", dest="dnssec", action="store_false",
help="Continue even when DNS replies aren't DNSSEC authenticated.")
parser.add_argument("--nameserver", help="Use a custom nameserver.")
parser.add_argument("--timeout", type=int, default=10, help="Network timeout in sec. Default: 10")
parser.add_argument("--version", action="version", version="%(prog)s " + VERSION)
args = parser.parse_args()
pyver = sys.version_info
if pyver[0] < 3 or (pyver[0] == 3 and pyver[1] < 4):
nagios_unknown("check_dane requires Python >= 3.4")
if args.port < 1 or args.port > 65535:
nagios_unknown("Invalid port")
if args.min_days_valid and not re.search(r"^\d+(,\d+)?$", args.min_days_valid):
nagios_unknown("--check-cert-expire takes INTEGER[,INTEGER] as arguments")
if args.timeout < 0:
nagios_unknown("Invalid timeout argument")
if args.connect_host:
connect_host = args.connect_host
else:
connect_host = args.host
if args.connect_port:
connect_port = args.connect_port
else:
connect_port = args.port
tlsa_records = get_tlsa_records(args)
has_usage1_tlsa = False
for record in tlsa_records:
if record.usage == 1:
has_usage1_tlsa = True
break
initial_check_pkix = (args.check_pkix or has_usage1_tlsa)
try:
# validate against PKIX if manually requested or we've found a usage=1 tlsa record
ssl_sock = connect_to_host(connect_host, connect_port, args, initial_check_pkix)
pkix_valid = initial_check_pkix
except (ssl.CertificateError, ssl.SSLError) as e:
if args.check_pkix:
nagios_critical(str(e))
else:
ssl_sock = connect_to_host(connect_host, connect_port, args, False)
pkix_valid = False
pkix_error = str(e)
cert_binary = ssl_sock.getpeercert(binary_form=True)
cert_dict = ssl_sock.getpeercert()
ssl_sock.close()
dane_valid_cert = False
for tlsa in tlsa_records:
if validate_dane(cert_binary, pkix_valid, tlsa):
dane_valid_cert = True
break
if not dane_valid_cert:
# test if it would match if it were pkix_valid
additional_msg = ""
for tlsa in tlsa_records:
if validate_dane(cert_binary, True, tlsa):
additional_msg = "\nIt matches a TLSA usage=1 record but fails PKIX validation:\n" + pkix_error
break
nagios_critical("Certificate doesn't match TLSA record" + additional_msg)
if pkix_valid and args.min_days_valid:
days_parts = args.min_days_valid.split(",")
if len(days_parts) == 2:
timedelta_valid = check_cert_expiry(args, cert_dict, int(days_parts[0]), int(days_parts[1]))
else:
timedelta_valid = check_cert_expiry(args, cert_dict, int(days_parts[0]))
expire_str = ", expires in {} days".format(timedelta_valid.days)
else:
expire_str = ""
message = "{}:{} cert matches TLSA record".format(args.host, args.port)
if not args.dnssec:
message += " (DNSSEC not validated)"
message += expire_str
nagios_ok(message)
if __name__ == "__main__":
main()
message = "{}:{} cert matches TLSA record".format(args.host, args.port)
if not args.dnssec:
message += " (DNSSEC not validated)"
message += expire_str
nagios_ok(message)
if __name__ == "__main__":
main()
# kate: space-indent on; indent-width 4;

View File

@ -0,0 +1,187 @@
#!/usr/bin/env python
# Check if an OpenVPN server runs on a given UDP or TCP port.
#
# Copyright 2013 Roland Wolters
# Copyright 2016 Alarig Le Lay
#
# Version 20160803
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import os
import sys
import time
import hmac
import hashlib
import struct
import socket
import argparse
import binascii
HMAC_CLIENT_KEY_START = 192
BUFFER_SIZE = 1024
ALGORITHMS_AVAILABLE = hashlib.algorithms_available \
if hasattr(hashlib, "algorithms_available") else hashlib.algorithms
def ok(msg):
print('OK: %s' % msg)
return 0
def critical(msg):
print('CRIT: %s' % msg)
return 2
def buildpacket(tcp, key, digestmod):
packet = 1
ts = int(time.time())
session = os.urandom(8)
if key:
# hmac
h = hmac.new(key, digestmod=digestmod)
h.update(struct.pack('>I', packet)) # packet id
h.update(struct.pack('>I', ts)) # net time
h.update(b'\x38') # type
h.update(session) # session id
h.update(struct.pack('>B', 0)) # message packet id array length
h.update(struct.pack('>I', 0)) # message packet id
# packet
result = b''
result += b'\x38' # type
result += session # session id
if key: result += h.digest() # hmac
result += struct.pack('>I', packet) # packet id
result += struct.pack('>I', ts) # net time
result += struct.pack('>B', 0) # message packet id array length
result += struct.pack('>I', 0) # message packet id
if tcp: result = struct.pack('>H', len(result)) + result
return result
def checkserver(host, port, tcp, timeout, key, digest):
packet = buildpacket(tcp, key, digest)
check = checkserver_tcp if tcp else checkserver_udp
return check(host, port, timeout, packet)
def checkserver_udp(host, port, timeout, packet):
# thanks to glucas for the idea
try:
af, socktype, proto, canonname, sa = socket.getaddrinfo(host, port, \
socket.AF_UNSPEC, socket.SOCK_DGRAM)[0]
s = socket.socket(af, socktype, proto)
s.settimeout(timeout)
except socket.error:
return critical('Unable to create UDP socket')
try:
s.sendto(packet, (host, port))
data, _ = s.recvfrom(BUFFER_SIZE)
reply = binascii.hexlify(data)
return ok('OpenVPN UDP server response (hex): %s' % reply)
except:
return critical('OpenVPN UDP server not responding')
finally:
s.close()
def checkserver_tcp(host, port, timeout, packet):
try:
af, socktype, proto, canonname, sa = socket.getaddrinfo(host, port, \
socket.AF_UNSPEC, socket.SOCK_STREAM)[0]
s = socket.socket(af, socktype, proto)
s.settimeout(timeout)
except socket.error:
return critical('Unable to create TCP socket')
try:
s.connect((host, port))
s.send(packet)
data = s.recv(BUFFER_SIZE)
if len(data) <= 0: raise RuntimeError
reply = binascii.hexlify(data)
return ok('OpenVPN TCP server response (hex): %s' % reply)
except:
return critical('OpenVPN TCP server not responding')
finally:
s.close()
def readkey(path):
key = None
try:
with open(path, 'r') as myfile: key = myfile.read()
except:
return None
index_start = key.find('-\n');
index_end = key.find('\n-', index_start);
if index_start < 0 or index_end < 0 or index_end <= index_start:
return None
index_start += 2
key = key[index_start:index_end].replace('\n', '').replace('\r', '')
return key
def optionsparser(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--port', help='set port number (default is %(default)d)', type=int, default=1194)
parser.add_argument('-t', '--tcp', help='use tcp instead of udp', action='store_true')
parser.add_argument('--timeout', help='set timeout (default is %(default)d)', type=int, default=5)
parser.add_argument('--digest', help='set HMAC digest (default is "%(default)s")', default='sha1')
parser.add_argument('--digest-size', help='set HMAC digest size', type=int)
parser.add_argument('--digest-key', help='set HMAC key')
parser.add_argument('--tls-auth', help='set tls-auth file')
parser.add_argument('host', help='the OpenVPN host name or IP')
return parser.parse_args(argv)
def main(argv=None):
args = optionsparser(argv)
if args.digest_size and args.digest_size < 0:
critical('digest size must be positive')
if args.tls_auth and args.digest_key:
critical('--tls-auth cannot go with --digest-key')
key = args.digest_key
digest = args.digest
digest_size = args.digest_size
digest = digest.lower()
if digest not in ALGORITHMS_AVAILABLE:
return critical('digest not available')
try:
digest = getattr(hashlib, digest)
if not digest_size: digest_size = digest().digest_size
except:
return critical('digest creation failed')
if args.tls_auth:
key = readkey(args.tls_auth)
if key == None: return critical('cannot read tls auth file')
index_start = HMAC_CLIENT_KEY_START * 2
index_end = (HMAC_CLIENT_KEY_START + digest_size) * 2
key = key[index_start:index_end]
if key: key = binascii.unhexlify(key)
return checkserver(args.host, args.port, args.tcp, args.timeout, key, digest)
if __name__ == '__main__':
code = main()
sys.exit(code)

View File

@ -0,0 +1,144 @@
#!/bin/sh
# Copyright (c) 2013 Stefan Huber <shuber@sthu.org>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
. $(dirname $0)/utils.sh
PROGNAME=$(basename $0)
REVISION="0.1"
usage() {
cat <<EOF
check_rdns v$REVISION
Copyright (c) 2013 Stefan Huber <shuber@sthu.org>
Usage: $PROGNAME -H ip-address [OPTIONS]
Arguments:
-H, --address IP-address The ip-addres on which reverse-DNS is performed.
Options:
-h, --help Print this text.
-a, --expect=HOST The expected result.
-s, --server=HOST The DNS server to contact.
-t, --timeout=SEC Seconds before lookup times out. (Default: 10)
-w, --warning=MSEC Return warning if lookup time exceeds value.
-c, --critical=MSEC Return critical if lookup time exceeds value.
-V, --version Print version info.
EOF
}
TEMP=`getopt -o "H:a:c:hs:t:w:V" --long "help,address:,expect:,critical:,server:,timeout:,warning:,version" -n "$PROGNAME" -- "$@"`
eval set - "$TEMP"
ADDRESS=
EXPECT=
SERVER=
TIMEOUT=10
WARNING=
CRITICAL=
while true; do
case "$1" in
-h | --help )
usage
exit $STATE_OK ;;
-V | --version )
echo "$PROGNAME v$REVISION"
exit $STATE_OK ;;
-H | --address )
ADDRESS="$2"; shift 2 ;;
-a | --expect )
EXPECT="$2"; shift 2 ;;
-s | --server )
SERVER="$2"; shift 2 ;;
-t | --timeout )
TIMEOUT="$2"; shift 2 ;;
-w | --warning )
WARNING="$2"; shift 2 ;;
-c | --critical )
CRITICAL="$2"; shift 2 ;;
-- )
shift
break ;;
* )
break ;;
esac
done
if [ -z "$ADDRESS" ]; then
echo "Error: No address given."
usage
exit $STATE_CRITICAL
fi
DIGOPTS="+time=$TIMEOUT +noquestion +noauthority -t PTR"
[ -z "$SERVER" ] || DIGOPTS="@$SERVER $DIGOPTS"
RESULT=$(dig $DIGOPTS -x "$ADDRESS"):
DIGSTATUS=$?
if [ $DIGSTATUS != "0" ]; then
echo "DNS failed: dig exit code $DIGSTATUS |"
exit $STATE_CRITICAL
fi
# Get the actual result
HOST=$(echo "$RESULT" | grep -m 1 -o "[[:space:]]IN[[:space:]]*PTR[[:space:]].*\.$" | awk '{ print $3 }' )
if [ -z "$HOST" ]; then
echo "DNS failed: reverse DNS gave no answer. |"
exit $STATE_CRITICAL
fi
# Get the query time in msec
QUERYTIME=$(echo "$RESULT" | grep -m 1 "Query time:" | cut -d ":" -f 2 | awk '{ print $1 }')
MATCHED=
if [ -n "$EXPECT" ]; then
if [ "$EXPECT" != "$HOST" ]; then
echo "DNS critical - query result \"$HOST\" != \"$EXPECT\", query time: $QUERYTIME msec |"
exit $STATE_CRITICAL
else
MATCHED=" (match ok)"
fi
fi
if [ -n "$CRITICAL" ] && [ "$QUERYTIME" -gt "$CRITICAL" ]; then
echo "DNS critical - query time $QUERYTIME msec too large ($CRITICAL msec), query result: \"$HOST\"$MATCHED |"
exit $STATE_CRITICAL
fi
if [ -n "$WARNING" ] && [ "$QUERYTIME" -gt "$WARNING" ]; then
echo "DNS warning - query time $QUERYTIME msec too large ($WARNING msec), query result: \"$HOST\"$MATCHED |"
exit $STATE_WARNING
fi
echo "DNS OK - query time $QUERYTIME msec, query result: \"$HOST\"$MATCHED |"
exit $STATE_OK

View File

@ -88,7 +88,7 @@
group: "{{ icinga2_server_group }}"
mode: 0600
notify: restart icinga2
# no_log: True
no_log: True
- name: execute icinga2 api setup command
command: icinga2 api setup
@ -103,5 +103,15 @@
state: present
notify: restart icinga2
- name: constants.conf file installed
template:
src: constants.conf.j2
dest: /etc/icinga2/constants.conf
owner: "{{ icinga2_server_user }}"
group: "{{ icinga2_server_group }}"
mode: 0644
notify: restart icinga2
no_log: True
- name: Flush handlers
meta: flush_handlers

View File

@ -6,6 +6,7 @@
#- import_tasks: install_icinga2.yml
#- import_tasks: install_mariadb.yml
#- import_tasks: install_ido.yml
- import_tasks: configure_icinga2_api_feature.yml
#- import_tasks: configure_icinga2_api_feature.yml
#- import_tasks: install_icingaweb2.yml
#- import_tasks: configure_icingaweb2.yml
- import_tasks: postconfigure_icinga2.yml

View File

@ -0,0 +1,40 @@
---
- name: Icinga2 post config file deployed
template:
src: 'conf.d/{{ item }}.j2'
dest: '/etc/icinga2/conf.d/{{ item }}'
owner: "{{ icinga2_server_user }}"
group: "{{ icinga2_server_group }}"
mode: 0644
loop:
- commands.conf
- groups.conf
- notifications.conf
- services.conf
- templates.conf
- users.conf
- timeperiods.conf
notify: restart icinga2
- name: Icinga2 custom commands deployed
template:
src: 'conf.d/command-custom.conf.j2'
dest: '/usr/share/icinga2/include/command-custom.conf'
owner: root
group: root
mode: 0644
notify: restart icinga2
- name: custom nagios plugins deployed
copy:
src: "{{ item }}"
dest: "{{ icinga2_server_nagios_plugins_location }}/{{ item }}"
owner: root
group: root
mode: 0755
loop:
- check_dane
- check_openvpn
- check_rdns
notify: restart icinga2

View File

@ -0,0 +1,143 @@
object CheckCommand "dane" {
import "plugin-check-command"
command = [ PluginDir + "/check_dane" ]
arguments = {
"--host" = {
value = "$dane_host$"
required = true
description = "Hostname to check"
}
"--port" = {
value = "$dane_port$"
required = true
description = "TCP port to check"
}
"--connect-host" = {
value = "$dane_connect_host$"
description = "Connect to this host instead of $dane_host$"
}
"--connect-port" = {
value = "$dane_connect_port$"
description = "Connect to this host instead of $dane_port$"
}
"--starttls" = {
value = "$dane_starttls$"
description = "Send the protocol-specific messages to enable TLS. Possible values: smtp, imap, xmpp, quassel"
}
"--check-pkix" = {
set_if = "$dane_check_pkix$"
description = "Additionally perform traditional checks on the certificate (ca trust path, hostname, expiry)."
}
"--nameserver" = {
value = "$dane_nameserver$"
description = "Use a custom nameserver."
}
"--min-days-valid" = {
value = "$dane_min_days_valid$"
description = "Minimum number of days a certificate has to be valid. Format: INTEGER[,INTEGER]. 1st is #days for warning, 2nd is critical."
}
"--timeout" = {
value = "$dane_timeout$"
description = "Network timeout in sec. Default: 10"
}
"--no-dnssec" = {
set_if = "$dane_no_dnssec$"
description = "Continue even when DNS replies aren't DNSSEC authenticated."
}
}
}
object CheckCommand "openvpn" {
import "ipv4-or-ipv6"
command = [ PluginDir + "/check_openvpn", "$openvpn_address$" ]
arguments = {
"-p" = {
value = "$openvpn_port$"
description = "set port number (default is 1194)"
}
"-t" = {
set_if = "$openvpn_tcp$"
description = "use tcp instead of udp"
}
"--timeout" = {
value = "$openvpn_timeout$"
description = "set timeout in seconds, for udp counted per packet (default is 2)"
}
"--digest" = {
value = "$openvpn_digest$"
description = "set digest algorithm (default is 'sha1')"
}
"--digest-size" = {
value = "$openvpn_digest_size$"
description = "set HMAC digest size"
}
"--digest-key-client" = {
value = "$openvpn_digest_key_client$"
description = "set client HMAC key"
}
"--digest-key-server" = {
value = "$openvpn_key_server$"
description = "set server HMAC key for packet validation"
}
"--tls-auth" = {
value = "$openvpn_tls_auth$"
description = "set tls-auth file"
}
"--tls-auth-inverse" = {
value = "$openvpn_tls_auth_inverse$"
description = "set tls-auth file direction to inverse (1)"
}
"--retrycount" = {
value = "$openvpn_retrycount$"
description = "number of udp retries before giving up (default is 3)"
}
"--no-validation" = {
value = "$openvpn_no_validation$"
description = "do not validate response"
}
}
vars.openvpn_address = "$check_address$"
vars.openvpn_tls_auth = "$openvpn_takey$"
}
object CheckCommand "by_ssh_wirebrass" {
import "by_ssh"
vars.by_ssh_custom_plugins_path = "{{ icinga2_server_nagios_plugins_location }}"
vars.by_ssh_logname = "nagios"
vars.by_ssh_identity = "/var/lib/icinga2/.ssh/id_rsa"
vars.by_ssh_options = [ "ControlMaster=auto","ControlPath=/var/run/icinga2/$host.name$","ControlPersist=10m"]
}
object CheckCommand "rdns" {
import "plugin-check-command"
command = [ PluginDir + "/check_rdns" ]
arguments = {
"-H" = {
value = "$rdns_address$"
required = true
description = "Address to reverse"
}
"-a" = {
value = "$rdns_expect$"
required = false
description = "Expected result"
}
"-s" = {
value = "$rdns_server$"
required = false
description = "The DNS server to contact"
}
}
}

View File

@ -0,0 +1,187 @@
/* Command objects */
/* Notification Commands
*
* Please check the documentation for all required and
* optional parameters.
*/
object NotificationCommand "mail-host-notification" {
command = [ ConfigDir + "/scripts/mail-host-notification.sh" ]
arguments += {
"-4" = "$notification_address$"
"-6" = "$notification_address6$"
"-b" = "$notification_author$"
"-c" = "$notification_comment$"
"-d" = {
required = true
value = "$notification_date$"
}
"-f" = {
value = "$notification_from$"
description = "Set from address. Requires GNU mailutils (Debian/Ubuntu) or mailx (RHEL/SUSE)"
}
"-i" = "$notification_icingaweb2url$"
"-l" = {
required = true
value = "$notification_hostname$"
}
"-n" = {
required = true
value = "$notification_hostdisplayname$"
}
"-o" = {
required = true
value = "$notification_hostoutput$"
}
"-r" = {
required = true
value = "$notification_useremail$"
}
"-s" = {
required = true
value = "$notification_hoststate$"
}
"-t" = {
required = true
value = "$notification_type$"
}
"-v" = "$notification_logtosyslog$"
}
vars += {
notification_address = "$address$"
notification_address6 = "$address6$"
notification_author = "$notification.author$"
notification_comment = "$notification.comment$"
notification_type = "$notification.type$"
notification_date = "$icinga.long_date_time$"
notification_hostname = "$host.name$"
notification_hostdisplayname = "$host.display_name$"
notification_hostoutput = "$host.output$"
notification_hoststate = "$host.state$"
notification_useremail = "$user.email$"
}
}
object NotificationCommand "mail-service-notification" {
command = [ ConfigDir + "/scripts/mail-service-notification.sh" ]
arguments += {
"-4" = "$notification_address$"
"-6" = "$notification_address6$"
"-b" = "$notification_author$"
"-c" = "$notification_comment$"
"-d" = {
required = true
value = "$notification_date$"
}
"-e" = {
required = true
value = "$notification_servicename$"
}
"-f" = {
value = "$notification_from$"
description = "Set from address. Requires GNU mailutils (Debian/Ubuntu) or mailx (RHEL/SUSE)"
}
"-i" = "$notification_icingaweb2url$"
"-l" = {
required = true
value = "$notification_hostname$"
}
"-n" = {
required = true
value = "$notification_hostdisplayname$"
}
"-o" = {
required = true
value = "$notification_serviceoutput$"
}
"-r" = {
required = true
value = "$notification_useremail$"
}
"-s" = {
required = true
value = "$notification_servicestate$"
}
"-t" = {
required = true
value = "$notification_type$"
}
"-u" = {
required = true
value = "$notification_servicedisplayname$"
}
"-v" = "$notification_logtosyslog$"
}
vars += {
notification_address = "$address$"
notification_address6 = "$address6$"
notification_author = "$notification.author$"
notification_comment = "$notification.comment$"
notification_type = "$notification.type$"
notification_date = "$icinga.long_date_time$"
notification_hostname = "$host.name$"
notification_hostdisplayname = "$host.display_name$"
notification_servicename = "$service.name$"
notification_serviceoutput = "$service.output$"
notification_servicestate = "$service.state$"
notification_useremail = "$user.email$"
notification_servicedisplayname = "$service.display_name$"
}
}
/*
* If you prefer to use the notification scripts with environment
* variables instead of command line parameters, you can use
* the following commands. They have been updated from < 2.7
* to support the new notification scripts and should help
* with an upgrade.
* Remove the comment blocks and comment the notification commands above.
*/
/*
object NotificationCommand "mail-host-notification" {
command = [ ConfigDir + "/scripts/mail-host-notification.sh" ]
env = {
NOTIFICATIONTYPE = "$notification.type$"
HOSTDISPLAYNAME = "$host.display_name$"
HOSTNAME = "$host.name$"
HOSTADDRESS = "$address$"
HOSTSTATE = "$host.state$"
LONGDATETIME = "$icinga.long_date_time$"
HOSTOUTPUT = "$host.output$"
NOTIFICATIONAUTHORNAME = "$notification.author$"
NOTIFICATIONCOMMENT = "$notification.comment$"
HOSTDISPLAYNAME = "$host.display_name$"
USEREMAIL = "$user.email$"
}
}
object NotificationCommand "mail-service-notification" {
command = [ ConfigDir + "/scripts/mail-service-notification.sh" ]
env = {
NOTIFICATIONTYPE = "$notification.type$"
SERVICENAME = "$service.name$"
HOSTNAME = "$host.name$"
HOSTDISPLAYNAME = "$host.display_name$"
HOSTADDRESS = "$address$"
SERVICESTATE = "$service.state$"
LONGDATETIME = "$icinga.long_date_time$"
SERVICEOUTPUT = "$service.output$"
NOTIFICATIONAUTHORNAME = "$notification.author$"
NOTIFICATIONCOMMENT = "$notification.comment$"
HOSTDISPLAYNAME = "$host.display_name$"
SERVICEDISPLAYNAME = "$service.display_name$"
USEREMAIL = "$user.email$"
}
}
*/
include "/usr/share/icinga2/include/command-custom.conf"

View File

@ -0,0 +1,44 @@
/**
* Host group examples.
*/
object HostGroup "linux-servers" {
display_name = "Linux Servers"
assign where host.vars.os == "Linux"
}
object HostGroup "windows-servers" {
display_name = "Windows Servers"
assign where host.vars.os == "Windows"
}
{% if icinga2_server_custom_hostgroup is defined %}
object HostGroup "{{ icinga2_server_custom_hostgroup }}" {
display_name = "{{ icinga2_server_custom_hostgroup }}"
assign where host.vars.owner == "{{ icinga2_server_custom_hostgroup }}"
}
{% endif %}
/**
* Service group examples.
*/
object ServiceGroup "ping" {
display_name = "Ping Checks"
assign where match("ping*", service.name)
}
object ServiceGroup "http" {
display_name = "HTTP Checks"
assign where match("http*", service.check_command)
}
object ServiceGroup "disk" {
display_name = "Disk Checks"
assign where match("disk*", service.check_command)
}

View File

@ -0,0 +1,33 @@
/**
* The example notification apply rules.
*
* Only applied if host/service objects have
* the custom variable `notification` defined
* and containing `mail` as key.
*
* Check `hosts.conf` for an example.
*/
apply Notification "mail-icingaadmin" to Host {
import "mail-host-notification"
user_groups = host.vars.notification.mail.groups
users = host.vars.notification.mail.users
interval = 1h
//vars.notification_logtosyslog = true
assign where host.vars.notification.mail
}
apply Notification "mail-icingaadmin" to Service {
import "mail-service-notification"
user_groups = host.vars.notification.mail.groups
users = host.vars.notification.mail.users
interval = 1h
//vars.notification_logtosyslog = true
assign where host.vars.notification.mail
}

View File

@ -0,0 +1,277 @@
/*
* Service apply rules.
*
* The CheckCommand objects `ping4`, `ping6`, etc
* are provided by the plugin check command templates.
* Check the documentation for details.
*
* Tip: Use `icinga2 object list --type Service` to
* list all service objects after running
* configuration validation (`icinga2 daemon -C`).
*/
/*
* This is an example host based on your
* local host's FQDN. Specify the NodeName
* constant in `constants.conf` or use your
* own description, e.g. "db-host-1".
*/
/*
* These are generic `ping4` and `ping6`
* checks applied to all hosts having the
* `address` resp. `address6` attribute
* defined.
*/
apply Service "ping4" {
import "generic-service"
check_command = "ping4"
assign where host.address
}
apply Service "ping6" {
import "generic-service"
check_command = "ping6"
assign where host.address6
}
/*
* Apply the `ssh` service to all hosts
* with the `address` attribute defined and
* the custom attribute `os` set to `Linux`.
*/
apply Service "ssh" {
import "generic-service"
check_command = "ssh"
assign where (host.address || host.address6) && host.vars.os == "Linux"
}
apply Service "dns-forward-ipv4" {
import "generic-service"
check_command = "dig"
vars.dig_lookup = "$host_name$"
vars.dig_server = "80.67.169.40"
vars.dig_record_type = "A"
vars.dig_ipv4 = "true"
if (host.vars.dig_expected_address) {
vars.dig_expected_address = host.vars.dig_expected_address
} else {
vars.dig_expected_address = "$address$"
}
assign where (host.address) && host.vars.os == "Linux"
}
apply Service "dns-forward-ipv6" {
import "generic-service"
check_command = "dig"
vars.dig_lookup = "$host_name$"
vars.dig_server = "2001:910:800::12"
vars.dig_record_type = "AAAA"
vars.dig_ipv6 = "true"
if (host.vars.dig_expected_address6) {
vars.dig_expected_address = host.vars.dig_expected_address6
} else {
vars.dig_expected_address = "$address6$"
}
assign where (host.address6) && host.vars.os == "Linux"
}
apply Service "dns-reverse-ipv4" {
import "generic-service"
check_command = "rdns"
vars.sla = "24x7"
vars.rdns_server = "80.67.169.40"
if (host.vars.rdns_expect) {
vars.rdns_expect = host.vars.rdns_expect
} else {
vars.rdns_expect = "$host_name$."
}
if (host.vars.rdns_address) {
vars.rdns_address = host.vars.rdns_address
} else {
vars.rdns_address = "$address$"
}
assign where (host.address) && host.vars.os == "Linux"# && host.name != "vm-mw-01.wirebrass.fr"
}
apply Service "dns-reverse-ipv6" {
import "generic-service"
check_command = "rdns"
vars.sla = "24x7"
vars.rdns_server = "2001:910:800::12"
if (host.vars.rdns_expect6) {
vars.rdns_expect = host.vars.rdns_expect6
} else {
vars.rdns_expect = "$host_name$."
}
if (host.vars.rdns_address6) {
vars.rdns_address = host.vars.rdns_address6
} else {
vars.rdns_address = "$address6$"
}
assign where (host.address6) && host.vars.os == "Linux" && host.name != "vm-ttn-01.wirebrass.fr" && host.name != "vm-fma-01.wirebrass.fr"# && host.name != "vm-mw-01.wirebrass.fr"
}
apply Service "ntp_by_ssh" {
import "generic-service"
check_command = "by_ssh_wirebrass"
vars.by_ssh_timeout = 30
vars.by_ssh_command = "$by_ssh_custom_plugins_path$check_ntp_time -H pool.ntp.org"
assign where host.vars.os == "Linux" && host.vars.agent_type == "ssh"
}
apply Service "uptime_by_ssh" {
import "generic-service"
check_command = "by_ssh_wirebrass"
vars.by_ssh_custom_uptime = 5184000
vars.by_ssh_command = "test $$(cut -d. -f1 /proc/uptime) -lt $by_ssh_custom_uptime$"
assign where host.vars.os == "Linux" && host.vars.agent_type == "ssh"
}
apply Service "load_by_ssh" {
import "generic-service"
check_command = "by_ssh_wirebrass"
vars.load_by_ssh_warn = "7.0,6.0,6.0"
vars.load_by_ssh_crit = "8.0,7.0,7.5"
vars.by_ssh_command = "$by_ssh_custom_plugins_path$check_load -w $load_by_ssh_warn$ -c $load_by_ssh_crit$"
assign where host.vars.os == "Linux" && host.vars.agent_type == "ssh"
}
apply Service "users_by_ssh" {
import "generic-service"
check_command = "by_ssh_wirebrass"
vars.users_wgreater = 5
vars.users_cgreater = 10
vars.by_ssh_command = "$by_ssh_custom_plugins_path$check_users -w $users_wgreater$ -c $users_cgreater$"
assign where host.vars.os == "Linux" && host.vars.agent_type == "ssh"
}
apply Service "disk_by_ssh_device" {
import "generic-service"
check_command = "by_ssh_wirebrass"
vars.by_ssh_command = "$by_ssh_custom_plugins_path$check_disk -w 20% -c 10% -A -x /sys/kernel/debug/tracing -x nsfs -x shm -x overlay"
assign where host.vars.os == "Linux" && host.vars.agent_type == "ssh"
}
apply Service "procs_zombie_by_ssh" {
import "generic-service"
check_command = "by_ssh_wirebrass"
vars.by_ssh_command = "$by_ssh_custom_plugins_path$check_procs -w 5 -c 10 -s Z"
assign where host.vars.os == "Linux" && host.vars.agent_type == "ssh"
}
apply Service "lastupdate_by_ssh" {
import "generic-service"
check_command = "by_ssh_wirebrass"
vars.by_ssh_command = "$by_ssh_custom_plugins_path$check_file_age -w 93600 -c 180000 -f /var/lastupdate"
assign where host.vars.os == "Linux" && host.vars.agent_type == "ssh" && host.name != "hv01.wirebrass.fr" && host.name != "hv02.wirebrass.fr" && host.name != "hv03.wirebrass.fr" && host.name != "radiosupinfo.wirebrass.fr" && host.name != "radio.supinfo.com.wirebrass.fr"
}
apply Service "procs_by_ssh" {
import "generic-service"
check_command = "by_ssh_wirebrass"
vars.procs_by_ssh_warn = 400
vars.procs_by_ssh_crit = 500
vars.by_ssh_command = "$by_ssh_custom_plugins_path$check_procs -w $procs_by_ssh_warn$ -c $procs_by_ssh_crit$"
assign where host.vars.os == "Linux" && host.vars.agent_type == "ssh"
}
apply Service for (http_vhost => config in host.vars.http_vhosts) {
import "generic-service"
check_command = "http"
vars += config
}
apply Service for (disk => config in host.vars.disks) {
import "generic-service"
check_command = "disk"
vars += config
}
apply Service "icinga" {
import "generic-service"
check_command = "icinga"
assign where host.name == NodeName
}
/*
apply Service "load" {
import "generic-service"
check_command = "load"
*/
/* Used by the ScheduledDowntime apply rule in `downtimes.conf`. */
/*vars.backup_downtime = "02:00-03:00"
assign where host.name == NodeName
}*/
apply Service "procs" {
import "generic-service"
check_command = "procs"
assign where host.name == NodeName
}
apply Service "swap" {
import "generic-service"
check_command = "swap"
assign where host.name == NodeName
}
apply Service "users" {
import "generic-service"
check_command = "users"
assign where host.name == NodeName
}

View File

@ -0,0 +1,95 @@
/*
* Generic template examples.
*/
/**
* Provides default settings for hosts. By convention
* all hosts should import this template.
*
* The CheckCommand object `hostalive` is provided by
* the plugin check command templates.
* Check the documentation for details.
*/
template Host "generic-host" {
max_check_attempts = 5
check_interval = 2m
retry_interval = 1m
check_command = "hostalive"
}
/**
* Provides default settings for services. By convention
* all services should import this template.
*/
template Service "generic-service" {
max_check_attempts = 5
check_interval = 2m
retry_interval = 1m
}
template Host "{{ icinga2_server_custom_hostgroup }}-host" {
import "generic-host"
vars.owner = "{{ icinga2_server_custom_hostgroup }}"
vars.notification["mail"] = {
groups = [ "{{ icinga2_server_custom_hostgroup }}" ]
}
}
/**
* Provides default settings for users. By convention
* all users should inherit from this template.
*/
template User "generic-user" {
}
/**
* Provides default settings for host notifications.
* By convention all host notifications should import
* this template.
*/
template Notification "mail-host-notification" {
command = "mail-host-notification"
states = [ Up, Down ]
types = [ Problem, Acknowledgement, Recovery, Custom,
FlappingStart, FlappingEnd,
DowntimeStart, DowntimeEnd, DowntimeRemoved ]
vars += {
// notification_icingaweb2url = "https://www.example.com/icingaweb2"
// notification_from = "Icinga 2 Host Monitoring <icinga@example.com>"
notification_logtosyslog = false
}
//period = "24x7"
period = "24x7minus4to5"
}
/**
* Provides default settings for service notifications.
* By convention all service notifications should import
* this template.
*/
template Notification "mail-service-notification" {
command = "mail-service-notification"
states = [ OK, Warning, Critical, Unknown ]
types = [ Problem, Acknowledgement, Recovery, Custom,
FlappingStart, FlappingEnd,
DowntimeStart, DowntimeEnd, DowntimeRemoved ]
vars += {
// notification_icingaweb2url = "https://www.example.com/icingaweb2"
// notification_from = "Icinga 2 Service Monitoring <icinga@example.com>"
notification_logtosyslog = false
}
//period = "24x7"
period = "24x7minus4to5"
}

View File

@ -0,0 +1,61 @@
/**
* Sample timeperiods for Icinga 2.
* Check the documentation for details.
*/
object TimePeriod "24x7" {
display_name = "Icinga 2 24x7 TimePeriod"
ranges = {
"monday" = "00:00-24:00"
"tuesday" = "00:00-24:00"
"wednesday" = "00:00-24:00"
"thursday" = "00:00-24:00"
"friday" = "00:00-24:00"
"saturday" = "00:00-24:00"
"sunday" = "00:00-24:00"
}
}
object TimePeriod "24x7minus2to3" {
display_name = "Icinga 2 24x7 TimePeriod without 2:00-2:30"
ranges = {
"monday" = "00:00-02:00,02:30-24:00"
"tuesday" = "00:00-02:00,02:30-24:00"
"wednesday" = "00:00-02:00,02:30-24:00"
"thursday" = "00:00-02:00,02:30-24:00"
"friday" = "00:00-02:00,02:30-24:00"
"saturday" = "00:00-02:00,02:30-24:00"
"sunday" = "00:00-02:00,02:30-24:00"
}
}
object TimePeriod "24x7minus4to5" {
display_name = "Icinga 2 24x7 TimePeriod without 4:00-5:00"
ranges = {
"monday" = "00:00-04:00,05:00-24:00"
"tuesday" = "00:00-04:00,05:00-24:00"
"wednesday" = "00:00-04:00,05:00-24:00"
"thursday" = "00:00-04:00,05:00-24:00"
"friday" = "00:00-04:00,05:00-24:00"
"saturday" = "00:00-04:00,05:00-24:00"
"sunday" = "00:00-04:00,05:00-24:00"
}
}
object TimePeriod "9to5" {
display_name = "Icinga 2 9to5 TimePeriod"
ranges = {
"monday" = "09:00-17:00"
"tuesday" = "09:00-17:00"
"wednesday" = "09:00-17:00"
"thursday" = "09:00-17:00"
"friday" = "09:00-17:00"
}
}
object TimePeriod "never" {
display_name = "Icinga 2 never TimePeriod"
ranges = {
}
}

View File

@ -0,0 +1,31 @@
/**
* The example user 'icingaadmin' and the example
* group 'icingaadmins'.
*/
object User "icingaadmin" {
import "generic-user"
display_name = "Icinga 2 Admin"
groups = [ "icingaadmins" ]
email = "root@localhost"
}
object UserGroup "icingaadmins" {
display_name = "Icinga 2 Admin Group"
}
object User "{{ icinga2_server_icingaweb2_main_user }}" {
import "generic-user"
display_name = "{{ icinga2_server_icingaweb2_main_user }}"
groups = [ "icingaadmins", "{{ icinga2_server_custom_hostgroup }}" ]
email = "{{ icinga2_server_icingaweb2_main_user_email }}"
}
object UserGroup "{{ icinga2_server_custom_hostgroup }}" {
display_name = "{{ icinga2_server_custom_hostgroup }}"
}

View File

@ -0,0 +1,28 @@
/**
* This file defines global constants which can be used in
* the other configuration files.
*/
/* The directory which contains the plugins from the Monitoring Plugins project. */
const PluginDir = "/usr/lib/nagios/plugins"
/* The directory which contains the Manubulon plugins.
* Check the documentation, chapter "SNMP Manubulon Plugin Check Commands", for details.
*/
const ManubulonPluginDir = "/usr/lib/nagios/plugins"
/* The directory which you use to store additional plugins which ITL provides user contributed command definitions for.
* Check the documentation, chapter "Plugins Contribution", for details.
*/
const PluginContribDir = "/usr/lib/nagios/plugins"
/* Our local instance name. By default this is the server's hostname as returned by `hostname --fqdn`.
* This should be the common name from the API certificate.
*/
const NodeName = "{{ inventory_hostname }}"
/* Our local zone name. */
const ZoneName = "{{ inventory_hostname }}"
/* Secret key for remote node tickets */
const TicketSalt = "{{ icinga2_server_ticket_salt }}"