Monday, December 29, 2014

GnuPG and proxy support

Via a long and tortuous route, I discovered an issue today with GnuPG and proxy support.

In short, if you are behind a proxy and you need to import an apt key using apt-key adv from keyserver.ubuntu.com, you're out of luck.  The bug reports for this issue are here on GnuPG's bug tracker and here on Ubuntu's bug tracker.

The good news:  since the issue is relatively minor-- the omission of a Host: header-- you can create a simple proxy server to proxy to your proxy!  Here's what I did in ruby:

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'

# This is a proxy server which will make sure every GET request 
# has a Host: header added which corresponds to the request host.  
# It exists to work around the bug at
# https://bugs.launchpad.net/ubuntu/+source/gnupg/+bug/789049
class GnuPGFixingProxyServer < WEBrick::HTTPProxyServer
  def setup_proxy_header(req, res)
    header = super
    header['Host'] ||= req.host
    header
  end
end

proxy_server = ENV['http_proxy'] ? URI(ENV['http_proxy']) : nil
proxy = GnuPGFixingProxyServer.new(BindAddress: '127.0.0.1', 
                                   Port: 3128, 
                                   ProxyURI: proxy_server)

trap 'INT' do
  proxy.shutdown
end

proxy.start

After that, I could tell apt to use http://localhost:3128 as its proxy, and as long as the http_proxy environment variable was set to the real proxy, it would send the requests out with the Host: header added if missing.

A this time, I run this proxy by running the script on the host needing to import the key prior to importation.  With a few minor changes, I'll be incorporating it into the provisioning process so all hosts can have this out the gate.