Add support for IPv6 CIDR ranges as subnets #14

Closed
samridh90 wants to merge 1 commit from ipv6 into master
samridh90 commented 2019-02-21 16:07:33 -05:00 (Migrated from github.com)

https://github.com/skx/simple-vpn/issues/12
A /64 subnet has 2^64 IP addresses which is way too many
to fit in-memory for the simple-vpn server. To add IPv6
support, we initialize the server with at-most 2^20 IPs
which translates to a /108 subnet. If we run out of IPs
in the /108, we expand the subnet to /107 and so on.

https://github.com/skx/simple-vpn/issues/12 A /64 subnet has 2^64 IP addresses which is way too many to fit in-memory for the simple-vpn server. To add IPv6 support, we initialize the server with at-most 2^20 IPs which translates to a /108 subnet. If we run out of IPs in the /108, we expand the subnet to /107 and so on.
skx commented 2019-02-21 23:43:48 -05:00 (Migrated from github.com)

Thanks for your submission.

I've had a quick look and it looks good, but I'll want to test it over the weekend before I'm sure.

(e.g. Do we need to add "-6" to the IP commands? I don't think so, but will need to test to be sure.)

Thanks for your submission. I've had a quick look and it looks good, but I'll want to test it over the weekend before I'm sure. (e.g. Do we need to add "-6" to the IP commands? I don't think so, but will need to test to be sure.)
samridh90 commented 2019-02-22 00:02:16 -05:00 (Migrated from github.com)

Sounds good. I did some basic testing

  1. Started the server
  2. Started a client
  3. Ran socat on the client interface and sent some packets to it using telnet

It's definitely a good idea to do some testing of your own to be sure.

Sounds good. I did some basic testing 1. Started the server 2. Started a client 3. Ran `socat` on the client interface and sent some packets to it using `telnet` It's definitely a good idea to do some testing of your own to be sure.
skx commented 2019-02-22 00:09:38 -05:00 (Migrated from github.com)

Yeah that's the kind of thing I'd do, but I'd connect and reconnect a number of machines and see that the IP-allocation makes sense. No leaks or gaps.

Also test the static assignment via name too.

Yeah that's the kind of thing I'd do, but I'd connect and reconnect a number of machines and see that the IP-allocation makes sense. No leaks or gaps. Also test the static assignment via name too.
samridh90 commented 2019-02-22 01:13:13 -05:00 (Migrated from github.com)

OK, I think there's something else that needs to be done to setup routing correctly with ip. I created 2 IPv6 clients and tried to send TCP packet from one to the other and it did not work. There's definitely something missing. I'll take a look

OK, I think there's something else that needs to be done to setup routing correctly with `ip`. I created 2 IPv6 clients and tried to send TCP packet from one to the other and it did not work. There's definitely something missing. I'll take a look
skx commented 2019-02-22 01:21:37 -05:00 (Migrated from github.com)

Probably worth checking the IP commands that get run.

Or exploring via the cli ip route ip addr probably need an -6 adding to them. The MTU and others will be OK without it I think. I'll explore tonight/tomorrow if you don't manage to see what the problem is before then.

Probably worth checking the IP commands that get run. Or exploring via the cli `ip route` `ip addr` __probably__ need an `-6` adding to them. The MTU and others will be OK without it I think. I'll explore tonight/tomorrow if you don't manage to see what the problem is before then.
samridh90 commented 2019-02-22 14:07:09 -05:00 (Migrated from github.com)

I tried -6 on the ip route/addr and that didn't seem to make a difference. I'm connecting to the server websocket over an IPv4 interface. I don't think that should make a difference but maybe that's what's breaking it

I tried `-6` on the `ip route/addr` and that didn't seem to make a difference. I'm connecting to the server websocket over an IPv4 interface. I don't think that should make a difference but maybe that's what's breaking it
skx commented 2019-02-22 14:28:01 -05:00 (Migrated from github.com)

I launched the server with this configuration-file:

    root@master ~ # grep -v ^\# server.cfg  | sort -u
    key = secret
    subnet = fde4:8dba:82e1:fefe::/64

The server launches and it shows:

   root@master ~ # ./simple-vpn server server.cfg 
   Subnet CIDR: provided size 64, using initial size 20
   VPN server has IP fde4:8dba:82e1:fefe::
   Running: 'ip link set dev svpn up'
   Running: 'ip link set mtu 1280 dev svpn'
   Launching the server on http://127.0.0.1:9000

Looks like the initial IP is bogus - notice how fefe:: is shown? Rather than "fefe::1".

Same with the client. When the client connects the remote IP of the master is shown as "fefe::"

To fix this manually you could, on the master run:

  • ip addr add fde4:8dba:82e1:fefe::1 dev svpn0

On the client something like this:

  • ip addr add fde4:8dba:82e1:fefe::10 dev tun0 -> Add a client IP
  • ip route add fde4:8dba:82e1:fefe::1/128 dev tun0 -> Allow access to the gateway
  • ip route add fde4:8dba:82e1:fefe::/64 via fde4:8dba:82e1:fefe::1/128 -> Route the range via the gateway. I think that's right

In short you're not allocating/iterating over the IPs correctly to assign the first to the master, and later ones to each client.

Does that help?

I launched the server with this configuration-file: root@master ~ # grep -v ^\# server.cfg | sort -u key = secret subnet = fde4:8dba:82e1:fefe::/64 The server launches and it shows: root@master ~ # ./simple-vpn server server.cfg Subnet CIDR: provided size 64, using initial size 20 VPN server has IP fde4:8dba:82e1:fefe:: Running: 'ip link set dev svpn up' Running: 'ip link set mtu 1280 dev svpn' Launching the server on http://127.0.0.1:9000 Looks like the initial IP is bogus - notice how `fefe::` is shown? Rather than "fefe::1". Same with the client. When the client connects the remote IP of the master is shown as "fefe::" To fix this manually you could, on the master run: * ip addr add fde4:8dba:82e1:fefe::1 dev svpn0 On the client something like this: * ip addr add fde4:8dba:82e1:fefe::10 dev tun0 -> Add a client IP * ip route add fde4:8dba:82e1:fefe::1/128 dev tun0 -> Allow access to the gateway * ip route add fde4:8dba:82e1:fefe::/64 via fde4:8dba:82e1:fefe::1/128 -> Route the range via the gateway. I think that's right In short you're not allocating/iterating over the IPs correctly to assign the first to the master, and later ones to each client. Does that help?
samridh90 commented 2019-02-22 15:02:09 -05:00 (Migrated from github.com)

I don't think that's the issue. For IPv6, fde4:8dba:82e1:fefe:: just means fde4:8dba:82e1:fefe:0000:0000:0000:0000. The 0 address is assigned to the server in this case. That's a reserved address in IPv4 but not in IPv6.
Just in case that was the issue, I tried assigning fde4:8dba:82e1:fefe:0000:0000:0000:0001 to the server and fde4:8dba:82e1:fefe:0000:0000:0000:0002 and fde4:8dba:82e1:fefe:0000:0000:0000:0003 to the clients by skipping the 0 address. That still didn't work.

I don't think that's the issue. For IPv6, `fde4:8dba:82e1:fefe::` just means `fde4:8dba:82e1:fefe:0000:0000:0000:0000`. The `0` address is assigned to the server in this case. That's a reserved address in IPv4 but not in IPv6. Just in case that was the issue, I tried assigning `fde4:8dba:82e1:fefe:0000:0000:0000:0001` to the server and `fde4:8dba:82e1:fefe:0000:0000:0000:0002` and `fde4:8dba:82e1:fefe:0000:0000:0000:0003` to the clients by skipping the `0` address. That still didn't work.
skx commented 2019-02-22 15:19:59 -05:00 (Migrated from github.com)

Good correction :)

  • Started master
    • Master is assigned ::
  • Started client1
    • Client1 is also assigned ::
  • Started client2
    • Client is also assigned ::

Something wrong there. I don't expect client1<->master to work, nor client2<->master, but client1<->client2 should, and won't if they have the same IP.

Good correction :) * Started master * Master is assigned :: * Started client1 * Client1 is also assigned :: * Started client2 * Client is also assigned :: Something wrong there. I don't expect client1<->master to work, nor client2<->master, but client1<->client2 should, and won't if they have the same IP.
samridh90 commented 2019-02-22 15:41:24 -05:00 (Migrated from github.com)

For reproducibility, I'm running the server on an ubuntu 18.04 VM in virtual box and running the clients in docker containers on the same VM.

Client.cfg
vpn = ws://localhost:9000

Here's my Dockerfile for the client:

FROM ubuntu:18.04
RUN apt-get update && \
    apt-get install -y apt-utils iproute2 socat net-tools telnet netcat traceroute
