mirror of
https://github.com/ovh/the-bastion.git
synced 2025-01-01 13:01:53 +08:00
feat: accountModify: add --osh-only (closes #97)
This commit is contained in:
parent
faf1079802
commit
a204313af9
9 changed files with 41 additions and 8 deletions
|
@ -363,7 +363,7 @@ else {
|
||||||
|
|
||||||
# push this flag to prevent ssh/telnet usage
|
# push this flag to prevent ssh/telnet usage
|
||||||
if ($oshOnly) {
|
if ($oshOnly) {
|
||||||
$fnret = OVH::Bastion::account_config(account => $account, key => "osh_only", value => "yes");
|
$fnret = OVH::Bastion::account_config(account => $account, key => OVH::Bastion::OPT_ACCOUNT_OSH_ONLY, value => "yes");
|
||||||
$fnret or HEXIT($fnret);
|
$fnret or HEXIT($fnret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,8 +178,12 @@ sub _toggle_yes_no {
|
||||||
my $keyname = $params{'keyname'};
|
my $keyname = $params{'keyname'};
|
||||||
my $keyfile = $params{'keyfile'};
|
my $keyfile = $params{'keyfile'};
|
||||||
my $value = $params{'value'};
|
my $value = $params{'value'};
|
||||||
|
my $public = $params{'public'};
|
||||||
|
|
||||||
$fnret = OVH::Bastion::account_config(account => $account, public => 1, key => $keyfile);
|
# by default, if public is not specified, it's 1
|
||||||
|
$public = 1 if !exists $params{'public'};
|
||||||
|
|
||||||
|
$fnret = OVH::Bastion::account_config(account => $account, public => $public, key => $keyfile);
|
||||||
if ($value eq 'yes') {
|
if ($value eq 'yes') {
|
||||||
osh_info "Setting this account as $keyname...";
|
osh_info "Setting this account as $keyname...";
|
||||||
if ($fnret) {
|
if ($fnret) {
|
||||||
|
@ -187,7 +191,7 @@ sub _toggle_yes_no {
|
||||||
return R('OK_NO_CHANGE');
|
return R('OK_NO_CHANGE');
|
||||||
}
|
}
|
||||||
|
|
||||||
$fnret = OVH::Bastion::account_config(account => $account, public => 1, key => $keyfile, value => 'yes');
|
$fnret = OVH::Bastion::account_config(account => $account, public => $public, key => $keyfile, value => 'yes');
|
||||||
if (!$fnret) {
|
if (!$fnret) {
|
||||||
osh_warn "... error while setting the option";
|
osh_warn "... error while setting the option";
|
||||||
return R('ERR_OPTION_CHANGE_FAILED');
|
return R('ERR_OPTION_CHANGE_FAILED');
|
||||||
|
@ -203,7 +207,7 @@ sub _toggle_yes_no {
|
||||||
return R('OK_NO_CHANGE');
|
return R('OK_NO_CHANGE');
|
||||||
}
|
}
|
||||||
|
|
||||||
$fnret = OVH::Bastion::account_config(account => $account, public => 1, key => $keyfile, delete => 1);
|
$fnret = OVH::Bastion::account_config(account => $account, public => $public, key => $keyfile, delete => 1);
|
||||||
if (!$fnret) {
|
if (!$fnret) {
|
||||||
osh_warn "... error while removing the option";
|
osh_warn "... error while removing the option";
|
||||||
return R('ERR_OPTION_CHANGE_FAILED');
|
return R('ERR_OPTION_CHANGE_FAILED');
|
||||||
|
@ -230,6 +234,9 @@ foreach my $tuple (@modify) {
|
||||||
elsif ($key eq 'idle-ignore') {
|
elsif ($key eq 'idle-ignore') {
|
||||||
$result{$jsonkey} = _toggle_yes_no(value => $value, keyfile => OVH::Bastion::OPT_ACCOUNT_IDLE_IGNORE, keyname => 'idle-ignore');
|
$result{$jsonkey} = _toggle_yes_no(value => $value, keyfile => OVH::Bastion::OPT_ACCOUNT_IDLE_IGNORE, keyname => 'idle-ignore');
|
||||||
}
|
}
|
||||||
|
elsif ($key eq 'osh-only') {
|
||||||
|
$result{$jsonkey} = _toggle_yes_no(value => $value, public => 0, keyfile => OVH::Bastion::OPT_ACCOUNT_OSH_ONLY, keyname => 'osh-only');
|
||||||
|
}
|
||||||
elsif ($key eq 'pam-auth-bypass') {
|
elsif ($key eq 'pam-auth-bypass') {
|
||||||
$fnret = OVH::Bastion::is_user_in_group(user => $account, group => OVH::Bastion::PAM_AUTH_BYPASS_GROUP);
|
$fnret = OVH::Bastion::is_user_in_group(user => $account, group => OVH::Bastion::PAM_AUTH_BYPASS_GROUP);
|
||||||
if ($value eq 'yes') {
|
if ($value eq 'yes') {
|
||||||
|
|
|
@ -34,7 +34,7 @@ Usage: --osh SCRIPT_NAME --account ACCOUNT [OPTIONS]
|
||||||
--uid-auto Auto-select an UID from the allowed range (the upper available one will be used)
|
--uid-auto Auto-select an UID from the allowed range (the upper available one will be used)
|
||||||
--always-active This account's activation won't be challenged on connection, even if the bastion is globally
|
--always-active This account's activation won't be challenged on connection, even if the bastion is globally
|
||||||
configured to check for account activation
|
configured to check for account activation
|
||||||
--osh-only This account will only be able to use OSH commands, and not connecting to machines (ssh or telnet)
|
--osh-only This account will only be able to use ``--osh`` commands, and can't connect anywhere through the bastion
|
||||||
--immutable-key Deny any subsequent modification of the account key (selfAddKey and selfDelKey are denied)
|
--immutable-key Deny any subsequent modification of the account key (selfAddKey and selfDelKey are denied)
|
||||||
--comment '"STRING"' An optional comment when creating the account. Quote it twice as shown if you're under a shell.
|
--comment '"STRING"' An optional comment when creating the account. Quote it twice as shown if you're under a shell.
|
||||||
--public-key '"KEY"' Account public SSH key to deposit on the bastion, if not present,
|
--public-key '"KEY"' Account public SSH key to deposit on the bastion, if not present,
|
||||||
|
|
|
@ -21,6 +21,7 @@ my $remainingOptions = OVH::Bastion::Plugin::begin(
|
||||||
"egress-strict-host-key-checking=s" => \$modify{'egress-strict-host-key-checking'},
|
"egress-strict-host-key-checking=s" => \$modify{'egress-strict-host-key-checking'},
|
||||||
"personal-egress-mfa-required=s" => \$modify{'personal-egress-mfa-required'},
|
"personal-egress-mfa-required=s" => \$modify{'personal-egress-mfa-required'},
|
||||||
"idle-ignore=s" => \$modify{'idle-ignore'},
|
"idle-ignore=s" => \$modify{'idle-ignore'},
|
||||||
|
"osh-only=s" => \$modify{'osh-only'},
|
||||||
},
|
},
|
||||||
helptext => <<'EOF',
|
helptext => <<'EOF',
|
||||||
Modify an account configuration
|
Modify an account configuration
|
||||||
|
@ -43,6 +44,7 @@ Usage: --osh SCRIPT_NAME --account ACCOUNT [--option value [--option value [...]
|
||||||
using the personal keys of the account, POLICY can be 'password', 'totp', 'any' or 'none'
|
using the personal keys of the account, POLICY can be 'password', 'totp', 'any' or 'none'
|
||||||
--always-active yes|no Set or unset the account as always active (i.e. disable the check of the 'active' status on this account)
|
--always-active yes|no Set or unset the account as always active (i.e. disable the check of the 'active' status on this account)
|
||||||
--idle-ignore yes|no If enabled, this account is immune to the idleLockTimeout and idleKillTimeout bastion-wide policy
|
--idle-ignore yes|no If enabled, this account is immune to the idleLockTimeout and idleKillTimeout bastion-wide policy
|
||||||
|
--osh-only yes|no If enabled, this account can only use ``--osh`` commands, and can't connect anywhere through the bastion
|
||||||
EOF
|
EOF
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ foreach my $key (qw{ mfa-password-required mfa-totp-required }) {
|
||||||
osh_exit 'ERR_INVALID_PARAMETER', "Expected '--$key yes' or '--$key no' or '--$key bypass' instead of '--$key $modify{$key}'";
|
osh_exit 'ERR_INVALID_PARAMETER', "Expected '--$key yes' or '--$key no' or '--$key bypass' instead of '--$key $modify{$key}'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach my $key (qw{ always-active pam-auth-bypass idle-ignore }) {
|
foreach my $key (qw{ always-active pam-auth-bypass idle-ignore osh-only }) {
|
||||||
next unless $modify{$key};
|
next unless $modify{$key};
|
||||||
if (not grep { $modify{$key} eq $_ } qw{ yes no }) {
|
if (not grep { $modify{$key} eq $_ } qw{ yes no }) {
|
||||||
help();
|
help();
|
||||||
|
|
|
@ -970,7 +970,7 @@ if (!$quiet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
# before doing stuff, check if we have the right to connect somewhere (some users are locked only to osh commands)
|
# before doing stuff, check if we have the right to connect somewhere (some users are locked only to osh commands)
|
||||||
$fnret = OVH::Bastion::account_config(account => $self, key => "osh_only");
|
$fnret = OVH::Bastion::account_config(account => $self, key => OVH::Bastion::OPT_ACCOUNT_OSH_ONLY);
|
||||||
if ($fnret and $fnret->value() =~ /yes/) {
|
if ($fnret and $fnret->value() =~ /yes/) {
|
||||||
$fnret = R('KO_ACCESS_DENIED', msg => "You don't have the right to connect anywhere");
|
$fnret = R('KO_ACCESS_DENIED', msg => "You don't have the right to connect anywhere");
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ Create a new bastion account
|
||||||
configured to check for account activation
|
configured to check for account activation
|
||||||
.. option:: --osh-only
|
.. option:: --osh-only
|
||||||
|
|
||||||
This account will only be able to use OSH commands, and not connecting to machines (ssh or telnet)
|
This account will only be able to use ``--osh`` commands, and can't connect anywhere through the bastion
|
||||||
|
|
||||||
.. option:: --immutable-key
|
.. option:: --immutable-key
|
||||||
|
|
||||||
|
|
|
@ -54,5 +54,9 @@ Modify an account configuration
|
||||||
|
|
||||||
If enabled, this account is immune to the idleLockTimeout and idleKillTimeout bastion-wide policy
|
If enabled, this account is immune to the idleLockTimeout and idleKillTimeout bastion-wide policy
|
||||||
|
|
||||||
|
.. option:: --osh-only yes|no
|
||||||
|
|
||||||
|
If enabled, this account can only use ``--osh`` commands, and can't connect anywhere through the bastion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ use constant {
|
||||||
OPT_ACCOUNT_INGRESS_PIV_GRACE => 'ingress_piv_grace',
|
OPT_ACCOUNT_INGRESS_PIV_GRACE => 'ingress_piv_grace',
|
||||||
OPT_ACCOUNT_ALWAYS_ACTIVE => 'always_active',
|
OPT_ACCOUNT_ALWAYS_ACTIVE => 'always_active',
|
||||||
OPT_ACCOUNT_IDLE_IGNORE => 'idle_ignore',
|
OPT_ACCOUNT_IDLE_IGNORE => 'idle_ignore',
|
||||||
|
OPT_ACCOUNT_OSH_ONLY => 'osh_only',
|
||||||
};
|
};
|
||||||
|
|
||||||
###########
|
###########
|
||||||
|
|
|
@ -40,6 +40,25 @@ testsuite_selfaccesses()
|
||||||
success realm modify_account1 $a0 --osh accountModify --pam-auth-bypass yes --account $account1
|
success realm modify_account1 $a0 --osh accountModify --pam-auth-bypass yes --account $account1
|
||||||
json .error_code OK .command accountModify
|
json .error_code OK .command accountModify
|
||||||
|
|
||||||
|
# test osh-only
|
||||||
|
success accountModify enable_osh_only $a0 --osh accountModify --osh-only yes --account $account1
|
||||||
|
json .error_code OK .command accountModify
|
||||||
|
|
||||||
|
# account1 can not connect to anything
|
||||||
|
run accountModify no_ssh_after_osh_only $a1 anybody@127.0.0.1
|
||||||
|
retvalshouldbe 107
|
||||||
|
json .error_code KO_ACCESS_DENIED .error_message "You don't have the right to connect anywhere"
|
||||||
|
|
||||||
|
success accountModify disable_osh_only $a0 --osh accountModify --osh-only no --account $account1
|
||||||
|
json .error_code OK .command accountModify
|
||||||
|
|
||||||
|
# account1 can connect now (or could if they were granted)
|
||||||
|
run accountModify can_ssh_after_osh_only_disable $a1 anybody@127.0.0.1
|
||||||
|
retvalshouldbe 107
|
||||||
|
json .error_code KO_ACCESS_DENIED
|
||||||
|
contain "Access denied"
|
||||||
|
nocontain "anywhere"
|
||||||
|
|
||||||
revoke accountModify
|
revoke accountModify
|
||||||
|
|
||||||
success selfListEgressKeys beforeadd $a1 -osh selfListEgressKeys
|
success selfListEgressKeys beforeadd $a1 -osh selfListEgressKeys
|
||||||
|
|
Loading…
Reference in a new issue