Coder Social home page Coder Social logo

dsvpn's Introduction

DSVPN

GitHub CI status CodeQL scan

DSVPN is a Dead Simple VPN, designed to address the most common use case for using a VPN:

[client device] ---- (untrusted/restricted network) ---- [vpn server] ---- [the Internet]

Features:

  • Runs on TCP. Works pretty much everywhere, including on public WiFi where only TCP/443 is open or reliable.
  • Uses only modern cryptography, with formally verified implementations.
  • Small and constant memory footprint. Doesn't perform any heap memory allocations.
  • Small (~25 KB), with an equally small and readable code base. No external dependencies.
  • Works out of the box. No lousy documentation to read. No configuration file. No post-configuration. Run a single-line command on the server, a similar one on the client and you're done. No firewall and routing rules to manually mess with.
  • Works on Linux (kernel >= 3.17), macOS and OpenBSD, as well as DragonFly BSD, FreeBSD and NetBSD in client and point-to-point modes. Adding support for other operating systems is trivial.
  • Doesn't leak between reconnects if the network doesn't change. Blocks IPv6 on the client to prevent IPv6 leaks.

Installation

make

On Raspberry Pi 3 and 4, use the following command instead to enable NEON optimizations:

env OPTFLAGS=-mfpu=neon make

Alternatively, if you have zig installed, it can be used to compile DSVPN:

zig build -Drelease

On macOS, DSVPN can be installed using Homebrew: brew install dsvpn.

Secret key

DSVPN uses a shared secret. Create it with the following command:

dd if=/dev/urandom of=vpn.key count=1 bs=32

And copy it on the server and the client.

If required, keys can be exported and imported in printable form:

base64 < vpn.key
echo 'HK940OkWcFqSmZXnCQ1w6jhQMZm0fZoEhQOOpzJ/l3w=' | base64 --decode > vpn.key

Example usage on the server

sudo ./dsvpn server vpn.key auto 1959

Here, I use port 1959. Everything else is set to the default values. If you want to use the default port (443), it doesn't even have to be specified, so the parameters can just be server vpn.key

Example usage on the client

sudo ./dsvpn client vpn.key 34.216.127.34 1959

This is a macOS client, connecting to the VPN server 34.216.127.34 on port 1959. The port number is optional here as well. And the IP can be replaced by a host name.

That's it

You are connected. Just hit Ctrl-C to disconnect.

Evaggelos Balaskas wrote a great blog post walking through the whole procedure: A Dead Simple VPN.

He also maintains systemd service files for DSVPN. Thank you Evaggelos!

A note on DNS

If you were previously using a DNS resolver only accessible from the local network, it won't be accessible through the VPN. That might be the only thing you may have to change. Use a public resolver, a local resolver, or DNSCrypt.

Or send a pull request implementing the required commands to change and revert the DNS settings, or redirect DNS queries to another resolver, for all supported operating systems.

Advanced configuration

dsvpn   "server"
        <key file>
        <vpn server ip or name>|"auto"
        <vpn server port>|"auto"
        <tun interface>|"auto"
        <local tun ip>|"auto"
        <remote tun ip>"auto"
        <external ip>|"auto"

dsvpn   "client"
        <key file>
        <vpn server ip or name>
        <vpn server port>|"auto"
        <tun interface>|"auto"
        <local tun ip>|"auto"
        <remote tun ip>|"auto"
        <gateway ip>|"auto"
  • server|client: use server on the server, and client on clients.
  • <key file>: path to the file with the secret key (e.g. vpn.key).
  • <vpn server ip or name>: on the client, it should be the IP address or the hostname of the server. On the server, it doesn't matter, so you can just use auto.
  • <vpn server port>: the TCP port to listen to/connect to for the VPN. Use 443 or anything else. auto will use 443.
  • <tun interface>: this is the name of the VPN interface. On Linux, you can set it to anything. Or macOS, it has to follow a more boring pattern. If you feel lazy, just use auto here.
  • <local tun ip>: local IP address of the tunnel. Use any private IP address that you don't use here.
  • <remote tun ip>: remote IP address of the tunnel. See above. The local and remote tunnel IPs must the same on the client and on the server, just reversed. For some reason, I tend to pick 192.168.192.254 for the server, and 192.168.192.1 for the client. These values will be used if you put auto for the local and remote tunnel IPs.
  • <external ip> (server only): the external IP address of the server. Can be left to "auto".
  • <gateway ip> (client only): the internal router IP address. The first line printed by netstat -rn will tell you (gateway).

