[PATCH] rpc: Pass OPENSSL_CONF through to ssh invocations

Richard W.M. Jones posted 1 patch 1 year, 9 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/20220725130939.1200674-1-rjones@redhat.com
src/rpc/virnetsocket.c | 1 +
1 file changed, 1 insertion(+)
[PATCH] rpc: Pass OPENSSL_CONF through to ssh invocations
Posted by Richard W.M. Jones 1 year, 9 months ago
It's no longer possible for libvirt to connect over the ssh transport
from RHEL 9 to RHEL 5.  This is because SHA1 signatures have been
effectively banned in RHEL 9 at the openssl level.  They are required
to check the RHEL 5 host key.  Note this is a separate issue from
openssh requiring additional configuration in order to connect to
older servers.

Connecting from a RHEL 9 client to RHEL 5 server:

$ cat ~/.ssh/config
Host 192.168.0.91
  KexAlgorithms            +diffie-hellman-group14-sha1
  MACs                     +hmac-sha1
  HostKeyAlgorithms        +ssh-rsa
  PubkeyAcceptedKeyTypes   +ssh-rsa
  PubkeyAcceptedAlgorithms +ssh-rsa

$ virsh -c 'qemu+ssh://root@192.168.0.91/system' list
error: failed to connect to the hypervisor
error: Cannot recv data: ssh_dispatch_run_fatal: Connection to 192.168.0.91 port 22: error in libcrypto: Connection reset by peer

"error in libcrypto: Connection reset by peer" is the characteristic
error of openssl having been modified to disable SHA1 by default.
(You will not see this on non-RHEL-derived distros.)

You could enable the legacy crypto policy which downgrades security on
the entire host, but a more fine-grained way to do this is to create
an alternate openssl configuration file that enables the "forbidden"
signatures.  However this requires passing the OPENSSL_CONF
environment variable through to ssh to specify the alternate
configuration.  Libvirt filters out this environment variable, but
this commit allows it through.  With this commit:

$ cat /var/tmp/openssl.cnf
.include /etc/ssl/openssl.cnf
[openssl_init]
alg_section = evp_properties
[evp_properties]
rh-allow-sha1-signatures = yes

$ OPENSSL_CONF=/var/tmp/openssl.cnf ./run virsh -c 'qemu+ssh://root@192.168.0.91/system' list
root@192.168.0.91's password:
 Id   Name   State
--------------------

