>Synopsis:      give ssh the opportunity for a second look for SSHFP
>Category:      user
>Environment:
        System      : OpenBSD 7.3
        Details     : OpenBSD 7.3 (GENERIC.MP) #2080: Sat Mar 25 14:20:25 MDT 
2023
                         
dera...@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP

        Architecture: OpenBSD.arm64
        Machine     : arm64
>Description:
        It currently isn't possible to store SSHFP keys for forwarded hosts
one had to create a new hostname for this with the same IP of where one is
SSH'ing to.  Here is another way.  SSHFP can lookup _service._tcp.host...
as a second option.  I have made this patch and tested it, typescript below.

>How-To-Repeat:

Script started on Fri Aug 11 17:07:35 2023
oceans$ date
Fri Aug 11 17:07:36 CEST 2023
oceans$ ssh -v -p 52522 stern
OpenSSH_9.3, LibreSSL 3.8.1
debug1: Reading configuration data /home/pjp/.ssh/config
debug1: /home/pjp/.ssh/config line 1: Applying options for stern
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Connecting to stern.delphinusdns.org [80.152.143.221] port 52522.
debug1: Connection established.
debug1: identity file /home/pjp/.ssh/id_rsa type 0
debug1: identity file /home/pjp/.ssh/id_rsa-cert type -1
debug1: identity file /home/pjp/.ssh/id_ecdsa type -1
debug1: identity file /home/pjp/.ssh/id_ecdsa-cert type -1
debug1: identity file /home/pjp/.ssh/id_ecdsa_sk type -1
debug1: identity file /home/pjp/.ssh/id_ecdsa_sk-cert type -1
debug1: identity file /home/pjp/.ssh/id_ed25519 type -1
debug1: identity file /home/pjp/.ssh/id_ed25519-cert type -1
debug1: identity file /home/pjp/.ssh/id_ed25519_sk type -1
debug1: identity file /home/pjp/.ssh/id_ed25519_sk-cert type -1
debug1: identity file /home/pjp/.ssh/id_xmss type -1
debug1: identity file /home/pjp/.ssh/id_xmss-cert type -1
debug1: identity file /home/pjp/.ssh/id_dsa type -1
debug1: identity file /home/pjp/.ssh/id_dsa-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_9.3
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.3
debug1: compat_banner: match: OpenSSH_9.3 pat OpenSSH* compat 0x04000000
debug1: Authenticating to stern.delphinusdns.org:52522 as 'pjp'
debug1: load_hostkeys: fopen /home/pjp/.ssh/known_hosts2: No such file or 
directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts: No such file or directory
debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or 
directory
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: sntrup761x25519-sha...@openssh.com
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: chacha20-poly1...@openssh.com MAC: 
<implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1...@openssh.com MAC: 
<implicit> compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Server host key: ssh-ed25519 
SHA256:SdKzxBNyL3fqrFxMM1b4IUG4YiQWR4zDAwTB0iQxyC0
debug1: found 8 secure fingerprints in DNS
debug1: verify_host_key_dns: failed SSHFP type 4 fptype 1
debug1: verify_host_key_dns: failed SSHFP type 4 fptype 2
debug1: mismatching host key fingerprint found in DNS
debug1: doing a second DNS SSHFP lookup on _52522._tcp.stern.delphinusdns.org
debug1: found 8 secure fingerprints in DNS
debug1: verify_host_key_dns: matched SSHFP type 4 fptype 1
debug1: verify_host_key_dns: matched SSHFP type 4 fptype 2
debug1: matching host key fingerprint found in DNS
debug1: rekey out after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey in after 134217728 blocks
debug1: Will attempt key: /home/pjp/.ssh/id_rsa RSA 
SHA256:NraIeolSeBLOeflBQEt4G9T8qxiy1loPTqw05I23DXs
debug1: Will attempt key: /home/pjp/.ssh/id_ecdsa
debug1: Will attempt key: /home/pjp/.ssh/id_ecdsa_sk
debug1: Will attempt key: /home/pjp/.ssh/id_ed25519
debug1: Will attempt key: /home/pjp/.ssh/id_ed25519_sk
debug1: Will attempt key: /home/pjp/.ssh/id_xmss
debug1: Will attempt key: /home/pjp/.ssh/id_dsa
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: 
server-sig-algs=<ssh-ed25519,sk-ssh-ed25...@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,sk-ecdsa-sha2-nistp...@openssh.com,webauthn-sk-ecdsa-sha2-nistp...@openssh.com,ssh-dss,ssh-rsa,rsa-sha2-256,rsa-sha2-512>
debug1: kex_input_ext_info: publickey-hostbo...@openssh.com=<0>
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,keyboard-interactive
debug1: Next authentication method: publickey
debug1: Offering public key: /home/pjp/.ssh/id_rsa RSA 
SHA256:NraIeolSeBLOeflBQEt4G9T8qxiy1loPTqw05I23DXs
debug1: Server accepts key: /home/pjp/.ssh/id_rsa RSA 
SHA256:NraIeolSeBLOeflBQEt4G9T8qxiy1loPTqw05I23DXs
Enter passphrase for key '/home/pjp/.ssh/id_rsa':

