first commit
This commit is contained in:
commit
5b9939ce8e
3
aur
Executable file
3
aur
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo -u repo HOME=/data/repo local-repo repo "$@"
|
14
aur-add
Executable file
14
aur-add
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -e $1 ]; then
|
||||
pkg=/tmp/$1
|
||||
cp $1 $pkg
|
||||
sudo chown repo:repo $pkg
|
||||
shift
|
||||
sudo -u repo HOME=/data/repo local-repo repo -a $pkg "$@"
|
||||
else
|
||||
sudo -u repo HOME=/data/repo local-repo repo -A "$@"
|
||||
fi
|
||||
[[ "$?" != "0" ]] && exit $?
|
||||
echo Now you can install the package
|
||||
echo $ pacman -Sy $@
|
3
aur-update
Executable file
3
aur-update
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo -u repo HOME=/data/repo local-repo repo -U
|
120
backup-container
Executable file
120
backup-container
Executable file
@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env ruby
|
||||
require 'json'
|
||||
require 'pathname'
|
||||
require 'fileutils'
|
||||
require 'optparse'
|
||||
|
||||
RSYNC_CMD="rsync"
|
||||
RSYNC_ARGS=["--archive", "--delete", "--numeric-ids"]
|
||||
ZFS_SNAPSHOT_CMD="zfs-auto-snapshot"
|
||||
# --quiet --syslog --label=daily --keep=31 backup/rsync"
|
||||
LXC_PATH=Pathname.new("/data/containers")
|
||||
BACKUP_LOCATIONS = %w{home srv etc usr/local}
|
||||
CONFIG_PATH="/etc/lxc/container.json"
|
||||
|
||||
BACKUP_PATH="/backup"
|
||||
#ZFS_DATASET="backup/rsync"
|
||||
|
||||
def load_config
|
||||
return JSON.load(File.open(CONFIG_PATH))
|
||||
rescue SystemCallError => e
|
||||
abort "failed to open configuration '#{CONFIG_PATH}', #{e}"
|
||||
rescue JSON::ParserError => e
|
||||
abort "failed to parse configuration '#{CONFIG_PATH}', #{e}"
|
||||
end
|
||||
|
||||
module Utils
|
||||
def self.sh(cmd, *args)
|
||||
pretty_args = args.map {|arg| "'#{arg}'"}
|
||||
puts ([cmd] + pretty_args).join(" ")
|
||||
system(cmd, *args)
|
||||
end
|
||||
|
||||
def self.backup(remote_path, local_path)
|
||||
sh RSYNC_CMD, *RSYNC_ARGS, remote_path, local_path
|
||||
end
|
||||
end
|
||||
|
||||
class Container
|
||||
def initialize(name, backup_paths, backup_scripts)
|
||||
@name = name
|
||||
@backup_paths = backup_paths
|
||||
@backup_scripts = backup_scripts
|
||||
@path = LXC_PATH.join(name, "rootfs")
|
||||
end
|
||||
def backup
|
||||
backup_paths = BACKUP_LOCATIONS
|
||||
if @backup_paths.is_a?(Array)
|
||||
backup_paths += @backup_paths
|
||||
end
|
||||
backup_paths.each do |relative_path|
|
||||
backup_path = @path.join(relative_path)
|
||||
local_path = Pathname.new(@name).join(relative_path)
|
||||
FileUtils.mkdir_p(local_path)
|
||||
|
||||
if File.exists?(backup_path) && !empty_directory?(backup_path)
|
||||
Utils.backup(backup_path.to_s, File.dirname(local_path))
|
||||
end
|
||||
end
|
||||
end
|
||||
def run_backup_scripts
|
||||
if @backup_scripts.is_a?(Array)
|
||||
@backup_scripts.each do |script|
|
||||
backup_script(script)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def backup_script(script)
|
||||
unless script.is_a?(Hash)
|
||||
abort("backup-scripts: Expected an Object, got #{script.class}")
|
||||
end
|
||||
command = script["command"]
|
||||
if command.nil?
|
||||
abort("command not set for backup-scripts for container '#{@name}'")
|
||||
end
|
||||
backupname = script["backupname"]
|
||||
if backupname.nil?
|
||||
abort("backupname not set for backup-scripts for container '#{@name}'")
|
||||
end
|
||||
backupname = backupname.gsub("/", "")
|
||||
FileUtils.mkdir_p(backupname)
|
||||
puts "cd #{backupname}"
|
||||
Dir.chdir(backupname) do
|
||||
Utils.sh(command)
|
||||
end
|
||||
end
|
||||
|
||||
def empty_directory?(path)
|
||||
return false unless Dir.exists?(path)
|
||||
return Dir.entries(path).size <= 2 # - [".", ".."]
|
||||
end
|
||||
end
|
||||
|
||||
options = {}
|
||||
OptionParser.new do |opts|
|
||||
opts.on("-l", "--label [LABEL]", String, "daily, hourly") do |label|
|
||||
options[:label] = label
|
||||
end
|
||||
opts.on("-k", "--keep [NUMBER]", Integer, "Number of backups to keep") do |keep|
|
||||
options[:keep] = keep
|
||||
end
|
||||
end.parse!
|
||||
|
||||
puts "cd #{BACKUP_PATH}"
|
||||
Dir.chdir(BACKUP_PATH) do
|
||||
BACKUP_LOCATIONS.each do |location|
|
||||
FileUtils.mkdir_p(location)
|
||||
Utils.backup("/" + location, "localhost")
|
||||
end
|
||||
config = load_config
|
||||
config["network"].each do |container, data|
|
||||
next if data["lxc"] == false
|
||||
container = Container.new(container, data["backup-paths"], data["backup-scripts"])
|
||||
container.backup
|
||||
container.run_backup_scripts
|
||||
end
|
||||
#args = ["--label", options[:label], "--keep", options[:keep].to_s, ZFS_DATASET]
|
||||
#Utils.sh(ZFS_SNAPSHOT_CMD, *args)
|
||||
end
|
16
backup-mysql
Executable file
16
backup-mysql
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
# TARGET: Backup-Ziel
|
||||
# IGNORE: Liste zu ignorierender Datenbanken (durch | getrennt)
|
||||
IGNORE="mysql|information_schema|performance_schema|test"
|
||||
PASSWORD="DtkXaU6ZeWeizvcZjRQJqY3no9dGf3ASa7N73Y8Z8PULxJVrvvrq7AAak4s2HvD2"
|
||||
|
||||
DBS="$(/usr/bin/mysql --host="mysql" --user="root" --password="$PASSWORD" -Bse 'show databases' | /usr/bin/grep -Ev $IGNORE)"
|
||||
|
||||
rm -f *.sql.bz2
|
||||
|
||||
for DB in $DBS; do
|
||||
/usr/bin/mysqldump --host="mysql" --user="root" --password="$PASSWORD" --skip-extended-insert --skip-comments "$DB" | bzip2 -c > "$DB.sql.bz2"
|
||||
done
|
||||
|
||||
echo "$0 - Backup erfolgreich durchgefuehrt"
|
||||
exit 0
|
13
backup-postgres
Executable file
13
backup-postgres
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
export PGPASS=/root/.pgpass
|
||||
|
||||
# restore:
|
||||
# psql -f $database.dump postgres
|
||||
LIST=$(psql -h postgres -U postgres -At -c "select datname from pg_database order by datname;")
|
||||
for d in $LIST
|
||||
do
|
||||
if [ "$d" != "template0" ]; then
|
||||
pg_dump -h postgres -U postgres "$d" | gzip -c > "$d.dump.gz"
|
||||
fi
|
||||
done
|
28
create-mysql-user-and-database
Executable file
28
create-mysql-user-and-database
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Usage: $0 <username>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
USER="$1"
|
||||
PASSWORD="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64 | xargs)"
|
||||
|
||||
cat <<EOF | mysql --host mysql --user root --password=$(cat /etc/mysql.secret)
|
||||
create database $USER;
|
||||
grant usage on *.* to '$USER'@'%' identified by '$PASSWORD';
|
||||
grant all privileges on $USER.* to '$USER'@'%';
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Password for user $USER is:"
|
||||
echo
|
||||
echo $PASSWORD
|
||||
echo
|
99
create-php-container
Executable file
99
create-php-container
Executable file
@ -0,0 +1,99 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -u
|
||||
bold=`tput bold`
|
||||
normal=`tput sgr0`
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $# -lt 2 ]
|
||||
then
|
||||
echo "Usage: $0 <name> <domain> [<features>]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NAME="$1"
|
||||
DOMAIN="$2"
|
||||
ROOTFS="/data/containers/$NAME/rootfs"
|
||||
WEBFS="/data/containers/web/rootfs"
|
||||
WEBPATH="/srv/http/$DOMAIN"
|
||||
NGINX="$WEBFS/etc/nginx"
|
||||
PHP_MODULES=('')
|
||||
shift 2
|
||||
|
||||
# handle extra options
|
||||
while (( "$#" ))
|
||||
do
|
||||
case $1 in
|
||||
mysql)
|
||||
PHP_MODULES=(mysqli mysql pdo_mysql)
|
||||
;;
|
||||
postgres)
|
||||
PHP_MODULES=(pgsql pdo_pgsql)
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# clone container
|
||||
echo "${bold}Cloning container ...$normal"
|
||||
TEMPFILE=$(mktemp)
|
||||
ruby -rjson -e 'puts ({php_extensions: ARGV}).to_json' "$PHP_MODULES[@]" > "$TEMPFILE"
|
||||
lxc-clone -o base -n "$NAME" -- --group php --vars "$TEMPFILE"
|
||||
rm "$TEMPFILE"
|
||||
|
||||
# configure bind mount
|
||||
UNIT_NAME=$(systemd-escape --path --suffix=mount "${WEBFS}${WEBPATH}")
|
||||
cat << EOF > "/etc/systemd/system/$UNIT_NAME"
|
||||
[Mount]
|
||||
What = ${ROOTFS}${WEBPATH}
|
||||
Where = ${WEBFS}${WEBPATH}
|
||||
Type = none
|
||||
Options = bind,ro
|
||||
|
||||
[Install]
|
||||
WantedBy=lxc-mount.target
|
||||
EOF
|
||||
|
||||
systemctl enable "$UNIT_NAME"
|
||||
systemctl start "$UNIT_NAME"
|
||||
|
||||
# configure nginx
|
||||
echo "${bold}Configuring nginx ...$normal"
|
||||
cat << EOF > "$NGINX/sites-available/$DOMAIN"
|
||||
server {
|
||||
listen 80;
|
||||
listen 443 ssl;
|
||||
index index.php index.html index.htm;
|
||||
|
||||
server_name $DOMAIN;
|
||||
|
||||
root /srv/http/$DOMAIN;
|
||||
location ~ \.(php|php5)$ {
|
||||
fastcgi_pass $NAME:9000;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi.conf;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
chroot "$WEBFS" nginx_ensite "$DOMAIN"
|
||||
|
||||
# restart nginx
|
||||
echo "${bold}Reload nginx ...$normal"
|
||||
lxc-attach -n web -- systemctl reload nginx
|
||||
|
||||
# configure filewall
|
||||
echo "${bold}Configuring firewall ...$normal"
|
||||
cat << EOF > "/etc/ferm.d/services/45-$NAME"
|
||||
&def_service($NAME, $NAME, tcp, 9000);
|
||||
&allow_service_for($NAME, web);
|
||||
EOF
|
||||
fw-apply
|
||||
|
||||
# start container
|
||||
echo "${bold}Starting container ...$normal"
|
||||
lxc-start -d -n "$NAME"
|
33
create-postgres-user-and-database
Executable file
33
create-postgres-user-and-database
Executable file
@ -0,0 +1,33 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
echo "Usage: $0 <username> [<database>]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
USER="$1"
|
||||
DBPASSWORD="$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64)"
|
||||
DATABASE="${2:-$USER}"
|
||||
export PGPASSFILE=/root/.pgpass
|
||||
|
||||
psql --host postgres --user postgres <<EOF
|
||||
create user "$USER";
|
||||
alter user "$USER" with password '$DBPASSWORD';
|
||||
create database "$DATABASE" with owner "$USER";
|
||||
grant all privileges on database "$DATABASE" to "$USER";
|
||||
EOF
|
||||
|
||||
echo
|
||||
echo "Password for user $USER is:"
|
||||
echo
|
||||
echo $DBPASSWORD
|
||||
echo
|
18
decrypt-zfs
Executable file
18
decrypt-zfs
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
if ! [ "$EUID" -eq 0 ]
|
||||
then
|
||||
echo "This must be run as root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
echo -n "Password for data storage: "
|
||||
read -s password
|
||||
echo
|
||||
|
||||
echo $password | cryptsetup luksOpen /dev/sda3 zfs_hd_1
|
||||
echo $password | cryptsetup luksOpen /dev/sdb3 zfs_hd_2
|
||||
|
||||
zfs mount -a
|
42
destroy-php-container
Executable file
42
destroy-php-container
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
|
||||
bold=`tput bold`
|
||||
normal=`tput sgr0`
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $# -lt 2 ]
|
||||
then
|
||||
echo "Usage: $0 <name> <domain> [<features>]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
NAME="$1"
|
||||
DOMAIN="$2"
|
||||
ROOTFS="/data/containers/$NAME/rootfs"
|
||||
WEBFS="/data/containers/web/rootfs"
|
||||
WEBPATH="/srv/http/$DOMAIN"
|
||||
NGINX="$WEBFS/etc/nginx"
|
||||
|
||||
# destroy container
|
||||
lxc-stop -n "$NAME"
|
||||
/usr/bin/lxc-destroy -n "$NAME"
|
||||
|
||||
# unconfigure nginx
|
||||
chroot "$WEBFS" nginx_dissite "$DOMAIN"
|
||||
rmdir "$WEBFS$WEBPATH"
|
||||
rm -f "$WEBFS/etc/nginx/sites-available/$DOMAIN"
|
||||
|
||||
# restart nginx
|
||||
lxc-attach -n web -- systemctl restart nginx
|
||||
|
||||
# unconfigure firewall
|
||||
rm -f "/etc/ferm.d/services/45-$NAME"
|
||||
fw-apply
|
||||
|
||||
# clean up container.json
|
||||
/etc/lxc/scripts/cleanup-container-file.rb
|
23
duplicity-backup
Executable file
23
duplicity-backup
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
## Remote backup script. Requires duplicity and gpg-agent with the keys and passphrases loaded as root.
|
||||
## Uses separate encryption and signing keys
|
||||
## Usage: 'backup_remote.sh'
|
||||
|
||||
enc_key=AF5834A6
|
||||
sign_key=AF5834A6
|
||||
src="/home"
|
||||
#dest="scp://u93722@u93722.your-backup.de/duplicity"
|
||||
dest="file:///mnt/backup/duplicity"
|
||||
|
||||
duplicity --gpg-options "--secret-keyring /data/duplicity/duplicity.sec --keyring /data/duplicity/duplicity.pub" \
|
||||
--verbosity notice \
|
||||
--encrypt-key "$enc_key" \
|
||||
--sign-key "$sign_key" \
|
||||
--full-if-older-than 60D \
|
||||
--num-retries 3 \
|
||||
--asynchronous-upload \
|
||||
--volsize 250 \
|
||||
--exclude-filelist-stdin \
|
||||
--archive-dir /data/duplicity/cache \
|
||||
--log-file /var/log/duplicity.log \
|
||||
"$src" "$dest"
|
15
fw-apply
Executable file
15
fw-apply
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ! [ $EUID -eq 0 ]
|
||||
then
|
||||
echo "Must be root!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd /etc
|
||||
|
||||
if ferm --interactive --timeout 10 ferm.conf
|
||||
then
|
||||
ferm -n -l --domain ip ferm.conf > /etc/iptables/iptables.rules
|
||||
ferm -n -l --domain ip6 ferm.conf > /etc/iptables/ip6tables.rules
|
||||
fi
|
11
list-all-pkgs
Executable file
11
list-all-pkgs
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
(
|
||||
for c in /data/containers/*
|
||||
do
|
||||
if [ -d "$c/rootfs" ]
|
||||
then
|
||||
pacman -r "$c/rootfs" -Q
|
||||
fi
|
||||
done
|
||||
) | cut -d ' ' -f 1 | sort | uniq
|
3
lxc-destroy
Executable file
3
lxc-destroy
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo use /usr/bin/lxc-destroy instead >&2
|
11
lxc-foreach
Executable file
11
lxc-foreach
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
for n in `lxc-ls`; do
|
||||
name=n
|
||||
r=/data/containers/$n/rootfs
|
||||
root=$r
|
||||
c=/data/containers/$n/config
|
||||
config=$c
|
||||
eval echo "$ $1"
|
||||
eval "$1"
|
||||
done
|
28
lxc-log
Executable file
28
lxc-log
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
die() { echo $1 1>&2; exit 1; }
|
||||
usage() { echo "USAGE: $SCRIPT NAME SERVICE [JOURNALCTL_OPTIONS...]"; exit 0; }
|
||||
|
||||
SCRIPT=${0##*/}
|
||||
[ $# -lt 2 ] && usage
|
||||
|
||||
case "$1" in
|
||||
--help|-h)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
CONTAINER=$1; shift
|
||||
SERVICE=$1; shift
|
||||
;;
|
||||
esac
|
||||
|
||||
CONTAINER_PATH="/data/containers/$CONTAINER"
|
||||
|
||||
[ $EUID -eq 0 ] || die "Needs root permission"
|
||||
[ -d "$CONTAINER_PATH" ] || die "No such container found: $CONTAINER"
|
||||
|
||||
SYSTEMD_CGROUP="/system.slice/system-lxc.slice/lxc@${CONTAINER}.service/system.slice/${SERVICE}.service"
|
||||
|
||||
journalctl _SYSTEMD_CGROUP=${SYSTEMD_CGROUP} "$@"
|
23
rsnapshot_cp_zfs
Executable file
23
rsnapshot_cp_zfs
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
# name of the volume
|
||||
zname=$(dirname $(dirname $(echo $2 | cut -b 2-)))
|
||||
|
||||
# name of the future snapshot
|
||||
bsname="$zname@rsnap-$(date +%F)"
|
||||
|
||||
sname=$bsname
|
||||
for i in 1 2 3 4 5
|
||||
do
|
||||
# exit if success
|
||||
zfs snapshot "$sname"
|
||||
if [ "x$?" == "x0" ]; then
|
||||
echo "backup started at $(date)" > $2/info
|
||||
exit 0
|
||||
fi
|
||||
# iterate over it if already exists
|
||||
sname=$bsname-v$i
|
||||
done
|
||||
|
||||
echo ERROR zfs_cp: something is really broken
|
||||
exit 1
|
7
smartdnotify
Executable file
7
smartdnotify
Executable file
@ -0,0 +1,7 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Send mail
|
||||
echo "$SMARTD_MESSAGE" | mail -s "$SMARTD_FAILTYPE" "$SMARTD_ADDRESS"
|
||||
|
||||
# Notify user
|
||||
wall "$SMARTD_MESSAGE"
|
764
ssl-cert-check
Executable file
764
ssl-cert-check
Executable file
@ -0,0 +1,764 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Program: SSL Certificate Check <ssl-cert-check>
|
||||
#
|
||||
# Source code home: http://prefetch.net/code/ssl-cert-check
|
||||
#
|
||||
# Documentation: http://prefetch.net/articles/checkcertificate.html
|
||||
#
|
||||
# Author: Matty < matty91 at gmail dot com >
|
||||
#
|
||||
# Current Version: 3.27
|
||||
#
|
||||
# Revision History:
|
||||
#
|
||||
# Version 3.27
|
||||
# - Allow white spaces to exist in the certificate file list
|
||||
# - Add an additional check to pick up bad / non-existent certificates
|
||||
# - Add a check to look for the existence of a mail program. Error out if it's not present.
|
||||
# - Enable the TLS -servername extension by default - Juergen Knaack & Johan Denoyer
|
||||
#
|
||||
# Version 3.26
|
||||
# - Allow the certificate type (PEM, DER, NET) to be passed on the command line
|
||||
#
|
||||
# Version 3.25
|
||||
# - Check for "no route to host" errors -- Dan Doyle
|
||||
# - Set RETCODE to 3 (unknown) if a connection error occurs -- Dan Doyle
|
||||
# - Documentation fixes
|
||||
#
|
||||
# Version 3.24
|
||||
# - Utilize the -clcerts option to limit the results to client certificates - Eitan Katznelson
|
||||
#
|
||||
# Version 3.23
|
||||
# - Fixed typo in date2julian routine -- Ken Cook
|
||||
#
|
||||
# Version 3.22
|
||||
# - Change the validation option to "-V"
|
||||
# - Add a "-v" option to specify a specific protocol version (ssl2, ssl3 or tls)
|
||||
#
|
||||
# Version 3.21
|
||||
# - Adjust e-mail checking to avoid exiting if notifications aren't enabled -- Nick Anderson
|
||||
# - Added the number of days until expiration to the Nagios output -- Nick Anderson
|
||||
#
|
||||
# Version 3.20
|
||||
# - Fixed a bug in certificate length checking -- Tim Nowaczyk
|
||||
#
|
||||
# Version 3.19
|
||||
# - Added check to verify the certificate retrieved is valid
|
||||
#
|
||||
# Version 3.18
|
||||
# - Add support for connecting to FTP servers -- Paul A Sand
|
||||
#
|
||||
# Version 3.17
|
||||
# - Add support for connecting to imap servers -- Joerg Pareigis
|
||||
#
|
||||
# Version 3.16
|
||||
# - Add support for connecting to the mail sbmission port -- Luis E. Munoz
|
||||
#
|
||||
# Version 3.15
|
||||
# - Adjusted the file checking logic to use the correct certificate -- Maciej Szudejko
|
||||
# - Add sbin to the default search paths for OpenBSD compatibility -- Alex Popov
|
||||
# - Use cut instead of substring processing to ensure compatibility -- Alex Popov
|
||||
#
|
||||
# Version 3.14
|
||||
# - Fixed the Common Name parser to handle DN's where the CN is not the last item
|
||||
# eg. EmailAddr -- Jason Brothers
|
||||
# - Added the ability to grab the serial number -- Jason Brothers
|
||||
# - Added the "-b" option to print results without a header -- Jason Brothers
|
||||
# - Added the "-v" option for certificate validation -- Jason Brothers
|
||||
#
|
||||
# Version 3.13
|
||||
# - Updated the subject line to include the hostname as well as
|
||||
# the common name embedded in the X509 certificate (if it's
|
||||
# available) -- idea proposed by Mike Burns
|
||||
#
|
||||
# Version 3.12
|
||||
# - Updated the license to allow redistribution and modification
|
||||
#
|
||||
# Version 3.11
|
||||
# - Added ability to comment out lines in files passed
|
||||
# to the "-f" option -- Brett Stauner
|
||||
# - Fixed comment next to file processing logic
|
||||
#
|
||||
# Version 3.10
|
||||
# - Fixed POP3 port -- Simon Matter
|
||||
#
|
||||
# Version 3.9
|
||||
# - Switched binary location logic to use which utility
|
||||
#
|
||||
# Version 3.8
|
||||
# - Fixed display on 80 column displays
|
||||
# - Cleaned up the formatting
|
||||
#
|
||||
# Version 3.7
|
||||
# - Fixed bug in NAGIOS tests -- Ben Allen
|
||||
#
|
||||
# Version 3.6
|
||||
# - Added support for certificates stored in PKCS#12 databases -- Ken Gallo
|
||||
# - Cleaned up comments
|
||||
# - Adjusted variables to be more consistent
|
||||
#
|
||||
# Version 3.5
|
||||
# - Added support for NAGIOS -- Quanah Gibson-Mount
|
||||
# - Added additional checks for mail -- Quanah Gibson-Mount
|
||||
# - Convert tabs to spaces -- Quanah Gibson-Mount
|
||||
# - Cleaned up usage() routine
|
||||
# - Added additional checks for openssl
|
||||
#
|
||||
# Version 3.4
|
||||
# - Added a missing "{" to line 364 -- Ken Gallo
|
||||
# - Move mktemp to the start of the main body to avoid errors
|
||||
# - Adjusted default binary paths to make sure the script just works
|
||||
# w/ Solaris, BSD and Linux hosts
|
||||
#
|
||||
# Version 3.3
|
||||
# - Added common name from X.509 certificate file to E-mail body / header -- Doug Curtis
|
||||
# - Fixed several documentation errors
|
||||
# - Use mktemp to create temporary files
|
||||
# - Convert printf, sed and awk to variables
|
||||
# - Check for printf, sed, awk and mktemp binaries
|
||||
# - Add additional logic to make sure mktemp returned a valid temporary file
|
||||
#
|
||||
# Version 3.2
|
||||
# - Added option to list certificates in the file passed to "-f".
|
||||
#
|
||||
# Version 3.1
|
||||
# - Added handling for starttls for smtp -- Marco Amrein
|
||||
# - Added handling for starttls for pop3 (without s) -- Marco Amrein
|
||||
# - Removed extra spacing at end of script
|
||||
#
|
||||
# Version 3.0
|
||||
# - Added "-i" option to print certificate issuer
|
||||
# - Removed $0 from Subject line of outbound e-mails
|
||||
# - Fixed some typographical errors
|
||||
# - Removed redundant "-b" option
|
||||
#
|
||||
# Version 2.0
|
||||
# - Fixed an issue with e-mails formatting incorrectly
|
||||
# - Added additional space to host column -- Darren-Perot Spruell
|
||||
# - Replaced GNU date dependency with CHRIS F. A. JOHNSON's
|
||||
# date2julian shell function. This routine can be found on
|
||||
# page 170 of Chris's book "Shell Scripting Recipes: A
|
||||
# Problem-Solution Approach," ISBN #1590594711. Julian function
|
||||
# was created based on a post to comp.unix.shell by Tapani Tarvainen.
|
||||
# - Cleaned up function descriptions
|
||||
# - Removed several lines of redundant code
|
||||
# - Adjusted the help message
|
||||
#
|
||||
# Version 1.1
|
||||
# - Added "-c" flag to report expiration status of a PEM encoded
|
||||
# certificate -- Hampus Lundqvist
|
||||
# - Updated the prints messages to display the reason a connection
|
||||
# failed (connection refused, connection timeout, bad cert, etc)
|
||||
# - Updated the GNU date checking routines
|
||||
# - Added checks for each binary required
|
||||
# - Added checks for connection timeouts
|
||||
# - Added checks for GNU date
|
||||
# - Added a "-h" option
|
||||
# - Cleaned up the documentation
|
||||
#
|
||||
# Version 1.0
|
||||
# Initial Release
|
||||
#
|
||||
# Last Updated: 02-27-2013
|
||||
#
|
||||
# Purpose:
|
||||
# ssl-cert-check checks to see if a digital certificate in X.509 format
|
||||
# has expired. ssl-cert-check can be run in interactive and batch mode,
|
||||
# and provides facilities to alarm if a certificate is about to expire.
|
||||
#
|
||||
# License:
|
||||
# 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 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.
|
||||
#
|
||||
# Requirements:
|
||||
# Requires openssl
|
||||
#
|
||||
# Installation:
|
||||
# Copy the shell script to a suitable location
|
||||
#
|
||||
# Tested platforms:
|
||||
# -- Solaris 9 using /bin/bash
|
||||
# -- Solaris 10 using /bin/bash
|
||||
# -- OS X 10.4.2 using /bin/bash
|
||||
# -- OpenBSD using /bin/sh
|
||||
# -- FreeBSD using /bin/sh
|
||||
# -- Centos Linux 3, 4, 5 & 6 using /bin/bash
|
||||
# -- Redhat Enterprise Linux 3, 4, 5 & 6 using /bin/bash
|
||||
#
|
||||
# Usage:
|
||||
# Refer to the usage() sub-routine, or invoke ssl-cert-check
|
||||
# with the "-h" option.
|
||||
#
|
||||
# Examples:
|
||||
# Please refer to the following site for documentation and examples:
|
||||
# http://prefetch.net/articles/checkcertificate.html
|
||||
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/ssl/bin:/usr/sfw/bin
|
||||
export PATH
|
||||
|
||||
# Who to page when an expired certificate is detected (cmdline: -e)
|
||||
ADMIN="joerg@higgsboson.tk"
|
||||
|
||||
# Number of days in the warning threshhold (cmdline: -x)
|
||||
WARNDAYS=30
|
||||
|
||||
# If QUIET is set to TRUE, don't print anything on the console (cmdline: -q)
|
||||
QUIET="FALSE"
|
||||
|
||||
# Don't send E-mail by default (cmdline: -a)
|
||||
ALARM="FALSE"
|
||||
|
||||
# Don't run as a Nagios plugin by default (cmdline: -n)
|
||||
NAGIOS="FALSE"
|
||||
|
||||
# NULL out the PKCSDBPASSWD variable for later use (cmdline: -k)
|
||||
PKCSDBPASSWD=""
|
||||
|
||||
# Type of certificate (PEM, DER, NET) (cmdline: -t)
|
||||
CERTTYPE="pem"
|
||||
|
||||
# Protocol version to use (cmdline: -v)
|
||||
VERSION=""
|
||||
|
||||
# Send along the servername when TLS is used
|
||||
TLSSERVERNAME="TRUE"
|
||||
|
||||
# Location of system binaries
|
||||
AWK=$(which awk)
|
||||
DATE=$(which date)
|
||||
GREP=$(which grep)
|
||||
OPENSSL=$(which openssl)
|
||||
PRINTF=$(which printf)
|
||||
SED=$(which sed)
|
||||
MKTEMP=$(which mktemp)
|
||||
|
||||
# Try to find a mail client
|
||||
if [ -f /usr/bin/mailx ]
|
||||
then
|
||||
MAIL="/usr/bin/mailx"
|
||||
elif [ -f /bin/mail ]
|
||||
then
|
||||
MAIL="/bin/mail"
|
||||
elif [ -f /usr/bin/mail ]
|
||||
then
|
||||
MAIL="/usr/bin/mail"
|
||||
elif [ -f /sbin/mail ]
|
||||
then
|
||||
MAIL="/sbin/mail"
|
||||
elif [ -f /usr/sbin/mail ]
|
||||
then
|
||||
MAIL="/usr/sbin/mail"
|
||||
else
|
||||
MAIL="cantfindit"
|
||||
fi
|
||||
|
||||
# Return code used by nagios. Initialize to 0.
|
||||
RETCODE=0
|
||||
|
||||
# Set the default umask to be somewhat restrictive
|
||||
umask 077
|
||||
|
||||
#############################################################################
|
||||
# Purpose: Convert a date from MONTH-DAY-YEAR to Julian format
|
||||
# Acknowledgements: Code was adapted from examples in the book
|
||||
# "Shell Scripting Recipes: A Problem-Solution Approach"
|
||||
# ( ISBN 1590594711 )
|
||||
# Arguments:
|
||||
# $1 -> Month (e.g., 06)
|
||||
# $2 -> Day (e.g., 08)
|
||||
# $3 -> Year (e.g., 2006)
|
||||
#############################################################################
|
||||
date2julian() {
|
||||
|
||||
if [ "${1}" != "" ] && [ "${2}" != "" ] && [ "${3}" != "" ]
|
||||
then
|
||||
## Since leap years add aday at the end of February,
|
||||
## calculations are done from 1 March 0000 (a fictional year)
|
||||
d2j_tmpmonth=$((12 * ${3} + ${1} - 3))
|
||||
|
||||
## If it is not yet March, the year is changed to the previous year
|
||||
d2j_tmpyear=$(( ${d2j_tmpmonth} / 12))
|
||||
|
||||
## The number of days from 1 March 0000 is calculated
|
||||
## and the number of days from 1 Jan. 4713BC is added
|
||||
echo $(( (734 * ${d2j_tmpmonth} + 15) / 24
|
||||
- 2 * ${d2j_tmpyear} + ${d2j_tmpyear}/4
|
||||
- ${d2j_tmpyear}/100 + ${d2j_tmpyear}/400 + $2 + 1721119 ))
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# Purpose: Convert a string month into an integer representation
|
||||
# Arguments:
|
||||
# $1 -> Month name (e.g., Sep)
|
||||
#############################################################################
|
||||
getmonth()
|
||||
{
|
||||
case ${1} in
|
||||
Jan) echo 1 ;;
|
||||
Feb) echo 2 ;;
|
||||
Mar) echo 3 ;;
|
||||
Apr) echo 4 ;;
|
||||
May) echo 5 ;;
|
||||
Jun) echo 6 ;;
|
||||
Jul) echo 7 ;;
|
||||
Aug) echo 8 ;;
|
||||
Sep) echo 9 ;;
|
||||
Oct) echo 10 ;;
|
||||
Nov) echo 11 ;;
|
||||
Dec) echo 12 ;;
|
||||
*) echo 0 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
#############################################################################
|
||||
# Purpose: Calculate the number of seconds between two dates
|
||||
# Arguments:
|
||||
# $1 -> Date #1
|
||||
# $2 -> Date #2
|
||||
#############################################################################
|
||||
date_diff()
|
||||
{
|
||||
if [ "${1}" != "" ] && [ "${2}" != "" ]
|
||||
then
|
||||
echo $((${2} - ${1}))
|
||||
else
|
||||
echo 0
|
||||
fi
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# Purpose: Print a line with the expiraton interval
|
||||
# Arguments:
|
||||
# $1 -> Hostname
|
||||
# $2 -> TCP Port
|
||||
# $3 -> Status of certification (e.g., expired or valid)
|
||||
# $4 -> Date when certificate will expire
|
||||
# $5 -> Days left until the certificate will expire
|
||||
# $6 -> Issuer of the certificate
|
||||
#####################################################################
|
||||
prints()
|
||||
{
|
||||
if [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]
|
||||
then
|
||||
MIN_DATE=$(echo $4 | ${AWK} '{ print $1, $2, $4 }')
|
||||
if [ "${NAGIOS}" == "TRUE" ]
|
||||
then
|
||||
${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "$MIN_DATE" \|days="$5"
|
||||
else
|
||||
${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "$MIN_DATE" "$5"
|
||||
fi
|
||||
elif [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${VALIDATION}" == "TRUE" ]
|
||||
then
|
||||
${PRINTF} "%-35s %-35s %-32s %-17s\n" "$1:$2" "$7" "$8" "$6"
|
||||
|
||||
elif [ "${QUIET}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]
|
||||
then
|
||||
MIN_DATE=$(echo $4 | ${AWK} '{ print $1, $2, $4 }')
|
||||
if [ "${NAGIOS}" == "TRUE" ]
|
||||
then
|
||||
${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "$MIN_DATE" \|days="$5"
|
||||
else
|
||||
${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "$MIN_DATE" "$5"
|
||||
fi
|
||||
elif [ "${QUIET}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ]
|
||||
then
|
||||
${PRINTF} "%-35s %-35s %-32s\n" "$1:$2" "$7" "$8"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
####################################################
|
||||
# Purpose: Print a heading with the relevant columns
|
||||
# Arguments:
|
||||
# None
|
||||
####################################################
|
||||
print_heading()
|
||||
{
|
||||
if [ "${NOHEADER}" != "TRUE" ]
|
||||
then
|
||||
if [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]
|
||||
then
|
||||
${PRINTF} "\n%-35s %-17s %-8s %-11s %-4s\n" "Host" "Issuer" "Status" "Expires" "Days"
|
||||
echo "----------------------------------- ----------------- -------- ----------- ----"
|
||||
|
||||
elif [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ]
|
||||
then
|
||||
${PRINTF} "\n%-35s %-35s %-32s %-17s\n" "Host" "Common Name" "Serial #" "Issuer"
|
||||
echo "----------------------------------- ----------------------------------- -------------------------------- -----------------"
|
||||
|
||||
elif [ "${QUIET}" != "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]
|
||||
then
|
||||
${PRINTF} "\n%-47s %-12s %-12s %-4s\n" "Host" "Status" "Expires" "Days"
|
||||
echo "----------------------------------------------- ------------ ------------ ----"
|
||||
|
||||
elif [ "${QUIET}" != "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ]
|
||||
then
|
||||
${PRINTF} "\n%-35s %-35s %-32s\n" "Host" "Common Name" "Serial #"
|
||||
echo "----------------------------------- ----------------------------------- --------------------------------"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
##########################################
|
||||
# Purpose: Describe how the script works
|
||||
# Arguments:
|
||||
# None
|
||||
##########################################
|
||||
usage()
|
||||
{
|
||||
echo "Usage: $0 [ -e email address ] [ -x days ] [-q] [-a] [-b] [-h] [-i] [-n] [-v]"
|
||||
echo " { [ -s common_name ] && [ -p port] } || { [ -f cert_file ] } || { [ -c certificate file ] }"
|
||||
echo ""
|
||||
echo " -a : Send a warning message through E-mail"
|
||||
echo " -b : Will not print header"
|
||||
echo " -c cert file : Print the expiration date for the PEM or PKCS12 formatted certificate in cert file"
|
||||
echo " -e E-mail address : E-mail address to send expiration notices"
|
||||
echo " -f cert file : File with a list of FQDNs and ports"
|
||||
echo " -h : Print this screen"
|
||||
echo " -i : Print the issuer of the certificate"
|
||||
echo " -k password : PKCS12 file password"
|
||||
echo " -n : Run as a Nagios plugin"
|
||||
echo " -p port : Port to connect to (interactive mode)"
|
||||
echo " -s commmon name : Server to connect to (interactive mode)"
|
||||
echo " -t type : Specify the certificate type"
|
||||
echo " -q : Don't print anything on the console"
|
||||
echo " -v : Specify a specific protocol version to use (tls, ssl2, ssl3)"
|
||||
echo " -V : Only print validation data"
|
||||
echo " -x days : Certificate expiration interval (eg. if cert_date < days)"
|
||||
echo ""
|
||||
}
|
||||
|
||||
|
||||
##########################################################################
|
||||
# Purpose: Connect to a server ($1) and port ($2) to see if a certificate
|
||||
# has expired
|
||||
# Arguments:
|
||||
# $1 -> Server name
|
||||
# $2 -> TCP port to connect to
|
||||
##########################################################################
|
||||
check_server_status() {
|
||||
|
||||
if [ "_${2}" = "_smtp" -o "_${2}" = "_25" ]
|
||||
then
|
||||
TLSFLAG="-starttls smtp"
|
||||
|
||||
elif [ "_${2}" = "_ftp" -o "_${2}" = "_21" ]
|
||||
then
|
||||
TLSFLAG="-starttls ftp"
|
||||
|
||||
elif [ "_${2}" = "_pop3" -o "_${2}" = "_110" ]
|
||||
then
|
||||
TLSFLAG="-starttls pop3"
|
||||
|
||||
elif [ "_${2}" = "_imap" -o "_${2}" = "_143" ]
|
||||
then
|
||||
TLSFLAG="-starttls imap"
|
||||
elif [ "_${2}" = "_submission" -o "_${2}" = "_587" ]
|
||||
then
|
||||
TLSFLAG="-starttls smtp -port ${2}"
|
||||
elif [ "_${2}" = "_xmpp-client" -o "_${2}" = "_xmpp-server" -o \
|
||||
"_${2}" = "_5269" -o "_${2}" = "_5222" ]
|
||||
then
|
||||
TLSFLAG="-starttls xmpp"
|
||||
else
|
||||
TLSFLAG=""
|
||||
fi
|
||||
|
||||
if [ "${VERSION}" != "" ]
|
||||
then
|
||||
VER="-${VERSION}"
|
||||
fi
|
||||
|
||||
if [ "${TLSSERVERNAME}" = "TRUE" ]
|
||||
then
|
||||
TLSFLAG="${TLSFLAG} -servername $1"
|
||||
fi
|
||||
|
||||
echo "" | ${OPENSSL} s_client ${VER} -connect ${1}:${2} ${TLSFLAG} 2> ${ERROR_TMP} 1> ${CERT_TMP}
|
||||
|
||||
if ${GREP} -i "Connection refused" ${ERROR_TMP} > /dev/null
|
||||
then
|
||||
prints ${1} ${2} "Connection refused" "Unknown"
|
||||
RETCODE=3
|
||||
|
||||
elif ${GREP} -i "No route to host" ${ERROR_TMP} > /dev/null
|
||||
then
|
||||
prints ${1} ${2} "No route to host" "Unknown"
|
||||
RETCODE=3
|
||||
|
||||
elif ${GREP} -i "gethostbyname failure" ${ERROR_TMP} > /dev/null
|
||||
then
|
||||
prints ${1} ${2} "Cannot resolve domain" "Unknown"
|
||||
RETCODE=3
|
||||
|
||||
elif ${GREP} -i "Operation timed out" ${ERROR_TMP} > /dev/null
|
||||
then
|
||||
prints ${1} ${2} "Operation timed out" "Unknown"
|
||||
RETCODE=3
|
||||
|
||||
elif ${GREP} -i "ssl handshake failure" ${ERROR_TMP} > /dev/null
|
||||
then
|
||||
prints ${1} ${2} "SSL handshake failed" "Unknown"
|
||||
RETCODE=3
|
||||
|
||||
elif ${GREP} -i "connect: Connection timed out" ${ERROR_TMP} > /dev/null
|
||||
then
|
||||
prints ${1} ${2} "Connection timed out" "Unknown"
|
||||
RETCODE=3
|
||||
|
||||
else
|
||||
check_file_status ${CERT_TMP} $1 $2
|
||||
fi
|
||||
}
|
||||
|
||||
#####################################################
|
||||
### Check the expiration status of a certificate file
|
||||
### Accepts three parameters:
|
||||
### $1 -> certificate file to process
|
||||
### $2 -> Server name
|
||||
### $3 -> Port number of certificate
|
||||
#####################################################
|
||||
check_file_status() {
|
||||
|
||||
CERTFILE=${1}
|
||||
HOST=${2}
|
||||
PORT=${3}
|
||||
|
||||
### Check to make sure the certificate file exists
|
||||
if [ ! -r ${CERTFILE} ] || [ ! -s ${CERTFILE} ]
|
||||
then
|
||||
echo "ERROR: The file named ${CERTFILE} is unreadable or doesn't exist"
|
||||
echo "ERROR: Please check to make sure the certificate for ${HOST}:${PORT} is valid"
|
||||
RETCODE=1
|
||||
return
|
||||
fi
|
||||
|
||||
### Grab the expiration date from the X.509 certificate
|
||||
if [ "${PKCSDBPASSWD}" != "" ]
|
||||
then
|
||||
# Extract the certificate from the PKCS#12 database, and
|
||||
# send the informational message to /dev/null
|
||||
${OPENSSL} pkcs12 -nokeys -in ${CERTFILE} \
|
||||
-out ${CERT_TMP} -clcerts -password pass:${PKCSDBPASSWD} 2> /dev/null
|
||||
|
||||
# Extract the expiration date from the certificate
|
||||
CERTDATE=$(${OPENSSL} x509 -in ${CERT_TMP} -enddate -noout | \
|
||||
${SED} 's/notAfter\=//')
|
||||
|
||||
# Extract the issuer from the certificate
|
||||
CERTISSUER=$(${OPENSSL} x509 -in ${CERT_TMP} -issuer -noout | \
|
||||
${AWK} 'BEGIN {RS="/" } $0 ~ /^O=/ \
|
||||
{ print substr($0,3,17)}')
|
||||
|
||||
### Grab the common name (CN) from the X.509 certificate
|
||||
COMMONNAME=$(${OPENSSL} x509 -in ${CERT_TMP} -subject -noout | \
|
||||
${SED} -e 's/.*CN=//' | \
|
||||
${SED} -e 's/\/.*//')
|
||||
|
||||
### Grab the serial number from the X.509 certificate
|
||||
SERIAL=$(${OPENSSL} x509 -in ${CERT_TMP} -serial -noout | \
|
||||
${SED} -e 's/serial=//')
|
||||
else
|
||||
# Extract the expiration date from the ceriticate
|
||||
CERTDATE=$(${OPENSSL} x509 -in ${CERTFILE} -enddate -noout -inform ${CERTTYPE} | \
|
||||
${SED} 's/notAfter\=//')
|
||||
|
||||
# Extract the issuer from the certificate
|
||||
CERTISSUER=$(${OPENSSL} x509 -in ${CERTFILE} -issuer -noout -inform ${CERTTYPE} | \
|
||||
${AWK} 'BEGIN {RS="/" } $0 ~ /^O=/ { print substr($0,3,17)}')
|
||||
|
||||
### Grab the common name (CN) from the X.509 certificate
|
||||
COMMONNAME=$(${OPENSSL} x509 -in ${CERTFILE} -subject -noout -inform ${CERTTYPE} | \
|
||||
${SED} -e 's/.*CN=//' | \
|
||||
${SED} -e 's/\/.*//')
|
||||
### Grab the serial number from the X.509 certificate
|
||||
SERIAL=$(${OPENSSL} x509 -in ${CERTFILE} -serial -noout -inform ${CERTTYPE} | \
|
||||
${SED} -e 's/serial=//')
|
||||
fi
|
||||
|
||||
### Split the result into parameters, and pass the relevant pieces to date2julian
|
||||
set -- ${CERTDATE}
|
||||
MONTH=$(getmonth ${1})
|
||||
|
||||
# Convert the date to seconds, and get the diff between NOW and the expiration date
|
||||
CERTJULIAN=$(date2julian ${MONTH#0} ${2#0} ${4})
|
||||
CERTDIFF=$(date_diff ${NOWJULIAN} ${CERTJULIAN})
|
||||
|
||||
if [ ${CERTDIFF} -lt 0 ]
|
||||
then
|
||||
if [ "${ALARM}" = "TRUE" ]
|
||||
then
|
||||
echo "The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" \
|
||||
| ${MAIL} -s "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" ${ADMIN}
|
||||
fi
|
||||
|
||||
prints ${HOST} ${PORT} "Expired" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
|
||||
RETCODE=2
|
||||
|
||||
elif [ ${CERTDIFF} -lt ${WARNDAYS} ]
|
||||
then
|
||||
if [ "${ALARM}" = "TRUE" ]
|
||||
then
|
||||
echo "The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire on ${CERTDATE}" \
|
||||
| ${MAIL} -s "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire in ${WARNDAYS}-days or less" ${ADMIN}
|
||||
fi
|
||||
prints ${HOST} ${PORT} "Expiring" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
|
||||
RETCODE=1
|
||||
|
||||
else
|
||||
prints ${HOST} ${PORT} "Valid" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
|
||||
RETCODE=0
|
||||
fi
|
||||
}
|
||||
|
||||
#################################
|
||||
### Start of main program
|
||||
#################################
|
||||
while getopts abinv:e:f:c:hk:p:s:t:qx:V option
|
||||
do
|
||||
case "${option}"
|
||||
in
|
||||
a) ALARM="TRUE";;
|
||||
b) NOHEADER="TRUE";;
|
||||
c) CERTFILE=${OPTARG};;
|
||||
e) ADMIN=${OPTARG};;
|
||||
f) SERVERFILE=$OPTARG;;
|
||||
h) usage
|
||||
exit 1;;
|
||||
i) ISSUER="TRUE";;
|
||||
k) PKCSDBPASSWD=${OPTARG};;
|
||||
n) NAGIOS="TRUE";;
|
||||
p) PORT=$OPTARG;;
|
||||
s) HOST=$OPTARG;;
|
||||
t) CERTTYPE=$OPTARG;;
|
||||
q) QUIET="TRUE";;
|
||||
v) VERSION=$OPTARG;;
|
||||
V) VALIDATION="TRUE";;
|
||||
x) WARNDAYS=$OPTARG;;
|
||||
\?) usage
|
||||
exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
### Check to make sure a openssl utility is available
|
||||
if [ ! -f ${OPENSSL} ]
|
||||
then
|
||||
echo "ERROR: The openssl binary does not exist in ${OPENSSL}."
|
||||
echo "FIX: Please modify the \${OPENSSL} variable in the program header."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Check to make sure a date utility is available
|
||||
if [ ! -f ${DATE} ]
|
||||
then
|
||||
echo "ERROR: The date binary does not exist in ${DATE} ."
|
||||
echo "FIX: Please modify the \${DATE} variable in the program header."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Check to make sure a grep utility is available
|
||||
if [ ! -f ${GREP} ]
|
||||
then
|
||||
echo "ERROR: The grep binary does not exist in ${GREP} ."
|
||||
echo "FIX: Please modify the \${GREP} variable in the program header."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Check to make sure the mktemp and printf utilities are available
|
||||
if [ ! -f ${MKTEMP} ] || [ ! -f ${PRINTF} ]
|
||||
then
|
||||
echo "ERROR: Unable to locate the mktemp or printf binary."
|
||||
echo "FIX: Please modify the \${MKTEMP} and \${PRINTF} variables in the program header."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Check to make sure the sed and awk binaries are available
|
||||
if [ ! -f ${SED} ] || [ ! -f ${AWK} ]
|
||||
then
|
||||
echo "ERROR: Unable to locate the sed or awk binary."
|
||||
echo "FIX: Please modify the \${SED} and \${AWK} variables in the program header."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Check to make sure a mail client is available it automated notifications are requested
|
||||
if [ "${ALARM}" = "TRUE" ] && [ ! -f ${MAIL} ]
|
||||
then
|
||||
echo "ERROR: You enabled automated alerts, but the mail binary could not be found."
|
||||
echo "FIX: Please modify the ${MAIL} variable in the program header."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Place to stash temporary files
|
||||
CERT_TMP=$($MKTEMP /var/tmp/cert.XXXXXX)
|
||||
ERROR_TMP=$($MKTEMP /var/tmp/error.XXXXXX)
|
||||
|
||||
### Baseline the dates so we have something to compare to
|
||||
MONTH=$(${DATE} "+%m")
|
||||
DAY=$(${DATE} "+%d")
|
||||
YEAR=$(${DATE} "+%Y")
|
||||
NOWJULIAN=$(date2julian ${MONTH#0} ${DAY#0} ${YEAR})
|
||||
|
||||
### Touch the files prior to using them
|
||||
if [ ! -z "${CERT_TMP}" ] && [ ! -z "${ERROR_TMP}" ]
|
||||
then
|
||||
touch ${CERT_TMP} ${ERROR_TMP}
|
||||
else
|
||||
echo "ERROR: Problem creating temporary files"
|
||||
echo "FIX: Check that mktemp works on your system"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### If a HOST and PORT were passed on the cmdline, use those values
|
||||
if [ "${HOST}" != "" ] && [ "${PORT}" != "" ]
|
||||
then
|
||||
print_heading
|
||||
check_server_status "${HOST}" "${PORT}"
|
||||
|
||||
### If a file is passed to the "-f" option on the command line, check
|
||||
### each certificate or server / port combination in the file to see if
|
||||
### they are about to expire
|
||||
elif [ -f "${SERVERFILE}" ]
|
||||
then
|
||||
print_heading
|
||||
egrep -v '(^#|^$)' ${SERVERFILE} | while read HOST PORT
|
||||
do
|
||||
if [ "$PORT" = "FILE" ]
|
||||
then
|
||||
check_file_status ${HOST} "FILE" "${HOST}"
|
||||
else
|
||||
check_server_status "${HOST}" "${PORT}"
|
||||
fi
|
||||
done
|
||||
|
||||
### Check to see if the certificate in CERTFILE is about to expire
|
||||
elif [ "${CERTFILE}" != "" ]
|
||||
then
|
||||
print_heading
|
||||
check_file_status ${CERTFILE} "FILE" "${CERTFILE}"
|
||||
|
||||
### There was an error, so print a detailed usage message and exit
|
||||
else
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Remove the temporary files
|
||||
rm -f ${CERT_TMP} ${ERROR_TMP}
|
||||
|
||||
### Exit with a success indicator
|
||||
if [ "${NAGIOS}" = "TRUE" ]; then
|
||||
exit $RETCODE
|
||||
else
|
||||
exit 0
|
||||
fi
|
76
update-motd
Executable file
76
update-motd
Executable file
@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
#Script to update motd with relevant information.
|
||||
|
||||
#Define output file
|
||||
motd="/etc/motd"
|
||||
|
||||
# Collect information
|
||||
# $USER is automatically defined
|
||||
HOSTNAME=`uname -n`
|
||||
KERNEL=`uname -rm`
|
||||
INSTALLED_KERNEL=$(pacman -Qi linux-lts | awk '/Version/ { print $3 }')
|
||||
CPU=`awk -F '[ :][ :]+' '/^model name/ { print $2; exit; }' /proc/cpuinfo`
|
||||
CPU_TEMP=$(($(</sys/class/thermal/thermal_zone0/temp) / 1000))
|
||||
#CPU=`uname -p`
|
||||
ARCH=`uname -m`
|
||||
PACMAN=`pacman -Qu | wc -l`
|
||||
DISC=`df -hT | awk '/md0/ {print $4 "/" $3 " (" $6 ")" }'`
|
||||
MEMORY1=`free -t -m | grep "buffers/cache" | awk '{print $3" MB";}'`
|
||||
MEMORY2=`free -t -m | grep "Mem" | awk '{print $2" MB";}'`
|
||||
PSA=`ps -Afl | wc -l`
|
||||
PSU=`ps U $USER h | wc -l`
|
||||
|
||||
#System uptime
|
||||
uptime=`cat /proc/uptime | cut -f1 -d.`
|
||||
upDays=$((uptime/60/60/24))
|
||||
upHours=$((uptime/60/60%24))
|
||||
upMins=$((uptime/60%60))
|
||||
upSecs=$((uptime%60))
|
||||
|
||||
|
||||
#System load
|
||||
LOAD1=`awk {'print $1'} /proc/loadavg`
|
||||
LOAD5=`awk {'print $2'} /proc/loadavg`
|
||||
LOAD15=`awk {'print $3'} /proc/loadavg`
|
||||
|
||||
#Color variables
|
||||
W="\033[00;37m"
|
||||
B="\033[01;36m"
|
||||
R="\033[01;34m"
|
||||
X="\033[01;37m"
|
||||
A="\033[01;32m"
|
||||
|
||||
#Clear screen before motd
|
||||
clear > $motd
|
||||
|
||||
echo -e "
|
||||
$A. $X
|
||||
$A/#\ $X _ $A _ _
|
||||
$A/###\ $X __ _ _ __ ___| |__ $A| (_)_ __ _ ___ __
|
||||
$A/#####\ $X / _' | '__/ __| '_ \ $A| | | '_ \| | | \ \/ /
|
||||
$A/##.-.##\ $X | (_| | | | (__| | | |$A| | | | | | |_| |> <
|
||||
$A/##( )##\ $X \__,_|_| \___|_| |_|$A|_|_|_| |_|\__,_/_/\_\\
|
||||
$A/#.-- --.#\ $X
|
||||
$A/' '\ $B
|
||||
" >> $motd
|
||||
|
||||
echo -e "$R===============================================================" >> $motd
|
||||
echo -e " $R KERNEL $W= $KERNEL (installed: $INSTALLED_KERNEL) " >> $motd
|
||||
echo -e " $R CPU $W= $CPU " >> $motd
|
||||
echo -e " $R HOSTNAME $W= $HOSTNAME " >> $motd
|
||||
echo -e " $R SYSTEM $W= $PACMAN packages can be updated " >> $motd
|
||||
echo -e " $R USERS $W= Currently `users | wc -w` users logged on " >> $motd
|
||||
echo -e "$R===============================================================" >> $motd
|
||||
echo -e " $R CPU Usage $W= $LOAD1 1 min $LOAD5 5 min $LOAD15 15 min " >> $motd
|
||||
echo -e " $R CPU Temperature $W= $CPU_TEMP" >> $motd
|
||||
echo -e " $R Memory Used $W= $MEMORY1 / $MEMORY2 " >> $motd
|
||||
echo -e " $R Swap in use $W= `free -m | tail -n 1 | awk '{print $3}'` MB " >> $motd
|
||||
echo -e " $R Processes $W= You are running $PSU of $PSA processes " >> $motd
|
||||
echo -e " $R System Uptime $W= $upDays days $upHours hours $upMins minutes $upSecs seconds " >> $motd
|
||||
echo -e " $R Disk Space Used (md0) $W= $DISC " >> $motd
|
||||
echo -e "$R===============================================================" >> $motd
|
||||
echo -en "$W" >> $motd
|
||||
zpool list >> $motd
|
||||
echo -e "$R===============================================================" >> $motd
|
||||
script -c "systemctl --failed" /dev/null | grep -E '●| UNIT' >> $motd
|
||||
echo -e "$X" >> $motd
|
Loading…
Reference in New Issue
Block a user