Wireguard - Providing access to just three specific internal IPs

Since some time now I’ve been using the Wireguard Add-on. It works pretty much perfectly, but I need to do some hardening. I’m sure it can be done, but I cannot seem to get it to work.

Short: I want only three IP addresses on my internal network to be accessible through Wireguard.
No other IPs should be accessible.

Network: 10.100.100.0/24
The following addresses should be accessible over Wireguard.

  • DNS (pihole ; 10.100.100.3 )
  • HA (10.100.100.140 )
  • NAS (10.100.100.200 )

I thought this would be achieved with the following setup, but I guess I was wrong.

server:
  host: mydnsname.domain.com
  addresses:
    - 172.27.66.1
  dns:
    - 10.100.100.3
peers:
  - name: hassio
    addresses:
      - 172.27.66.2
    allowed_ips: []
    client_allowed_ips:
      - 172.27.66.0/24
      - 10.100.100.3/32
      - 10.100.100.140/32
      - 10.100.100.200/32

But when this connection is used, I can also connect to for example 10.100.100.168…

Can my objective be achieved with the add-on?

I don’t think it is possible with the add-on (not 100% sure). But wouldn’t this have more sense to be set in you firewall of your router? That is where I would set this up.

Well, after establishing the connection the Wireguard client is ‘dropped off’ behind the firewall or router. There is no router/firewall between the Wireguard IPs and the LAN, except for the IPTables based routing configuration that exists on the Wireguard host.
I guess I have to do something with the server.post_up, but how? I tried the syntax I expected, but this is simply discarded once I hit save.

Option: server.post_up (optional)

Allows you to run commands after WireGuard has been started. This is useful for modifying things like routing. If not provided, the add-on will by default route all traffic coming in from the VPN through your home network.

If you like to disable that, setting this option to "off", will disable that behavior.

By default it executes the following:

iptables -A FORWARD -i %i -j ACCEPT
iptables -A FORWARD -o %i -j ACCEPT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

I would be needing the add the following two lines. The first one drops all traffic to the 10.100.100.0 network, the second one allow the traffic to the three specific IPs.

iptables -I FORWARD -i wg0 -d 10.100.100.0/24 -j DROP
iptables -I FORWARD -i wg0 -d 10.100.100.3/32,10.100.100.140/32,10.100.100.200 -j ACCEPT

Tried to find example configurations which include some of these post_up configuration, but I guess my Google-fu is a bit rusty.

I’m struggling a bit with the use case here.

So client_allowed_ips doesn’t actually do anything if all you do is set it in the wireguard add-on configuration. What it actually does is add that information into the client configuration profiles that it makes which you are then supposed to import on your respective devices. For example, here’s the wireguard profile I imported onto my mac:

[Interface]
PrivateKey = <redacted>
Address = 172.27.66.3/24
DNS = 192.168.1.5, 172.30.32.3

[Peer]
PublicKey = <redacted>
AllowedIPs = 0.0.0.0/0
Endpoint = <redacted>
PersistentKeepalive = 25

Whatever you put in client_allowed_ips is used to fill in that AllowedIPs field which is then imported.

But here’s where I struggle with the use case. Are the clients connecting via Wireguard untrusted? If so then yea there’s some problems. Wireguard configurations are just text files imported to the other machines. If those other users can import the configuration then they can edit the file and change allowed IPs back to 0.0.0.0/0.

Now the iptables route you’re going down seems like it would allow you to control what clients can do from the server. But if the clients are actually untrusted then all you achieve by going that route is security by obscurity. Anyone that can get to HA can edit the configuration of your wireguard add-on. So if a client didn’t like the access you gave them they could just remove your post_up logic and restart.

If you truly need a zero-trust set up where only you can control this and no one else then I’d say don’t use the add-on. Deploy wireguard on a different system on your network and set it up so that system can only see exactly what you want it to see. Or if you’re a system administrator and these are managed systems then set AllowedIPs, deploy the configurations for users on their machines and don’t give them rights to edit it (although I can’t imagine you’d be using the HA add-on in that case).

Or use the client_allowed_ips, only give people you trust access, and set up the profiles for them. HA doesn’t actually have role based access control right now so I would strongly advise against any situation where you allow untrusted clients into your HA application.

1 Like

Thanks. Indeed, the client_allowed_ips or AllowedIps doesn’t do what I thought it does.
I indeed need to consider this as a zero trust situation, so the VPN configuration needs to be completely outside the reach of the users and HA.
I will take the approach you propose; different system altogether.

1 Like

Ok fair enough. Just be careful if you’re allowing untrusted clients into HA. I assume you will not be making those users admins but as it says here:
Screen Shot 2021-04-29 at 3.32.29 PM

I will say that I did a quick test just now and I was unable to log in as a user and use the websockets API to make myself an admin, it rejected that request. So there is some of restriction but I don’t know how much. I’ve never seen documentation saying all that the websockets API can do so I’m not even sure what the exposure is there. I basically just learn by watching what the UI does with dev tools which is a recipe for missing something bad.

I’d recommend assuming the entire HA application is untrusted in that case and completely sandboxing it so the worst it can do is take down itself. Since it sounds like those untrusted users will be able to access it.