IAmStoxe / wirehole

WireHole is a combination of WireGuard, Pi-hole, and Unbound in a docker-compose project with the intent of enabling users to quickly and easily create a personally managed full or split-tunnel WireGuard VPN with ad blocking capabilities thanks to Pi-hole, and DNS caching, additional privacy options, and upstream providers via Unbound.
https://iamstoxe.com
Other
4.63k stars 312 forks source link

Possible to forward WG client IPs to pihole to be able to leverage groups? #37

Open shayaknyc opened 2 years ago

shayaknyc commented 2 years ago

Absolutely in love with this docker-compose setup. I'm really kind of a n00b with docker and docker-compose and learning along the way and so happy this more or less works right out of the box. The only thing I wish we could do using this config set up is be able to pass along each of the WG client IPs over through pihole so that I can manage groups and whitelist certain domains for different devices, etc. Is this at all possible with this kind of set up?

ben-dd commented 2 years ago

There is a project out there called Mistborn that is able to do that but it also includes a lot of other services and I found it a bit overkill for my needs. Wirehole would be damn near perfect that functionality.

shayaknyc commented 2 years ago

There is a project out there called Mistborn that is able to do that but it also includes a lot of other services and I found it a bit overkill for my needs. Wirehole would be damn near perfect that functionality.

OMG had no idea this even existed. Thanks for the tip! It may, in fact, have everything I need!

shayaknyc commented 2 years ago

There is a project out there called Mistborn that is able to do that but it also includes a lot of other services and I found it a bit overkill for my needs. Wirehole would be damn near perfect that functionality.

OMG had no idea this even existed. Thanks for the tip! It may, in fact, have everything I need!

Actually, almost everything I want....no unbound...I'd rather be running a recursive DNS locally than have to rely on DoH/DNSCrypt - but it's definitely a start! Regardless, still LOVE wirehole, so if there's any way to configure it in such a way that we can pass WG clients to pihole in this config, that would be AMAZING.

oschmidteu commented 2 years ago

There is a project out there called Mistborn that is able to do that but it also includes a lot of other services and I found it a bit overkill for my needs. Wirehole would be damn near perfect that functionality.

I just gave it a try but as you already mention its a to much for my needs. Wirehole is perfect except the fact that I only see one client: wireguard.wirehole_private_network

thomasmerz commented 2 years ago

Wirehole is perfect except the fact that I only see one client: wireguard.wirehole_private_network

This doesn't fit to https://github.com/IAmStoxe/wirehole/issues/23#issuecomment-943126750 or do I understand it totally wrong?

batteredhedgehog commented 2 years ago

I've been looking into this. The wireguard container uses masquerading to hide all client IPs so that requests look like they come from the wireguard container itself. You can see this in the wireguard container

root@xxxx# iptables -t nat -L -v -n | grep MASQUERADE
 7766  499K MASQUERADE  all  --  *      eth+    0.0.0.0/0            0.0.0.0/0           

This rule can be removed manually from within the wireguard container using:

iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

The masquerade rule is added by the wireguard configuration in /config/wg0.conf - which seems to be generated from PostUp and PostDown clauses in wireguard/templates/server.conf . To make this change permanent would require removing the last iptables clauses from the template.

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

The other containers then need to know how to route traffic to 10.6.0.0/24. In the pihole container this can be configured manually, but I'm not sure how get this rule to stick when the container restarts.

ip route add 10.6.0.0/24 via 10.2.0.3

I dont know how to add the route to the unbound container. It doesn't seem to have networking tools. Perhaps someone can help here.

batteredhedgehog commented 2 years ago

OK.. I haven't had any experience with s6-overlay, so took me a little to work out how to hook into its initialisation routine to make the routing work after container restart. Its not a perfect setup - I dont really like having the network details in this scripting - but it is working now. With the above changes to the wireguard container (you might have to delete the wireguard/wg0.conf to ensure it gets re-created) I have wireguard client IP addresses showing up in the pi-hole ui.

I created a very simple shell script that adds the required route using the command I listed above pihole-wireguard-route.sh :

#!/bin/sh
ip route add 10.6.0.0/24 via 10.2.0.3

I then mounted this into the pihole container using the following volume mounts in the docker-compose.yaml file

    volumes:
      - "./etc-pihole/:/etc/pihole/"
      - "./etc-dnsmasq.d/:/etc/dnsmasq.d/"
      - "./pihole-wireguard-route.sh:/etc/cont-init.d/10-pihole-wireguard-route.sh"
RhanCandia commented 1 year ago

OK.. I haven't had any experience with s6-overlay, so took me a little to work out how to hook into its initialisation routine to make the routing work after container restart. Its not a perfect setup - I dont really like having the network details in this scripting - but it is working now. With the above changes to the wireguard container (you might have to delete the wireguard/wg0.conf to ensure it gets re-created) I have wireguard client IP addresses showing up in the pi-hole ui.

I created a very simple shell script that adds the required route using the command I listed above pihole-wireguard-route.sh :

#!/bin/sh
ip route add 10.6.0.0/24 via 10.2.0.3

I then mounted this into the pihole container using the following volume mounts in the docker-compose.yaml file

    volumes:
      - "./etc-pihole/:/etc/pihole/"
      - "./etc-dnsmasq.d/:/etc/dnsmasq.d/"
      - "./pihole-wireguard-route.sh:/etc/cont-init.d/10-pihole-wireguard-route.sh"

