Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tinyproxy unable to forward Connect methods

I'm trying to set up a transparent proxy for all types of frames (HTTP, HTTPS), I'm using tinyproxy to do so. I've already set up my router to redirect (using NAT) all incoming and outgoing frames to tinyproxy (which is listening on port 8888).

I tried accessing a HTTPS website (https://www.google.com/), but I get a SSL connection error. Looking through the tinyproxy logs, I see the following:

CONNECT   Mar 24 23:34:27 [22533]: Connect (file descriptor 11): 128.112.94.38 [128.112.94.38]
CONNECT   Mar 24 23:34:27 [22533]: Request (file descriptor 11): 
WARNING   Mar 24 23:34:27 [22533]: Could not retrieve all the headers from the client
INFO      Mar 24 23:34:27 [22533]: Read request entity of 103 bytes

The tinyproxy documentation says that as long as I set the following lines in the tinyproxy.conf file, forwarding of Connect frames should work transparently:

# ConnectPort: This is a list of ports allowed by tinyproxy when the
# CONNECT method is used.  To disable the CONNECT method altogether, set
# the value to 0.  If no ConnectPort line is found, all ports are
# allowed (which is not very secure.)
#
# The following two ports are used by SSL.
ConnectPort 443
ConnectPort 563

I've also tried removing all ConnectPort lines to see if that works (it doesn't). Does anyone know why I'm unable to forward HTTPS traffic transparently?

like image 287
Hansen Qian Avatar asked Mar 25 '16 05:03

Hansen Qian


2 Answers

You're not using the term "frame" (L2) in the normal networking sense, TCP or HTTP/HTTPS connections (L6/7) are better terms to use here.

tinyproxy will deal with either HTTP proxy-request connections, of which CONNECT is one type, or non-proxy HTTP requests when in transparent mode (which you can confirm is enabled in the list of features shown with tinyproxy -h).

When the browser is configured to use a proxy, it amends its outbound requests accordingly. In transparent mode the browser is unaware of the proxy (and must not be configured with one). The ConnectPort option lists the ports the clients are allow to CONNECT to (to prevent abuse) in normal proxy mode.

If you are using tinyproxy in transparent mode for HTTPS, there is no CONNECT, and more importantly there are no headers (which is why you see that error) and no URL. Normally host/port parts can be deduced/inferred from the destination IP, port and SNI extension -- since tinyproxy relies on some external firewall to redirect (change destination IP) connections to it, it doesn't have complete information for the request.

At this time tinyproxy can only be used as a transparent HTTP proxy, something the documentation is a little vague about. Without HTTPS inspection (i.e. decryption of TLS connections) to access the client request it can't even be a simple TCP connection forwarder. Other proxies like squid do support TLS inspection (sslbump).

like image 169
mr.spuratic Avatar answered Oct 09 '22 03:10

mr.spuratic


To transparently forward TLS traffic through a proxy server (no man-in-the-middle) you need a proxifier. If your browser or some other client is not aware that it is communicating through a proxy server, it won't use the CONNECT method to establish a connection through the proxy. This is what the proxyfier is doing for you.

For Linux there's for example redsocks. For my Raspberry Pi running Raspbian there was a package in the default repository. To install it type:

sudo apt-get install redsocks

Below is a sample of the /etc/redsocks.conf

redsocks {
    /* `local_ip' defaults to 127.0.0.1 for security reasons,
     * use 0.0.0.0 if you want to listen on every interface.
     * `local_*' are used as port to redirect to.
     */
    local_ip = 0.0.0.0;
    local_port = 12345;

    // `ip' and `port' are IP and tcp-port of proxy-server
    // You can also use hostname instead of IP, only one (random)
    // address of multihomed host will be used.
    ip = [proxy ip];
    port = [proxy port];


    // known types: socks4, socks5, http-connect, http-relay
    type = http-connect;

    // login = "foobar";
    // password = "baz";
 }

To forward TLS traffic use the http-connect type. For regular HTTP traffic use http-relay. You need a separate redsocks section for each.

Then you need an iptables rule to redirect TLS traffic to the redsocks service

sudo iptables -A PREROUTING -t nat -p tcp --dport 443 -j REDIRECT --to-port 12345

Similarily reroute HTTP traffic from port 80 to the port you are using for http-relay.

With this configuration in place, every client on your machine will transparently use the proxy without having to adapt the configuration for each.

like image 29
Emanuel Seidinger Avatar answered Oct 09 '22 01:10

Emanuel Seidinger