Re: Match on AddressFamily

Anton Khirnov <[email protected]> Sun, 31 May 2026 17:04:29 +0200
Newsgroups gmane.network.openssh.devel
Message-ID <[email protected]>
Hi,
Quoting Marc Haber (2026-05-31 16:31:44)
> Hi,
> 
> I have in my client config:
> 
> Match Localnetwork 2001:db8:43fa:bc82::/64
>    BindAddress 2001:db8:43fa:bc82::1f:100
> 
> to ask my ssh client to use a static address instead of the privacy IPv6 
> address when I am at my home network.

RFC5014 defines a proper way to handle this without hardcoding any
addresses, by adding a socket option to express address type preference
(public, temporary, etc.). I sent a patch a couple years ago
implementing it in openssh, but it was not accepted (might have had
something to with the fact that only Linux implements this RFC).

These days I'm using ssh via a wrapper script that intercepts socket()
and adds the relevant socket option. It's not ideal, but seems to work
well enough. Source attached, if you're interested.

Cheers,
-- 
Anton Khirnov

_______________________________________________
openssh-unix-dev mailing list
[email protected]
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
socket_v6_prefer_public.c (text/x-c, 976 B)
#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <netinet/in.h>
#include <sys/socket.h>
#include <linux/ipv6.h>

#define _GNU_SOURCE
#include <dlfcn.h>

int socket(int domain, int type, int protocol)
{
    static int (*socket_orig)(int, int, int) = NULL;
    int sock;

    if (!socket_orig) {
        socket_orig = dlsym(RTLD_NEXT, "socket");
        if (!socket_orig) {
            fprintf(stderr, "Error retrieving libc socket(): %s\n", dlerror());
            errno = EINVAL;
            return -1;
        }
    }

    sock = socket_orig(domain, type, protocol);
    if (sock < 0)
        return sock;

    if (domain == AF_INET6) {
        int val = IPV6_PREFER_SRC_PUBLIC;
        int ret = setsockopt(sock, IPPROTO_IPV6, IPV6_ADDR_PREFERENCES,
                             &val, sizeof(val));
        if (ret < 0)
            fprintf(stderr, "Could not set address preferences: %s\n",
                    strerror(errno));
    }

    return sock;
}