Dominique Dumont: About LWP::UserAgent, https and proxy setup
Hello
The last few weeks, I ve been banging my head to use uscan, Pithub and JIRA::Client::Automated behind a corporate firewall. They are all written in Perl and use LWP::UserAgent to fetch information from Internet. At $work, using a proxy is mandatory to connect to Internet. But LWP::UserAgent https connection does not work through a proxy. This bug was reported 10 years ago but is still not fixed.
Here s my plan to fix (or work-around) this issue, at least for Debian.
Before going further, let s step back to explain briefly what is https and how proxies work.
https is not a protocol by itself. https is plain http over a socket encrypted with SSL (aka TLS). To create a https connection, the agent must first setup the SSL socket with the server. Then the agent uses http protocol to communicate with the server. All the traffic is encrypted on agent side and decrypted on server side by the SSL layer.
When creating a connection through a proxy, things get a little more complicated. Plain http requests (like GET, POST and so on ) are sent to the proxy as if the proxy was the http server. Then, the proxy forwards the request to the actual server.
From what I ve read, most proxy servers refuse to plainly forward encrypted data to a web server. First a negotiation to create a tunnel towards the web server must be done by sending a http CONNECT request to the proxy server. The encrypted socket is then set up between the user and the web server through the proxy. Once this encrypted tunnel is set up, the usual http communication can be done.
Let s go back to LWP::UserAgent. To create a connection over SSL, LWP::UserAgent will use a SSL library to setup the socket. This SSL library can be IO::Socket::SSL or Net::SSL. Direct https connection with LWP::UserAgent works fine with either library.
When trying to setup a https connection through a proxy, LWP::UserAgent will try to use the proxy like a regular http proxy without going through the CONNECT phase. This does not work.
Net::SSL is able to setup correctly an SSL socket through a proxy provided the proxy server is specified in an https_proxy environment variable. But LWP::UserAgent will also try to (badly) setup the proxy when this variable is set. One can find various work-around to play with %ENV to bypass LWP::UserAgent. So I ve proposed a patch to make LWP::UserAgent skip the https_proxy variable. Then Net::SSL can handle the connection to the proxy.
I hope this blog will push upstream to either apply this path or tell me why it s a bad idea (which is possible, I ve some trouble to believe that a 10 years old bug can be fixed by such a simple patch)
[ Edited ] I was right to worry. Turns out that relying on Net::SSL is a bad idea: SSL certificates are not checked correctly with this library. For more details, see https://github.com/libwww-perl/libwww-perl/pull/51 and https://bugzilla.redhat.com/show_bug.cgi?id=705044 . I m going to push JGMYERS set of patches on libwww-perl repositories
Anyway, this patch works provided:
Tagged: debian, https_proxy, Perl
- Net::SSL is loaded by the application
- the proxy is setup with https_proxy environment variable
- LWP user agent is created this way:
my $ua = LWP::UserAgent->new( env_proxy => 1, ssl_opts => verify_hostname => 0 );The verify_hostname parameter is used by IO::Socket::SSL.
LWP::UserAgent bails out if Net::SSL is used while this parameter is not set to 0.
$ua->proxy( https => ...);JGMYERS has proposed a set of patches to fix this problem. But these patches are more invasive and I do not dare to push them to Debian. Last but not least, this blog avoids the issue of host name verification or peer authentication. Net::SSL and Crypt::SSLeay are able to perform such a verification, but I did not verify this point. Next step is to provide simple patches to let uscan, Pithub and JIRA::Client::Automated correctly connect through proxies without jumping through hoops. All the best
Tagged: debian, https_proxy, Perl
Today I'm recuperating, and almost back to full health.
Unfortunately I made the mistake of online-shopping, oops.
Good job I stopped myself from registaring all the domains, but I did get two that I liked: spare.io & edinburgh.io.
I've updated my database to record them, but I wonder what do other people use to remind them about expiration dates of domains, SSL-certificates, & etc?
I googled and didn't find a definitive free/paid service, but it seems like something lots of people need to be reminded about..
Maybe people just rely on registrars sending strident emails. (Of course the redemption period for domains make it reasonably safe to forget for a day or two, until your customers complain and your emails start to bounce..)
The point of switching to a new init system is to get rid of huge init scripts. Well, here s an example OpenRC runscript, rewriting /etc/init.d/rsyslog:
Many protocols today allow you to upgrade to TLS from within a cleartext version of the protocol. This often falls under the rubric of "STARTTLS", though different protocols have different ways of doing it. I often forget the exact steps, and when i'm debugging a TLS connection (e.g. with tools like
This could have been a blog post about toothbrushes for monkeys, which I
seem to have dreamed about this morning. But then I was vaguely listening
to the
In a comment to yesterday s post on
A new maintenance release 0.10.6 of
Sometimes building the same code on multiple architectures is useful to detect horrors like: