Replies: 2 comments
-
It sounds like Cloudflare tunnels uses the users the running peer connection as an exit node. The WireGuard docs do have some details on how you can route all traffic from the internet facing connection into your private network, which may allow you to use their hostnames. For security and easy of use I chose to make this explicit. If you're using Traefik or another web proxy you can configure it on your private connection to resolve the hosts for you depending on the domain name or path used and this could be the name of a linked private Docker container or even a hostname that only available on your private network say. Another option that I use, is to use Docker-WireGuard-Tunnel in conjunction with Headscale & Tailscale (guide/walk-through) to create a WireGuard overlay/mesh network. This way all clients get a separate Tailscale hostname/IP they can use to connect to each other. Originally I did use iptables for routing, but this has issues when using the container on fly.io (firecracker) as they have restrictions that prevent them from using iptables. |
Beta Was this translation helpful? Give feedback.
-
Interesting. I do not have these same restrictions. I have been playing around with the iptables version as I would imagine iptables is able to perform better due to less abstraction. It does seem that the iptables version is unable to expose IP addresses belonging to other machines on the network of the peer. I changed the wg-start.sh to look like this. #!/bin/bash
if [ ! -f /etc/wireguard/wg0.conf ]; then
server_private="$(wg genkey)"
server_public=$(echo "${server_private}" | wg pubkey)
cat >/etc/wireguard/wg0.conf <<EOF
[Interface]
PrivateKey = $server_private
# PublicKey = $server_public
Address = 10.0.50.254/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
SaveConfig = true
EOF
if [[ ${DOMAIN} && ${PEERS} ]]; then
count=${PEERS//[a-z]/}
for peer_number in $(seq $count); do
peer_private="$(wg genkey)"
peer_public=$(echo "${peer_private}" | wg pubkey)
cat >/mnt/peers/peer$peer_number.conf <<EOF
[Interface]
PrivateKey = $peer_private
# PublicKey = $peer_public
Address = 10.0.50.$peer_number/15
[Peer]
PublicKey = $server_public
Endpoint = $DOMAIN:51820
AllowedIPs = 10.0.50.254/32
PersistentKeepalive = 25
EOF
cat >>/etc/wireguard/wg0.conf <<EOF
[Peer]
# peer$peer_number
PublicKey = $peer_public
AllowedIPs = 10.0.50.$peer_number/32
EOF
done
fi
fi
IFS=',' read -ra SERVICE <<< "$SERVICES"
for serv in "${SERVICE[@]}"; do
service_parts=(${serv//\:/ })
peer_number=${service_parts[0]//[a-z]/}
service_hostname=${service_parts[1]}
container_port=${service_parts[2]}
expose_port_as=${service_parts[3]}
if [[ ${DOMAIN} && ${PEERS} ]]; then
iptables -t nat -A PREROUTING -p tcp --dport $expose_port_as -j DNAT --to-destination 10.0.50.$peer_number:$expose_port_as
else
if [[ $service_hostname =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo "The variable contains an IPv4 address: $service_hostname"
iptables -t nat -A PREROUTING -p tcp --dport $expose_port_as -j DNAT --to-destination $service_hostname:$container_port
else
echo "The variable does not contain an IPv4 address: $service_hostname"
container_ip=`ping -c1 $service_hostname | sed -nE 's/^PING[^(]+\(([^)]+)\).*/\1/p'`
iptables -t nat -A PREROUTING -p tcp --dport $expose_port_as -j DNAT --to-destination $container_ip:$container_port
fi
fi
done
iptables -t nat -A POSTROUTING -j MASQUERADE
## Startup modified from https://github.com/activeeos/wireguard-docker
# Find a Wireguard interface
interfaces=$(find /etc/wireguard -type f)
if [ -z $interfaces ]; then
echo "$(date): Interface not found in /etc/wireguard" >&2
exit 1
fi
start_interfaces() {
for interface in $interfaces; do
echo "$(date): Starting Wireguard $interface"
wg-quick up $interface
done
}
stop_interfaces() {
for interface in $interfaces; do
wg-quick down $interface
done
}
start_interfaces
# Handle shutdown behaviour
finish() {
echo "$(date): Shutting down Wireguard"
timeout 5 stop_interfaces
exit 0
}
trap finish TERM INT QUIT
wg
while :; do
if [ `timeout 5 wg | wc -l` == 0 ]; then
exit 1
fi
sleep 10
done I bypassed domain resolution if an IP address was provided in the |
Beta Was this translation helpful? Give feedback.
-
Not necessarly an issue, just some of my thoughts on what would make Docker WireGuard Tunnel more ideal for my use personally, possible others.
I first started using Cloudflare Tunnel to punch a hole in my network, I really like the simplicity of Cloudflare Tunnel, as it's able to resolve peer hostnames without having to configure anything on either side, however I was yearning for a self hosted option as I wanted to traffic more than just HTTP.
I started with rathole, it's lightweight and forwards both TCP and UDP, however there's two things that don't make it a perfect fit for my use case, firstly it proxies UDP over TCP, which is less than ideal, secondly it doesn't resolve peer sided hostnames without a configuration file on both sides.
Docker WireGuard Tunnel has the potential to be my perfect solution, due to having the primary focus of linking Docker containers, however it has one of the same issues that rathole has, it doesn't resolve peer hostnames without configuring an environment variable on both the peer and server.
It leaves me wondering, I know Cloudflare Tunnel uses WireGuard under the hood, however does it do anything special with DNS to achieve peer sided hostname resolution via the server.
Would it be possible to add a single peer mode option to Docker WireGuard Tunnel, which would make it operate similarly to Cloudflare Tunnel, where the server is able to resolve peer sided hostnames without manually specify those hostnames server side?
Networking is far from my specialty, I have done some searching on the topic, and from what I gathered, it's possible to have a WireGuard peer resolve hostnames located on the server's network (https://www.reddit.com/r/WireGuard/comments/i8bkfr/comment/g1cz2dl), however is it possible the other way around, and if so, would that all play nice with Docker so that the server can resolve hostnames on the peer without the need for manual host to port configuration and rinetd (probably routing with iptabels instead)?
Beta Was this translation helpful? Give feedback.
All reactions