Skip to content

Commit

Permalink
feat: replace --wait by a tcp-based connection try
Browse files Browse the repository at this point in the history
  • Loading branch information
speed47 committed Apr 9, 2024
1 parent cc41bff commit 2770f39
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 37 deletions.
46 changes: 16 additions & 30 deletions bin/shell/osh.pl
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,6 @@ sub main_exit {
"interactive|i" => \my $interactive,
"netconf" => \my $netconf,
"wait" => \my $wait,
"wait-port=i" => \my $wait_port,
"ssh-as=s" => \my $sshAs,
"use-key=s" => \my $useKey,
"kbd-interactive" => \my $userKbdInteractive,
Expand Down Expand Up @@ -1488,39 +1487,27 @@ sub main_exit {

# if --wait is specified, we wait for the host to be alive before connecting
if ($wait) {
require IO::Socket::INET;
my $startedat = time();
osh_info "Pinging $host, will connect as soon as it's alive...";
while (1) {
my @pingcmd = qw{ fping -- };
push @pingcmd, $host;

my $fnretexec = OVH::Bastion::execute(cmd => \@pingcmd, noisy_stdout => 1, noisy_stderr => 1);
$fnretexec or exit(OVH::Bastion::EXIT_EXEC_FAILED);
if ($fnretexec->value->{'sysret'} == 0) {
my $loops = 0;
osh_info "Waiting for port $port to be open on $host before attempting to connect...";
while ($loops < 3600) { # can be up to 2h (socket timeout + sleep 1)
my $Sock = IO::Socket::INET->new(
Proto => 'tcp',
Timeout => 1,
PeerAddr => $ip,
PeerPort => $port,
);
if ($Sock) {
osh_info "Alive after waiting for " . (time() - $startedat) . " seconds, connecting...";
sleep 2 if (time() > $startedat + 1); # so that ssh has the time to startup... hopefully
$Sock->close();
last;
}
sleep 1;
}
}

# if --wait-port is specified, we wait for the host specific port to be open before connecting
if ($wait_port) {
my $startedat = time();
osh_info "Testing $host port $wait_port, will connect as soon as it's open...";
while (1) {
my @testportcmd = qw{ nc -w 1 -z -v -n };
push @testportcmd, $host, $wait_port;

my $fnretexec = OVH::Bastion::execute(cmd => \@testportcmd, noisy_stdout => 1, noisy_stderr => 1);
$fnretexec or exit(OVH::Bastion::EXIT_EXEC_FAILED);
if ($fnretexec->value->{'sysret'} == 0) {
osh_info "Open after waiting for " . (time() - $startedat) . " seconds, connecting...";
sleep 2 if (time() > $startedat + 1); # so that ssh has the time to startup... hopefully
last;
sleep 1; # to avoid looping too fast if the failure is immediate and not a timeout (i.e. port closed)
$loops++;
if ($loops % 5 == 0) {
osh_info("Still trying to connect to $host:$port after " . (time() - $startedat) . " seconds...");
}
sleep 1;
}
}

Expand Down Expand Up @@ -2021,7 +2008,6 @@ sub long_help {
--always-escape Bypass config and force the bugged behavior of old bastions for REMOTE_COMMAND escaping. Don't use.
--never-escape Bypass config and force the new behavior of new bastions for REMOTE_COMMAND escaping. Don't use.
--wait Ping the host before connecting to it (useful to ssh just after a reboot!)
--wait-port Test the host specific port to be open before connecting to it
--long-help Print this
[REMOTE_COMMAND]
Expand Down
27 changes: 20 additions & 7 deletions tests/functional/tests.d/350-groups.sh
Original file line number Diff line number Diff line change
Expand Up @@ -141,28 +141,41 @@ EOS

# now that we have several keys, take the opportunity to test force-key

plgfail a1_add_access_force_key_and_pwd_g1 $a1 --osh groupAddServer --host 127.1.2.3 --user-any --port-any --force --force-password '$1$2$3456' --force-key "$key1fp" --group $group1
plgfail a1_add_access_force_key_and_pwd_g1 $a1 --osh groupAddServer --host 127.0.0.5 --user-any --port-any --force --force-password '$1$2$3456' --force-key "$key1fp" --group $group1
json .error_code ERR_INCOMPATIBLE_PARAMETERS

success a1_add_access_force_key_g1 $a1 --osh groupAddServer --host 127.1.2.3 --user 'ar@base' --port-any --force --force-key "$key1fp" --group $group1
success a1_add_access_force_key_g1 $a1 --osh groupAddServer --host 127.0.0.5 --user 'ar@base' --port-any --force --force-key "$key1fp" --group $group1
.value.user 'ar@base'

success a1_list_servers_check_force_key_g1 $a1 --osh groupListServers --group $group1
json '.value|.[]|select(.ip=="127.1.2.3")|.forceKey' "$key1fp"
json '.value|.[]|select(.ip=="127.1.2.3")|.user' "ar@base"
json '.value|.[]|select(.ip=="127.0.0.5")|.forceKey' "$key1fp"
json '.value|.[]|select(.ip=="127.0.0.5")|.user' "ar@base"

# try to use the force key
# try to use the force key AND --wait

run a1_connect_g1_with_forcekey $a1 ar@base@127.1.2.3 -- false
run a1_connect_g1_with_forcekey_and_wait $a1 --wait ar@base@127.0.0.5 -- false
contain 'Connecting...'
contain 'FORCED IN ACL'
contain "$key1fp"
nocontain "$key0fp"
contain "Waiting for port 22 to be open on "
contain REGEX "Alive after waiting for [0-9] seconds"

success a1_remove_forcekey_acl_g1 $a1 --osh groupDelServer --host 127.1.2.3 --user 'ar@base' --port-any --group $group1
success a1_remove_forcekey_acl_g1 $a1 --osh groupDelServer --host 127.0.0.5 --user 'ar@base' --port-any --group $group1

# /force-key

success a1_add_non_routable_ip $a1 --osh groupAddServer --host 192.0.2.0 --user-any --port-any --force --group $group1

run a1_ssh_wait $a1 --wait 192.0.2.0
retvalshouldbe 124 # timeout
contain "Waiting for port 22 to be open on 192.0.2.0"
contain REGEX "Still trying to connect to 192.0.2.0:22 after 1[0-9] seconds"

success a1_remove_non_routable_ip $a1 --osh groupDelServer --host 192.0.2.0 --user-any --port-any --group $group1

# test --alive

run a0_del_key_g1 $a0 --osh groupDelEgressKey --group $group1 --id $key1id
retvalshouldbe 106
json .command null .error_code KO_RESTRICTED_COMMAND .value null
Expand Down

0 comments on commit 2770f39

Please sign in to comment.