gnupg2 not honoring http-proxy argument

Bug #1788190 reported by wheelerlaw
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
gnupg2 (Ubuntu)
New
Undecided
Unassigned

Bug Description

I discovered this while running the following apt-key command:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823

I was hoping apt-key would pick up the http_proxy environment variable, however it did not. So I had to pass it into gpg manually:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --keyserver-options http-proxy=$http_proxy --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823

However, that still didn't work. So I messed around with running gnupg manually and found that the dirmngr has a bug in the implementation of its HTTP client. Essentially, dirmngr does not handle the http_proxy quite right, as it is still trying to resolve the hostname of the keyserver instead of just proxying the request through the HTTP proxy defined with the http-proxy argument.

I configured dirmngr to show all debugging output:
$ cat ~/.gnupg/dirmngr.conf
log-file /home/wlaw/.gnupg/dirmngr.log
verbose
debug all

Output of running gpg manually:

$ gpg --debug-level guru --keyserver hkp://keyserver.ubuntu.com:80 --keyserver-options http-proxy=$http_proxy --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
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/wlaw/.gnupg
gpg: DBG: chan_3 <- # Config: /home/wlaw/.gnupg/dirmngr.conf
gpg: DBG: chan_3 <- OK Dirmngr 2.2.4 at your service
gpg: DBG: connection to the dirmngr established
gpg: DBG: chan_3 -> GETINFO version
gpg: DBG: chan_3 <- D 2.2.4
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> OPTION http-proxy=http://localhost:3128/
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> KEYSERVER --clear hkp://keyserver.ubuntu.com:80
gpg: DBG: chan_3 <- OK
gpg: DBG: chan_3 -> KS_GET -- 0x2EE0EA64E40A89B84B2DF73499E82A75642AC823
gpg: DBG: chan_3 <- ERR 167772346 No keyserver available <Dirmngr>
gpg: keyserver receive failed: No keyserver available
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: rndjent stat: collector=0x0000000000000000 calls=0 bytes=0
gpg: secmem usage: 0/65536 bytes in 0 blocks

Output of dirmngr.log:

$ cat ~/.gnupg/dirmngr.log
2018-08-21 10:18:41 dirmngr[22513.0] permanently loaded certificates: 139
2018-08-21 10:18:41 dirmngr[22513.0] runtime cached certificates: 0
2018-08-21 10:18:41 dirmngr[22513.0] trusted certificates: 139 (138,0,0,1)
2018-08-21 10:18:41 dirmngr[22513.6] handler for fd 6 started
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> # Home: /home/wlaw/.gnupg
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> # Config: /home/wlaw/.gnupg/dirmngr.conf
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> OK Dirmngr 2.2.4 at your service
2018-08-21 10:18:41 dirmngr[22513.6] connection from process 22512 (1000:1000)
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 <- GETINFO version
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> D 2.2.4
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> OK
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 <- OPTION http-proxy=http://localhost:3128/
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> OK
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 <- KEYSERVER --clear hkp://keyserver.ubuntu.com:80
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> OK
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 <- KS_GET -- 0x2EE0EA64E40A89B84B2DF73499E82A75642AC823
2018-08-21 10:18:41 dirmngr[22513.6] DBG: dns: libdns initialized
2018-08-21 10:18:41 dirmngr[22513.6] DBG: dns: resolve_dns_name(keyserver.ubuntu.com): No name
2018-08-21 10:18:41 dirmngr[22513.6] resolving 'keyserver.ubuntu.com' failed: No name
2018-08-21 10:18:41 dirmngr[22513.6] number of system provided CAs: 138
2018-08-21 10:18:41 dirmngr[22513.6] DBG: http.c:connect_server: trying name='localhost' port=3128
2018-08-21 10:18:41 dirmngr[22513.6] DBG: dns: resolve_dns_name(localhost): Success
2018-08-21 10:18:41 dirmngr[22513.6] can't connect to 'localhost': no IP address for host
2018-08-21 10:18:41 dirmngr[22513.6] error connecting to 'http://keyserver.ubuntu.com:80': Unknown host
2018-08-21 10:18:41 dirmngr[22513.6] marking host 'keyserver.ubuntu.com' as dead
2018-08-21 10:18:41 dirmngr[22513.6] DBG: dns: resolve_dns_name(keyserver.ubuntu.com): No name
2018-08-21 10:18:41 dirmngr[22513.6] resolving 'keyserver.ubuntu.com' failed: No name
2018-08-21 10:18:41 dirmngr[22513.6] host 'keyserver.ubuntu.com' marked as dead
2018-08-21 10:18:41 dirmngr[22513.6] command 'KS_GET' failed: No keyserver available
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> ERR 167772346 No keyserver available <Dirmngr>
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 <- BYE
2018-08-21 10:18:41 dirmngr[22513.6] DBG: chan_6 -> OK closing connection
2018-08-21 10:18:41 dirmngr[22513.6] handler for fd 6 terminated

