Bug 2217 - allow using _ssh._tcp SRV records
Summary: allow using _ssh._tcp SRV records
Status: NEW
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 6.5p1
Hardware: All All
: P5 enhancement
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-25 04:23 AEDT by chrysn
Modified: 2022-12-29 01:02 AEDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description chrysn 2014-03-25 04:23:27 AEDT
i think it would be a good idea for ssh to look up _ssh._tcp records to allow virtual services.

how it would work
=================

whenever an ssh connection is created, instead of looking up the A/AAAA
record of the hostname, _ssh._tcp.${hostname} is queried for SRV
records. if one exists, the request is resolved further by the usual
rules of SRV records; otherwise, an A/AAAA record is used.

an SRV record allows load balancing (when equal priorities are used),
fallback (with different priorities) and (which is what i'd use it for)
selecting the port.

how it (doesn't) affect security
================================

ssh is used to relying on insecure dns before creating a secured
connection. if an SRV record is used, the original hostname (without the
_ssh._tcp part, ie. what the user requested) should be used as the
default HostKeyAlias. this allows migration to and from plain dns hosts
without disturbing existing known_hosts files.

basically, treat the dns resolver like a rogue dns server. if it
redirects us to a place where the server can present the correct
fingerprint, we're fine, if not, we detect it.

of course, if more than one SRV record exists, the same host key has to
be present on multiple servers. this is the same situation as with
migrating servers where admins copy the old ssh key to the new machine;
whether this is acceptable or not is up to the administrator's
discretion, and most likely depends on how he distributes his
known_hosts data.

i don't know how this would interact with ssh keys verified via dns-sec,
if that is a thing.

existing implementations
========================

so far, i've only seen _ssh._tcp records in SRV record examples, for
discovering local services (when it's not ssh itself that uses it,
programs like nautilus that display connectable machines nearby), and an
ssh wrapper at [1].

as a side effect, this would add SRV support to all other protocols that
rely on ssh (eg rsync and git). they might want to override the prefix
(maybe _ssh+git._tcp), but then again, that prefix would have to be
stored in known_hosts.


(this text was originally written for https://bugs.debian.org/297173; as it will not be followed furthere there for unrelated reasons, reporting it here directly)

note on relationships with other bugs: SRV records were mentioned in bug #1742, but afaict don't belong there, as getaddrinfo will not resolve SRV records. that bug brings up the good point about ports, though. i think that the port in an SRV record should never end up in a known_hosts file, because what matters is the user's intention ("i want to connect to the service i know as git.example.com (whereever it currently resides)"), not the implementation. specifying an explicit port should probably disable SRV lookups.
Comment 1 András Korn 2014-03-28 09:35:16 AEDT
FWIW, wrapsrv already offers a way of implementing this idea outside ssh.

It would be even better to support something like SNI inside OpenSSH, though: show the client the host key that matches the host it expects to see.
Comment 2 Jeremy Saklad 2022-12-29 01:02:12 AEDT
This would be invaluable, particularly for services like Git.

I try to maintain strict separation between machines and the services they provide, such that I can move the service to a different machine without disrupting access. I also want to provide multiple methods of access, such as through an onion service. I currently use these records to convey that:

```
_ssh._tcp.git.saklad5.com. 604800 IN	SRV	0 0 22 yqxxaadd7hhmjzyier2jftbnzxw3ddvbm4ggz5y7yuxzmcxlpcmwdcyd.onion.
_ssh._tcp.git.saklad5.com. 604800 IN	SRV	1 0 22 baza.saklad5.com.
```

The principles of RFC 7673 and similar specs apply here: when using DANE, OpenSSH must validate the delegation with DNSSEC then query SSHFP records for the ultimate target. If any link in the chain of resolution isn't secured, validation fails.

Assuming DNSSEC is used correctly, the records above should mean that `ssh git@git.saklad5.com` is equivalent to `ssh git@ yqxxaadd7hhmjzyier2jftbnzxw3ddvbm4ggz5y7yuxzmcxlpcmwdcyd.onion:22`, falling back to `ssh git@baza.saklad5.com:22`. In keeping with RFC 7686, OpenSSH would immediately skip the onion address unless configured with Tor support.