There are two SOCKS proxies that I know about that support transparent proxying for any outgoing TCP connection: Tor and redsocks. Unlike HTTP proxies, these SOCKS proxies can transparently proxy any outgoing TCP connection, including encrypted protocols and protocols without metadata or headers.

Both of these proxies require the use of NAT to redirect any outgoing TCP traffic to the proxy's local port. For instance, if I am running Tor with TransPort 9040 on my local machine, I would need to add an iptables rule like this:

iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-port 9040

To my knowledge, this would replace the original destination IP and port with and 9040, so given that this is an encrypted stream (like SSH) or one without headers (like whois), how does the proxy know the original destination IP and port?

1 Answer 1


Here is how it does it:

static int getdestaddr_iptables(int fd, const struct sockaddr_in *client, const struct sockaddr_in *bindaddr, struct sockaddr_in *destaddr)
        socklen_t socklen = sizeof(*destaddr);
        int error;

        error = getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, destaddr, &socklen);
        if (error) {
                log_errno(LOG_WARNING, "getsockopt");
                return -1;
        return 0;

iptables overrides the original destination address but it remembers the old one. The application code can then fetch it by asking for a special socket option, SO_ORIGINAL_DST.

  • 1
    Awesome answer! So this means that you have to be running the proxy software on the same computer that is handling the NAT, right?
    – hololeap
    Nov 8, 2014 at 4:50
  • 6
    Absolutely, @hololeap. If the proxy server is to run on a different system as the packet redirector then you need such protocols as Cisco's WCCP.
    – Celada
    Nov 8, 2014 at 17:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .