naggie / dsnet

FAST command to manage a centralised wireguard VPN. Think wg-quick but quicker: key generation + address allocation.
https://calbryant.uk/blog/how-to-set-up-a-wireguard-vpn-in-minutes-with-dsnet/
MIT License
673 stars 33 forks source link

DNS doesn't work properly #55

Closed ethindp closed 2 years ago

ethindp commented 3 years ago

So I've set up a configuration and have added 0.0.0.0/0 to the networks array. However, when I connect DNS doesn't work -- I can't ping google.com. I've enabled IP forwarding on both IPv4 and IPv6 and have set up unbound as a DNS server, and have pointed my config at that DNS server. But it still doesn't work. I've even tried 8.8.8.8 as a DNS server and no go. What am I doing wrong?

naggie commented 3 years ago

Does the internet work in general or is it just DNS?

Can you ping 8.8.8.8?

frillip commented 3 years ago

Assuming everything worked before you added the default route, it's unlikely to be DNS. You are probably trying to send wireguard packets over the wireguard interface.

What is your current routing table? You may have to add a static route to your wireguard server via your current gateway if you want to use a 0.0.0.0/0 route, you'll need to add something like ip route add x.x.x.x via 192.168.1.1 dev eth0 where x.x.x.x is your wireguard server address.

naggie commented 3 years ago

Obligatory Haiku image

ethindp commented 3 years ago

No, I can't ping any IP address. I've tried various different ways and no go. I've never needed to add routes before so...

On 5/15/21, Callan Bryant @.***> wrote:

Obligatory Haiku image

-- You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub: https://github.com/naggie/dsnet/issues/55#issuecomment-841625254

-- Signed, Ethin D. Probst

naggie commented 3 years ago

Have you enabled IP forwarding on the server?

frillip commented 3 years ago

Assuming from your original post you have enabled IP forwarding, are you able to ping your wireguard server IP whilst connected? If not, it's a routing problem.

If you can ping it whilst connected, it may be a NAT problem. Have you set up any nat iptables rules on the server? You'll need these if you want to talk to external hosts from internal hosts

ethindp commented 3 years ago

@naggie I've enabled IP forwarding on the server. @frillip I am able to ping the server. My firewall configuration is this (I modified it from this one):

#!/usr/sbin/nft -f

# Hook order is: ingress -> prerouting -> input/output/forward -> postrouting

# Start by flushing all the rules.
flush ruleset

# Defining variables is easy in nftables scripts.
define wan = eth0
define vpn = wg0
define vpn_net4 = 10.81.108.1/22
define vpn_net6 = fd00:84bb:f72f:b600::/64

