cybozu-go / transocks

Transparent SOCKS5 / HTTP proxy in Go
MIT License
467 stars 61 forks source link

Why pure iptables forwarding/transparent proxy can work for DNS protocol, but for socks5/http protocols, other tools, say, transocks, must be used? #24

Closed hongyi-zhao closed 3 years ago

hongyi-zhao commented 3 years ago

Hi,

On Ubuntu 20.04, I've docker installed working the way of the default bridge network, as shown below:

werner@X10DAi-01:~$ docker -v
Docker version 19.03.12, build 48a66213fe
werner@X10DAi-01:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state
UP group default qlen 1000
    link/ether 3c:ec:ef:00:f1:28 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.3/24 brd 192.168.0.255 scope global dynamic enp4s0
       valid_lft 3688sec preferred_lft 3688sec
    inet6 fe80::3eec:efff:fe00:f128/64 scope link
       valid_lft forever preferred_lft forever
3: enp5s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state
DOWN group default qlen 1000
    link/ether 3c:ec:ef:00:f1:29 brd ff:ff:ff:ff:ff:ff
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
state DOWN group default
    link/ether 02:42:fd:6f:8c:9b brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

At the same time, I use systemd-resolvd stub resolver as the host network DNS server, as shown below:

werner@X10DAi-01:~$ egrep -v '^[[:blank:]]*(#|$)' /etc/resolv.conf
nameserver 127.0.0.53
options edns0
werner@X10DAi-01:~$ realpath -e /etc/resolv.conf
/run/systemd/resolve/stub-resolv.conf

With the following settings done on the host, I can use the host network DNS server in the docker container via setting 172.17.0.1 as the DNS server:

$ sudo sysctl -w net.ipv4.conf.docker0.route_localnet=1

$ sudo iptables -t nat -I PREROUTING -i docker0 -p udp --dport 53 -j
DNAT --to-destination 127.0.0.53
$ sudo iptables -t nat -I PREROUTING -i docker0 -p tcp --dport 53 -j
DNAT --to-destination 127.0.0.53

But I want to extend this method to the case of using the host network socks5/http servers in docker container, say, socks5 server on 127.0.0.1:18888 and http server on 127.0.0.1:8080, by setting the following iptables rules:

$ sudo iptables -t nat -I PREROUTING -i docker0 -p tcp --dport 18888
-j DNAT --to-destination 127.0.0.1

$ sudo iptables -t nat -I PREROUTING -i docker0 -p tcp --dport 8080 -j
DNAT --to-destination 127.0.0.1

But, this method doesn't get me to use the host socks5/http servers in docker container with the following forms:

socks5 proxy server: 172.17.0.1:18888
http proxy server: 172.17.0.1:8080

Any hints for this problem will be highly appreciated.

Sincerely, HY

ymmt2005 commented 3 years ago

It looks like your problem is not related to transocks.

hongyi-zhao commented 3 years ago

Yes/maybe. I mean why can't I purely based on iptables to achieve all the work transocks does.

ymmt2005 commented 3 years ago

Both SOCKS and HTTP proxy are application protocols. Hence an application needs to speak the protocol if they need to connect to such a server.

transocks is a program to translate bare TCP communications into SOCKS or HTTP requests. You can't do this with iptables.

hongyi-zhao commented 3 years ago

Both SOCKS and HTTP proxy are application protocols.

Why the DNS query can be solved purely based on iptables just as I've mentioned above? Do you mean DNS proxy isn't an application protocol?

ymmt2005 commented 3 years ago

It's because the DNS query packet is just routed to the DNS server.

SOCKS and HTTP proxy servers are not the final destination. They are just transits, and you need to speak a special proxy protocol to use such a transit.

hongyi-zhao commented 3 years ago

If so, why not purely rely on transocks to do the whole job and remove the needs for dependent on iptables?

ymmt2005 commented 3 years ago

transocks needs iptables to redirect packets to itself. transocks cannot do this by itself because it is a userland program.

hongyi-zhao commented 3 years ago

Thanks a lot for clarifying my doubt. Another question: there is another similar project for the same purpose called redsocks. What's the difference between this two projects?

ymmt2005 commented 3 years ago

We first tried to use redsocks actually, and found that it is not quite stable for a large amount of traffics. So we developed transocks as an alternative.

We are running this in our production environments for years w/o problems.

hongyi-zhao commented 3 years ago

Thanks a lot. Got it. I'll try to solve my problems with transocks.