Opened 9 years ago

Closed 7 years ago

#24 closed defect (fixed)

mod-proxy test in gnutls_hooks.c inadequate; breaks localhost encryption

Reported by: Peter Gamache Owned by: Daniel Kahn Gillmor
Priority: major Component: code
Version: Keywords: gnutls_hooks.c, localhost, mod_proxy


The following block of code in gnutls_hooks.c doesn't actually test for use by mod_proxy, but takes a shortcut (comparing IPs) that breaks local connectivity for processes running on the same host:

if (c->remote_addr->hostname || apr_strnatcmp(c->remote_ip,c->local_ip) == 0) {
/* Connection initiated by Apache (mod_proxy) => ignore */
         return OK;

These work fine when coming from other hosts but break if used on the same machine that's running Apache+gnutls:

# gnutls-cli-debug localhost
Resolving 'localhost'...
Connecting to ''...
Checking for SSL 3.0 support... no
Checking whether %COMPAT is required... yes
Checking for TLS 1.0 support... no
Checking for TLS 1.1 support... no
Checking fallback from TLS 1.1 to... failed
Checking for TLS 1.2 support... no
Checking whether we need to disable TLS 1.0... yes

Server does not support any of SSL 3.0, TLS 1.0 and TLS 1.1

# openssl s_client -connect localhost:443
140710953731744:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:787:
no peer certificate available
No client certificate CA names sent
SSL handshake has read 7 bytes and written 305 bytes
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE

Guess what works though? A plaintext request on port 443:

# telnet localhost 443
Connected to localhost.
Escape character is '^]'.
<html><body text="#ffffff" bgcolor="#000000"><p><tt>It is pitch black.  You are likely to be eaten by a grue.<br />></tt></p></body></html>
Connection closed by foreign host.

Change History (2)

comment:1 Changed 9 years ago by Peter Gamache

Ugly but effective workaround (at least on Linux, YMMV elsewhere):

Assuming a server IP of

1) Create an interface alias, let's call it eth0:1
2) Set eth0:1 to an unused ip on the same subnet, e.g.
3) Use iptables nat rule to do source nat on port 443 traffic:

sudo iptables -t nat -A POSTROUTING -s -d -p tcp --dport 443 -j SNAT --to

Since the requests no longer appear to be coming from the same IP, this effectively works around the flaw. If you need localhost to do the same thing, create a lo:1 alias and give it an IP of, then use this line (untested, should probably work):

sudo iptables -t nat -A POSTROUTING -s -d -p tcp --dport 443 -j SNAT --to
Last edited 9 years ago by Peter Gamache (previous) (diff)

comment:2 Changed 7 years ago by Thomas Klute

Resolution: fixed
Status: newclosed

I believe this was the same issue as described in #98. Client connections from localhost work since 0.6, proxy TLS connections since 0.7.

Note: See TracTickets for help on using tickets.