At our sites, we have many situations where we hide many SSH hosts behind a single IP address, where a Firewall is doing NAT and port forwarding. For example, we may have 3 hosts (each with different host keys), A, B, and C. For example: Host A: 1.1.1.1 port 2222 Host B: 1.1.1.1 port 22 Host C: 1.1.1.1 port 2020 Unfortunately, the known_hosts file only records the IP address of the machine, and therefore if a person connects to host A, accepts the host key, and then tries to connect to host B or host C they will get a message indicating that the host key has changed. In our production environment, we force our users to use strick host key checking, and they don't have direct access to their known_hosts file. This bug/feature request is for the inclusion of the port number in the known_hosts file. I'd recommend in the known_hosts format: ip.ip.ip.ip:port ... ... where the :port is new, and if not specified defaults to port 22. Thanks, Devin Nate
As a workaround you could set the nohostauthenticationforlocalhost option; this disables checking for localhost. Alas, this has the very undesireable property of leaving those connections unverified.
Checking the source finds the "right" way to do this: use the HostKeyAlias option. Your suggested fix would be automatic and easier, but HostKeyAlias seems to be the way to get things done without a patch.
First try at a patch to do this. The patch changes the known_hosts file format. Format is host:port. Nothing else changes, so multiple aliases etc are permitted. This patch does NOT include DNS based host key checking updates, i.e. those found in verify_host_key_dns() Patch is against openssh-3.9p1 If any openssh developers capable of getting code into the official tree are watching, please consider this patch for inclusion into a future release. Thanks, Devin Nate
Created attachment 716 [details] Patch includes port numbers in known_hosts file
I'm closing this because it was already tagged and rejected in bug ID 393. Please review that bug id to understand why using host:ip in known_hosts file is not wise. - Ben
Interesting.. I read through bug 393. Thanks for the pointer, Ben. I'm not sure if the question is up for consideration or not. There appear to be 2 different requirements, and having read through bug 393 it didn't seem like either side was really understanding the requirements. In particular, I didn't realize the impact this patch would have on HostBasedAuthenciation. Definitely, the 1:many problem you mentioned is a problem - which of several host keys to use. That is a very significant problem- it would totally break Hostbaseauth. The problem I have is several hundred ssh servers, located behind (fewer) dhcp changing IP addresses that many of our Customers have. For each ip address (approx 100), there are 3 or so ssh servers (running on different ports forwarded from the single IP). On a daily basis, someone (or lots) are moving IP addresses. I need to ensure our staff can connect safely and securely and ensure our Customers are equally protected. To that end, our staff can accept new host keys but cannot connect if an already known hostkey doesn't match what it should (i.e. ssh StrictHostKeyCheck ask). We explicitely disable HostBasedAuth (and all related auth tyes) on all of these installs. As per bug 393, maintaining a ssh_config file with the necessary mappings is not a viable option, commercially- we just have too many hosts changing too often. Our Customer base is growing, so the problem is getting bigger. The interesting thing is that these are quite different requirements. One is hostbasedauth and one is MITM-mitigation. I would still like to see this feature, but as you noted there needs to be a method that ensures 1:1 for hostbasedauth to work properly. This is what I see: 1) For sites with multiple machines behind 1 IP address; only 1 of those machines could connect to another ssh server using hostbasedauth, given openssh 3.9p1 unchanged. Assuming one of these hosts connects to a ssh server: 2) The server that is connected to is able to lookup the host pub key because it knows the ip address of the connecting host (in this case, the NAT ip). Since there's 1:1 match between ip/hostname and the key files, the ssh server knows which key to select. Therefore, the conclusion that I think I can draw is that hostbasedauth works for all hosts that have the same ip address and host keys. Stated another way, hostbasedauth does not work for hosts that share a common ip address but different host keys. If that is true, then assuming a patch similar to mine were accepted, causing multiple keys with the same ip address to be in the known_hosts files, the question is how to identify which of the potential lines hould be used to get the host key from. The answer to that could be to have a flag to tell the functions in auth.c (and in particular check_key_in_hostfiles()) to know about the special flag so that only one host line matches. Perhaps the easiest to impliment would be a special indicator similar to a port number. Potential example: ip.ip.ip.ip:hostbasedauth In this way, a line in a known_hosts file with :hostbasedauth after the hostname, ip, or alias, would be singled out for use by a ssh server for hostbasedauth. This would maintain the 1:1. Also, since I'd venture to guess folks using hostbasedauth are a little more fluent with Unix and ssh (since they've at least had to know how to edit a rhosts or shosts file), they would seem fairly well equiped to add a hostbasedauth flag. The largest disadvantage that I see, which isn't so much a disadvantage for me, is that the known_hosts entry with the :hostbasedauth is not shared for outgoing connections - and therefore in situation where host A connects to host B using hostbasedauth, and then from host B connects back to host A using whatever, host B will have 2 entries for host A: 1 for the hostbasedauth and 1 for the standard hostauth/MITM-mitigation. Any comments, thoughts, chance of getting this bug un-wontfixed? Thanks, Devin Nate
Created attachment 717 [details] Same patch as before, updated auth.c to look for 'hostbasedauth' flag in place of port number for HostBasedAuth
Created attachment 719 [details] Patch to add PortAware to ssh client Summary: Permit ssh client and ssh server to preserve all backwards compat while at the same time permitting ssh client to be 'port aware'. I believe that both mechanisms (PortAware and HostKeyAlias) can co-exist. I am not asking to replace one with the other, I'd sure like both though, and I believe the following is a way to have both in such a way that backwards compat is maintained, no features are lost, and the port feature is gained. SSH CLIENT 1) ssh will use the host documented in HostKeyAlias if there is one. No port information will be used for key retrieval or key addition. (i.e. ssh client will work identical as before if there is a HostKeyAlias specified). 2) ssh will use host & port if there is not an explicit HostKeyAlias. Port information will be appended to the hostname and/or ip address in the format @port (the mailing lists noted that @ is a better seperator). SSH SERVER 1) sshd will use host/ip address only for HostbasedAuth. It will not use any port information for key retrieval. (i.e. sshd server will work identical as before, no changes to be made). ADDITIONAL FEATURES: 1) ssh client becomes 'port aware'. COMPAT MAINTAINED 1) ssh client connections still can use all the features of the HostKeyAlias functionality, both for key learning and key retrieval. ssh client is identical when HostKeyAlias information is specified. 2) For non-HostKeyAlias entries, ssh client behavior is identical to before except that port info is used to save and retrieve known_hosts entries. 3) sshd does not process port information and therefore operates identical to before. POTENTIAL CONSEQUENCES 1) Since ssh client may learn with @port info (i.e. when there is no HostKeyAlias), and since sshd ignores @port info, users will need to make sure that keys to be read by sshd for HostbasedAuthentication appear without the @port information. Since current info is stored without @port info, full backward compat is maintained for people already doing this. Only newly added hosts need to be verified. POTENTIAL CONFIG ISSUES [ NOT IMPLIMENTED IN THIS PATCH ] 1) Since there is some controversy, perhaps a ssh option for ssh_config or from the command line exists to enable the port-aware behavior. ssh_config example: PortAware [ yes | no ] (default to no to maintain backwards compat).
This is the same as (at least) bug 80, bug 393, bug 454, bug 523, and bug 537. I hope the number of bugs submitted on this convince that it is a real problem, at least..
Do note as what bug 454 states don't use ":" as a host:port separator. user@port is fine. Otherwise you run into IPv6 issues. - Ben
My most current patch 'PortAware' uses @ as per bug 454 as the port seperator. It was good advice to read all the past comments :) Thanks, Devin Nate
It seems as though this really ought to have been reopened after all that discussion..even if just to be re-closed. Since this bug has a proposed patch and bug 454 doesn't, perhaps that should be closed as a duplicate of this one?
*** Bug 454 has been marked as a duplicate of this bug. ***
Any chance that this patch will actually be applied?
Probably not as it stands because it breaks every known_hosts file in existence: $ grep myserver ~/.ssh/known_hosts myserver,192.168.32.1 ssh-rsa AAAA[snip] $ ./ssh -o hashknownhosts=no gate The authenticity of host 'myserver (192.168.32.1@22)' can't be established. Perhaps it ought to check for a matching "server@port" first, then "server" before failing?
Created attachment 912 [details] Update patch #719 to -current Updated to -current. Only looked at it briefly, but there seems to be unnecessary changes in there (eg the changes to ssh_kex2()).
(In reply to comment #15) > Perhaps it ought to check for a matching "server@port" first, then "server" > before failing? Thinking about this: how about if a missing "@port" portion implied "@22", and when creating new entries for port 22 the "@port" portion was omitted? That would mean that a patched ssh would still create known_hosts files that are compatible with older versions for the common case (handy for, eg, an NFS-mounted /home shared by multiple hosts).
That would also allow the correct use of hashed hostnames without the @port appendage.
Created attachment 913 [details] A key of "hostname" implies port 22, also fix HashKnownHosts Implement semantics proposed in comment #17, and make it play nice with HashKnownHosts. The cases I can see are: a) "ssh hostname" stores a key for "hostname" b) "ssh -p 222 hostname" stores a key for "hostname@222". c) "ssh -p 222 -o hostkeyalias=foo hostname" stores a key for "foo". The only change in semantics I can see is for case b) when there's a key for "hostname" but not "hostname@222". Without the patch it'll match "hostname", with the patch it'll give a "no matching key" error. I think this is probably acceptable.
Created attachment 914 [details] known hosts port patch, cleaned up, updated man page
Comment on attachment 914 [details] known hosts port patch, cleaned up, updated man page >Index: sshconnect.c >=================================================================== >RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/sshconnect.c,v >retrieving revision 1.129 >diff -u -p -r1.129 sshconnect.c >--- sshconnect.c 14 Mar 2005 12:08:12 -0000 1.129 >+++ sshconnect.c 14 May 2005 12:13:10 -0000 ... >+ if (snprintf(hoststr, len, "%s@%hu", host, port) >= len) >+ fatal("check_host_key: snprintf failed"); >+ len = strlen(ip) + sizeof(port) * 4 + 2; >+ ipstr = xmalloc(len); >+ if (snprintf(ipstr, len, "%s@%hu", ip, port) >= len) >+ fatal("check_host_key: snprintf failed"); Current style is to check snprintf's return != -1 and < len because of old busted implementations that return -1. I think our snprintf returns >= len on truncation, but we should set a good example anyway. Otherwise this looks pretty much OK.
Comment on attachment 914 [details] known hosts port patch, cleaned up, updated man page Also noticed this minor improvement: >+ u_short port = options.port ? options.port : SSH_DEFAULT_PORT; [...] >- ssh_kex2(host, hostaddr); >+ ssh_kex2(host, port, hostaddr); Since check_host_key() will happily accept a port of zero as meaning the default, we could just feed it options.port. In fact, we could do away with the extra argument entirely and just use options.port directly, which would cut the diff a bit.
Created attachment 920 [details] port-aware known hosts, simplified Used options.port rather than passing a port number around as an argument. This reduced the overall diff by about 25%. Should still behave exactly the same as attachment #914 [details].
Created attachment 946 [details] Implement port spec as per sshd(8) ListenAddress Implement semantics proposed here: http://marc.theaimsgroup.com/?l=openssh-unix-dev&m=112317383118528 The following are valid hostname entries: localhost 127.0.0.1 ::1 localhost:222 127.0.0.1:222 [::1]:222 The first 3 should remain backward compatible with older versions and are written if possible. The syntax is compatible with the sshd(8) ListenAddress option (uses the same parser). Only lightly tested here as it's late. Anyone interested in this please test. A better description for the man page would also be welcome.
Created attachment 954 [details] Debug traces of sshd and ssh When I tested the Patch against OpenSSH 4.2p1 the ssh client coredumps. The debug traces are attached. This happens in hpux.
Let me add to the voice of support for including ports into the known_hosts file (it's unclear to me from reading the comments as to whether there is an intent to put it into the distribution or whether it will remain a patch). There are many perfectly legitimate situations in which multiple ssh ports are open on different ports, and there is no reason why they should all have the same "host key". In fact, the name "host key" presupposes, without much good evidence, that "host" is the appropriate administrative unit for security; let's call it a "service key", and then it's obvious that it should be stored under both host and port. I understand that the maintainers are concerned about spoofing, but the scenarios that would lead to that strike me as unlikely. In contrast, the current situation causes everybody to constantly delete keys from known_hosts, which really creates the potential for man-in-the-middle attacks. The problem is exacerbated by the poor documentation of this problem in the ssh manual page.
additional voices don't matter, test reports for the patch.
(In reply to comment #25) > Created an attachment (id=954) [edit] > Debug traces of sshd and ssh > > When I tested the Patch against OpenSSH 4.2p1 the ssh client coredumps. The > debug traces are attached. This happens in hpux. I don't see how the patch could have affected the DH exchange where it crashes. You don't happen to be using gcc-4.x on your HP-UX box, do you? I've personally had problems with 4.0.0 and helped someone who traced problems to 4.0.1, both on HPPA.
Im using HP C compiler. I will cross check the patch with prior versions of OpenSSH and will let you know the results.
(In reply to comment #29) > Im using HP C compiler. I will cross check the patch with prior versions of > OpenSSH and will let you know the results. Also, if you're using openssl-0.9.8, please try 0.9.7g instead. The debug trace shows a client-side coredump very similar to bug #1085.
Just a add on details for attachment id=954 , Im using OpenSSH_4.2p1, OpenSSL 0.9.7e
(In reply to comment #31) > Just a add on details for attachment id=954 , Im using > OpenSSH_4.2p1, OpenSSL 0.9.7e Senthil, could you please feed your ssh to a debugger and see where it dies? If you have gdb, this is something like: $ gdb /path/to/ssh (gdb) set args -vvv server.example.com (gdb) run [wait for segfault] (gdb) backtrace Then attach the output? Thanks.
Created attachment 980 [details] Simplified version of attachment id #946. Seems to work OK with HashKnownHosts and HostbasedAuthentication (at least, as well as can be expected).
The patch id=980 works without any problem in HP-UX. When I digged more on this to find the corner case, I found in the patch id=946 the following code seems to be responsible for the problem. >if ((p = strchr(host, ':')) != NULL && strchr(p+1, ':') != NULL) >ret = asprintf(&p, "[%s]:%hd", host, port); /* IPv6 */ >else >ret = asprintf(&p, "%s:%hd", host, port); This call asprintf is not supported in HP-UX libc and it is part of glibc. Even when I used the equivalent sprintf to avoid compilation errors, it results in coredump as said in attachment id=954. If needed I will attach the gdb backtrace of the coredump.
(In reply to comment #34) > The patch id=980 works without any problem in HP-UX. Thanks. > This call asprintf is not supported in HP-UX libc and it is part of glibc. asprintf is a GNUism but it's present on many other systems, but not all. If we end up using in within OpenSSH then we'll add an implementation to libopenbsd-compat for those systems that don't have it natively. > Even when I used the equivalent sprintf to avoid compilation errors, it > results in coredump as said in attachment id=954. A literal asprintf->sprintf replacement doesn't allocate any memory, so unless you did a malloc too then that's probably the reason for the crash (attempting to deref an uninitialized pointer). > If needed I will attach the gdb backtrace of the coredump. Not necessary, unless you can reproduce the crash with attachment #980 [details]. In general, when reporting problems you should mention if you've made any changes, even if if you think they're not related. Usually it won't matter, but sometimes it does. Same goes for oddball compiler flags (if you're seeing intermittent crashes after building with "./configure --with-cflags=-'-Dsizeof(x)=rand()'" then we don't care so much :-)
Created attachment 1051 [details] Support ip:port for know_hosts file
Comment on attachment 1051 [details] Support ip:port for know_hosts file Hi, Here a simple patch to add the know_hosts port support has suggested by Devin Nate on previous post. This patch add ip:port instead of ip Please test and report if it work or not.
Created attachment 1052 [details] Support ip:port in known_hosts file Hi Forget the previous patch I sent, Here is the correct/working patch supporting the ip:port in known_hosts file. cat ~/.ssh/known_hosts localhost:22 ssh-rsa AAAAB3Nza..... localhost:8022 ssh-rsa AAAAB3Nza..... /\ | The port feature is now include Martial
Created attachment 1073 [details] Patch 980 for 4.3p2 with minor modifications Hi folks, The work looks good. I'm uploading a very slightly modified version of patch 980 (the latest by Darren Tucker). It appears to me to be the best. Darren, thanks. This patch is applied against 4.3p2. The differences when compared against patch 980 are: 1) In sshconnect.c, where the Darren patch 980 did: ip = xstrdup(ntop); + ip = put_host_port(ntop, options.port); I didn't understand why the ip = xstrdup(ntop); wasn't removed, so this patch does: - ip = xstrdup(ntop); + ip = put_host_port(ntop, options.port); 2) Applies cleanly against openssh 4.3p2 (the addition of some code to misc.h caused the patch to fail, and file location offsets are a bit different). 3) The modifications to sshconnect2.c were removed, they appeared to be there for debugging only. The relavent section from patch 980 was: -- sshconnect2.c 31 Aug 2005 09:46:27 -0000 1.131 +++ sshconnect2.c 3 Oct 2005 02:25:14 -0000 @@ -1303,6 +1303,8 @@ userauth_hostbased(Authctxt *authctxt) u_int blen, slen; int ok, i, len, found = 0; + debug("%s called", __func__); + Thanks, Devin Nate
Created attachment 1131 [details] Update patch #1073. Updated the patch to OpenBSD-current. Simplified put_host_port by using asprintf again (we now have it in Portable's libopenbsd-compat for platforms that don't have a native one). BTW we're not using the method in patch #1052 ("ip:host" unconditionally) because it will invalidate all existing known_hosts files (see comment #15).
Created attachment 1132 [details] Patch #1073 with fallback. This is essentially the same as patch #1131, except that it also checks for a matching hostkey without the port identifier. Currently, if you have something like this in ssh_config: Host foo Hostname foo.example.com Port 222 then you will have an entry like this in ssh_config: foo.example.com ssh-rsa AAAA[...] With patch #1131, this will no longer match since it's a non-default port. This patch adds a second check for this condition, so the key verification doesn't fail. Note that this only occurs when a) you *do* use a non-default port and b) you *don't* use a HostKeyAlias, so unless both of these are true patch #1131 will behave the same as you're used to.
*** Bug 1198 has been marked as a duplicate of this bug. ***
Patch #1131 has been applied and will be in tomorrow's snapshot. Thanks to all.
Need to mention user-visible change in release notes: using non-default ports will no longer match host keys without port identifier. Connections using the default port (ie 22) and ones that use HostKeyAlias (regardless of the port) are not affected.
Hi all; Darren, thank you very much for your effort- it is sure appreciated. And as Darren said, thanks to all! Devin Nate
With the release of 4.4, we believe that this bug is now closed. For information about the release please see http://www.openssh.com/txt/release-4.4 .
*** Bug 1662 has been marked as a duplicate of this bug. ***