#! /usr/bin/env perl # vim: set filetype=perl ts=4 sw=4 sts=4 et: use common::sense; 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-piv-grace-reaper.conf", secure => 1, ); my $config; if (!$fnret) { if (-e OVH::Bastion::main_configuration_directory() . "/osh-piv-grace-reaper.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->{'syslog_facility'} //= ($config->{'SyslogFacility'} // 'local6'); $config->{'enabled'} //= ($config->{'Enabled'} // 1); # logging if ($config->{'syslog_facility'}) { OVH::SimpleLog::setSyslog($config->{'syslog_facility'}); } if (!$config->{'enabled'}) { _log "Script is disabled."; exit 0; } _log "Looking for accounts with a PIV grace..."; # loop through all the accounts, and only work on those that have a grace period set $fnret = OVH::Bastion::get_account_list(); if (!$fnret) { _err "Couldn't get account list: " . $fnret->msg; exit 1; } foreach my $account (sort keys %{$fnret->value}) { # if account doesn't have PIV grace, we have nothing to do $fnret = OVH::Bastion::account_config( account => $account, public => 1, key => OVH::Bastion::OPT_ACCOUNT_INGRESS_PIV_GRACE ); next if !$fnret; # we have PIV grace set for this account my $expiry = $fnret->value; my $human = OVH::Bastion::duration2human(seconds => ($expiry - time()))->value; _log "Account $account has PIV grace expiry set to $expiry (" . $human->{'human'} . ")"; # is PIV grace TTL expired? if (time() < $expiry) { _log "... grace for $account is not expired yet, skipping..."; next; } # it is: remove it _log "... grace for $account is expired, removing it"; $fnret = OVH::Bastion::account_config( account => $account, public => 1, key => OVH::Bastion::OPT_ACCOUNT_INGRESS_PIV_GRACE, delete => 1 ); if (!$fnret) { warn_syslog("Couldn't remove grace flag for $account: " . $fnret->msg); _err "... couldn't remove grace flag for $account"; next; } $fnret = OVH::Bastion::syslogFormatted( severity => 'info', type => 'account', fields => [ [action => 'modify'], [account => $account], [item => 'piv_grace'], [old => 'true'], [new => 'false'], [comment => "PIV grace up to " . $human->{'human'} . " has been removed"] ] ); # PIV grace expired, if the effective piv policy for this account is enabled (depending on global and account specific policy), # we need to remove the non-PIV keys from the account's authorized_keys2 file, as we're now out from grace $fnret = OVH::Bastion::is_effective_piv_account_policy_enabled(account => $account); if ($fnret->is_err) { my $msg = "Couldn't get the effective PIV account policy of $account (" . $fnret->msg . ")"; warn_syslog($msg); _err("... $msg"); } elsif ($fnret->is_ok) { # effective policy is enabled, remove non-piv keys OVH::SimpleLog::closeSyslog(); $fnret = OVH::Bastion::ssh_ingress_keys_piv_apply(action => "enable", account => $account); if ($config && $config->{'SyslogFacility'}) { OVH::SimpleLog::setSyslog($config->{'SyslogFacility'}); } if (!$fnret) { my $msg = "failed to re-enforce PIV policy for $account (" . $fnret->msg . ")"; warn_syslog($msg); _err("... $msg"); } else { _log "... re-enforced PIV policy for $account"; } } else { _log "... effective policy is disabled for this $account, not disabling non-PIV keys"; } } _log "Done, got " . (OVH::SimpleLog::nb_errors()) . " error(s) and " . (OVH::SimpleLog::nb_warnings()) . " warning(s).";