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

Add support for IPv6 CIDR ranges as subnets #14

Closed
wants to merge 1 commit into from

Conversation

samridh90
Copy link

@samridh90 samridh90 commented Feb 21, 2019

#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.

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
Copy link
Owner

skx commented Feb 22, 2019

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
Copy link
Author

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
Copy link
Owner

skx commented Feb 22, 2019

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
Copy link
Author

samridh90 commented Feb 22, 2019

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
Copy link
Owner

skx commented Feb 22, 2019

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
Copy link
Author

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
Copy link
Owner

skx commented Feb 22, 2019

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
Copy link
Author

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
Copy link
Owner

skx commented Feb 22, 2019

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
Copy link
Author

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
Copy link
Owner

skx commented Feb 23, 2019

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 skx mentioned this pull request Feb 23, 2019
@skx
Copy link
Owner

skx commented Feb 23, 2019

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
Copy link
Author

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
Copy link
Owner

skx commented Feb 23, 2019

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

Of course its a hack ..

@samridh90
Copy link
Author

samridh90 commented Feb 23, 2019

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
Copy link
Owner

skx commented Feb 23, 2019

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
Copy link
Owner

skx commented Feb 24, 2019

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

@skx skx closed this Feb 24, 2019
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

Successfully merging this pull request may close these issues.

2 participants