Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowed ip's and specific network routing. #179

Open
tetricky opened this issue Dec 11, 2024 · 46 comments
Open

Allowed ip's and specific network routing. #179

tetricky opened this issue Dec 11, 2024 · 46 comments

Comments

@tetricky
Copy link

I would like to create configs that restrict access to specified networks (targets) but allow for other routes for client machines to happen local to those machines (ie internet access occurs locally, routing to clients on the VPN to allow ssh over the local wireguard network).

I am far from a wireguard expert, but my understanding is that this can be achieved using "AllowedIPs"

So my hope/expectation is that if I create a VPN, with an endpoint only on the local wireguard VPN subnet (or the the network itself - eg. xxx.xxx.xxx.xxx/24 ?) that I can create configs where the AllowedIPs are just for the valid endpoints.

Example use case. I have my desktop, I want to access the internet, and my local network, as normal. I then want to be able to VPN to my servers remotely on the VPN network to perform admin tasks over ssh, etc. While the desktop continues to route internet and other local LAN traffic, over my local network and internet connection.

What I expect to happen: I create a Target, which is the subnet of my VPN network. I create a peer group, which is the computers/server that I want to be able to connect together. I do not include the whole network (0.0.0.0/0), only the VPN subnet. Creating configs for this group should then have "AllowedIPs" set as the VPN subnet. In fact it allows all routes (0.0.0.0/0)

