Skip to content

Instantly share code, notes, and snippets.

@rogeriotaques
Last active July 20, 2020 01:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rogeriotaques/7ed47ef66631e8455a97c33423c54361 to your computer and use it in GitHub Desktop.
Save rogeriotaques/7ed47ef66631e8455a97c33423c54361 to your computer and use it in GitHub Desktop.
Security package watcher in PHP
<?php
/**
* This script checks for security updates in the server and
* it's expected to be scheduled for a daily run.
*
* It will notify the $notify address if one or more security
* package updates are found.
*/
function exceptionErrorHandler($errNo, $errStr, $errFile, $errLine ) {
if (error_reporting() == 0) {
// @ sign temporary disabled error reporting
return;
}
throw new ErrorException($errStr, 0, $errNo, $errFile, $errLine);
} // exceptionErrorHandler
set_error_handler("exceptionErrorHandler");
// Who is sending the notification
$sender = 'admin@domain.tld';
// To who the notification will be sent
$notify = 'you@domain.tld';
// Give a name to identify your server. Usually the hostname.
$server = 'domain.tld';
// What mounted disk should be checked
$mountedDisk = '/dev/sda'; # '/dev/disk1s1' when macOS;
// What's the maximum usage before sending a notification for disk over usage
$diskUsageBoundary = 80; # %
// #############################################
// ### DON'T CHANGE ANYTHING FROM THIS POINT ###
// ### UNLESS YOU KNOW WHAT YOU'RE DOING ###
// #############################################
// If this file exist, a reboot is required
$reboot = file_exists('/var/run/reboot-required');
$matches = [];
// Gather info about available updates
// $note = @file_get_contents('/var/lib/update-notifier/updates-available');
// $note = preg_replace("/\n/", " ", $note);
try {
// Gather info about available updates
$note = file_get_contents('/var/lib/update-notifier/updates-available');
$note = preg_replace("/\n/", " ", $note);
// Gather info about disk usage
$res = exec("df -h | grep {$mountedDisk}");
$res = preg_replace('/\s{2,}/', ' ', $res);
$intUsedRate = 0;
$usedRate = null;
if (!empty($res) && $res) {
list($mountPoint, $totalSize, $usedSpace, $freeSpace, $usedRate) = explode(' ', $res);
$intUsedRate = (int) preg_replace('/[^0-9]/i', '', $usedRate);
}
// Clear used rate when not passed the boundary
if ($diskUsageBoundary > $intUsedRate) {
$usedRate = null;
}
// Set a flag to control whether to send or not send a notification
$shouldNotify = (bool) (preg_match("/\d+\supdates?/i", $note, $matches) || !empty($usedRate) || $reboot);
// Notify when needed
if ($shouldNotify) {
$headers = "From: {$sender} \n";
$body = [
"This is an automated message. \n",
];
$count = (int) preg_replace("/[^0-9]/i", '', $matches[0]);
if ($count) {
$body[] = "{$count} pending security updates has been found.";
}
if (!empty($usedRate)) {
$body[] = "{$mountedDisk} is {$usedRate} used. Needs an urgent review.";
$body[] = "As general it is like: ";
exec("df -h", $out);
$body[] = "\t" . implode("\n\t", $out);
}
if ($reboot) {
$body[] = "** A reboot is required. **";
}
$body[] = "Please review the '{$server}' server ASAP.";
// echo implode("\n", $body) . "\n";
mail($notify, "Server '{$server}' Pending Review", implode("\n", $body) . "\n", $headers, "-f {$sender}");
// For automated updates, if there're security package updates
// it can be automatically ran with :
// sudo unattended-upgrade -d # verbose or
// sudo unattended-upgrade # quitely
}
} cacth(Exception $e) {
$body = "Error Code: {$e->getCode()}\n\nDescription: {$e->getMessage()}\n";
mail($notify, "Server '{$server}' updates review failed", $body, $headers, "-f {$sender}");
}
echo "Daily updates review complete. \n";
@MESWEB
Copy link

MESWEB commented Jul 16, 2020

$note = @file_get_contents('/var/lib/update-notifier/updates-available');
never use @ in php

@rogeriotaques
Copy link
Author

Hey @MESWEB!

Thanks for your comment, however, it was not very constructive since it can be way too opinionated.

Could you please elaborate it more, giving more information about why you believe people should never use something? That will make it more constructive and give more directions to anyone coming to this gist later on.

Cheers.

@rogeriotaques
Copy link
Author

Hey @MESWEB! Thank you for contributing and sharing the link, now I few the comment is way more constructive! ;) I'm updating the Gist with an implementation that doesn't use the @. 🍻 R.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment