mirror of
https://github.com/ovh/the-bastion.git
synced 2024-09-20 06:55:58 +08:00
feat: add osh-cleanup-guest-key-access.pl script
This script removes system-level access to group keys to old guests of groups that no longer have any active access to servers of that group. This only happens when the last access to be removed from them had a TTL.
This commit is contained in:
parent
f43fdaaf82
commit
e71aa7b975
158
bin/cron/osh-cleanup-guest-key-access.pl
Executable file
158
bin/cron/osh-cleanup-guest-key-access.pl
Executable file
|
@ -0,0 +1,158 @@
|
|||
#! /usr/bin/env perl
|
||||
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
|
||||
use common::sense;
|
||||
use Getopt::Long;
|
||||
|
||||
use File::Basename;
|
||||
use lib dirname(__FILE__) . '/../../lib/perl';
|
||||
use OVH::Bastion;
|
||||
use OVH::Result;
|
||||
use OVH::SimpleLog;
|
||||
|
||||
# this'll be used in syslog
|
||||
$ENV{'UNIQID'} = OVH::Bastion::generate_uniq_id()->value;
|
||||
|
||||
my $fnret;
|
||||
|
||||
# abort early if we're not a master instance
|
||||
if (OVH::Bastion::config('readOnlySlaveMode')->value) {
|
||||
_log "We're not a master instance, don't do anything";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
$fnret = OVH::Bastion::load_configuration_file(
|
||||
file => OVH::Bastion::main_configuration_directory() . "/osh-cleanup-guest-access.conf",
|
||||
secure => 1,
|
||||
keywords => [qw{ SyslogFacility }],
|
||||
);
|
||||
|
||||
my $config;
|
||||
if (!$fnret) {
|
||||
if (-e OVH::Bastion::main_configuration_directory() . "/osh-cleanup-guest-access.conf") {
|
||||
_warn "Error while loading configuration, continuing anyway with default values...";
|
||||
}
|
||||
else {
|
||||
_log "No configuration file found, using default config values...";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$config = $fnret->value;
|
||||
if (ref $config ne 'HASH') {
|
||||
_warn "Invalid data returned while loading configuration, continuing anyway with default values...";
|
||||
}
|
||||
}
|
||||
|
||||
# set default values
|
||||
$config = {} if ref $config ne 'HASH';
|
||||
$config->{'SyslogFacility'} //= 'local6';
|
||||
|
||||
# logging
|
||||
if ($config->{'SyslogFacility'}) {
|
||||
OVH::SimpleLog::setSyslog($config->{'SyslogFacility'});
|
||||
}
|
||||
|
||||
# command-line
|
||||
sub print_usage {
|
||||
print <<"EOF";
|
||||
|
||||
$0 [options]
|
||||
|
||||
--dry-run Don't actually do anything, just report what would be done
|
||||
--verbose More detailed logging
|
||||
|
||||
EOF
|
||||
return 1;
|
||||
}
|
||||
|
||||
my ($dryRun, $verbose);
|
||||
{
|
||||
my $optwarn = 'Unknown error';
|
||||
local $SIG{'__WARN__'} = sub { $optwarn = shift; };
|
||||
if (
|
||||
!GetOptions(
|
||||
"dry-run" => \$dryRun,
|
||||
"verbose+" => \$verbose,
|
||||
)
|
||||
)
|
||||
{
|
||||
_err "Error while parsing command-line options: $optwarn";
|
||||
print_usage();
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
_log "Looking for group guests that no longer have any access to any server of the group...";
|
||||
|
||||
$fnret = OVH::Bastion::get_group_list(groupType => "key");
|
||||
if (!$fnret) {
|
||||
_err "Couldn't get group list:" . $fnret->msg;
|
||||
exit 1;
|
||||
}
|
||||
my $groups = $fnret->value;
|
||||
|
||||
foreach my $shortGroup (sort keys %$groups) {
|
||||
foreach my $account (@{$groups->{$shortGroup}{'members'}}) {
|
||||
next if ($account eq 'allowkeeper'); # don't need to check this special user
|
||||
|
||||
_log "<$shortGroup/$account> checking if group guest..." if $verbose;
|
||||
|
||||
# rule out realm accounts, we would need to check every remote account's info
|
||||
next if ($account =~ /^realm_/);
|
||||
|
||||
# the "members" of the system group key$shortGroup might be either members or guests,
|
||||
# so we first rule out members
|
||||
next if OVH::Bastion::is_group_member(account => $account, group => $shortGroup);
|
||||
|
||||
# it seems to be a guest, double-check that
|
||||
next if !OVH::Bastion::is_group_guest(account => $account, group => $shortGroup);
|
||||
|
||||
_log "<$shortGroup/$account> found a guest, checking remaining accesses..." if $verbose;
|
||||
|
||||
# okay, any access remaining?
|
||||
$fnret = OVH::Bastion::get_acl_way(way => 'groupguest', group => $shortGroup, account => $account);
|
||||
if (!$fnret) {
|
||||
_warn "<$shortGroup/$account> Error getting guest accesses ($fnret), skipping";
|
||||
next;
|
||||
}
|
||||
elsif ($fnret->err eq 'OK') {
|
||||
_log "<$shortGroup/$account> The account still has " . (@{$fnret->value}) . " accesses to the group, skipping" if $verbose;
|
||||
next;
|
||||
}
|
||||
elsif ($fnret->err eq 'OK_EMPTY' && !@{$fnret->value}) {
|
||||
|
||||
# this is a guest, but no ACL remains (probably the last one had a TTL),
|
||||
# so we'll cleanup this guest
|
||||
if ($dryRun) {
|
||||
_log "<$shortGroup/$account> The account is a guest of group but has no remaining access, would have cleaned up in non-dry-run mode";
|
||||
next;
|
||||
}
|
||||
_log "<$shortGroup/$account> The account is a guest of group but has no remaining access, cleaning up...";
|
||||
|
||||
# get $group from $shortGroup
|
||||
$fnret = OVH::Bastion::is_valid_group_and_existing(group => $shortGroup, groupType => 'key');
|
||||
if (!$fnret) {
|
||||
_warn "<$shortGroup/$account> Group seems invalid ($fnret), skipping";
|
||||
next;
|
||||
}
|
||||
my $group = $fnret->value->{'group'};
|
||||
|
||||
# remove account from group
|
||||
my @command = qw{ /usr/bin/env perl -T };
|
||||
push @command, $OVH::Bastion::BASEPATH . '/bin/helper/osh-groupSetRole';
|
||||
push @command, '--type', 'guest';
|
||||
push @command, '--group', $group;
|
||||
push @command, '--account', $account;
|
||||
push @command, '--action', 'del';
|
||||
$fnret = OVH::Bastion::helper(cmd => \@command);
|
||||
|
||||
if (!$fnret) {
|
||||
_err "<$shortGroup/$account> Failed to revoke key access: $fnret";
|
||||
}
|
||||
else {
|
||||
_log "<$shortGroup/$account> Key access revoked";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_log "Done, got " . (OVH::SimpleLog::nb_errors()) . " error(s) and " . (OVH::SimpleLog::nb_warnings()) . " warning(s).";
|
16
etc/bastion/osh-cleanup-guest-key-access.conf.dist
Normal file
16
etc/bastion/osh-cleanup-guest-key-access.conf.dist
Normal file
|
@ -0,0 +1,16 @@
|
|||
###############################################################################
|
||||
## Config for /opt/bastion/bin/cron/osh-cleanup-guest-key-access.pl, the script
|
||||
## responsible for cleaning up dangling accesses to group keys to group guests
|
||||
## that no longer have access to any server of the group (happens when the last
|
||||
## access expired with a TTL).
|
||||
## This is a JSON file.
|
||||
###############################################################################
|
||||
{
|
||||
# > Logging
|
||||
# >> These options configure the way the script logs its actions
|
||||
#
|
||||
# SyslogFacility (string)
|
||||
# DESC: The syslog facility to use for logging the script output. If set to the empty string, we'll not log through syslog at all. If this configuration option is missing from your config file altogether, the default value will be used (local6), which means that we'll log to syslog.
|
||||
# DEFAULT: local6
|
||||
"SyslogFacility": "local6"
|
||||
}
|
2
etc/cron.d/osh-cleanup-guest-key-access.dist
Normal file
2
etc/cron.d/osh-cleanup-guest-key-access.dist
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Check each 5 minutes that we don't have dangling guests still having access to keys
|
||||
*/5 * * * * root /opt/bastion/bin/cron/osh-cleanup-guest-key-access.pl >/dev/null
|
|
@ -73,6 +73,13 @@ testsuite_scripts()
|
|||
nocontain "ERROR:"
|
||||
nocontain "Unexpected termination"
|
||||
|
||||
# cleanup guest key access
|
||||
|
||||
success cleanup_guest_key_access $r0 /opt/bastion/bin/cron/osh-cleanup-guest-key-access.pl
|
||||
contain "Done"
|
||||
nocontain "WARN:"
|
||||
nocontain "ERROR:"
|
||||
|
||||
# encrypt rsync (nothing to encrypt)
|
||||
|
||||
success encrypt_rsync_none $r0 /opt/bastion/bin/cron/osh-encrypt-rsync.pl
|
||||
|
@ -80,7 +87,6 @@ testsuite_scripts()
|
|||
contain "Done"
|
||||
nocontain "WARN:"
|
||||
nocontain "ERROR:"
|
||||
nocontain "Unexpected termination"
|
||||
|
||||
# ttyrec subfolders cleanup
|
||||
success ttyrec_cleanup $r0 /opt/bastion/bin/cron/osh-remove-empty-folders.sh
|
||||
|
|
Loading…
Reference in a new issue