From 4ef9c6ddde35c4042b6bb799671f95dcf3e11c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lesimple?= Date: Thu, 12 Sep 2024 10:37:36 +0000 Subject: [PATCH] feat: add --egress-session-multiplexing option to accountModify --- bin/helper/osh-accountModify | 44 +++++++++++++++++++ bin/plugin/restricted/accountModify | 11 +++++ bin/shell/osh.pl | 4 ++ .../plugins/restricted/accountModify.rst | 7 +++ etc/bastion/osh-sync-watcher.rsyncfilter.dist | 1 + 5 files changed, 67 insertions(+) diff --git a/bin/helper/osh-accountModify b/bin/helper/osh-accountModify index 322d619ed..8789bf77c 100755 --- a/bin/helper/osh-accountModify +++ b/bin/helper/osh-accountModify @@ -398,6 +398,50 @@ foreach my $tuple (@modify) { } } } + elsif ($key eq 'egress-session-multiplexing') { + osh_info "Changing the egress ControlMaster/ControlPath options for this account..."; + my $controlPath; + my $controlMaster; + if ($value eq 'default') { + # keep both vars undef, which will remove them from the account config file + ; + } + elsif ($value eq 'yes') { + $controlMaster = 'auto'; + # '~' is handled by ssh_config as the account's home directory + # '%C' is a hash of local hostname, remote host, remote user, remote port + $controlPath = "~/tmp/ssh_egress_%C"; + } + elsif ($value eq 'no') { + # never create a master connection + $controlMaster = 'no'; + # 'none' is understood specifically for ssh_config as 'never try to use a master connection' + $controlPath = 'none'; + } + else { + osh_warn "Invalid parameter '$value', skipping"; + $result{$jsonkey} = R('ERR_INVALID_PARAMETER'); + } + $fnret = OVH::Bastion::account_ssh_config_set( + account => $account, + key => "ControlMaster", + value => $controlMaster, + ); + if ($fnret) { + $fnret = OVH::Bastion::account_ssh_config_set( + account => $account, + key => "ControlPath", + value => $controlPath, + ); + } + $result{$jsonkey} = $fnret; + if ($fnret) { + osh_info "... modification done"; + } + else { + osh_warn "... error while setting policy: $fnret"; + } + } elsif ($key eq 'personal-egress-mfa-required') { osh_info "Changing the MFA policy for egress connections using the personal access (and keys) of the account..."; diff --git a/bin/plugin/restricted/accountModify b/bin/plugin/restricted/accountModify index 074f26401..5c393fc13 100755 --- a/bin/plugin/restricted/accountModify +++ b/bin/plugin/restricted/accountModify @@ -19,6 +19,7 @@ my $remainingOptions = OVH::Bastion::Plugin::begin( "pam-auth-bypass=s" => \$modify{'pam-auth-bypass'}, "always-active=s" => \$modify{'always-active'}, "egress-strict-host-key-checking=s" => \$modify{'egress-strict-host-key-checking'}, + "egress-session-multiplexing=s" => \$modify{'egress-session-multiplexing'}, "personal-egress-mfa-required=s" => \$modify{'personal-egress-mfa-required'}, "idle-ignore=s" => \$modify{'idle-ignore'}, "max-inactive-days=i" => \$modify{'max-inactive-days'}, @@ -47,6 +48,10 @@ Usage: --osh SCRIPT_NAME --account ACCOUNT [--option value [--option value [...] This effectively suppress the host key checking entirely. Please don't enable this blindly. 'default' will remove this account's ``StrictHostKeyChecking`` setting override. All the other policies carry the same meaning that what is documented in `man ssh_config`. + --egress-session-multiplexing POLICY Modify the egress SSH behavior of this account regarding ``ControlMaster`` and ``ControlPath``. POLICY can be: + 'yes', setting ``ControlMaster`` to 'auto' and setting ``ControlPath`` properly for session sharing, + 'no', setting ``ControlMaster`` to 'no' and ``ControlPath`` to 'none', + 'default', removing this account ``ControlMaster`` and ``ControlPath`` overrides altogether. --personal-egress-mfa-required POLICY Enforce UNIX password requirement, or TOTP requirement, or any MFA requirement, when connecting to a server 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) @@ -110,6 +115,12 @@ if ($modify{'personal-egress-mfa-required'} && !grep { $modify{'personal-egress- osh_exit 'ERR_INVALID_PARAMETER', "Expected option 'password', 'totp', 'any', 'none' to --personal-egress-mfa-required"; } +if ($modify{'egress-session-multiplexing'} && !grep { $modify{'egress-session-multiplexing'} eq $_ } + qw{ yes no default }) +{ + help(); + osh_exit 'ERR_INVALID_PARAMETER', "Expected option 'yes', 'no' or 'default' --egress-session-multiplexing"; +} if ($modify{'max-inactive-days'} && $modify{'max-inactive-days'} !~ /^(?:\d+|-1)$/) { help(); osh_exit "ERR_INVALID_PARAMETER", diff --git a/bin/shell/osh.pl b/bin/shell/osh.pl index 81e67951e..a7917fc71 100755 --- a/bin/shell/osh.pl +++ b/bin/shell/osh.pl @@ -1570,6 +1570,10 @@ sub main_exit { # then convert to json: $ENV{'LC_BASTION_DETAILS'} = encode_json(\@details_json); +# make sure $home/tmp exists, as it might be used for egress ssh connection multiplexing. +# just attempt to create it instead of check+create, as it's not faster to do otherwise. +mkdir "$home/tmp", 0700; + # here is a nice hack to drastically improve the memory footprint of a # heavily used bastion. we exec() another script that is way lighter, see # comments in the connect.pl file for more information. diff --git a/doc/sphinx/plugins/restricted/accountModify.rst b/doc/sphinx/plugins/restricted/accountModify.rst index 47f5452ee..d68db6c55 100644 --- a/doc/sphinx/plugins/restricted/accountModify.rst +++ b/doc/sphinx/plugins/restricted/accountModify.rst @@ -46,6 +46,13 @@ Modify an account configuration This effectively suppress the host key checking entirely. Please don't enable this blindly. 'default' will remove this account's ``StrictHostKeyChecking`` setting override. All the other policies carry the same meaning that what is documented in `man ssh_config`. +.. option:: --egress-session-multiplexing POLICY + + Modify the egress SSH behavior of this account regarding ``ControlMaster`` and ``ControlPath``. POLICY can be: + + 'yes', setting ``ControlMaster`` to 'auto' and setting ``ControlPath`` properly for session sharing, + 'no', setting ``ControlMaster`` to 'no' and ``ControlPath`` to 'none', + 'default', removing this account ``ControlMaster`` and ``ControlPath`` overrides altogether. .. option:: --personal-egress-mfa-required POLICY Enforce UNIX password requirement, or TOTP requirement, or any MFA requirement, when connecting to a server diff --git a/etc/bastion/osh-sync-watcher.rsyncfilter.dist b/etc/bastion/osh-sync-watcher.rsyncfilter.dist index 5837a3236..410215301 100644 --- a/etc/bastion/osh-sync-watcher.rsyncfilter.dist +++ b/etc/bastion/osh-sync-watcher.rsyncfilter.dist @@ -35,6 +35,7 @@ - /home/*/*.log - /home/*/*.gz - /home/*/lastlog +- /home/*/tmp/ - /home/*/.ssh/known_hosts + /home/*/***