ADD ./ /
RUN sed -i 's/localhost/172.17.0.1/g' ./etc/client.cfg
CMD mkdir -p /dev/net && \
    mknod /dev/net/tun c 10 200 && \
    chmod 600 /dev/net/tun && \
    /bin/bash

To build:
docker build --rm -f "Dockerfile" -t simple-vpn:latest .

To run:
docker run --rm -it --cap-add=NET_ADMIN --sysctl net.ipv6.conf.all.disable_ipv6=0 simple-vpn:latest

Run the client:
./simple-vpn client ./etc/client.cfg

For reproducibility, I'm running the server on an ubuntu 18.04 VM in virtual box and running the clients in docker containers on the same VM. Client.cfg `vpn = ws://localhost:9000` Here's my Dockerfile for the client: ``` FROM ubuntu:18.04 RUN apt-get update && \ apt-get install -y apt-utils iproute2 socat net-tools telnet netcat traceroute ADD ./ / RUN sed -i 's/localhost/172.17.0.1/g' ./etc/client.cfg CMD mkdir -p /dev/net && \ mknod /dev/net/tun c 10 200 && \ chmod 600 /dev/net/tun && \ /bin/bash ``` To build: ` docker build --rm -f "Dockerfile" -t simple-vpn:latest .` To run: `docker run --rm -it --cap-add=NET_ADMIN --sysctl net.ipv6.conf.all.disable_ipv6=0 simple-vpn:latest` Run the client: `./simple-vpn client ./etc/client.cfg`
skx commented 2019-02-22 23:53:11 -05:00 (Migrated from github.com)

Thanks for the overview; I'm using real hosts. You've gotten me curious now, and I will be attacking this myself later in the day.

  • Want to allow 192.16.0.0/16
  • Want to allow fde4:8dba:82e1:fefe::/64.

But I see nothing wrong with saying "max 256/1024 clients". Doing that will cut down on the allocations I think. I'll concentrate on the IP allocation, and I hope if/when that is right it'll just work.

Thanks for the overview; I'm using real hosts. You've gotten me curious now, and I will be attacking this myself later in the day. * Want to allow 192.16.0.0/16 * Want to allow fde4:8dba:82e1:fefe::/64. But I see nothing wrong with saying "max 256/1024 clients". Doing that will cut down on the allocations I think. I'll concentrate on the IP allocation, and I hope if/when that is right it'll just work.
skx commented 2019-02-23 00:53:07 -05:00 (Migrated from github.com)

OK I'm happy with #15 to allocate IPs better.

Routing fails. Looks like shared/socketHandler.go needs updating.

This is annoying and harder than it needs to be :/

OK I'm happy with #15 to allocate IPs better. Routing fails. Looks like `shared/socketHandler.go` needs updating. This is annoying and harder than it needs to be :/
samridh90 commented 2019-02-23 01:11:04 -05:00 (Migrated from github.com)

I'd be curious to know what needs to be updated in socketHandler.go. That was pretty much what I noticed as well irrespective of how allocation works.

I'd be curious to know what needs to be updated in `socketHandler.go`. That was pretty much what I noticed as well irrespective of how allocation works.
skx commented 2019-02-23 01:19:14 -05:00 (Migrated from github.com)

See the last commit on #15; results in a working system.

Of course its a hack ..

See the last commit on #15; results in a working system. Of course its a hack ..
samridh90 commented 2019-02-23 01:26:13 -05:00 (Migrated from github.com)

How about using https://github.com/songgao/water/blob/master/waterutil/tun.go to determine if the packet is v4 or v6 and then extracting the mac address based on that?

How about using https://github.com/songgao/water/blob/master/waterutil/tun.go to determine if the packet is v4 or v6 and then extracting the mac address based on that?
skx commented 2019-02-23 04:25:27 -05:00 (Migrated from github.com)

Yup that works.

Sorry for the duplication, and I do appreciate your contribution but I'm going to close this PR now, and keep going with my own. If you could test it that would be useful, and good.

Yup that works. Sorry for the duplication, and I do appreciate your contribution but I'm going to close this PR now, and keep going with my own. If you could test it that would be useful, and good.
skx commented 2019-02-24 01:18:50 -05:00 (Migrated from github.com)

Closing, in favor of #15, but thank-you.

Closing, in favor of #15, but thank-you.

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
skx/simple-vpn!14
No description provided.