If all the remaining parameters of a command would be auto, they don't have to be specified.

Related projects

Why

I needed a VPN that works in an environment where only TCP/80 and TCP/443 are open.

WireGuard doesn't work over TCP.

GloryTun is excellent, but requires post-configuration and the maintained branch uses UDP.

I forgot about VTUN-libsodium. But it would have been too much complexity and attack surface for a simple use case.

OpenVPN is horribly difficult to set up.

Sshuttle is very nice and I've been using it a lot in the past, but it's not a VPN. It doesn't tunnel non-TCP traffic. It also requires a full Python install, which I'd rather avoid on my router.

Everything else I looked at was either too difficult to use, slow, bloated, didn't work on macOS, didn't work on small devices, was complicated to cross-compile due to dependencies, wasn't maintained, or didn't feel secure.

TCP-over-TCP is not as bad as some documents describe. It works surprisingly well in practice, especially with modern congestion control algorithms (BBR). For traditional algorithms that rely on packet loss, DSVPN couples the inner and outer congestion controllers by lowering TCP_NOTSENT_LOWAT and dropping packets when congestion is detected at the outer layer.

Cryptography

The cryptographic primitives used in DSVPN are available as a standalone project: Charm.

Guarantees, support, feature additions

None.

This is not intended to be a replacement for GloryTun or WireGuard. This is what I use, because it solves a problem I had. Extending it to solve different problems is not planned, but feel free to fork it and tailor it to your needs!

dsvpn's People

Contributors

angristan avatar bapt avatar bsdlme avatar cofyc avatar jandelgado avatar jedisct1 avatar jungle-boogie avatar morrisonbrett avatar nnathan avatar tommd avatar us avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dsvpn's Issues

Do we expect an Ubuntu 18.04.x client to work?

Do we expect an Ubuntu 18.04.x client to work?

It does not for me. I run the following...

root@node111 Sep 09 19:03:15 /root# ./dsvpn.bin.ubuntu-18.04.2 client 2019-09-08-dsvpn.key node113.xxx.tld 2001
Interface: [tun0]

...and it hangs all (possibly?) network interfaces - or at least, my DigitalOcean (DO) instance's sshd ceases to respond, and the only way I know thus far to get it (node111) is to power-cycle it from DO's control panel web page.

Again, this problematic behavior is only for client-side operations.

The same DO VPS above, when running as a dsvpn server, seems to server a macOS client fine. Same for node113 (who is attempting to server node111 as a client) to the same macOS client.

plain-text key, stuck ssh connection and up voting for multi-client support

dsvpn core concept is fantastic, thank you so much for coding and sharing it!

My use case is to expose some local servers to a public domain name over one Amazon lightsail instance with DNS pointing to the domain.

  1. if you connect to the remote instance over SSH to setup dsvpn server, as soon as you run it the SSH connection get stuck. Is it because any of the routing rules?

  2. is it possible to support plain-text .key? It makes much easier to share the key between local and remote machines by just copying and pasting without having to transfer files or SSH, SFTP or HTTP.

  • one up vote for multi-client support;

doesn't compile on debian

Thanks for this!

I might not have time to investigate, so just copy/pasting the error I'm getting:

