The ssh client should include an option to choose IPv6 socket options for outgoing connection source address selection. Indeed the default should probably be to select the public address (instead of letting the kernel autoselect) - otherwise, if you have ipv6 privacy extensions configured outgoing ssh connections eventually break as the source address expires (by default a new one is generated daily and old ones expire after 7 days). You are affected if use_tempaddr on the outgoing interface is set to 2 (please note this setting can only be meaningfully changed on a down'ed interface). For example: /proc/sys/net/ipv6/conf/${INTERFACE}/use_tempaddr: 2 /proc/sys/net/ipv6/conf/${INTERFACE}/temp_prefered_lft: 86400 /proc/sys/net/ipv6/conf/${INTERFACE}/temp_valid_lft: 604800 To quote linux+v2.6.29.6/include/linux/in6.h: /* RFC5014: Source address selection */ #define IPV6_ADDR_PREFERENCES 72 #define IPV6_PREFER_SRC_TMP 0x0001 #define IPV6_PREFER_SRC_PUBLIC 0x0002 #define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100 #define IPV6_PREFER_SRC_COA 0x0004 #define IPV6_PREFER_SRC_HOME 0x0400 #define IPV6_PREFER_SRC_CGA 0x0008 #define IPV6_PREFER_SRC_NONCGA 0x0800 so you need to call setsockopt(socket, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &value, sizeof(value)). Supported should probably be values of 'default', 'tmp', 'public' and an explicit integer value.
Created attachment 363770 [details] first attempt at a patch: spec file
Created attachment 363771 [details] first attempt at a patch: patch proper
First attempt at a patch which adds this support. As yet, untested (although it does build). The main problem seems to be that the constants aren't defined outside of <linux/in6.h> (or <linux/ipv6.h>) which includes them. AFAICT openssh appears not to use linux specific include files... Not sure how to procede...
Patch appears to function. - v4 works normally $ ssh -4 root@fate 'lsof -i -n' | egrep '^ssh.*ESTABLISHED' sshd 4201 root 3r IPv4 919505 0t0 TCP 1.2.3.4:ssh->5.6.7.8:32598 (ESTABLISHED) - v6 defaults to asking for public ip $ ssh -6 root@fate 'lsof -i -n' | egrep '^ssh.*ESTABLISHED' sshd 4204 root 3r IPv6 919579 0t0 TCP [A:B:C:D::2]:ssh->[D:E:A:D:21f:5bff:fee8:xxxx]:37626 (ESTABLISHED) - if you ask for none, we skip the setsockopt and get the kernel default of tmp ip (use_tempaddr == 2) $ ssh -6 -o IPv6AddressPreference=none root@fate 'lsof -i -n' | egrep '^ssh.*ESTABLISHED' sshd 4207 root 3r IPv6 919653 0t0 TCP [A:B:C:D::2]:ssh->[D:E:A:D:e811:55f:6eda:yyyy]:55648 (ESTABLISHED) - if you ask for tmp, you get it $ ssh -6 -o IPv6AddressPreference=tmp root@fate 'lsof -i -n' | egrep '^ssh.*ESTABLISHED' sshd 4210 root 3r IPv6 919745 0t0 TCP [A:B:C:D::2]:ssh->[D:E:A:D:e811:55f:6eda:yyyy]:55650 (ESTABLISHED) - if you ask for public, you get it $ ssh -6 -o IPv6AddressPreference=public root@fate 'lsof -i -n' | egrep '^ssh.*ESTABLISHED' sshd 4213 root 3r IPv6 919841 0t0 TCP [A:B:C:D::2]:ssh->[D:E:A:D:21f:5bff:fee8:xxxx]:53395 (ESTABLISHED) How do we proceed from here?
Oh, one last thing. - if you pass in '1' (tmp): it works - if you pass in '2' (public): it works - if you pass in a numeric value that the kernel doesn't like $ ssh -6 -o IPv6AddressPreference=3 root@fate 'lsof -i -n' | egrep '^ssh.*ESTABLISHED' setsockopt(..., IPV6_ADDR_PREFERENCES, [3]): Invalid argument sshd 4219 root 3r IPv6 919958 0t0 TCP [A:B:C:D::2]:ssh->[2620:0:1000:1301:e811:55f:6eda:yyyy]:37349 (ESTABLISHED) You get an error message (error message appears to be on stdout), but the connection still succeeds.
Have you sent the patch upstream?
No, I haven't, yet. I'm wondering where to pull the constants from, and how linux specific this is... I also still have to clean the patch up.
From the kernel source (and the RFC), it looks like you can set one of: #define IPV6_PREFER_SRC_TMP 0x0001 #define IPV6_PREFER_SRC_PUBLIC 0x0002 #define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100 (the last being effectively 0) and one of: #define IPV6_PREFER_SRC_COA 0x0004 #define IPV6_PREFER_SRC_HOME 0x0400 (the last being effectively 0) and one of: #define IPV6_PREFER_SRC_CGA 0x0008 #define IPV6_PREFER_SRC_NONCGA 0x0800 (the last being effectively 0, and the first being currently unimplemented in linux) The flags which I mention are effectively zero, allow you to clear a previously set flag from that group, but don't actually get retained in the kernel socket state. To me this suggests the default value should actually be IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA. The meaning is: prefer a public IP (temp ones could expire), prefer a home ip (instead of a care-of-address, this is for mobility on the client/roadwarrior), prefer a non care-give-address ip (again for mobility on the server/gateway). Current linux default behaviour is PUBTMP_DEFAULT | HOME | NONCGA. Where whether PUBTMP_DEFAULT means PUBLIC or TMP depends on a configuration setting of the output interface. Since ssh connections have a tendency to be looong, and are usually to servers which we trust at least a little bit, using the longest duration source IP seems appropriate. This implies PUBLIC, not TMP or PUBTMP_DEFAULT. This also implies HOME - not COA, and to a lesser degree NONCGA - not CGA. I'll make the changes. This also clearly needs a better way to be specified in the config file. Maybe I should split this into 3 separate options? The RFC specifies the flag names, but not their values, they're supposed to be a result of #include <netinet/in.h>. As such encoding the values directly into the patch would be linux specific. The values also apparently haven't yet made it into netinet/in.h (at least in F11). I see them only in linux/in6.h and indirectly in linux/ipv6.h. Further reading the RFC, it looks like the patch has to be further modified to add the flag values to the initial getaddrinfo call. Since dst address selection (may) depend on src address selection, and as such the getaddrinfo call needs to have something along the lines of: preferences = IPV6_PREFER_SRC_TMP; hints.ai_flags |= AI_EXTFLAGS; hints.ai_eflags = preferences; /* Fill in other hints fields */ getaddrinfo(....,&hints,. &ai0..); I'll take another stab at this.
CGA = cryptographically generated addresses, and not care-giver-address, doesn't change the fact we want NONCGA as default IMHO. The RFC seems to make no reference of which header file should define IPV6_ADDR_PREFERENCES. It also appears that IPV6_PREFER_SRC_PUBTMP_DEFAULT is Linux specific. The RFC specifies the default to be IPV6_PREFER_SRC_PUBLIC and makes no mention of PUBTMP_DEFAULT.
This message is a reminder that Fedora 11 is nearing its end of life. Approximately 30 (thirty) days from now Fedora will stop maintaining and issuing updates for Fedora 11. It is Fedora's policy to close all bug reports from releases that are no longer maintained. At that time this bug will be closed as WONTFIX if it remains open with a Fedora 'version' of '11'. Package Maintainer: If you wish for this bug to remain open because you plan to fix it in a currently maintained version, simply change the 'version' to a later Fedora version prior to Fedora 11's end of life. Bug Reporter: Thank you for reporting this issue and we are sorry that we may not be able to fix it before Fedora 11 is end of life. If you would still like to see this bug fixed and are able to reproduce it against a later version of Fedora please change the 'version' of this bug to the applicable version. If you are unable to change the version, please add a comment here and someone will do it for you. Although we aim to fix as many bugs as possible during every release's lifetime, sometimes those efforts are overtaken by events. Often a more recent Fedora release includes newer upstream software that fixes bugs or makes them obsolete. The process we are following is described here: http://fedoraproject.org/wiki/BugZappers/HouseKeeping
Still present in F12, I should really get back around to fixing this...
If the values of the constants are RFC-based, make own header in openssh sources, or maybe the compat sources, using linux headers if exists (configure.ac is your friend) and send it upstream please. Without it I can NOT accept it.
Do you plan to provide the patch and send it upstream?
Reporter, can you please respond? Without it I'll have to close this request
I do very much plan to get this done, unfortunately I just haven't had the time to work on it lately. However, this has sat around for way too long, I'll try and take another stab at the patch soon.
Maciej thans you.
Any chance of seeing this patch go upstream to be included in the official OpenSSH release soon? I am using Debian GNU/Linux and would very much like to take advantage of the functionality described in this report, which, apparently, is still missing from OpenSSH as of November 2010. The problem seems to be to make this patch more portable but unfortunately the general API described in RFC 5014 is still not available in <netinet/in.h> and <netdb.h> as suggested by the RFC, at least not on my system. On Linux, it is available through <linux/in6.h> but including that directly results in a redefinition of 'struct in6_addr', amongst others. I am lacking the skills required for cleaning up and submitting this patch, but maybe Maciej or somebody else can look into it. Another idea would be to just send the patch as-is to the OpenSSH dev mailing list and see if someone over there can finish the work. It would be a terrible shame if this patch was lost in this bug report.
Maciej do you plan to finish this patch soon?
Ping
Closed for lack of data. You can re-open anytime you want.