This is only a problem when you're on a network that does not resolve DNS of internet hostnames (i.e. some sort of split-horizon setup). However, that shouldn't matter, because dirmngr should not be trying to resolve the address on its own if a proxy server has been defined and provided as an argument.

I can curl the hostname just fine using the HTTP proxy:

$ curl keyserver.ubuntu.com -o keyserver -vvv
* Rebuilt URL to: keyserver.ubuntu.com/
  % Total % Received % Xferd Average Speed Time Time Time Current
                                 Dload Upload Total Spent Left Speed
  0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3128 (#0)
> GET http://keyserver.ubuntu.com/ HTTP/1.1
> Host: keyserver.ubuntu.com
> User-Agent: curl/7.58.0
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Date: Tue, 21 Aug 2018 12:15:44 GMT
< Server: sks_www/1.1.6
< Content-Length: 5004
< Content-Type: text/html; charset=UTF-8
< Access-Control-Allow-Origin: *
< Vary: Accept-Encoding
< Warning: 110 squid/3.5.12 "Response is stale"
< X-Cache: HIT from cassava.canonical.com
< X-Cache-Lookup: HIT from cassava.canonical.com:3128
< Via: 1.1 cassava.canonical.com (squid/3.5.12)
< Proxy-Connection: Keep-Alive
< Connection: Keep-Alive
< Age: 7534
<
{ [3595 bytes data]
100 5004 100 5004 0 0 56224 0 --:--:-- --:--:-- --:--:-- 56224
* Connection #0 to host localhost left intact

ProblemType: Bug
DistroRelease: Ubuntu 18.04
Package: gnupg2 2.2.4-1ubuntu1.1
ProcVersionSignature: Ubuntu 4.15.0-30.32-generic 4.15.18
Uname: Linux 4.15.0-30-generic x86_64
NonfreeKernelModules: talpa_vfshook talpa_pedconnector talpa_pedevice talpa_vcdevice talpa_core talpa_linux talpa_syscallhook wl nvidia_modeset nvidia
ApportVersion: 2.20.9-0ubuntu7.2
Architecture: amd64
CurrentDesktop: ubuntu:GNOME
Date: Tue Aug 21 10:04:02 2018
InstallationDate: Installed on 2018-04-06 (136 days ago)
InstallationMedia: Ubuntu 16.04.4 LTS "Xenial Xerus" - Release amd64 (20180228)
PackageArchitecture: all
ProcEnviron:
 TERM=xterm-256color
 PATH=(custom, no user)
 XDG_RUNTIME_DIR=<set>
 LANG=en_US.UTF-8
 SHELL=/bin/bash
SourcePackage: gnupg2
UpgradeStatus: Upgraded to bionic on 2018-05-11 (101 days ago)

Revision history for this message
wheelerlaw (wheelerlaw) wrote :
description: updated
Revision history for this message
wheelerlaw (wheelerlaw) wrote :

Okay, it looks like issues have been created upstream (https://dev.gnupg.org/T3065#111023). But it appears that the gpg devs don't really get how to implement a standards compliant HTTP client:

> Note that an HTTP proxy is independent of the DNS resolver because it works at the HTTP layer.

Revision history for this message
wheelerlaw (wheelerlaw) wrote :

The workaround for now is to use curl to fetch the keys instead:

$ curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&options=mr&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | gpg --import
gpg: key 99E82A75642AC823: public key "sbt build tool <email address hidden>" imported
gpg: Total number processed: 1
gpg: imported: 1

Revision history for this message
wheelerlaw (wheelerlaw) wrote :

Or if you are using sudo apt-key instead of gpg directly:

curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&options=mr&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key adv --import -

Revision history for this message
Julian Andres Klode (juliank) wrote :

If you have to, better do

curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&options=mr&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo tee /etc/apt/trusted.gpg.d/$somename.asc

or similar - store armored keys in .asc files, unarmored keys in .gpg files in trusted.gpg.d.

apt-key is deprecated.

Revision history for this message
Bryan Quigley (bryanquigley) wrote :

@juliank Should C#5 work on 16.04? Trying it via multipass and it doesn't get the keys added to apt-key list.

Is apt-key deprecated on 16.04? Trying to figure out how we should be writing this for official documentation purposes. AFAICT when adding a pubic PPA using add-apt-repo.. it still uses apt-key.

Revision history for this message
Bryan Quigley (bryanquigley) wrote :

The conclusion I've reached is that something like C#5 is good for 18.04, but for 16.04 and earlier we should still use apt-key.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.