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
Cc:

Description

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 '127.0.0.1:443'...
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
CONNECTED(00000003)
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
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /
<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 192.168.10.10

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. 192.168.10.11
3) Use iptables nat rule to do source nat on port 443 traffic:

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

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 127.0.0.2, then use this line (untested, should probably work):

sudo iptables -t nat -A POSTROUTING -s 127.0.0.1 -d 127.0.0.1 -p tcp --dport 443 -j SNAT --to 127.0.0.2
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.