oceans$ exit

Script done on Fri Aug 11 17:08:02 2023

at the time this was tested on a few days old OpenBSD system:

oceans$ sysctl kern.version
kern.version=OpenBSD 7.3-current (GENERIC.MP) #394: Tue Aug  8 10:57:21 MDT 2023
    dera...@riscv64.openbsd.org:/usr/src/sys/arch/riscv64/compile/GENERIC.MP



>Fix:


Index: dns.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/dns.c,v
retrieving revision 1.44
diff -u -p -u -r1.44 dns.c
--- dns.c       10 Mar 2023 04:06:21 -0000      1.44
+++ dns.c       11 Aug 2023 15:09:31 -0000
@@ -187,12 +187,12 @@ is_numeric_hostname(const char *hostname
 }
 
 /*
- * Verify the given hostname, address and host key using DNS.
+ * Verify the given hostname, address, port and host key using DNS.
  * Returns 0 if lookup succeeds, -1 otherwise
  */
 int
-verify_host_key_dns(const char *hostname, struct sockaddr *address,
-    struct sshkey *hostkey, int *flags)
+verify_host_key_dns(const char *hostname, u_short port, 
+    struct sockaddr *address, struct sshkey *hostkey, int *flags)
 {
        u_int counter;
        int result;
@@ -206,6 +206,7 @@ verify_host_key_dns(const char *hostname
        u_int8_t dnskey_digest_type;
        u_char *dnskey_digest;
        size_t dnskey_digest_len;
+       char newhost[NI_MAXHOST];
 
        *flags = 0;
 
@@ -293,6 +294,25 @@ verify_host_key_dns(const char *hostname
        else
                debug("no host key fingerprint found in DNS");
 
+       if ((*flags & DNS_VERIFY_FAILED) && (port != 0)) {
+               int saveflags, ret;
+
+               if (snprintf(newhost, sizeof(newhost), "_%u._tcp.%s", port,
+                       hostname) >= (int)sizeof(newhost)) {
+                       /* the port addition to host didn't fit, just return */
+                       return 0;
+               }
+
+               debug("doing a second DNS SSHFP lookup on %s", newhost);
+
+               saveflags = *flags;
+               ret = verify_host_key_dns(newhost, 0, address, hostkey, flags);
+               if (ret == -1) {
+                       debug("verify_host_key_dns() ret -1 restoring flags");
+                       *flags = saveflags;
+               }
+       }
+               
        return 0;
 }
 
Index: dns.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/dns.h,v
retrieving revision 1.20
diff -u -p -u -r1.20 dns.h
--- dns.h       10 Feb 2023 04:56:30 -0000      1.20
+++ dns.h       11 Aug 2023 15:09:31 -0000
@@ -52,7 +52,7 @@ enum sshfp_hashes {
 #define DNS_VERIFY_SECURE      0x00000004
 #define DNS_VERIFY_FAILED      0x00000008
 
-int    verify_host_key_dns(const char *, struct sockaddr *,
+int    verify_host_key_dns(const char *, u_short, struct sockaddr *,
     struct sshkey *, int *);
 int    export_dns_rr(const char *, struct sshkey *, FILE *, int, int);
 
Index: sshconnect.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/sshconnect.c,v
retrieving revision 1.363
diff -u -p -u -r1.363 sshconnect.c
--- sshconnect.c        10 Mar 2023 07:17:08 -0000      1.363
+++ sshconnect.c        11 Aug 2023 15:09:32 -0000
@@ -1468,7 +1468,8 @@ verify_host_key(char *host, struct socka
                        goto out;
                if (sshkey_is_cert(plain))
                        sshkey_drop_cert(plain);
-               if (verify_host_key_dns(host, hostaddr, plain, &flags) == 0) {
+               if (verify_host_key_dns(host, options.port,
+                       hostaddr, plain, &flags) == 0) {
                        if (flags & DNS_VERIFY_FOUND) {
                                if (options.verify_host_key_dns == 1 &&
                                    flags & DNS_VERIFY_MATCH &&







dmesg:
OpenBSD 7.3 (GENERIC.MP) #2080: Sat Mar 25 14:20:25 MDT 2023
    dera...@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP

see earlier posts.

Reply via email to