mirror of
https://github.com/ovh/the-bastion.git
synced 2025-01-09 00:44:49 +08:00
108 lines
3.1 KiB
Perl
Executable file
108 lines
3.1 KiB
Perl
Executable file
#! /usr/bin/env perl
|
|
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
|
#
|
|
# DESC: Check that the bastion code works (healtheck)
|
|
|
|
use strict;
|
|
use warnings;
|
|
use File::Basename;
|
|
use Getopt::Long;
|
|
|
|
my $PROBE_NAME = basename($0);
|
|
my $debug;
|
|
|
|
## no critic (Subroutines::RequireArgUnpacking)
|
|
## no critic (Subroutines::RequireFinalReturn)
|
|
|
|
sub _out {
|
|
my ($criticity, $msg) = @_;
|
|
printf "%s %4s - %s\n", $PROBE_NAME, $criticity, $msg;
|
|
}
|
|
|
|
sub _dbg { _out('dbg', $_[0]) if $debug; }
|
|
sub _info { _out('info', $_[0]); }
|
|
sub _warn { _out('WARN', $_[0]); }
|
|
sub _err { _out('ERR!', $_[0]); }
|
|
|
|
sub success { my $msg = shift; _info($msg) if $msg; _info("status=OK"); exit(0); }
|
|
sub warning { my $msg = shift; _warn($msg) if $msg; _info("status=WARN"); exit(1); }
|
|
sub failure { my $msg = shift; _err($msg) if $msg; _info("status=FAILURE"); exit(2); }
|
|
sub unknown { my $msg = shift; _err($msg) if $msg; _info("status=UNKNOWN"); exit(3); }
|
|
|
|
# OPTIONS
|
|
|
|
my $host = "127.0.0.1";
|
|
my $port = 22;
|
|
my $account = 'healthcheck';
|
|
my $keyfile = '/home/healthcheck/.ssh/id_healthcheck';
|
|
my $kbdinteractive = 0;
|
|
|
|
GetOptions(
|
|
"help" => \my $help,
|
|
"debug!" => \$debug,
|
|
"host=s" => \$host,
|
|
"port=i" => \$port,
|
|
"account=s" => \$account,
|
|
"keyfile=s" => \$keyfile,
|
|
"kbd-interactive" => \$kbdinteractive,
|
|
) or unknown("Failed parsing command-line");
|
|
|
|
# HELP
|
|
|
|
if ($help) {
|
|
print <<"EOF";
|
|
|
|
$PROBE_NAME [options]
|
|
|
|
--help This help message
|
|
--debug Increase verbosity of logs
|
|
--host HOST Host to connect to. Default: $host
|
|
--port PORT Port to connect to. Default: $port
|
|
--account ACCOUNT Account name to use to authenticate. Default: $account
|
|
--keyfile PATH Path to the private SSH key file to authenticate. Defaut: $keyfile
|
|
--kbd-interactive Allow keyboard-interactive authentication. Default: $kbdinteractive
|
|
|
|
Note: don't specify an other option than --help to get the proper default values.
|
|
|
|
EOF
|
|
unknown();
|
|
}
|
|
|
|
# CODE
|
|
|
|
if ($account !~ /^[a-zA-Z0-9._-]+$/) {
|
|
unknown("Specified account is invalid ($account)");
|
|
}
|
|
|
|
if ($host !~ /^[a-zA-Z0-9._-]+$/) {
|
|
unknown("Specified host is invalid ($host)");
|
|
}
|
|
|
|
if ($port <= 0 || $port > 65535) {
|
|
unknown("Specified port is invalid ($port)");
|
|
}
|
|
|
|
if (!-f -r $keyfile) {
|
|
unknown("Specified keyfile '$keyfile' is not readable or not a file");
|
|
}
|
|
|
|
# first; check that sudo is healthy
|
|
_dbg("Checking sudo viability...");
|
|
my $sysret = system(qw{ sudo -n -v });
|
|
if ($sysret != 0) {
|
|
critical("sudo is broken!");
|
|
}
|
|
|
|
my @cmd = ('ssh', '-l', $account, '-i', $keyfile, '-p', $port);
|
|
if ($kbdinteractive) {
|
|
push @cmd,
|
|
('-o', 'KbdInteractiveAuthentication=yes', '-o', 'PreferredAuthentications=publickey,keyboard-interactive');
|
|
}
|
|
push @cmd, ($host, '--', '-q', '--osh', 'info');
|
|
_dbg("Executing: " . join(" ", @cmd));
|
|
|
|
$sysret = system(@cmd);
|
|
if ($sysret == 0) {
|
|
success("Connection worked and ended successfully");
|
|
}
|
|
failure("Connection failed (SSH return code = " . ($sysret >> 8) . ")");
|