Docker-Warp-Socks icon indicating copy to clipboard operation
Docker-Warp-Socks copied to clipboard

Network connection problem between containers

Open flrngel opened this issue 9 months ago • 8 comments

Hello,

I've pinpointed two core issues in the current implementation that prevent it from connecting with other containers through Docker-Warp-Socks. Below, I've detailed these problems along with proposed solutions:

Identified Problems:

  1. DNS Resolution Issue: The DNS setup in /etc/resolv.conf, specifically pointing to 1.1.1.1, obstructs the ability to locate other containers' IP addresses using their names.

  2. Device Specification in Dante: Dante does not facilitate device non-specification, preventing the utilization of inherent OS behavior, which seems to be the most straightforward solution at the moment. This issue can be substantiated using various curl commands within the DWS container: curl --interface eth0, curl --interface warp, and simply, curl.

Proposed Solutions:

  1. Integrate dnsmasq: Implement dnsmasq to allow DNS queries to both the 1.1.1.1 server and the Docker network gateway.

  2. Adopt shadowsocks-libev: Introduce shadowsocks-libev to overcome the device specification constraint in Dante, enabling the exploitation of native OS behavior.

I have documented both the problems and solutions here: Docker-Warp-Socks Test Repository.

Kindly share your thoughts.

flrngel avatar Sep 12 '23 05:09 flrngel

Hi Derrick

Thanks for your attention to this little demo project. I have roughly looked through the issues and conclude that the minimum requirement is to connect the local devices inside this small global-proxy environment container.

However, as I tested before and am aware, the issues you specify may be fake demands and have many ways to bypass them.

For DNS Resolution, in the spirit of minimal tasks, I suggest having an independent service to handle local services, since there is no need to proxy such streams through the warp. You can configure front-end load balancing services like NGINX, HAPROXY, or XRAY, etc.

For device specification in Dante, I did not see any solid evidence to support replacing Dante with SS so far.

Plz let me know if you have any other questions! 🤗

Mon-ius avatar Sep 12 '23 17:09 Mon-ius

Theoretically, you're right. The warp proxy should be used for external traffic that heads to the internet. But in reality, most software doesn't support "conditional proxy" meaning that software doesn't determine if the URL heads to the internet or the local. I think this PR is for the case if the DWS is willing to handle the exceptions.

This repo performs two things. 1) Use WireGuard to connect the WARP VPN (warp device setups). 2) Use Dante to enable the proxy server and proxies the requests through the warp device.

The warp device uses the WARP VPN. And the WARP VPN can't reach the local network. We can avoid this by using eth0, which does not use WARP VPN and can reach the local network.

Dante cannot automatically do this because it always has to specify the device on its configuration file. (detail here - claimer: goproxy uses the first device of the list, so it's not a solution).

As I said, merging this PR completely depends on the decision if the DWS is willing to handle the exception that requests for the local network - which should not use the proxy. In my case, I'm using RSSHub and it doesn't support conditional proxy. Some part of the automations, I had to scrape the local network, but the software always uses the proxy, so ended up doing this.

flrngel avatar Sep 12 '23 19:09 flrngel

Curious to know if your responses are generated by AI in a workflow. Could you share the prompt? To be frank, I am more interested in your RSSHub solution and other automation solutions. If you could provide some snippets, I believe it would be beneficial to find a comprehensive solution for such specific scenarios.

BTW, I think it is time to write an example to teach people how to use this microservice by simply using another microservice. 🤗

Mon-ius avatar Sep 13 '23 08:09 Mon-ius

Also, I would like to share some tips on how to debug this project. Hopefully, this will help have a more comprehensive understanding of the generic solution and submit more reliable PRs.

First, to save time, the software installation is frozen inside monius/docker-warp-socks:meta, the related file is dev/Metefile. If you want to add something, be sure to put it there. Then, you can just wait a few seconds to go 🤗

docker rm -f "$(docker ps -a -q)" && docker rmi -f "$(docker images -a -q)"

docker run --privileged --restart=always -itd \
    --name warp_debug \
    --sysctl net.ipv6.conf.all.disable_ipv6=0 \
    --sysctl net.ipv4.conf.all.src_valid_mark=1 \
    --cap-add NET_ADMIN --cap-add SYS_MODULE \
    -p 9091:9091 \
    -v /lib/modules:/lib/modules \
    monius/docker-warp-socks:meta

docker exec -it warp_debug /bin/bash

Second, initialize the fundation step, implement ViRb3/wgcf, then you will have a global-proxy container environment by creating a warp interface 🤗

IFACE=$(ip route show default | grep default | awk '{print $5}')
IPv4=$(ifconfig "$IFACE" | awk '/inet /{print $2}' | cut -d' ' -f2)
IPv6=$(ifconfig "$IFACE" | awk '/inet6 /{print $2}' | cut -d' ' -f2)
TAR="https://api.github.com/repos/ViRb3/wgcf/releases/latest"
ARCH=$(dpkg --print-architecture)
URL=$(curl -fsSL ${TAR} | grep 'browser_download_url' | cut -d'"' -f4 | grep linux | grep "${ARCH}")
curl -LSs "${URL}" -o ./wgcf && chmod +x ./wgcf && mv ./wgcf /usr/bin
wgcf register --accept-tos && wgcf generate && mv wgcf-profile.conf /etc/wireguard/warp.conf
sed -i "/\[Interface\]/a PostDown = ip -6 rule delete from ${IPv6}  lookup main" /etc/wireguard/warp.conf
sed -i "/\[Interface\]/a PostUp = ip -6 rule add from ${IPv6} lookup main" /etc/wireguard/warp.conf
sed -i "/\[Interface\]/a PostDown = ip -4 rule delete from ${IPv4} lookup main" /etc/wireguard/warp.conf
sed -i "/\[Interface\]/a PostUp = ip -4 rule add from ${IPv4} lookup main" /etc/wireguard/warp.conf

wg-quick up warp

Third, inside the container, you will find that all network streams are routed to the warp network by default; But you can still access the normal environment if you specify iface, see;

curl https://www.cloudflare.com/cdn-cgi/trace
curl --interface eth0 https://www.cloudflare.com/cdn-cgi/trace
curl --interface warp https://www.cloudflare.com/cdn-cgi/trace

Finally, you will need to find an appropriate solution to re-route the traffic to the container. Here, we choose dante for simplification. However, considering your proposed two issues, it could be also achieved by configuring dante. I am just too lazy to do that, including the password verification 😊.

The default config for dante is:

logoutput: stderr

internal: eth0 port = 9091
external: wgcf

user.unprivileged: nobody

socksmethod: none
clientmethod: none

client pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
    log: error
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
}

