Contao-Monitoring mit Icinga
von Kirsten Roschanski
Motivation
Mit jedem neuen Contao Update wird die Sicherheit verbessert, Fehler werden behoben und neue Funktionen hinzugefügt. Daher ist es zu empfehlen, dass man seine Contao Installation immer auf dem neusten Stand hält. Vor allem wenn man sich um mehrere Installationen kümmert, kann dies sehr unübersichtlich werden. Daher überprüfen wir unsere Installationen über Icinga2.
Voraussetzung
Man braucht hier für:
- einen github-Token um die Versionsnummern auszulesen
- einen Contao-Mananger-Token
github-Token
Diesen kann man ganz einfach unter https://github.com/settings/tokens
erstellen.
Dieser wird in der config.php gespeichert.
<?php
# https://github.com/settings/tokens
$github_token = 'GITHUB_TOKEN';
$contaoVersions = [
"4.9" => [
"start" => '20200215',
"end" => '20240214'
],
"4.13" => [
"start" => '20220215',
"end" => '20260214'
],
"5.0" => [
"start" => '20220815',
"end" => '20230214'
],
"5.1" => [
"start" => '20230215',
"end" => '20230814'
],
"5.2" => [
"start" => '20230815',
"end" => '20240214'
] ,
"5.3" => [
"start" => '20240215',
"end" => '20280814'
] ,
"5.4" => [
"start" => '20240815',
"end" => '20250214'
] ,
"5.5" => [
"start" => '20250215',
"end" => '20250814'
]
];
Contao-Manager-Link
Das Check-Contao-Update-Skript
# Angeregt von Admin Intelligence https://blog.admin-intelligence.de/nextcloud-mit-icinga2-auf-updates-ueberpruefen/
#!/usr/bin/php
<?php
# Source
#
$shortopts = "";
$shortopts .= "H:"; // Hostname
$shortopts .= "T:"; // Token
$shortopts .= "S"; // noSSL
$shortopts .= "c"; // no contao-manager via href
$shortopts .= "p"; // perfdata output
$longopts = array(
"help"
);
$options = getopt($shortopts, $longopts);
if(array_key_exists("help",$options)){
echo "HELP:\n";
echo " -H hostname (required)\n";
echo " -T token (required)\n";
echo " -S SSL\n";
echo " -c contao-manager via href\n";
echo " -p perfdata output\n";
exit(3);
}
if (!function_exists('curl_exec')){
echo "Please install curl";
exit(3);
}
if(!array_key_exists("H",$options)){
echo "Please Specify a Host";
exit(3);
}
if(!array_key_exists("T",$options)){
echo "Please Specify a Token";
exit(3);
}
if(!array_key_exists("S",$options)){
$contao_server = "https://".$options["H"];
}else{
$contao_server = "http://".$options["H"];
}
$contao_status_url = "$contao_server/contao-manager.phar.php/api/server/contao";
function error($e){
echo "Something went wrong: $e";
exit(3);
}
function get_newest_version($contao_releases = "https://api.github.com/repos/contao/contao/tags?per_page=100"){
require_once realpath( dirname( __FILE__ ) )."/config.php";
$headers = array(
'Content-Type: application/json',
'Accept: application/vnd.github+json',
'Authorization: Bearer ' . $github_token,
);
$curl = curl_init($contao_releases);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_USERAGENT, 'Icinga');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
try{
$response = curl_exec ($curl);
curl_close($curl);
}catch(Exception $e){
error($e);
}
$arrData = json_decode($response, true);
if(is_array($arrData)){
$return = [];
foreach ($arrData as $data) {
$arrVersion = explode('.', $data['name']);
$strMainVersion = $arrVersion[0] . '.' . $arrVersion[1];
$return[$strMainVersion][] = $data['name'];
}
foreach ($return as $strMainVersion => $data) {
$arrMainVersions = array_keys($contaoVersions);
if(!in_array($strMainVersion, $arrMainVersions)) {
unset($return[$strMainVersion]);
}
}
foreach ($return as $strMainVersion => $data) {
$return[$strMainVersion] = $data[0];
}
return $return;
}
return false;
}
function get_installed_version($contao_status_url , $token){
$headers = array(
'Content-Type: application/json',
'Connection: Close',
'Authorization: Bearer ' . $token,
);
$curl = curl_init($contao_status_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_USERAGENT, 'Icinga');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
try{
$response = curl_exec ($curl);
curl_close($curl);
}catch(Exception $e){
error($e);
}
$arrData = json_decode($response, true);
if(is_array($arrData)){
return $arrData["version"];
}
return false;
}
# get data
$newer=get_newest_version();
$actual=get_installed_version($contao_status_url, $options["T"]);
$arrVersion = explode('.', $actual);
$strMainVersion = $arrVersion[0] . '.' . $arrVersion[1];
$newer = $newer[$strMainVersion];
# perfdata
if(array_key_exists("p",$options)){
$perfdata = "running=".str_replace(".", "", $actual)." stable=".str_replace(".", "", $newer);
}
else {
$perfdata = "";
}
# output
if (version_compare($newer,$actual,"eq")) {
if (!array_key_exists("c",$options)) {
echo "<a href='$contao_server/contao-manager.phar.php' target=_blank>Current version is ($actual). (channel: stable, version: $newer)|$perfdata</a>";
} else {
echo "Current version is ($actual). (channel: stable, version: $newer)|$perfdata";
}
exit(0);
} else {
if (!array_key_exists("c",$options)) {
echo "<a href='$contao_server/contao-manager.phar.php' target=_blank>Current version is ($actual). Update to contao $newer available. (channel: stable)|$perfdata</a>";
} else {
echo "Current version is ($actual). Update to contao $newer available. (channel: stable)|$perfdata";
}
exit(1);
}
Das Checkskript sollte unter check_contao_update
gespeichert werden.
Zuerst muss das Skript ausführbar gemacht werdenchmod +x check_nextcloud_update.php
So führt man das Skript aus:./check_contao_update.php -H kirsten-roschanski.de -T CONATO-MANGER-TOKEN
Das Checkskript muss nun in den Nagios-Plugin-Ordner verschoben werden und anschließend muss ein neuer Icinga-Command dafür geschrieben werden.
Icinga-Command
object CheckCommand "check_contao_updates" {
import "plugin-check-command"
command = [PluginDir + "/check_contao_update.php" ]
arguments += {
"-H" = {
required = true
value = "$contao_host$"
}
"-T" = {
required = true
value = "$contao_managertoken$"
}
}
}
Icinga-Service
Damit wir den Check in einen Host aktivieren können, müssen wir dafür einen neuen Service schreiben. Der Service kann folgendermaßen aussehen.
/// *** check_contao_updates *** ///
apply Service for (contao_name => config in host.vars.check_contao_updates) {
import "24/7"
check_timeout = "900"
name = "check_contao_updates_" + contao_name
display_name = "Contao Updates " + contao_name
vars += config
check_command = "check_contao_updates"
assign where host.vars.check_contao_updates
ignore where host.vars.check_contao_updates.enable_check == false
}
Aktivierung im Host
Zu guter Letzt aktivieren wir den Check in der Hostconfig. Das kann man mit folgender Zeile erreichen:
vars.check_contao_updates["kirsten-roschanski.de (Update)"] = {
contao_host = "kirsten-roschanski.de"
contao_managertoken = "123456789123456789"
contao_ssl = true
}
Icinga noch einmal neu laden:
/etc/init.d/icinga2 reload
Jetzt können wir unseren neuen Contao-Check auf unserer Icingaweb2 Oberfläche finden.