cc -march=native -Ofast -Wall -W -Wshadow -Wmissing-prototypes  -Iinclude -o dsvpn src/vpn.c src/charm.c src/os.c
src/charm.c: In function ‘uc_randombytes_buf’:
src/charm.c:329:26: error: ‘SYS_getrandom’ undeclared (first use in this function)
     if ((size_t) syscall(SYS_getrandom, buf, (int) len, 0) != len) {
                          ^
src/charm.c:329:26: note: each undeclared identifier is reported only once for each function it appears in
Makefile:7: recipe for target 'dsvpn' failed
make: *** [dsvpn] Error 1

IPv6: support it or block it?

Since dsvpn forwards all the client's traffic to the server, it is clearly made for users who want to access the internet through the VPN.

Currently, if I'm not mistaken, IPv6 isn't handled at all. Adding support for it shouldn't be to hard although it may make the command line quite bloated. What do you think of at least blocking it when in client mode so the user's IPv6 isn't "leaking"?

Dockerfile

Howdy,

I have created a Dockerfile for dsvpn that clocks in at 5.61MB.

### Builder

FROM alpine AS builder
RUN apk --no-cache add gcc git make linux-headers musl-dev
WORKDIR /opt
RUN git clone https://github.com/jedisct1/dsvpn /opt
RUN make

### Packed application

FROM alpine
COPY --from=builder /opt/dsvpn /
ENTRYPOINT ["/dsvpn"]

It still needs heavy testing, but you can run it via:

docker run \
    --device=/dev/net/tun \
    --cap-add=NET_ADMIN \
    --volume $(pwd)/vpn.key:/vpn.key \
dsvpn:latest server vpn.key auto

DSVPN & Time Capsule

I'm trying to understand how DSVPN works (and it works very well :) ) - expect one item.

Normally when I use my OpenVPN setup I can see my time capsule on my home local network when I connect to the VPN (as the VPN terminates in my home).

With DSVPN an Arp -a doesn't show any clients on my home network, but I can VNC to my RaspberryPi if I use the local IP that I fetch directly from the Pi.

So the network does seem to work, and seemingly is secure, I was wondering if you could help me understand how I might get devices like the Time Capsule to show under Network in finder? or maybe explain if this isn't possible due to how simple DSVPN is?

Is there a caveat with regard to connectivity or security when compared with OpenVPN? (assuming XooDoo is safe) I guess not?

Weird behaviour when connecting from domestic internet service

I love DSVPN, it's a really handy and lightweight tool.

It works well when connect from a public internet point (generally using 172. or 10. local addresses).

However over the Christmas I was trying too use it from a more regular domestic setup (192.) back to my regular setup domestic network (also 192.) it doesn't work.

I can connect successfully, however when trying to access my routers web config page on 192.168.0.1, I instead end up loading the router web config page locally.

I guess it's because both my router and the local router are both 192.168.0.1, however I noticed I can't access any other devices on my home network either.

Is this expected behaviour?

Unable to load the key file

I'm not sure what I am missing here:

root@server:~/dsvpn/src# dd if=/dev/urandom of=vpn.key count=1 bs=32
1+0 records in
1+0 records out
32 bytes copied, 0.000321688 s, 99.5 kB/s
root@server:~/dsvpn/src# ./dsvpn server auto vpn.key 192.168.192.254 192.168.192.1 auto 443 eth0 auto
Unable to load the key file [vpn.key]
root@server:~/dsvpn/src# stat vpn.key
  File: vpn.key
  Size: 32        	Blocks: 8          IO Block: 4096   regular file
Device: fe01h/65025d	Inode: 133976      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-07-17 20:22:18.102941000 +0000
Modify: 2019-07-17 20:23:02.838941000 +0000
Change: 2019-07-17 20:23:02.838941000 +0000
 Birth: -

I have the same issue on macOS. Since argv[3] is correctly set, I assume the issue is elsewhere (safe_read() maybe?)

Client-Server connectivity only

Running commit 8ffd8e1. At work, I can connect to server, and communication between server and client (running macOS Mojave) works, but Internet access is lost. Work setup might not be the best to test this, so will try from home and report the behaviour.

A way to connect to the server through a specific interface?

I have a client with 2 interfaces and 2 different IPs. I want to create a tunnel for a specific interface only, so I would like that all the traffic that goes through this tunnel is done along this specific interface.

Is there any way I can do that?

Reconnection does not appear to work on Linux

I love this program. This seems to be unexpected behavior.

My setup: Laptop - network from an external device
dsvpn runs on my laptop.

After I unplug my network, I get

Unable to write data to the TCP socket: Resource temporarily unavailable

Then, a loop.

Trying to reconnect
Command [ip route show default 2>/dev/null|awk '/default/{print $3}'] failed]
Connecting to $THE_IP:$THE_PORT...
Client connection failed: Connection timed out

Rinse and repeat until I plug the network back in. At that point, I wait until the Connection timed out, and then saw:

Trying to reconnect
Connecting to $THE_IP:$THE_PORT...