I tried this and while my client IPs started appearing on PiHole, I lost my internet connection. I wonder what I did wrong.

batteredhedgehog commented 1 year ago

Yah. I'm just using my setup for DNS. Not as a general VPN. You would need a different setup to also use the VPN for internet access. I'm not exactly sure how to configure it that way.

Haschi99 commented 1 year ago

Is there already an idea for a solution to see the single clients in the PiHole e.g. via another route config ?

alonbg commented 1 year ago

A working setup:

  1. merge pihole into wirguard's network (networks, dns)
  2. have dnsmasq listening on all interfaces (as dns queries arrive from wg0)
pihole:
    depends_on: [ unbound ]
    container_name: pihole
    image: pihole/pihole:latest
    restart: unless-stopped
    network_mode: "container:wireguard" #  assign pihole to wirguard's network
    hostname: pihole
    environment:
      TZ: "Etc/UTC"
      FTLCONF_LOCAL_IPV4: 10.2.0.100 # Internal IP of pihole
      PIHOLE_DNS_: 10.2.0.200 # Unbound IP
      DNSMASQ_LISTENING: "all" #dnsmasq to listen on all interfaces
    .
    . 
wireguard:
    .
    dns:
      - 127.0.0.1
      - 10.2.0.100 # Points to pihole
      - 10.2.0.200 # Points to unbound
    networks:
      private_network:
        ipv4_address: 10.2.0.100
        aliases:
          - pihole #optional

@IAmStoxe FYI

dParikesit commented 11 months ago

I've been looking into this. The wireguard container uses masquerading to hide all client IPs so that requests look like they come from the wireguard container itself. You can see this in the wireguard container

root@xxxx# iptables -t nat -L -v -n | grep MASQUERADE
 7766  499K MASQUERADE  all  --  *      eth+    0.0.0.0/0            0.0.0.0/0           

This rule can be removed manually from within the wireguard container using:

iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

The masquerade rule is added by the wireguard configuration in /config/wg0.conf - which seems to be generated from PostUp and PostDown clauses in wireguard/templates/server.conf . To make this change permanent would require removing the last iptables clauses from the template.

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

The other containers then need to know how to route traffic to 10.6.0.0/24. In the pihole container this can be configured manually, but I'm not sure how get this rule to stick when the container restarts.

ip route add 10.6.0.0/24 via 10.2.0.3

I dont know how to add the route to the unbound container. It doesn't seem to have networking tools. Perhaps someone can help here.

I followed this instruction and now my pi hole is able to identify wg IP and filter the request. But my clients don't receive any of the filter result (infinite loading on client), even though I'm able to ping clients' wg IP from the pi hole container, and I'm able to ping the pi hole container from my client. Any suggestions?

edit: In pi hole container, tcpdump confirms that icmp packets is able to go to wg client, but other packets can't. This is getting weirder

edit 2: found it. change PostUp masquerade to

iptables -t nat -A POSTROUTING ! -d ${module.exports.DOCKER_SUBNET} -o eth+ -j MASQUERADE;

where docker subnet is the network that the container used. Other PostUp stay the same

eifellovkas commented 6 months ago

I've been looking into this. The wireguard container uses masquerading to hide all client IPs so that requests look like they come from the wireguard container itself. You can see this in the wireguard container

root@xxxx# iptables -t nat -L -v -n | grep MASQUERADE
 7766  499K MASQUERADE  all  --  *      eth+    0.0.0.0/0            0.0.0.0/0           

This rule can be removed manually from within the wireguard container using:

iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

The masquerade rule is added by the wireguard configuration in /config/wg0.conf - which seems to be generated from PostUp and PostDown clauses in wireguard/templates/server.conf . To make this change permanent would require removing the last iptables clauses from the template.

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth+ -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE

The other containers then need to know how to route traffic to 10.6.0.0/24. In the pihole container this can be configured manually, but I'm not sure how get this rule to stick when the container restarts.

ip route add 10.6.0.0/24 via 10.2.0.3

I dont know how to add the route to the unbound container. It doesn't seem to have networking tools. Perhaps someone can help here.

I followed this instruction and now my pi hole is able to identify wg IP and filter the request. But my clients don't receive any of the filter result (infinite loading on client), even though I'm able to ping clients' wg IP from the pi hole container, and I'm able to ping the pi hole container from my client. Any suggestions?

edit: In pi hole container, tcpdump confirms that icmp packets is able to go to wg client, but other packets can't. This is getting weirder

edit 2: found it. change PostUp masquerade to

iptables -t nat -A POSTROUTING ! -d ${module.exports.DOCKER_SUBNET} -o eth+ -j MASQUERADE;

where docker subnet is the network that the container used. Other PostUp stay the same

Thank you both guys so much! After so many hours I was able to make it work with your advice, I am very grateful. You are awesome!!

dathtd119 commented 2 months ago

This is something 🔥🔥, i was facing this issue with my wg-easy + adguard home, where I need to see my client address, and this just help. If someone else is facing this problem, in the wg-easy compose, just add:

environment:
      *
      - WG_POST_UP=iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o
        %i -j ACCEPT;iptables -t nat -A POSTROUTING ! -d {wg-easy subnet} -o eth+
        -j MASQUERADE
      - WG_POST_DOWN=iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o
        %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth+ -j MASQUERADE