Essentially my argument here is that OPENSSL_CONF is sufficiently
similar in nature to KRB5CCNAME, SSH* and XAUTHORITY that we should
permit it to be passed through.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2062360
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
---
 src/rpc/virnetsocket.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 32f506d2d4..8280bda007 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -855,6 +855,7 @@ int virNetSocketNewConnectSSH(const char *nodename,
     virCommandAddEnvPass(cmd, "KRB5CCNAME");
     virCommandAddEnvPass(cmd, "SSH_AUTH_SOCK");
     virCommandAddEnvPass(cmd, "SSH_ASKPASS");
+    virCommandAddEnvPass(cmd, "OPENSSL_CONF");
     virCommandAddEnvPass(cmd, "DISPLAY");
     virCommandAddEnvPass(cmd, "XAUTHORITY");
     virCommandClearCaps(cmd);
-- 
2.31.1
Re: [PATCH] rpc: Pass OPENSSL_CONF through to ssh invocations
Posted by Laszlo Ersek 1 year, 9 months ago
On 07/25/22 15:09, Richard W.M. Jones wrote:
> It's no longer possible for libvirt to connect over the ssh transport
> from RHEL 9 to RHEL 5.  This is because SHA1 signatures have been
> effectively banned in RHEL 9 at the openssl level.  They are required
> to check the RHEL 5 host key.  Note this is a separate issue from
> openssh requiring additional configuration in order to connect to
> older servers.
> 
> Connecting from a RHEL 9 client to RHEL 5 server:
> 
> $ cat ~/.ssh/config
> Host 192.168.0.91
>   KexAlgorithms            +diffie-hellman-group14-sha1
>   MACs                     +hmac-sha1
>   HostKeyAlgorithms        +ssh-rsa
>   PubkeyAcceptedKeyTypes   +ssh-rsa
>   PubkeyAcceptedAlgorithms +ssh-rsa
> 
> $ virsh -c 'qemu+ssh://root@192.168.0.91/system' list
> error: failed to connect to the hypervisor
> error: Cannot recv data: ssh_dispatch_run_fatal: Connection to 192.168.0.91 port 22: error in libcrypto: Connection reset by peer
> 
> "error in libcrypto: Connection reset by peer" is the characteristic
> error of openssl having been modified to disable SHA1 by default.
> (You will not see this on non-RHEL-derived distros.)
> 
> You could enable the legacy crypto policy which downgrades security on
> the entire host, but a more fine-grained way to do this is to create
> an alternate openssl configuration file that enables the "forbidden"
> signatures.  However this requires passing the OPENSSL_CONF
> environment variable through to ssh to specify the alternate
> configuration.  Libvirt filters out this environment variable, but
> this commit allows it through.  With this commit:
> 
> $ cat /var/tmp/openssl.cnf
> .include /etc/ssl/openssl.cnf
> [openssl_init]
> alg_section = evp_properties
> [evp_properties]
> rh-allow-sha1-signatures = yes
> 
> $ OPENSSL_CONF=/var/tmp/openssl.cnf ./run virsh -c 'qemu+ssh://root@192.168.0.91/system' list
> root@192.168.0.91's password:
>  Id   Name   State
> --------------------
> 
> Essentially my argument here is that OPENSSL_CONF is sufficiently
> similar in nature to KRB5CCNAME, SSH* and XAUTHORITY that we should
> permit it to be passed through.
> 
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2062360
> Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
> ---
>  src/rpc/virnetsocket.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
> index 32f506d2d4..8280bda007 100644
> --- a/src/rpc/virnetsocket.c
> +++ b/src/rpc/virnetsocket.c
> @@ -855,6 +855,7 @@ int virNetSocketNewConnectSSH(const char *nodename,
>      virCommandAddEnvPass(cmd, "KRB5CCNAME");
>      virCommandAddEnvPass(cmd, "SSH_AUTH_SOCK");
>      virCommandAddEnvPass(cmd, "SSH_ASKPASS");
> +    virCommandAddEnvPass(cmd, "OPENSSL_CONF");
>      virCommandAddEnvPass(cmd, "DISPLAY");
>      virCommandAddEnvPass(cmd, "XAUTHORITY");
>      virCommandClearCaps(cmd);
> 

Acked-by: Laszlo Ersek <lersek@redhat.com>
Re: [PATCH] rpc: Pass OPENSSL_CONF through to ssh invocations
Posted by Michal Prívozník 1 year, 9 months ago
On 7/25/22 15:38, Laszlo Ersek wrote:
> On 07/25/22 15:09, Richard W.M. Jones wrote:
>> It's no longer possible for libvirt to connect over the ssh transport
>> from RHEL 9 to RHEL 5.  This is because SHA1 signatures have been
>> effectively banned in RHEL 9 at the openssl level.  They are required
>> to check the RHEL 5 host key.  Note this is a separate issue from
>> openssh requiring additional configuration in order to connect to
>> older servers.
>>
>> Connecting from a RHEL 9 client to RHEL 5 server:
>>
>> $ cat ~/.ssh/config
>> Host 192.168.0.91
>>   KexAlgorithms            +diffie-hellman-group14-sha1
>>   MACs                     +hmac-sha1
>>   HostKeyAlgorithms        +ssh-rsa
>>   PubkeyAcceptedKeyTypes   +ssh-rsa
>>   PubkeyAcceptedAlgorithms +ssh-rsa
>>
>> $ virsh -c 'qemu+ssh://root@192.168.0.91/system' list
>> error: failed to connect to the hypervisor
>> error: Cannot recv data: ssh_dispatch_run_fatal: Connection to 192.168.0.91 port 22: error in libcrypto: Connection reset by peer
>>
>> "error in libcrypto: Connection reset by peer" is the characteristic
>> error of openssl having been modified to disable SHA1 by default.
>> (You will not see this on non-RHEL-derived distros.)
>>
>> You could enable the legacy crypto policy which downgrades security on
>> the entire host, but a more fine-grained way to do this is to create
>> an alternate openssl configuration file that enables the "forbidden"
>> signatures.  However this requires passing the OPENSSL_CONF
>> environment variable through to ssh to specify the alternate
>> configuration.  Libvirt filters out this environment variable, but
>> this commit allows it through.  With this commit:
>>
>> $ cat /var/tmp/openssl.cnf
>> .include /etc/ssl/openssl.cnf
>> [openssl_init]
>> alg_section = evp_properties
>> [evp_properties]
>> rh-allow-sha1-signatures = yes
>>
>> $ OPENSSL_CONF=/var/tmp/openssl.cnf ./run virsh -c 'qemu+ssh://root@192.168.0.91/system' list
>> root@192.168.0.91's password:
>>  Id   Name   State
>> --------------------
>>
>> Essentially my argument here is that OPENSSL_CONF is sufficiently
>> similar in nature to KRB5CCNAME, SSH* and XAUTHORITY that we should
>> permit it to be passed through.
>>
>> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2062360
>> Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
>> ---
>>  src/rpc/virnetsocket.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
>> index 32f506d2d4..8280bda007 100644
>> --- a/src/rpc/virnetsocket.c
>> +++ b/src/rpc/virnetsocket.c
>> @@ -855,6 +855,7 @@ int virNetSocketNewConnectSSH(const char *nodename,
>>      virCommandAddEnvPass(cmd, "KRB5CCNAME");
>>      virCommandAddEnvPass(cmd, "SSH_AUTH_SOCK");
>>      virCommandAddEnvPass(cmd, "SSH_ASKPASS");
>> +    virCommandAddEnvPass(cmd, "OPENSSL_CONF");
>>      virCommandAddEnvPass(cmd, "DISPLAY");
>>      virCommandAddEnvPass(cmd, "XAUTHORITY");
>>      virCommandClearCaps(cmd);
>>
> 
> Acked-by: Laszlo Ersek <lersek@redhat.com>
> 

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>

and merged.

Michal