# Set up  tables.
# A simple firewall will only need one table but there can be multiple.
# The "inet" indicates that this table will handle both ipv4 (ip) and ipv6 (ip6).
table inet inbound {
  # Sets are dictionaries and maps of ports, addresses etc.
  # These can then easily be used in the rules.
  # Sets can be named whatever you like.
  # TCP ports to allow
  set tcp_accepted {
    # The "inet_service" are for tcp/udp ports and "flags interval" allows to set intervals, see the mosh
    # ports below.
    type inet_service; flags interval;
    elements = {
      29999,10333,12000,7777,8888,10215,42069,27500,3478,5349,3479,5350,8448,8443,8080,6837,53
    }
  }

  # UDP ports to allow
  set udp_accepted {
    type inet_service; flags interval;
    elements = {
      10333, 10215, 27500, 3478, 5349, 3479, 5350, 49152-65535,53
    }
  }

  # The first chain
  chain incoming {
    # This line sets what traffic the chain will handle, the priority and default policy.
    # The priority comes in when you in another table have a chain set to "hook input" and want to
    # specify in what order they should run.
    # Use a semicolon to separate multiple commands on one row.
    type filter hook input priority 0; policy drop;

    # Drop invalid packets.
    ct state invalid drop

    # Drop none SYN packets.
    tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop

    # Limit ping requests.
    ip protocol icmp icmp type echo-request limit rate over 1/second burst 5 packets drop
    ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 1/second burst 5 packets drop

    # OBS! Rules with "limit" need to be put before rules accepting "established" connections.
    # Allow all incomming established and related traffic.
    ct state established,related accept

    # Allow loopback.
    # Interfaces can be set with "iif" or "iifname" (oif/oifname). If the interface can come and go use
    # "iifname", otherwise use "iif" since it performs better.
    iif lo accept

    # Allow certain inbound ICMP types (ping, traceroute).
    # With these allowed we are a good network citizen.
    ip protocol icmp icmp type { destination-unreachable, echo-reply, echo-request, source-quench, time-exceeded } accept
    # Without the nd-* ones ipv6 will not work.
    ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, echo-reply, echo-request, nd-neighbor-solicit,  nd-router-advert, nd-neighbor-advert, packet-too-big, parameter-problem, time-exceeded } accept

    # Allow needed tcp and udp ports.
    iifname $wan tcp dport @tcp_accepted ct state new accept
    iifname $wan udp dport @udp_accepted ct state new accept

    # Allow WireGuard clients to access DNS and services.
    iifname $vpn udp dport 53 ct state new accept
    iifname $vpn tcp dport @tcp_accepted ct state new accept
    iifname $vpn udp dport @udp_accepted ct state new accept

    # Allow VPN clients to communicate with each other.
    iifname $vpn oifname $vpn ct state new accept
  }

  chain forwarding {
    type filter hook forward priority 0; policy drop;

    # Drop invalid packets.
    ct state invalid drop

    # Forward all established and related traffic.
    ct state established,related accept

    # Forward WireGuard traffic.
    # Allow WireGuard traffic to access the internet via wan.
    iifname $vpn oifname $wan ct state new accept
  }

  chain outgoing {
    type filter hook output priority 0; policy drop;

    # I believe settings "policy accept" would be the same but I prefer explicit rules.

    # Drop invalid packets.
    ct state invalid drop

    # Allow all other outgoing traffic.
    # For some reason ipv6 ICMP needs to be explicitly allowed here.
    ip6 nexthdr ipv6-icmp accept
    ct state new,established,related accept
  }
}

# Separate table for hook pre- and postrouting.
# If using kernel 5.2 or later you can replace "ip" with "inet" to also filter IPv6 traffic.
table inet router {
  # With kernel 4.17 or earlier both need to be set even when one is empty.
  chain prerouting {
    type nat hook prerouting priority -100;
  }

  chain postrouting {
    type nat hook postrouting priority 100;

    # Masquerade WireGuard traffic.
    # All WireGuard traffic will look like it comes from the servers IP address.
    oifname $wan ip saddr $vpn_net4 masquerade
    oifname $wan ip6 saddr $vpn_net6 masquerade
  }
}

# Separate table for hook ingress to filter bad packets early.
table netdev filter {
  # List of ipv4 addresses to block.
  set blocklist_v4 {
    # The "ipv4_addr" are for ipv4 addresses and "flags interval" allows to set intervals.
    type ipv4_addr; flags interval;
    elements = {
      172.16.254.1,172.16.254.2
    }
  }

  chain ingress {
    # For some reason the interface must be hardcoded here
    type filter hook ingress device eth0 priority -500;

    # Drop all fragments.
    ip frag-off & 0x1fff != 0 counter drop

    # Drop bad addresses.
    ip saddr @blocklist_v4 counter drop

    # Drop XMAS packets.
    tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop

    # Drop NULL packets.
    tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop

    # Drop uncommon MSS values.
    tcp flags syn tcp option maxseg size 1-535 counter drop
  }
}

