gpg: Address family not supported by protocol if kernel doesn't support ipv6
Closed, ResolvedPublic

Description

Running gnupg version 2.1.22 on an IPv4 only linux system fails to connect to keyservers, i.e. I get the error message

gpg: keyserver send failed: Address family not supported by protocol

When I enable IPv6 by loading the ipv6 kernel module the error goes away andd everything works as expected.

Specifically:
gpg -vv --debug-all --keyserver keyring.debian.org --recv-keys ...

gpg: Optionen werden aus '/home/gerddie/.gnupg/gpg.conf' gelesen
gpg: enabled debug flags: packet mpi crypto filter iobuf memory cache memstat trust hashing ipc clock lookup extprog
gpg: DBG: [not enabled in the source] start
gpg: DBG: chan_3 <- # Home: /home/gerddie/.gnupg
gpg: DBG: chan_3 <- # Config: [none]
gpg: DBG: chan_3 <- OK Dirmngr 2.1.22 at your service
gpg: DBG: connection to the dirmngr established
gpg: DBG: chan_3 -> GETINFO version
gpg: DBG: chan_3 <- D 2.1.22
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> KEYSERVER --clear hkp://keyring.debian.org
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> KS_GET -- 0xD5C2F9BFCA128BBA22A77218872F702C4D6E25A8
gpg: DBG: chan_3 <- ERR 167804933 Address family not supported by protocol <Dirmngr>
gpg: Failed to receive from key server: Address family not supported by protocol
gpg: DBG: chan_3 -> BYE
gpg: DBG: [not enabled in the source] stop
gpg: keydb: handles=0 locks=0 parse=0 get=0
gpg: build=0 update=0 insert=0 delete=0
gpg: reset=0 found=0 not=0 cache=0 not=0
gpg: kid_not_found_cache: count=0 peak=0 flushes=0
gpg: sig_cache: total=0 cached=0 good=0 bad=0
gpg: random usage: poolsize=600 mixed=0 polls=0/0 added=0/0

outmix=0 getlvl1=0/0 getlvl2=0/0

gpg: secmem usage: 0/65536 bytes in 0 blocks

The same command worked fine with version 2.1.15.

see also Debian #870806

best,
Gert

gerddie created this task.Aug 5 2017, 11:48 AM
werner triaged this task as Low priority.Aug 5 2017, 3:03 PM
werner added a project: dirmngr.
werner added a subscriber: werner.

If you don't have a TCP enabled OS, you can use configure --disable-dirmngr.

And yes, I consider v6 the standard IP implementation theses days. So I would claim that there is no need for a fix. Now, if we have a similar problem with an OS w/o legacy IP support, we should fix that of course.

werner added a comment.Aug 5 2017, 3:05 PM

BTW, dirmngr has an option --disable-ipv4.

I see your point.

In any case, an error message that is a bit more specific about what exactly goes wrong would be still be helpful, i.e. it could point out that in this case ipv6 was tried and failed.

If you don't have a TCP enabled OS, you can use configure --disable-dirmngr.

If IPv4 is enabled but not IPv6, IP stack _is_available and dirmngr should work

And yes, I consider v6 the standard IP implementation theses days. So I would claim that there is no need for a fix. Now, if we have a similar problem with an OS w/o legacy IP support, we should fix that of course.

IPv6 as standard sounds like wishful thinking, in terms of deployment I see 9 machines with IPv4 only for every machine with dual-stack (non-scientific numbers). A failure on IPv4 only only adds to a poor user experience, and for me... people complaining that the pools aren't working

frougon added a subscriber: frougon.Oct 9 2017, 1:33 PM

The workaround I've found is to put:

disable-ipv6

in ~/.gnupg/dirmngr.conf. It's a pity that IPv4 isn't supported by default anymore, because some people disable IPv6 on their boxes *precisely* for security reasons---following the same logic that leads one to only install the server software one needs, and open only the needed ports on a firewall, no more.

dkg added a subscriber: dkg.Oct 9 2017, 4:15 PM

I agree with @kristianf that dirmngr should be more clever about this sort of failure. The error message could be clearer at least, but the right response is really to skip all IPv4 addresses if the machine has no IPv4 stack, and to skip all IPv6 addresses if the machine has no IPv6 stack.

werner added a comment.Oct 9 2017, 5:08 PM

The question is how to detect whether v4 or v6 is supported. Most systems support both versions but that does not mean that they can actually be used (i.e. due to improper setup or no connectivity). Even the "address family" not supported can be due to a missing kernel module and thus be a transient error message.

A better warning message is of course justified. I need a way to force such a warning for testing, though.

Hello Werner and other participants,

According to https://stackoverflow.com/questions/13441324/ipv6-connectivity-test-in-c Microsoft does a connection test to an IPv4-only box and another one to an IPv6-only box in order to determine connectivity. I suspect such a method wouldn't be much appreciated for GnuPG...

OTOH, https://stackoverflow.com/questions/28097823/how-to-test-from-userspace-if-the-kernel-supports-ipv6 mentions the existence of /proc/net/if_inet6. I can say that on my Linux systems where IPv6 is disabled with ipv6.disable=1 on the kernel command line, this file doesn't exist. So maybe this could be used for Linux, at least?

Note that I don't see any /proc/net/if_inet4 either, although I do have IPv4 connectivity.

Just posting this in case this can help improve out-of-the-box user experience, otherwise the workaround I mentioned above is enough for my needs.

Thanks!

mgorny added a subscriber: mgorny.Feb 1 2018, 1:40 PM

This can easily be solved by adding two more cases to handle_send_request_error(): for GPG_ERR_EADDRNOTAVAIL (that's IPv6 disabled via procfs) and GPG_ERR_EAFNOSUPPORT (that's missing kernel support). Normally I'd submit a patch but I don't care enough to jump through all the hoops just to get two-line change in.

The patch is available in our downstream bugtracker as attachment to https://bugs.gentoo.org/646194

werner closed this task as Resolved.Feb 22 2018, 8:55 PM
werner claimed this task.

Will go into 2.2.6