Ultimately it would be good to be able to generate configs for each peer that reflects the peer groups (and their endpoints) that they belong to, including more then one, and a potentially different routing pattern (AllowedIP's) for each peer depending on the peer groups they belong to.

I am unsure what might be possible, and how to achieve that...but ideally it would not involve manual editing of the configs.

@vijaygill vijaygill reopened this Dec 11, 2024
@vijaygill
Copy link
Owner

vijaygill commented Dec 11, 2024

@tetricky Please test this image and let me know.
docker pull ghcr.io/vijaygill/wg-ui-plus:develop

The code now looks at a peer -> peer-groups -> targets and creates a list of all IP addresses / network addresses and put them in AllowedIPs setting (comma separated).

Note: If the list happens to have "0.0.0.0/0" (internet) by virtue of any peer-group, it overrides the whole list and only "0.0.0.0/0" is used.

@tetricky
Copy link
Author

I'm not seeing that behaviour.

I'm not an iptables expert, but that looks okay with rules for individual clients - that is to say the 'server' has iptables rules to accept the WG subnet peer adresses, and reject outside those indiovidual addresses. Looks good as far as my knowledge extends.

However in the peer config files, if I have a server subnet 10.0.0.0/24 and peers 10.0.0.2, 10.0.0.3, 10.0.0.4, in the config files I'm getting "AllowedIPs = 10.0.0.0" - I don't think this routes. It should be 10.0.0.0/24 or at least 10.0.0.2, 10.0.0.3, 10.0.0.4

@vijaygill
Copy link
Owner

I'm not seeing that behaviour.

I'm not an iptables expert, but that looks okay with rules for individual clients - that is to say the 'server' has iptables rules to accept the WG subnet peer adresses, and reject outside those indiovidual addresses. Looks good as far as my knowledge extends.

However in the peer config files, if I have a server subnet 10.0.0.0/24 and peers 10.0.0.2, 10.0.0.3, 10.0.0.4, in the config files I'm getting "AllowedIPs = 10.0.0.0" - I don't think this routes. It should be 10.0.0.0/24 or at least 10.0.0.2, 10.0.0.3, 10.0.0.4

I have this peer configured to access two different targets (via two different peer-groups) and I got the following configuration file. Keys have been removed.

My layout is
This Peer -> PeerGroup1 -> 192.168.0.31
This Peer -> PeerGroup2 -> 192.168.0.71

This change does not affect the IPTables rules, it changes just the client configuration (the QR code you can OR .conf file you can download).

How are your peer -> peer-groups->targets related?

`

Settings for this client.

[Interface]
Address = 192.168.2.4
ListenPort = 1196
PrivateKey = ?????
DNS = 192.168.0.5

Settings for the peer on the server side.

[Peer]
PublicKey = ?????
Endpoint = ????:1196
AllowedIPs = 192.168.0.31,192.168.0.71

`

@vijaygill
Copy link
Owner

@tetricky after a fifth read of your message, I think I misunderstood your requirement. I assumed you wanted allowed IPs to be of the targets. But your last message seems to mean that you want it to be the IP addresses of peer's that can "see" each other. Am I right? If that's the case, I might need to implement it differently.

@tetricky
Copy link
Author

I have:

Server: Network address: 10.0.0.1; Local Networks: 10.0.0.0/24
Targets: Work: 10.0.0.0/24; Internet: 0.0.0.0/0

Work peer group (host2, host3, at 10.0.0.2-3) -> VPN subnet target (10.0.0.0/24)
Mobile peer group (host2) -> 0.0.0.0/0

So for

host2:

# Settings for this client.
[Interface]
Address = 10.0.0.2
ListenPort = 1196
PrivateKey = privatekeyhere
DNS = 1.1.1.1

# Settings for the peer on the server side.
[Peer]
PublicKey = publickeyhere
Endpoint = domain.host.name:51820
AllowedIPs = 0.0.0.0

host3:

# Settings for this client.
[Interface]
Address = 10.0.0.3
ListenPort = 1196
PrivateKey = privatekeyhere
DNS = 1.1.1.1

# Settings for the peer on the server side.
[Peer]
PublicKey = publickeyhere
Endpoint = domain.host.name:51820
AllowedIPs = 10.0.0.0

I think also I may not be correctly understanding the required server configuration and target configuration to achieve my use case.

In server configs Network Address - which network? Public IP, or wg VPN address? How do I use Local Network in conjuction with a target to exclude all newtork access apart from the peer group subnet?

Some of this may be me configuring things wrong....for which I apologise.

@tetricky
Copy link
Author

tetricky commented Dec 11, 2024

@tetricky after a fifth read of your message, I think I misunderstood your requirement. I assumed you wanted allowed IPs to be of the targets. But your last message seems to mean that you want it to be the IP addresses of peer's that can "see" each other. Am I right? If that's the case, I might need to implement it differently.

Sorry if I have not been clear.

Yes - I want to be able to set up a wireguard interface where joined hosts can see each other, but not have traffic outside that network subnet routed through the interface - defined by the AllowedIPs and their respective subnets which comes from Targets (ideally - ie set a target as the wg subnet if possible).

Also - a VPN that hosts can route their network traffic to endpoints (where an endpoint might be the whole of the internet)

I may be asking the wrong, or an impossible thing...but my understanding from wireguard was by changing the AllowedIPs that determines where a client machine routed traffic...and I was hoping that your tool would then allow the server to act as host to route to subnets that it was also a member of.

I could be getting the wrong end of the stick.

@vijaygill
Copy link
Owner

@tetricky - ah that clears it up further. Does the following logic suit you then?
The AllowedIPs should be a list of

  1. The IP's of all the targets a Peer is allowed access to (via its associated peer-groups->tartets).
  2. The IP's of all the peers who are members of the peer-groups this peer is member of. In other words, all peers which are part of a peer-group can see each other. Since a peer can be member of multiple groups, this list can become large quite soon.

Do I make sense here and is that acceptable solution?

@tetricky
Copy link
Author

That makes sense, and it's functionality that will meet what I'm looking to do.

@vijaygill
Copy link
Owner

That makes sense, and it's functionality that will meet what I'm looking to do.

No problem, I will do that.

Since these settings are for clients, how do you plan to push out these changes? for example if you add/remove peers from peer-groups and/or add/remove targets these AllowedIPs thingy will require new configs to be sent to clients so that they can recreate their wireguard tunnels.

@vijaygill
Copy link
Owner

vijaygill commented Dec 11, 2024

@tetricky - give it a go...
another image is available -
docker pull ghcr.io/vijaygill/wg-ui-plus:develop

@tetricky
Copy link
Author

That is generating correct AllowedIPs for the peers.....but it's not picking up the mask for the Target configuration.....so in the AllowedIPs you get 0.0.0.0 when you should get 0.0.0.0/0 and 10.0.0.0 when you should get 10.0.0.0/24 (from the above example).

@tetricky
Copy link
Author

Since these settings are for clients, how do you plan to push out these changes? for example if you add/remove peers from peer-groups and/or add/remove targets these AllowedIPs thingy will require new configs to be sent to clients so that they can recreate their wireguard tunnels.

Just issue updated configs to the clients. I can copy the configs across to the client machines, briefly open the ssh port on the firewall, take the wireguard interface down, copy the new config, bring the interface back up, reconnect over the wg interface, and then close the ssh port in the firewall.

...or just leave the configs as is when removing a host...the host just wont respond because it's not there. Because it's a server and clients (hub/spoke) rather than a mesh I don't necessarily have to rebuild with all host configs. Particularly if Targets allow me to route to whole subnets. Then with another instance to manage another server config (on the same server computer) I'm hoping to be able to use Targets to route to another wireguard interface on the same machine. If I need that (potential use case, managing completely separate work and home networks on completely different subnets).

@tetricky
Copy link
Author

Is there an argument that you don't need to add peer group IP addresses to the AllowedIPs? These can be included by adding the subnet (assuming the mask works), or individual peers, as Targets - which is more flexible...there may be cases where peer access is not required between peers (as in a guest network), but individual peers could be defined individually where required.

All the client machines need to be able to do is route to the Target (plus mask) IP as one of the AllowedIPs.

@vijaygill
Copy link
Owner

vijaygill commented Dec 12, 2024

@tetricky -I have made the changes. I have tested and I see following on my side

AllowedIPs = 192.168.0.0/24,192.168.0.31/32,192.168.0.71/32,192.168.2.2/32,192.168.2.3/32,192.168.2.5/32,192.168.2.7/32
and
AllowedIPs = 0.0.0.0/0

Pull new image
docker pull ghcr.io/vijaygill/wg-ui-plus:develop

If all goes well with your testing, I will add a checkbox to "Server Configuration" on the lines of "Strict AllowedIPs" which will enable your feature if checked else it will default to "0.0.0.0/0".

@tetricky
Copy link
Author

This is good. I believe the configs for the peers are now being created correctly.

There is an issue with the IP-Tables creation. Where there is a target created, and a rule is added to allow traffic from the peer group, there doesn't appear to be a matching return route...so for example if we ssh from the peer group to the Target, the request will be routed, but the reply from the target doesn't have a matching rule, so it hits DROP - Everything going to local network ...and fails.

@vijaygill
Copy link
Owner

This is good. I believe the configs for the peers are now being created correctly.

There is an issue with the IP-Tables creation. Where there is a target created, and a rule is added to allow traffic from the peer group, there doesn't appear to be a matching return route...so for example if we ssh from the peer group to the Target, the request will be routed, but the reply from the target doesn't have a matching rule, so it hits DROP - Everything going to local network ...and fails.

There does not need to be a return rule because look at the first rule in the chain (FORWARD chain). It says let all the packets pass from "any" to "any" for the packets with state RELATED or ESTABLISHED.

Rules are checked from top to bottom.

If your packet is ending up at the last "Drop - everything...." it means it did not match any rule above that one. Can you post your iptables rules and the example along with expected and actual observations? It is difficult to tell without looking at your rules.

@tetricky
Copy link
Author

I think my issue might be that the server (ie the wg-ui-plus host) doesn't have an ip address in the network.

I had thought the "Network Address" in the server config was this...but I can't find a matching address on the server. So it might not be failing because of the routes, but rather because the server isn't part of the network.

I'm not sure if this is correct, or how to resolve it.

@vijaygill
Copy link
Owner

That "Network Address" shows a pop-up help when you hover mouse over it.
Again, I need more information to look at before I can help you.

@tetricky
Copy link
Author

It says "Network Address of the VPN". Which I don't understand. Which is entirely down to me...but I'm prettuy sure that is my problem. How do I make the server itself have an address on the VPN subnet?

@vijaygill
Copy link
Owner

If you share the desired layout (even a hand-scribbed diagram or ascii drawing will do), I might be of any help there.

@tetricky
Copy link
Author

tetricky commented Dec 12, 2024

The server, with a network of 10.0.0.0/24 doesn't appear to have an address of 10.0.0.1. It does not appear to have an address on the VPN subnet. I can't ping it (even from itself).

@vijaygill
Copy link
Owner

vijaygill commented Dec 12, 2024

The server, with a network of 10.0.0.0/24 doesn't appear to have an address of 10.0.0.1. It does not appear to have an address on the VPN subnet. I can't ping it (even from itself).

Yeah I noticed that after posting my message and that's why I deleted it.

Try 10.0.0.1/24 in that field and regenerate config files.

I did it with 192.168.2.1/24 in my settings and got the ip address set for wg0.

image

I will change the label and help in the "Server Configuration" screen.

@tetricky
Copy link
Author

I have refreshed all the configs, and I can now ping the server from itself...but I can't ping the server from peers that have it's address as a target.

I am thinking that I might need to wipe it, and start again from scratch.

@vijaygill
Copy link
Owner

I have refreshed all the configs, and I can now ping the server from itself...but I can't ping the server from peers that have it's address as a target.

I am thinking that I might need to wipe it, and start again from scratch.

hang on! A flashbulb moment for me! If we step-back a little bit...

Why do you need the server itself as the target? it does not run anything except the python application + wireguard.

Do you want the "host" as target where this docker container is running? Then all the above does not matter.

For example my container runs on 192.168.0.31 so I will have that as a target instead of the IP 192.168.2.1 which is the ip address of the wg0 interface within the container.

@tetricky
Copy link
Author

Yes. I want the 'host' as a target...because as well as running wg-ui-plus, it also hosts various services, and is in the cloud where ideally I want to maintain it over a wireguard interface, rather than just an obscure ssh port....so there will be ssh, sftp, into the host itself required as a minimum.

Then , in addition, I would like peers within a qualifying peer group to be able to ssh into other targets, for similar maintenance.

@vijaygill
Copy link
Owner

Here is the layout of the same setup I have (the LIVE instance for my setup)
Notice I have a target for SSH on the 192.168.0.31 (which is the host where my VPN runs). currently there is only one peer in this peer-group "GitServer - SSH Users". And things are working as per my liking.

image

@tetricky
Copy link
Author

tetricky commented Dec 12, 2024

So in this scenario have you added GitServer as a target? Presumably not as a peer and it doesn't have a IP address on the 192.168.2.0 subnet (which seems to be your VPN subnet)?

I was looking to keep all traffic within the encrypted wireguard tunnel, and not expose ports externally (particularly important for Samba shares).

@vijaygill
Copy link
Owner

I am not sure we are on the same page here.
The VPN is kind of entry point for my setup. Then peers (on the move and part of 192.168.2.0/24) can access the targets that are allowed for them.
There is nothing "within" the VPN network.
The targets are machines/networks within my LAN (192.168.0.0/24) or internet (0.0.0.0/0).

@tetricky
Copy link
Author

Indeed. So in my case the targets are on the internet (not inside a protected LAN)...which requires their ports to be open, and accessible to all. What I was looking for was to have "Targets" inside the VPN, so peers could access service within the VPN, without exposing ports externally.

@vijaygill
Copy link
Owner

Indeed. So in my case the targets are on the internet (not inside a protected LAN)...which requires their ports to be open, and accessible to all. What I was looking for was to have "Targets" inside the VPN, so peers could access service within the VPN, without exposing ports externally.

I don't know where your infrastructure is hosted, does it provide secure networking within VM's? so you do not have to expose anything to the outer world?

@tetricky
Copy link
Author

It's more a case that I have hosted servers, and some equipment in other LAN's, and some at home. I was looking for a way to make the wireguard network the secure network. To network these machines together over a wireguard network, which then allows me to maintain and access services over multiple locations, but within a secure encrypted tunnel.

@vijaygill
Copy link
Owner

To network these machines together over a wireguard net

Interesting. I will think about it and see how that can be implemented.

@tetricky
Copy link
Author

There is a value in what you have here - in that peer groups can be given access to specific Targets.

It would fit my use case if the targets could be in the VPN subnet.

@vijaygill
Copy link
Owner

There is a value in what you have here - in that peer groups can be given access to specific Targets.

It would fit my use case if the targets could be in the VPN subnet.

The current architecture already has link between Peer-Groups and Targets.

Your requirement need that targets can be within VPN's own network.

I will try to implement it today / ASAP when I get a chance.

@vijaygill
Copy link
Owner

vijaygill commented Dec 12, 2024

@tetricky pull latest image now.

docker pull ghcr.io/vijaygill/wg-ui-plus:develop

I tested by adding my own VPN server as one the targets and linking it with one of the peer-groups my mobile phone is member of. I could open the web page of the VPN itself using http://192.168.2.1:8000.

image

@vijaygill
Copy link
Owner

vijaygill commented Dec 12, 2024

@tetricky - I have added a checkbox in Server Configuration page to allow switching between 0.0.0.0/0 or stricter list for AllowedIPs.
You might need to check it to have your stricter list of AllowedIPs.

@tetricky
Copy link
Author

tetricky commented Dec 13, 2024

Yes, I think that works. I am still having some problems though.

For some reason the server (host of wg-ui-plus, but also a required member/peer of my VPN) address is showing as 192.168.2.1 despite setting the network address as 10.0.0.0/24.

So I looked at removing all settings and recreating from scratch.

Taking down all the interfaces, removing the config directory, and removing the database, I initialised the container again. This produced the default settings and a mobile and laptop placeholders. Changing the Network Address in the server configuration (to 10.0.0.0/24) did not change the server address. Also it seems that the default configuration has a clash of ip address for the default server and laptop placeholder.

# Settings for Server.
[Interface]
Address = 192.168.2.1
ListenPort = 51820
PrivateKey = ABbayP6hgXwoNp8Vc6S+aJTWxbWmIQ/RuigYxAEEHVw=

PostUp = /config/wireguard/scripts/post-up.sh
PostDown = /config/wireguard/scripts/post-down.sh


# Server-side settings for the client.
# Mobile phone
[Peer]
PublicKey = QPJ3nC24lj3YSDV2YfxXAqb5oDkzjpkVwQFTbY+RvTY=
AllowedIPs = 192.168.2.1/32
PersistentKeepalive = 25
#PresharedKey = <this is optional>


# Server-side settings for the client.
# Laptop
[Peer]
PublicKey = Mt7sRWbZzbp7zhTkj0VToUs7w1FZ3BiNwexgWAIJ/T0=
AllowedIPs = 192.168.2.2/32
PersistentKeepalive = 25
#PresharedKey = <this is optional>

Really I (also other people) need to be able to set the subnet range for the VPN - to be able to accommodate different ip ranges to not clash with other things that might already exist.

So I think what might be needed is: Set the server ip address as the first available ip in the subnet defined as Network Address. Also set the default placeholder peers (laptop, mobile) as the next ip addresses in the range, without either of them being the same as the server ip address (although these can be deleted, and re-created as necessary - assuming this clears up all legacy references in the initially created configs?). Also/instead would it be appropriate to create the server as a peer on the network? - currently changing the Network Address and then creating a peer uses the first ip address in the defined subnet....so the server is 'excluded'.

Also it would be handy to have an on/off switch. ie the ability to turn off the VPN, and remove all configs. Then to be able to 'turn it back on'. Ideally such that configs can be generated 'offline' and then turned on when the config files and routing has been created.

@vijaygill
Copy link
Owner

I found why it is stuck at 192.168.2.1. I will fix the code in the evening. I will also test it with 10.0.0.0 to test for your scenario.

vijaygill added a commit that referenced this issue Dec 13, 2024
…the VPN. Also server ip address is also added to AllowedIPs if strict Allowed IPs is enabled.
@vijaygill
Copy link
Owner

@tetricky - I have made more changes now. Pull latest develop image.
Your ideas are useful, but can you please open one issue per idea so I can prioritise and work on those individually? Thanks.

@tetricky
Copy link
Author

I apologise if I was discussing out of range. I very much appreciate the efforts that you are going to, and my intention was constructive, not demanding.

Right. I pull the new image, set the server config, create a target for the server host (so the host server, rather than the container itself - I do this because I couldn't ping the wg-ui-plus host container/pod from the local server), create an admin peer group, remove internet as a target, create a remote peer, add it to the peer group with the host server target.

The wg interface starts on the hosts...but no data comes up on the network....and the wg-ui-plus interface shows th4e hosts are not connected.

For some reason the peers are no longer able to route to the wg-ui-plus server container.

@vijaygill
Copy link
Owner

vijaygill commented Dec 14, 2024

I apologise if I was discussing out of range. I very much appreciate the efforts that you are going to, and my intention was constructive, not demanding.

Right. I pull the new image, set the server config, create a target for the server host (so the host server, rather than the container itself - I do this because I couldn't ping the wg-ui-plus host container/pod from the local server), create an admin peer group, remove internet as a target, create a remote peer, add it to the peer group with the host server target.

The wg interface starts on the hosts...but no data comes up on the network....and the wg-ui-plus interface shows th4e hosts are not connected.

For some reason the peers are no longer able to route to the wg-ui-plus server container.

Ah no! You did not come across as demanding! I love coding. I have used open-source a lot and this is my tiny contribution back to the community.

That behaviour is strange. I tested it with strict and without strict AllowedIP's. Give me more time to test a bit more. In the haste to sort out your issue, I am spewing out half-baked solution.

Going forward, can you please test every behaviour in both modes - strict and non-strict allowedIP's so I can isolate the cause and implement the fix. Thanks.

@tetricky
Copy link
Author

I'm not getting any connectivity through the VPN at all, because the client peer is no longer connecting to the server. In Monitor Peers there is no active connection.

@vijaygill
Copy link
Owner

@tetricky that's strange. I tested it last evening and it worked in my test instance.
Anyway, I will have a look today.

@tetricky
Copy link
Author

When I get some time I'll tear it down, and start again with no changes made to the initial settings...but unfortunately I'm tied up on other things for the next couple of days.

@vijaygill
Copy link
Owner

vijaygill commented Dec 15, 2024

@tetricky - I tested things again and I could not find any issue. May be because of muscle memory I am unable to replicate your scenario.

Also to help you in tearing-down and setting-up quicker, following environment variables can be used to set configuration values during creating of instance. I use these in my docker-compose during testing so I do not have to go to server configuration screen and set things up from scratch. I know these are not documented right now, but I will do so in future.

WG_NETWORK_ADDRESS
WG_HOST_NAME_EXTERNAL
WG_LOCAL_NETWORKS
WG_UPSTREAM_DNS_SERVER
WG_PORT_EXTERNAL
WG_PORT_INTERNAL
WG_STRICT_ALLOWED_IPS_IN_PEER_CONFIG (can be 1/y/yes/true)

And restarting a container with a new value of "WG_NETWORK_ADDRESS" makes the system reassign ip addresses again (to server and peers).

@tetricky
Copy link
Author

Thank you for that. I will be having a crack at this sun/mon, and will feed back my results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants