I'm having a problem running two separate instances of sshd on different ports. The two instances of sshd have their own host keys. Unfortunately, the ssh clients seem to associate the host keys based only on the host, not the host and port. [Why would any sane person do what I've described? Well, the truth is that I'm connecting to a different machine through a firewall using port forwarding.] As a work-around, I copied the host keys in /etc/sshd from one machine to the other and restarted sshd, so now both hosts have the same key. Now I'm hoping that doesn't cause any problems.
You can use the HostKeyAlias option in ~/.ssh/config or /etc/ssh_config to "rename" hosts to avoid these collisions.
Services are provided on an IP:PORT pair basis. Assuming anything else is silly. The existance of a workaround for the bug does not imply the non- existance of the bug itself. OpenSSH should behave correctly in the default case, not require users to muck about with their configs. If you wish to consider it a low priority bug, fine (I'm dropping it to P3). But a bug it is.
HostKeyAlias isn't just *a* solution, it's the right solution. SSH connects to hosts, not to ports -- the port is just some address that may or may not lead to a specific desired host, possibly the machine listening on that port, possibly somewhere else. We identify by destination, not by route. Theory aside, what we want is for a given firewall to be able to remap a port on the external interface to an SSHD on the backend, with the client authenticating (and independently encrypting) against this forwarded link. Instead of: alice$ ssh -p 2022 user@firewall either conflicting with the firewall's actual ssh key *or* somehow associating the key with the firewall itself(or, in the localhost variant involving 127.0.0.1, just not authenticating at all), HostKeyAlias lets us inform the client of its expected cryptographically validated destination: Bob. alice$ ssh -o HostKeyAlias="Bob" -p 2022 user@firewall I do have a better syntax for this that might someday actually work, but there is no bug beyond that. It's as incorrect to see Bob's key associated with the firewall as it would be to see it associated with, say, MAE-West. Firewall's just the route -- Bob's who we're looking for. That being said -- you're generally correct about services mapping to IP:PORT. SSH escapes this general purpose simplification, because its services don't always remain on the same IP:PORT. SSL makes a similar judgement, authenticating DNS names but not IPs or Ports. You are you, no matter your phone number. It's much the same for cryptographically verified identity.
A fursther comment: ssh works on port 22, that is what has been reserved by the IANA. Anything else is a special case.
The IANA number is nice, but I wouldn't call "anything else a special case". If it wasn't for the nature of the crypto identity, he'd have a good argument that we weren't elegantly supporting multiple servers living on the same host. It's a bit strange coming up with an example, but suppose web browsers didn't attach the alternate port to relative links. Sure, you could download the HTML page, but any linked images would either have to be absolutely specified or would be attempted to be sucked from the server on port 80, the "IANA" port. It'd be presumptively incorrect behavior, even if the original page was retrieved via HTTP. Multiple servers on the same host have different content, and that's OK. Keep in mind -- port shifting is pretty much the only way to virtual host HTTP over SSL. SSH is a much different story, though. "Multiple servers living on the same host" represent one of two things: A) An alternate SSHD running locally, possibly for testing purposes. The keys should match, and as does the desired destination. B) An alternate SSHD running remotely, probably port forwarded. The keys ought not match, because someone's trying to go elsewhere. Content is not identity. Who you are is different than what you say. Anyway, IANA is a suggestion and a reservation; it excludes other services from using SSH's port, but shouldn't be construed to restrict SSH to 22. Flexibility is a good thing. --Dan
This "HostKeyAlias" business seems like a flimsy excuse for not implmeenting a feature that users want. In this age of ubiquitous firewalls and NAT, it is NOT reasonable to assume that two ports on the same IP address refer to the same host, or to the same SSH server. Even if you run two SSH daemons on one host, as Dan Kaminsky suggests, it is NOT necessarily the case that they are under the same administrative control or have the same security requirements, so it is not reasonable to assume that they must have the same key. I fail to see what the harm would be in storing the port number as part of the known hosts database. In the rare cases where there were two ports on the same SSH server that did use the same key, it's not like this would cause the user any problems. Furthermore, it is not clear how to use the HostAlias option in a configuration file to do the right thing. It may well be possible, but the documentation does not explain it adequately. Suppose I have a machine "firewall", and port 1234 on its IP address is mapped to port 22 on an internal host "foo". I tried putting the following in the SSH configuration of an external machine: Host foo HostKeyAlias foo HostName firewall Port 1234 This basically works, except that it still gives a warning: Warning: the RSA host key for 'foo' differs from the key for the IP address 'xx.xx.xx.xx' Offending key for IP in /home/xx/.ssh/known_hosts:xx Matching host key in /home/ss/.ssh/known_hosts:xx Are you sure you want to continue connecting (yes/no)? So my questions are: 1) What do I need to put in my SSH config so that I can say "ssh foo" and get the right behavior? 2) Why is it so undesirable to simply implement a reasonable feature that users want? I'd much rather just say "ssh -p 1234 firewall" and have the right thing happen, because I have a lot of hosts behind firewalls, and a lot of outside hosts that access them, and I really don't want to have to create n*m entries in SSH configurations to deal with it. Lest you think that I'm begging for someone else to spend time writing code for me, I'll point out that I'm perfectly happy to write the patch, provided that there's a reasonable chance that it will be integrated into the standard code base. I don't want to have to rebuild SSH to add the patch every time there's an update from the vendor; I would much rather see this feature become standard, and it's obvious that other users would also.
I forgot to mention the other reason why I want the requested feature. Sometimes with the firewall/NAT, I map a firewall port (say 1234) to the same port on an internal machine, and run the sshd on that port. The reason for this is that my DNS servers are set up so that inside the firewall/NAT, a DNS lookup for foo will return its local IP address, but from the outside DNS will return the address of the firewall. So it would be nice to be able to say "ssh -p 1234 foo" on my laptop and have the right thing happen, regardless of whether my laptop is currently attached to the interior network or somewhere on the internet at large. For this to work correctly, the knownhosts entry should contain an entry matching the hostname and the port number. And if I didn't want to always type the "-p" option, I could put that in the SSH configuration, but I wouldn't need two configuration entries for the same host.
you might want to combine HostKeyAlias with CheckHostIP=no
I have several ssh-connections forwarded over ssh-Tunnels at various Ports at localhost, all alike the following scheme: Host MYTUNNELHOST # ssh -f -L 32xxx:MYTUNNELHOST:22 -N INTERMEDIATEHOST Port 32xxx HostName localhost HostKeyAlias MYTUNNELHOST Protocol 1 ... -> No conflicting Keys, although all goes over localhost and different Ports... Just one stanza in /etc/ssh/ssh_config and works... I say: "ssh MYTUNNELHOST" but connect is to localhost:32xxx MYTUNNELHOST doesn't even need to be resolvable to an IP!!!!
Mass change of RESOLVED bugs to CLOSED