Bugzilla – Attachment 2863 Details for
Bug 2606
IPv6 bind address vs autoconfiguration privacy
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
extend BindAddress option to select the type of IPv6 src address
0001-extend-BindAddress-option-to-select-the-type-of-IPv6.patch (text/plain), 7.33 KB, created by
Stefan Tomanek
on 2016-08-23 05:59:16 AEST
(
hide
)
Description:
extend BindAddress option to select the type of IPv6 src address
Filename:
MIME Type:
Creator:
Stefan Tomanek
Created:
2016-08-23 05:59:16 AEST
Size:
7.33 KB
patch
obsolete
>From 33657527851d95cb7c6877bea3b9b89131d409b9 Mon Sep 17 00:00:00 2001 >From: Stefan Tomanek <stefan.tomanek@wertarbyte.de> >Date: Fri, 19 Aug 2016 20:00:59 +0200 >Subject: [PATCH] extend BindAddress option to select the type of IPv6 address > >When using IPv6 autoconfiguration, the IP address is deducted using the unique >hardware address of the network card and the announced network prefix. Since >this might lead to privacy issues, most operating systems generate >pseudo-random addresses that are rotated in regular intervals. > >This can be a problem for long-running connections if a address is invalidated >while still in use - the connection "hangs". Even though expired addresses are >usually retained for a long timeframe to prevent this, accidental dis- and >reconnection (e.g. when using a wireless network) flushes the list of >previously used addresses. > >By setting appropiate socket options, the kernel can be instructed to use the >public (and static) source address for the outgoing connection. This change >implements this functionality for SSH, adding special behaviour to the option >"BindAddress" (-b) that can be set to "%pub(lic)", "%t(e)mp", indicating the >preference for the type of address to be used. The prefixed percentage sign is >used to distinguish the arguments from ordinary hostnames (just like ping6 does >with appended interface names on link local addresses). >--- > configure.ac | 13 ++++++++++ > ssh_config.5 | 16 ++++++++++++ > sshconnect.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- > 3 files changed, 107 insertions(+), 5 deletions(-) > >diff --git a/configure.ac b/configure.ac >index a3c22c1..7635e55 100644 >--- a/configure.ac >+++ b/configure.ac >@@ -493,6 +493,9 @@ SPP_MSG="no" > # the --with-solaris-privs option and --with-sandbox=solaris). > SOLARIS_PRIVS="no" > >+# Support for IPv6 source address preference selection >+IPV6_SRC_ADDR_PREF_MSG="no" >+ > # Check for some target-specific stuff > case "$host" in > *-*-aix*) >@@ -784,6 +787,15 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) > [Define if cmsg_type is not passed correctly]) > ;; > esac >+ # linux specific IPv6 sock options >+ AC_CHECK_HEADERS([linux/in6.h]) >+ if test "x$ac_cv_header_linux_in6_h" = "xyes" ; then >+ AC_DEFINE([HAS_IPV6_SRC_PREF], [1], >+ [System has IPv6 source address preference flags]) >+ AC_DEFINE([LINUX_IPV6_PREF_FLAGS], [1], >+ [Use Linux specific IPv6 options]) >+ IPV6_SRC_ADDR_PREF_MSG="yes (Linux)" >+ fi > # tun(4) forwarding compat code > AC_CHECK_HEADERS([linux/if_tun.h]) > if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then >@@ -5099,6 +5111,7 @@ echo " Solaris project support: $SP_MSG" > echo " Solaris privilege support: $SPP_MSG" > echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" > echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" >+echo "IPv6 src addr preference selection: $IPV6_SRC_ADDR_PREF_MSG" > echo " BSD Auth support: $BSD_AUTH_MSG" > echo " Random number source: $RAND_MSG" > echo " Privsep sandbox style: $SANDBOX_STYLE" >diff --git a/ssh_config.5 b/ssh_config.5 >index 7630e7b..ae8d0e8 100644 >--- a/ssh_config.5 >+++ b/ssh_config.5 >@@ -284,6 +284,22 @@ Note that this option does not work if > .Cm UsePrivilegedPort > is set to > .Dq yes . >+.Pp >+Additionally, this option may be used to control the selection of IPv6 >+binding addresses on platforms that support it. >+A >+.Cm BindAddress >+of >+.Dq %public >+or >+.Dq %pub >+will cause >+.Xr ssh 1 >+to use a stable public IPv6 address, while >+.Dq %temp >+or >+.Dq %tmp >+will prefer a randomised temporary address. > .It Cm CanonicalDomains > When > .Cm CanonicalizeHostname >diff --git a/sshconnect.c b/sshconnect.c >index 356ec79..68417cb 100644 >--- a/sshconnect.c >+++ b/sshconnect.c >@@ -66,6 +66,10 @@ > #include "ssherr.h" > #include "authfd.h" > >+#ifdef LINUX_IPV6_PREF_FLAGS >+# include <linux/in6.h> >+#endif >+ > char *client_version_string = NULL; > char *server_version_string = NULL; > Key *previous_host_key = NULL; >@@ -267,6 +271,51 @@ ssh_kill_proxy_command(void) > kill(proxy_command_pid, SIGHUP); > } > >+#ifdef HAS_IPV6_SRC_PREF >+enum ssh_bindpref {BINDPREF_PUB, BINDPREF_TMP}; >+ >+static int >+ssh_mod_ipv6bindpref(int fd, enum ssh_bindpref pref) >+{ >+# ifdef LINUX_IPV6_PREF_FLAGS >+ int val; >+ int err; >+ socklen_t len = sizeof(val); >+ int add = 0; >+ switch (pref) { >+ case BINDPREF_PUB: >+ add = IPV6_PREFER_SRC_PUBLIC; >+ break; >+ case BINDPREF_TMP: >+ add = IPV6_PREFER_SRC_TMP; >+ break; >+ default: >+ error("Unknown ssh_bindpref value"); >+ return -1; >+ } >+ err = getsockopt(fd, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &val, &len); >+ if (err < 0) { >+ error("getsockopt IPV6_ADDR_PREFERENCES: %.100s", >+ strerror(errno)); >+ return err; >+ } >+ >+ val &= ~(IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP| >+ IPV6_PREFER_SRC_PUBTMP_DEFAULT); >+ val |= add; >+ err = setsockopt(fd, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES, &val, len); >+ if (err < 0) { >+ error("setsockopt IPV6_ADDR_PREFERENCES: %.100s", >+ strerror(errno)); >+ } >+ return err; >+# else >+ error("Setting IPv6 address source address not supported"); >+ return -1; >+# endif >+} >+#endif >+ > /* > * Creates a (possibly privileged) socket for use as the ssh connection. > */ >@@ -275,6 +324,7 @@ ssh_create_socket(int privileged, struct addrinfo *ai) > { > int sock, r, gaierr; > struct addrinfo hints, *res = NULL; >+ char *bind_address = options.bind_address; > > sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); > if (sock < 0) { >@@ -283,19 +333,42 @@ ssh_create_socket(int privileged, struct addrinfo *ai) > } > fcntl(sock, F_SETFD, FD_CLOEXEC); > >+ /* Set IPV6_ADDR_PREFERENCES through magic bind address */ >+ if (bind_address && bind_address[0] == '%') { >+#if defined(HAS_IPV6_SRC_PREF) >+ if (ai->ai_family != AF_INET6) { >+ debug("Not setting address preference on" >+ " non-IPv6 socket"); >+ } else if (strcmp(bind_address, "%pub") == 0 || >+ strcmp(bind_address, "%public") == 0) { >+ debug("Setting preference for public IPv6 address"); >+ ssh_mod_ipv6bindpref(sock, BINDPREF_PUB); >+ } else if (strcmp(bind_address, "%tmp") == 0 || >+ strcmp(bind_address, "%temp") == 0) { >+ debug("Setting preference for temporary IPv6 address"); >+ ssh_mod_ipv6bindpref(sock, BINDPREF_TMP); >+ } else { >+ error("Unknown bind address preference: '%s'", >+ bind_address); >+ } >+#else >+ error("IPv6 address preference selection not supported"); >+#endif >+ bind_address = NULL; >+ } > /* Bind the socket to an alternative local IP address */ >- if (options.bind_address == NULL && !privileged) >+ if (bind_address == NULL && !privileged) > return sock; > >- if (options.bind_address) { >+ if (bind_address) { > memset(&hints, 0, sizeof(hints)); > hints.ai_family = ai->ai_family; > hints.ai_socktype = ai->ai_socktype; > hints.ai_protocol = ai->ai_protocol; > hints.ai_flags = AI_PASSIVE; >- gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); >+ gaierr = getaddrinfo(bind_address, NULL, &hints, &res); > if (gaierr) { >- error("getaddrinfo: %s: %s", options.bind_address, >+ error("getaddrinfo: %s: %s", bind_address, > ssh_gai_strerror(gaierr)); > close(sock); > return -1; >@@ -316,7 +389,7 @@ ssh_create_socket(int privileged, struct addrinfo *ai) > } > } else { > if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) { >- error("bind: %s: %s", options.bind_address, >+ error("bind: %s: %s", bind_address, > strerror(errno)); > fail: > close(sock); >-- >2.1.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2606
:
2862
|
2863
|
2865