I'm still able to ping the server and I'm able to get DNS responses from it. I just can't actually access the internet, either via IP or hostname. Here's the relevant dsnet configuration:

    "Network": "10.81.108.0/22",
    "Network6": "fd00:84bb:f72f:b600::/64",
    "IP": "10.81.108.1",
    "IP6": "fd00:84bb:f72f:b600:f25f:490b:c85:8c4e",
    "DNS": "8.8.8.8",
    "Networks": [
        "0.0.0.0/0"
    ],
    "Peers": [
        {
            "Hostname": "ethin",
            "IP": "10.81.108.2",
            "IP6": "fd00:84bb:f72f:b600:c016:c57e:d73:7d13",
            "Added": "2021-05-15T00:52:21.60145053-05:00",
            "Networks": ["0.0.0.0/0"],
        }
    ]
}

This isn't a completely valid configuration but it gives the relevant information. I've tried modifying DNS to the 10.81.108.1 server (because I put a DNS server up there) but still no go. I've tried various other ones including multiple servers and still it doesn't work. So I'm really getting confused on exactly what's going wrong. I've also imported it into NetworkManager and no go there either.

frillip commented 3 years ago

Ok, if you can ping the external server IP whilst connected, and other internal peers, it sounds like could be firewall/NAT related.

I'm not very familiar with nftables, but given it looks broadly similar to the one you originally copied, I'm going to assume it is mostly ok. What did catch my eye though was this line: oifname $wan ip6 saddr $vpn_net6 masquerade. As IPv6 isn't generally NAT'd, perhaps try removing this?

Though, having a closer look at the dsnet config...

Your dsnet configuration also seems to list a default route on one of the peers: "Networks": ["0.0.0.0/0"],. This would indicate to the server that the entire internet is available at that peer, which I am assuming is not the case! If you remove 0.0.0.0/0 from the Networks list for the peer, what happens? Similarly for the Networks section in the head of the dsnet config.

ethindp commented 3 years ago

No, I can't ping the external server IP. I can ping the internal one that the server has in the VPN only. The server's VPN IP is 10.81.108.1, and I can ping that, but I can't ping the external one (192.53.120.45).

On 5/16/21, Phil Martin @.***> wrote:

Ok, if you can ping the external server IP whilst connected, and other internal peers, it sounds like could be firewall/NAT related.

I'm not very familiar with nftables, but given it looks broadly similar to the one you originally copied, I'm going to assume it is mostly ok. What did catch my eye though was this line: oifname $wan ip6 saddr $vpn_net6 masquerade. As IPv6 isn't generally NAT'd, perhaps try removing this?

Though, having a closer look at the dsnet config...

Your dsnet configuration also seems to list a default route on one of the peers: "Networks": ["0.0.0.0/0"],. This would indicate to the server that the entire internet is available at that peer, which I am assuming is not the case! If you remove 0.0.0.0/0 from the Networks list for the peer, what happens? Similarly for the Networks section in the head of the dsnet config.

-- You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub: https://github.com/naggie/dsnet/issues/55#issuecomment-841848520

-- Signed, Ethin D. Probst

frillip commented 3 years ago

Ok, can you show us the output of ip route for both the client and the server?

ethindp commented 3 years ago

Sure. On the server side:

default via 192.53.120.1 dev eth0 proto static 
10.81.108.0/22 dev wg0 proto kernel scope link src 10.81.108.1 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 
192.53.120.0/24 dev eth0 proto kernel scope link src 192.53.120.45 
192.168.128.0/17 dev eth0 proto kernel scope link src 192.168.128.105 

On the client:

default via 192.168.1.1 dev wlan0 proto dhcp metric 600 
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.118 metric 600 

And when I activate the VPN:

default via 192.168.1.1 dev wlan0 proto dhcp metric 600 
10.81.108.0/22 dev ethin proto static scope link metric 50 
10.81.108.0/22 dev ethin proto kernel scope link src 10.81.108.2 metric 50 
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.118 metric 600 
naggie commented 2 years ago

Closed due to inactivity