From 8abf1cb3f9d7719ede655ac75bd7ba6d100ffc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Lesimple?= Date: Tue, 5 Mar 2024 16:14:49 +0000 Subject: [PATCH] fix: connect.pl: don't look for error messages when sysret==0 --- bin/shell/connect.pl | 102 ++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/bin/shell/connect.pl b/bin/shell/connect.pl index a5a04e94d..f2b7d2e30 100755 --- a/bin/shell/connect.pl +++ b/bin/shell/connect.pl @@ -144,7 +144,7 @@ sub exit_sig { } } -# now guessify if the ssh worked or not +# now guessify whether the ssh worked or not my @comments; my $header; @@ -154,7 +154,8 @@ sub exit_sig { } else { if (open(my $fh_ttyrec, '<', $saveFile)) { - read $fh_ttyrec, $header, 2000; # 2K if there's the host key changed warning + # get the first 2k bytes so we can look for an error message and give some guidance to the user + read $fh_ttyrec, $header, 2000; close($fh_ttyrec); } } @@ -164,6 +165,7 @@ sub exit_sig { push @comments, 'ttyrec_empty'; } else { + # get the first 2k bytes so we can look for an error message and give some guidance to the user my $fnret = OVH::Bastion::execute( cmd => ['zstd', '-d', '-c', "$saveFile.zst"], max_stdout_bytes => 2000, @@ -177,48 +179,57 @@ sub exit_sig { } if ($header) { - if ($header =~ /Permission denied \(publickey/) { - push @comments, 'permission_denied'; - OVH::Bastion::osh_crit( - "BASTION SAYS: The remote server ($ip) refused all the keys we tried (see the list just above), " - . "there are FOUR things to verify:"); - OVH::Bastion::osh_warn( - <<"EOS" -1) Check the remote account's authorized_keys on $ip, did you add the proper key there? (personal key or group key) -2) Did you tell the bastion you added a key to the remote server, so it knows it has to use it? See the actually used keys just above. If you didn't, do it with selfAddPersonalAccess or groupAddServer. -3) Check the from="" part of the remote account's authorized_keys' keyline. Are all the bastion IPs present? Master and slave(s)? See groupInfo or selfListEgressKeys to get the proper keyline to copy/paste. -4) Did you check the 3 above points carefully? Really? Because if you did, you wouldn't be reading this 4th bullet point, as your problem would already be fixed ;) + # Now look for well-known error messages and explain them to the user. + + # Note that some are known to be critical (i.e. implies that ssh failed), so we also + # ensure that the sysret is non-zero, otherwise these are just false positives, either + # printed by the remote server (using ssh there) and not by our own ssh, or simply appearing + # in the output without being generated by our local ssh client. + if ($sysret != 0) { + if ($header =~ /Permission denied \(publickey/) { + push @comments, 'permission_denied'; + OVH::Bastion::osh_crit( + "BASTION SAYS: The remote server ($ip) refused all the keys we tried (see the list just above), " + . "there are FOUR things to verify:"); + OVH::Bastion::osh_warn( + <<"EOS" + 1) Check the remote account's authorized_keys on $ip, did you add the proper key there? (personal key or group key) + 2) Did you tell the bastion you added a key to the remote server, so it knows it has to use it? See the actually used keys just above. If you didn't, do it with selfAddPersonalAccess or groupAddServer. + 3) Check the from="" part of the remote account's authorized_keys' keyline. Are all the bastion IPs present? Master and slave(s)? See groupInfo or selfListEgressKeys to get the proper keyline to copy/paste. + 4) Did you check the 3 above points carefully? Really? Because if you did, you wouldn't be reading this 4th bullet point, as your problem would already be fixed ;) EOS - ); - } - if ($header =~ /Permission denied \(keyboard-interactive/) { - push @comments, 'permission_denied'; - if (!OVH::Bastion::config('keyboardInteractiveAllowed')->value) { - OVH::Bastion::osh_crit("BASTION SAYS: The remote server ($ip) wanted to use keyboard-interactive " - . "authentication, but it's not enabled on this bastion!"); + ); + } + if ($header =~ /Permission denied \(keyboard-interactive/) { + push @comments, 'permission_denied'; + if (!OVH::Bastion::config('keyboardInteractiveAllowed')->value) { + OVH::Bastion::osh_crit("BASTION SAYS: The remote server ($ip) wanted to use keyboard-interactive " + . "authentication, but it's not enabled on this bastion!"); + } + } + if ($header =~ /Too many authentication failures/) { + push @comments, 'too_many_auth_fail'; + OVH::Bastion::osh_crit("BASTION SAYS: The remote server ($ip) disconnected us before we got " + . "a chance to try all the keys we wanted to (see the list just above)."); + OVH::Bastion::osh_warn("This usually happens if there are too many keys to try, for example if you have " + . "numerous personal keys of if $ip is in many groups you have access to."); + OVH::Bastion::osh_warn("Either reduce the number of keys to try, or modify $ip\'s " + . "sshd \"MaxAuthTries\" configuration option."); + } + if ($header =~ /ssh: connect to host \S+ port \d+: Connection timed out/) { + push @comments, 'connection_timeout'; + } + elsif ($header =~ /ssh: connect to host \S+ port \d+: Connection refused/) { + push @comments, 'connection_refused'; + } + elsif ($header =~ /ssh: connect to host \S+ port \d+: /) { + push @comments, 'connection_error'; } } - if ($header =~ /Too many authentication failures/) { - push @comments, 'too_many_auth_fail'; - OVH::Bastion::osh_crit("BASTION SAYS: The remote server ($ip) disconnected us before we got " - . "a chance to try all the keys we wanted to (see the list just above)."); - OVH::Bastion::osh_warn("This usually happens if there are too many keys to try, for example if you have " - . "numerous personal keys of if $ip is in many groups you have access to."); - OVH::Bastion::osh_warn("Either reduce the number of keys to try, or modify $ip\'s " - . "sshd \"MaxAuthTries\" configuration option."); - } - push @comments, 'hostkey_changed' if $header =~ /IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY/; - push @comments, 'hostkey_saved' if $header =~ /Warning: Permanently added /; - if ($header =~ /ssh: connect to host \S+ port \d+: Connection timed out/) { - push @comments, 'connection_timeout'; - } - elsif ($header =~ /ssh: connect to host \S+ port \d+: Connection refused/) { - push @comments, 'connection_refused'; - } - elsif ($header =~ /ssh: connect to host \S+ port \d+: /) { - push @comments, 'connection_error'; - } - elsif ($header =~ /authentication is disabled to avoid man-in-the-middle attacks/) { + + # These ones are not always critical, but we still detect them + # for our logs (@comments is part of the log we generate). + if ($header =~ /authentication is disabled to avoid man-in-the-middle attacks/) { push @comments, 'passauth_disabled'; # be nice and explain to the user cf ticket BASTION-10 @@ -230,14 +241,15 @@ sub exit_sig { . "with `$bastionName --osh selfForgetHostKey --host $ip --port $port'"); } } + push @comments, 'hostkey_changed' if $header =~ /IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY/; + push @comments, 'hostkey_saved' if $header =~ /Warning: Permanently added /; - # if strict host key checking is enabled, be nice and explain how to remove this error + # If strict host key checking is enabled, be nice and explain how to remove this error if ($header =~ /you have requested strict checking/) { my $bastionName = OVH::Bastion::config('bastionName')->value; OVH::Bastion::osh_crit("BASTION SAYS: Connection has been blocked because of the hostkey mismatch on $ip."); - OVH::Bastion::osh_crit( - "If you are aware of this change, remove the hostkey cache with `$bastionName --osh selfForgetHostKey --host $ip --port $port'" - ); + OVH::Bastion::osh_crit("If you are aware of this change, remove the hostkey cache " + . "with `$bastionName --osh selfForgetHostKey --host $ip --port $port'"); } } elsif (!@comments) {