And another configuration including the user:passwd verfication for reference is:

logoutput: syslog
user.privileged: root
user.unprivileged: nobody

internal: 0.0.0.0 port=1080

external: eth0

socksmethod: username

clientmethod: none

client pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
}

Hope above could help to rebuild the PRs to submit 🤗

Mon-ius avatar Sep 13 '23 11:09 Mon-ius

I'm not sure if you have checked this repository that I mentioned earlier.

TLDR; Check this:

# Cloudflare test
root@038b6edd1f9a:/# curl https://www.cloudflare.com/cdn-cgi/trace
warp=on
root@038b6edd1f9a:/# curl --interface eth0 https://www.cloudflare.com/cdn-cgi/trace
warp=off
root@038b6edd1f9a:/# curl --interface warp https://www.cloudflare.com/cdn-cgi/trace
warp=on

# Internal connection test
root@038b6edd1f9a:/# curl 192.168.112.4:8080
hello
root@038b6edd1f9a:/# curl --interface eth0 192.168.112.4:8080
hello
root@038b6edd1f9a:/# curl --interface warp 192.168.112.4:8080
(error)

# ip rule
root@038b6edd1f9a:/# ip rule list
0:      from all lookup local
32763:  from 192.168.112.2 lookup main
32764:  from all lookup main suppress_prefixlength 0
32765:  not from all fwmark 0xca6c lookup 51820
32766:  from all lookup main
32767:  from all lookup default

Without an interface, it follows the ip rule, but when the device is specified, it doesn't follow the rule.

This is why Dante cannot be a solution since they always need to specify the device.

You can debug both devices using tcpdump -i eth0and tcpdump -i warp to see how specifying the device ignores the ip rule. (You can check the funny thing that DNS goes to WARP device but HTTP packets don't, because DNS query triggered by a system so it follows the ip rule)

flrngel avatar Sep 13 '23 18:09 flrngel

root@c404ad9ea1ce:/tmp# curl -fsSL https://github.com/AUTOM77/RFBS/releases/download/v0.1.0/rfbs-x86_64-unknown-linux-musl.tar.gz | tar -xz
root@c404ad9ea1ce:/tmp# ./rfbs &
root@c404ad9ea1ce:/tmp# curl 127.0.0.1:8080
Hello, World

root@c404ad9ea1ce:/tmp# curl --interface eth0 127.0.0.1:8080
root@c404ad9ea1ce:/tmp# curl --interface warp 127.0.0.1:8080
root@c404ad9ea1ce:/tmp# curl --interface lo 127.0.0.1:8080
Hello, World

There are two solutions as far:

  • Bridge the interfaces into one.
  • Compose up a gateway serivice with Docker-Warp-Socks

Too busy recently, will be back soon for a official example. 🤗

Mon-ius avatar Sep 14 '23 14:09 Mon-ius

I'm not sure why you are testing 127.0.0.1 for this issue. Good luck with your solution; will follow up later 🤗

flrngel avatar Sep 14 '23 16:09 flrngel

would u like to review https://github.com/Mon-ius/Docker-Warp-Socks/issues/24 which I think is similar to your dnsmasq proposal 🤗

Mon-ius avatar Feb 28 '24 17:02 Mon-ius