I waited for over a minute without a connection being made.

Then I control C twice, and rerun the program. It connects quickly without complaint, perfectly.

Interface: [tun0]
Trying to reconnect
Connecting to $THE_IP:$THE_PORT...
net.ipv4.tcp_congestion_control = bbr
Connected

Ideal behavior: at least after the connection attempt doomed to fail finally fails, the connection would succeed. I appreciate the unnecessary added complexity of reconnecting the moment it is possible, and wish only for an eventual link.

Thank you for this!

No connectivity

Server: FreeBSD
Client : Mac (darwin)

The client says connected:
Interface: [utun3]
Trying to reconnect
Connecting to X.X.X.X:8080...
add host X.X.X.X: gateway 192.168.1.1
add net 0: gateway 192.168.192.254
add net 128: gateway 192.168.192.254
add net 0000::/1: gateway 64:ff9b::192.168.192.254
add net 8000::/1: gateway 64:ff9b::192.168.192.254
Connected

However in the server log it says:
net.inet.ip.forwarding: 1 -> 1
Authentication failed
Accepting a new client failed: Permission denied

I can ping/ssh to the server on the local int (192.168.192.254)

However, nothing else is working (8.8.8.8, 1.1.1.1 etc etc)

No firewall on server, and no firewall on my mac.

Any ideas ?

make install patch

Hello,

My first attempt at a make install, so I'm not even submitting a pull request for this.

diff --git a/Makefile b/Makefile
index 1206e0e..a272283 100644
--- a/Makefile
+++ b/Makefile
@@ -8,3 +8,6 @@ dsvpn: Makefile src/vpn.c src/charm.c src/os.c include/charm.h include/vpn.h inc
 
 clean:
        rm -f dsvpn *~
+
+install: dsvpn
+       cp dsvpn /usr/local/sbin

Wired connection is connecting to VPS, but unable to get outside.

I have set up a VPS with DSVPN running as server. I can connect with our wired no problem, but I am not getting out from VPS. If I switch to my 4G-connection through my phone with wifi, I can connect and get internet just fine with DSVPN.

I will paste some information I think is relevant. If someone spots something, or need more information, let me know and I will paste more. Please and thank you.

Wired connection without VPN:

➜  ~ ifconfig
enp0s25: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.111.0.85  netmask 255.255.0.0  broadcast 10.111.255.255
        inet6 fe80::9f6:3b4:49dc:47e0  prefixlen 64  scopeid 0x20<link>
        ether 34:e6:d7:50:52:27  txqueuelen 1000  (Ethernet)
        RX packets 285  bytes 83017 (83.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 93  bytes 23727 (23.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 20  memory 0xe2e00000-e2e20000  

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 178  bytes 13978 (13.9 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 178  bytes 13978 (13.9 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

➜  ~ ip r
default via 10.111.0.1 dev enp0s25 proto dhcp metric 100 
10.111.0.0/16 dev enp0s25 proto kernel scope link src 10.111.0.85 metric 100 
169.254.0.0/16 dev enp0s25 scope link metric 1000 

➜  ~ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.111.0.1      0.0.0.0         UG    100    0        0 enp0s25
10.111.0.0      0.0.0.0         255.255.0.0     U     100    0        0 enp0s25
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 enp0s25

Wired connection with VPN:

➜  ~ ifconfig
enp0s25: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.111.0.85  netmask 255.255.0.0  broadcast 10.111.255.255
        inet6 fe80::9f6:3b4:49dc:47e0  prefixlen 64  scopeid 0x20<link>
        ether 34:e6:d7:50:52:27  txqueuelen 1000  (Ethernet)
        RX packets 59693  bytes 12117992 (12.1 MB)
        RX errors 0  dropped 481  overruns 0  frame 0
        TX packets 7546  bytes 1530621 (1.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 20  memory 0xe2e00000-e2e20000

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 12057  bytes 1102304 (1.1 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12057  bytes 1102304 (1.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 9000
        inet 192.168.192.1  netmask 255.255.255.255  destination 192.168.192.254
        inet6 64:ff9b::c0a8:c001  prefixlen 96  scopeid 0x0<global>
        inet6 fe80::8b89:cd0d:b297:bfeb  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
        RX packets 1  bytes 48 (48.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 149  bytes 23164 (23.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

➜  ~ ip r
default via 10.111.0.1 dev enp0s25 proto dhcp metric 100
10.111.0.0/16 dev enp0s25 proto kernel scope link src 10.111.0.85 metric 100
169.254.0.0/16 dev enp0s25 scope link metric 1000
192.168.192.254 dev tun0 proto kernel scope link src 192.168.192.1 

➜  ~ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.111.0.1      0.0.0.0         UG    100    0        0 enp0s25
10.111.0.0      0.0.0.0         255.255.0.0     U     100    0        0 enp0s25
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 enp0s25
192.168.192.254 0.0.0.0         255.255.255.255 UH    0      0        0 tun0

How do you like shadowsocks-libev?

What's the differences between dsvpn and shadowsocks-libev? It works over TCP, doesn't require a lot of configuration, and is "for embedded devices and low-end boxes".

I'm asking this because I'm considering replacing shadowsocks with dsvpn. Yeah I know you provide no guarantees, but its minimalistic design really got me, and a smaller code base generally means more hackability. In case it's relevant, I use ss to bypass the censorship of GFW, and ss is the go-to choice for most people for this purpose.

I'm connected but can't ping anything

Hi, i don't know why but I can't make it work
On the server sudo dsvpn server /home/roman/vpn.key auto 4000
On the client sudo dsvpn client Bureau/vpn.key theip 4000
The output on the client :

Interface: [tun0]
Trying to reconnect
Connecting to theip:4000...
net.ipv4.tcp_congestion_control = bbr
Connected

The output on the server :

Interface: [tun1]
net.ipv4.ip_forward = 1
Listening to *:4000
Accepting new client from [myip]
Accepted

The route that get added is 192.168.10.0/24 dev eno1 proto kernel scope link src 192.168.10.99 metric 100
On this post it is 0.0.0.0/1 via 192.168.192.254 dev tun0
Thanks

cdn support

If you want to use a CDN service, such as Cloudflare. The request needs to be disguised as an HTTP request. for example:

client exchange key request:

GET / HTTP/1.1\r\n
Host: example.com\r\n
User-Agent: foobar/1.0\r\n
Upgrade: websocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Key: base64-key\r\n\r\n

server exchange key response:

HTTP/1.1 101 Switching Protocols\r\n
Server: nginx/1.0\r\n
Date: Mon, 11 Nov 2019 12:48:23 GMT\r\n
Upgrade: websocket\r\n
Connection: Upgrade\r\n
Sec-WebSocket-Accept: base64-key\r\n\r\n

What about TINC?

In the README.md you note a few vpn servers & clients but I do not hear you about tinc, is there a reason for that? Because it is possible to use TCPOnly = yes and set the port to the desired port you want. It is ofc a little bit bigger: 488K but I do not see you mention tinc and I was wondering why?

Would you consider making releases?

I'd like to see about getting this into homebrew. I think it meets most of the acceptable requirements, but probably needs a fixed release. You've recently added a version number, but it's not bound to any specific source code base. An alternative is to simply tag git commits with the version.

Thanks.

on centos7.6, when run client, all the network lost connection

when I run the dsvpn client on the centos7.6, it show create tun0 port, and then lost all the network connection. Even if I restart the network service , but it can not connect the normal network, so I have to reboot the system.
Is there some condtion need to run the client?

probable congestion issue with virtual machines ?

Hi,

Disclaimer: I am not sure if this is a congestion issue.

Problem: The dsvpn-client VM network traffic seems frozen. tcpdump & ping do not show any traffic in tun0 device or eth0. Although if you leave ping for a long time open .. at some point will return a package with huge delay.

dsvpn: release v0.1.0

  • Server: Ubuntu 18.04.2 LTS (VPS - hetzer)

  • Client: Ubuntu 18.04.2 LTS (Virtual Machine - qemu/kvm)

  • dsvpn server /root/dsvpn.key auto 443 auto 10.8.0.254 10.8.0.2

  • dsvpn client /root/dsvpn.key <server_ip> 443 auto 10.8.0.2 10.8.0.254

Client <--> Server, successfully connected.

To reduce any possible iptable misconfiguration, default policies are ACCEPT in dsvpn-server, dsvpn-client & host of vm (archlinux). I have also made tests by using the auto setting in dsvpn (without using 10.8.0.0/24), same result.

I can not ping the dsvpn-client from the dsvpn-server when this happens and vice-verse.

Before

# sysctl net.core.default_qdisc
net.core.default_qdisc = fq_codel

# sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = cubic

# sysctl net.ipv4.tcp_notsent_lowat
net.ipv4.tcp_notsent_lowat = 4294967295

After

# sysctl net.core.default_qdisc
net.core.default_qdisc = fq_codel

# sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = bbr

# sysctl net.ipv4.tcp_notsent_lowat
net.ipv4.tcp_notsent_lowat = 4294967295

For testing I am using this file from a fixed location:

curl -O ftp://speedtest:[email protected]/test100Mb.db

Even when I stop curl, I still can not ping the dsvpn-server. I need to restart the connection. The download of the test file is just an example, the same exact thing happens if you just keep a running ping (icmp) to the dsvpn-server but takes more time. I also tested by running a dig +trace +tcp google.com. Same result.

I have an exact copy of this dsvpn-client VM that runs opevpn over TCP but I do not see any problem there. Actually the dsvpn-client VM is a clone of the openvpn VM.

What I have already tried,

  • Change MTU from 9000 to 1400 in both dsvpn-server & dsvpn-client
  • Change net.ipv4.tcp_congestion_control to previous settings
  • Change net.ipv4.tcp_notsent_lowat . Lowering this value will froze EVERY connection - had to reset VMs

When using my host machine (archlinux) with the same dsvpn binary & dsvpn,key, everything works as advertised.

Due to the libvird iptables rules, I can even ping dsvpn-server from the dsvpn client VM, without opening the connection. Traffic goes through host. The above test with curl was 1201k when using dsvpn-client in my host and not in the VM.

I am attaching a screenshot that explains what is the problem.

image

Any advice would be appreciated,
thanks

-ebal

connect two clients through a public server

Hi many thx for this i'm using dsvpn at work and it's soo easy to setup that i'd like to use it anywhere. :)
I wonder which are the steps I have to take in order to do this:

  • client A (at home) connects to public server Z (hosted at for ex. scaleway)
  • client B (at sea house) connects to public server Z (as above)
    ... missing steps ...
  • client A and B can "see" each other.

I want to send small messages (mqtt which i know how to setup) between A to B
Is it possible?

I don't want to waste your time, if this is out of scope or totally lame feel free to close this issue.

Can I use this over Wireguard, and just tunnel UDP traffic over it?

Using Wireguard for a redundant setup right now (all packets get duplicated) basically my whole internet goes through it. But for reasons (Proper packet sequence, packet order, out of order) i want to tunnel my network-wide udp packets over DSVPN that runs over the wireguard tunnel.

So basically Internal network UDP packets -> DSVPN -> Wireguard -> DSVPN -> UDP.

How does dsvpn work with routes, you describe that it works out of the box so it already touches routes and stuff itself?

Edit: Mhh, If NO_DEFAULT_ROUTES has been defined, default routes will not be installed. Guess that helps!

Doesn't compile on Ubuntu 14.04

FYI: Doesn't build on this amd64 Ubuntu 14.04 VPS (EOL April 2022, not 2019 it seems)

I don't expect a fix but maybe worth mentioning some sort of minimal whatever it is... Kernel version probably?

% make
cc -march=native -Ofast -Wall -W -Wshadow -Wmissing-prototypes  -Iinclude -o dsvpn src/vpn.c src/charm.c src/os.c
src/charm.c: In function ‘uc_randombytes_buf’:
src/charm.c:329:26: error: ‘SYS_getrandom’ undeclared (first use in this function)
     if ((size_t) syscall(SYS_getrandom, buf, (int) len, 0) != len) {
                          ^
src/charm.c:329:26: note: each undeclared identifier is reported only once for each function it appears in
make: *** [dsvpn] Error 1
% uname -a
Linux xyz 2.6.32-042stab127.2 #1 SMP Thu Jan 4 16:41:44 MSK 2018 x86_64 x86_64 x86_64 GNU/Linux

% lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 14.04.6 LTS
Release:	14.04
Codename:	trusty

compatibility with Asuswrt-Merlin

hi,

I was trying to compile dsvpn on my router (Asuswrt-Merlin, 384.14_2) and it does not contain any linux headers and SYS_getrandom is not defined in headers of GCC either which is installed by opkg (package manager on Asuswrt-Merlin). So I need to define it manually:

opkg install gcc
make CC=gcc OPTFLAGS="-DSYS_getrandom=278"

Maybe we can define it if the arch is arm64, like this:

+++ b/src/charm.c
@@ -328,6 +328,9 @@ void uc_memzero(void *buf, size_t len)
 void uc_randombytes_buf(void *buf, size_t len)
 {
 #ifdef __linux__
+#if defined(__aarch64__) && !defined(SYS_getrandom)
+#define SYS_getrandom 278
+#endif
     if ((size_t) syscall(SYS_getrandom, buf, (int) len, 0) != len) {
         abort();
     }

What do you think?

Details of crypto

I don't see any reference on which crypto is used and for which type of attacks is strong against.

DsVPN as a client crashes Gnome

I'm experimenting with dsvpn 0.1.3 on different systems, a laptop and a desktop computer. Usually on Arch Linux with (currently) Gnome 3.34 as desktop environment. Inside a bridged virtualbox I run Ubuntu 19.04 as a control.

I can run dsvpn on both systems with Arch Linux as a server without a problem. The server starts up, and it can receive connections. When I use the Ubuntu-VM as a client, the connection is stable. The problem starts with both Gnome systems.

After a short moment both systems crash completely. Mouse and keyboard don't work anymore. The systems don't answer ssh logins or pings. On the laptop (Dell XPS 15 9570) the caps lock led starts flashing. I have to pull the plug to restart the systems. I'm not sure, what's going on there.

charm selftests

Hi,

Wireguard used to have a selftest that would run on loading the kernel module. It would basically run the crypto primitive a few times to make sure it satisfies a KAT (Known-Answer-Test).

I would like to see the same with dsvpn+charm.

Is this something you would be amenable to? I feel like there's not much enthusiasm for self tests. For example cryptographer software engineer Colin Percival made a diasastrous bug where he removed a line incrementing nonce during a refactor and it was caught by code review. A noisy failure would've been a better choice and this is exactly the type of protection a crypto self test would afford.

I recommend a crypto selftest running for every invocation of dsvpn, usage screen, etc. It is essentially an initialisation assertion.

Is this something you would be amenable to? If so, would you want the feature first implemented in charm and then brought into dsvpn through upstream merge? I'm happy to write the code and figure out the niggly details.

I just want dsvpn to have high assurance and a bit of sensible paranoia :).

GFW certificated

very nice little program, tested server on Debian10 and client on macOS, worked great, it even adds routes and MASQUERADE automatically!

but it is already GFW (you may heard of it, if not, it stands for Great Fire Wall) certificated, several mins later, disconnected and not able to connect again. Anyway, thanks for this great program.

How can I connect a smart TV client to the DSVPN server

First of all thanks for creating this awesome piece of software! It works great! 👍 ❤️

I want to connect my Samsung Smart TV to the VPN server but not sure what's a good way to do it. I cannot install custom software/client on the TV to be able to connect. It does however allow me to change the network settings and set up a custom DNS server for the TV. Can I somehow use that to route the traffic via VPN server?

One possibility is create a hotspot and then route the traffic through some other device's client, but I would like to avoid the extra hop if it's possible. I have a couple of questions:

  1. Is there a way to skip authentication on the server side (without shared key) but only allow traffic from specific IP (or IPs)
  2. Can I somehow use the TV DNS settings to connect to the VPN server

Early users: something to try

Hi early users :)

If you have some minutes to spare, could you try something?

In src/charm.c, just for the test, change

#define ROUNDS 12

to

#define ROUNDS 1

Now, in include/vpn.h, try to change

#define BUFFERBLOAT_CONTROL 0

to

#define BUFFERBLOAT_CONTROL 1

And report which setting give you better speed and/or latency.

You can also try to tweak NOTSENT_LOWAT and DEFAULT_MTU a little bit.

Results may vary a lot according to what kind of connection you have.

Different endianness causing "Authentication failed"

I got bunch of Authentication failed when trying to transfer the secret key between the server and the client. After some investigation, I figured out that the machines have difference endianness.

On OpenBSD host

bash-5.0$ hexdump vpn.key
0000000    af1c    d078    16e9    5a70    9992    e795    0d09    ea70
0000010    5038    9931    7db4    049a    0385    a78e    7f32    7c97
0000020

On macOS client

$ hexdump vpn.key
0000000 1c af 78 d0 e9 16 70 5a 92 99 95 e7 09 0d 70 ea
0000010 38 50 31 99 b4 7d 9a 04 85 03 8e a7 32 7f 97 7c
0000020

Any thoughts?

Illegal instruction error when executing on RaspberryPi Zero

Hello,

On PiZero (armv61), it compiles fine but fails during server execution:

$ env OPTFLAGS=-mfpu=neon make
cc -march=native -Ofast -Wall -W -Wshadow -Wmissing-prototypes -mfpu=neon -Iinclude -o dsvpn src/vpn.c src/charm.c src/os.c
strip dsvpn

I tried with different parameters (default port etc) but I get the same error:

$ sudo ./dsvpn server vpn.key auto 1959
Illegal instruction

Thanks,
IO.

It's perfect, but doesn't work

Compiled OK, started, listening on port but when connection attempt is made from client, it just sayin "Aborted" and server is no longer working.

Client: MacOS 10.14.5
Connecting to xxx.xxx.xxx.xxx:1959...
Client connection failed: Connection refused

Server: Lunux Debian
dsvpn# ./dsvpn server vpn.key auto 1959
Interface: [tun0]
net.ipv4.ip_forward = 1
RTNETLINK answers: Invalid argument
Listening to *:1959
Accepting new client from [yyy.yyy.yyy.yyy]
Aborted

OpenBSD server?

Hello @jedisct1,

Thanks for spending your weekend writing dsvpn. No doubt that your efforts will help many people with their VPN needs.

I'm really happy to see that your README mentions using dsvpn on OpenBSD - my preferred operating system. It was a big surprise to say the least.

I was wondering if you would consider writing code for dsvpn to run on OpenBSD as a server. Everybody knows about WireGuard and its userspace implementation using golang, but that won't work on arm64 devices, like the nanopi, pine64, raspberry pi - at least on OpenBSD. Yes, there is iked in base but that is UDP, which is why you wrote dsvpn in the first place.

Thanks for any consideration!

Best,
j.b.

Would you consider support for client mobility?

So wireguard supports client mobility - it's actually easy in the wireguard land because it's all UDP.

In TCP land it's a bit more difficult.

The simplest possible scenario I can think of is simply accepting multiple connections, and broadcasting all packets that are received from other networks back to the client connections.

Probably a more reliable approach is to probably prenegotiate some cookie that identifies the vpn connection and it's associated packets, and when a new connection comes in and sends the cookie over, all new packets come back to the newly established client.

In both the above, I guess there'd be some need to have some reconnection system since a transition from one network to another, I think, should close the sockets.

armv8 support

Howdy,

It would be great if ARMv8 support was added:

cc -march=native -Ofast -Wall -W -Wshadow -Wmissing-prototypes  -Iinclude -o dsvpn src/vpn.c src/charm.c src/os.c
cc1: error: unknown value 'armv8-a-march=armv8-a' for -march
cc1: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a native
cc1: error: unknown value 'armv8-a-march=armv8-a' for -march
cc1: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a native
cc1: error: unknown value 'armv8-a-march=armv8-a' for -march
cc1: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a native
make: *** [Makefile:6: dsvpn] Error 1

Thanks,
Jason

Ability to save to a configuration file, etc.

Will it be possible to add the ability to save all settings to a configuration file? That way we could simply call dsvpn --config /path/to/config on both, server and client—this is in addition of being able to use it as it is done today.

Along the line to make it simpler, would it be possible to autodetect the external gateway, and interface, so they don't have to be entered?

Handle firewall cleanup

I noticed that when exiting the VPN, the firewall rules and routing modifications aren't removed.

I wanted to make a PR for this, my idea was to catch SIGINT with signal() and then call a del_firewall_rules() function. However I'd need to pass a pointer to context to this function and I can't to this with signal (unless the variable is global).

I'm not very experienced with C so I guess you will know how to do it properly!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.