Decentralized VPN in golang

LCVPN - Light decentralized VPN in golang

Originally this repo was just an answer on a question "how much time it'll take to write my own simple VPN in golang" (answer is about 3 hours for first prototype), but now it used in production in different environments.

So, LCVPN is

  • Very light and easy (one similar config on all hosts)
  • Use same config for all hosts (autedetect local params) - useful with puppet etc
  • Uses AES-128, AES-192 or AES-256 encryption (note that AES-256 is much slower than AES-128 on most computers) + optional HMAC-SHA256 or (super secure! 😅 ) NONE encryption (just copy without modification)
  • Communicates via UDP directly to selected host (no central server)
  • Works only on Linux (uses TUN device)
  • Support of basic routing - can be used to connect several networks
  • Multithread send and receive - scaleable for big traffc
  • Due to use so_reuseport better result in case of bigger number of hosts
  • It's still in beta stage, use it on your own risk (and please use only versions marked as "release")

alt tag

Install and run

You need golang (at least 1.5) installed and configured:

$ go get -u github.com/kanocz/lcvpn

if you have config in /etc/lcvpn.conf

$ sudo $GOPATH/bin/lcvpn

if you want to specify different location of config (or if you need to run several instances)

$ sudo $GOPATH/bin/lcvpn -config lcvpn.conf

if you host is hidden behind firewall (with udp port forward) lcvpn is unable to detect which "remote" is localhost. In this case use next syntax:

$ sudo $GOPATH/bin/lcvpn -local berlin -config lcvpn.conf

Config example

[main]
port = 23456
encryption = aescbc
mainkey = 4A34E352D7C32FC42F1CEB0CAA54D40E9D1EEDAF14EBCBCECA429E1B2EF72D21
altkey = 1111111117C32FC42F1CEB0CAA54D40E9D1EEDAF14EBCBCECA429E1B2EF72D21
broadcast = 192.168.3.255
netcidr = 24
recvThreads = 4
sendThreads = 4

[remote "prague"]
ExtIP = 46.234.105.229
LocIP = 192.168.3.15
route = 192.168.10.0/24
route = 192.168.15.0/24
route = 192.168.20.0/24

[remote "berlin"]
ExtIP = 103.224.182.245
LocIP = 192.168.3.8
route = 192.168.11.0/24

[remote "kiev"]
ExtIP = 95.168.211.37
LocIP = 192.168.3.3

where port is UDP port for communication
encryption is aescbc for AES-CBC, aescbchmac for AES-CBC+HMAC-SHA245 or none for no encryption
for aescbc mainkey/altkey is hex form of 16, 24 or 32 bytes key (for AES-128, AES-192 or AES-256)
for aescbchmac mainkey/altkey is 32 bytes longer for none mainkey/altkey mainkey/altkey is just ignored number of remotes is virtualy unlimited, each takes about 256 bytes in memory

Config reload

Config is reloaded on HUP signal. In case of invalid config just log message will appeared, previous one is used.
P.S.: listening udp socket is not reopened for now, so on port change restart is needed

Online key change

altkey configuration option allows specify alternative encryption key that will be used in case if decription with primary one failed. This allow to use next algoritm to change keys without link going offline:

  • In normal state only mainkey is set (setting altkey is more cpu-consuming)
  • Set altkey to new key on all hosts and send HUP signal
  • Exchange altkey and aeskey on all hosts and send HUP signal
  • Remove altkey (with old key) from configs on all hosts and send HUP signal again
  • We are running with new key :)

Roadmap

  • 100% unit test coverage
  • please let me know if you need anything more
Owner
Comments
  • UDP NAT hole punching

    UDP NAT hole punching

    It will be awesome if you use stun server tu bypass NAT's

    and other awesome option will be to support dynamicIP nodes.

    in Europe lot of ISP provide a dynamicIP to their clients. This is not a problem if you connect to a static public IP node like cloud providers but if we want real P2P Vpn we need to conect to all nodes, lot of these nodes can change their public IP after 1day-week so lcvpn could be resilent to that, something like check every X seconds if the ip is the same if not publish the ip to other nodes using a K/V(there are some public services on internet)

  • how service side send out the ip packets to target server

    how service side send out the ip packets to target server

    I notice you just write ip packets into the tun device after decryption, is that data will go to the LAN?

    in my test case code, the icmp request packet disappered after writtrn to tun

  • Error: Unable to get UDP socket: unknown port udp/

    Error: Unable to get UDP socket: unknown port udp/

    Hello. I've got error: "Unable to get UDP socket: unknown port udp/"

    Machine: virtualbox ip: 192.168.1.50 conf: [main] port = 1234 aeskey = A3E8DD8E33C0887C6A86EF47AF6B008C00508B00FA18666658EBB2805D2BFF48

    altkey = 1111111117C32FC42F1CEB0CAA54D40E9D1EEDAF14EBCBCECA429E1B2EF72D21

    broadcast = 10.0.0.255 netcidr = 24 recvThreads = 4 sendThreads = 4

    [remote "phy1.dc1"] ExtIP = 192.168.1.50 LocIP = 10.0.0.1

    Start: /home/golang/bin/lcvpn -config /etc/lcvpn.conf -local phy1.dc1

    Error: 2016/04/29 14:29:08 Interface allocated: tun0 2016/04/29 14:29:08 Interface parameters configured 2016/04/29 14:29:08 Unable to get UDP socket: unknown port udp/

    It appears after update host kernel to 4.4.0-21-generic.

    I've tried to change port to another - same errror. Any ideas how to fix it?

  • slow performance

    slow performance

    iperf on direct connection got 900mbps (1ms) with lcvpn 500mbps

    iperf over internet 600mbps stables between 2 servers(50ms) with lcvpn 30mbps

    Why this diference?

  • license mit/bsd

    license mit/bsd

    The lcvpn project looks quite interesting, thank you. I would like experiment with it.

    Would you consider changing the license to MIT or BSD (like Go)?

  • [Question] support for same subnet

    [Question] support for same subnet

    Hi may I ask if the vpn supports VMs within same subnet but across different locations, as shown below:

    can I only install the VPN on the 2 servers itself then route packet for all 4 VMs in the 2 servers?

    image

    [main] port = 23456 broadcast = 192.168.2.255 netcidr = 24 recvThreads = 4 sendThreads = 4

    [remote "prague"] ExtIP = 10.0.0.2 LocIP = 192.168.2.2 route = 192.168.2.0/24

    [remote "berlin"] ExtIP = 10.0.0.3 LocIP = 192.168.2.1 route = 192.168.2.0/24

  • Lcvpn unexpectedly dying

    Lcvpn unexpectedly dying

    Hello. This is me again =) My lcvpn goes down, when VM containers trying to connect through it. Thi is log:

    May 20 18:49:25 phy1 lcvpn[32531]: panic: runtime error: slice bounds out of range
    May 20 18:49:25 phy1 lcvpn[32531]: goroutine 21 [running]:
    May 20 18:49:25 phy1 lcvpn[32531]: panic(0x788de0, 0xc82000e050)
    May 20 18:49:25 phy1 lcvpn[32531]: #011/usr/local/go/src/runtime/panic.go:464 +0x3e6
    May 20 18:49:25 phy1 lcvpn[32531]: main.sndrThread(0xc82001e050, 0xc8200519e0)
    May 20 18:49:25 phy1 lcvpn[32531]: #011/home/golang/src/github.com/kanocz/lcvpn/main.go:180 +0x192e
    May 20 18:49:25 phy1 lcvpn[32531]: created by main.main
    May 20 18:49:25 phy1 lcvpn[32531]: #011/home/golang/src/github.com/kanocz/lcvpn/main.go:324 +0x1384
    May 20 18:49:25 phy1 systemd[1]: lcvpn.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
    May 20 18:49:25 phy1 systemd[1]: lcvpn.service: Unit entered failed state.
    May 20 18:49:25 phy1 systemd[1]: lcvpn.service: Failed with result 'exit-code'.
    
  • connect through firewall (no port forwarding)

    connect through firewall (no port forwarding)

    Hey,

    can two servers connect to each other, if server 1 can contact server 2 but not the other way around due to firewall restrictions / missing port forwarding?

    As Server 1 connects to Server 2, Server 2 should not need to connect to Server 1 anymore right (even tho it can't)?

    I tried to set it up but i failed. No connection established between both hosts.

  • encounter error on mac os x

    encounter error on mac os x

    hi. after i ran "go get -u -v github.com/kanocz/lcvpn" under $GOPATH, it shows: ...

    github.com/kanocz/lcvpn

    src/github.com/kanocz/lcvpn/iface.go:26:16: undefined: water.NewTUN src/github.com/kanocz/lcvpn/iface.go:35:15: undefined: tenus.NewLinkFrom src/github.com/kanocz/lcvpn/iface.go:89:11: undefined: "github.com/kanocz/lcvpn/netlink".DelRoute yudeMacBook-Air:gopath brite$

    how to fix the errors?

  • It can be use for my scene?

    It can be use for my scene?

    Hi,

    I have a scene that i need solve with VPN. My home raspberry need connect to my VPN on amazon and my customers need connect their pc/ios/android devices to that same VPN on amazon to access to raspberry.

    How i can do it with this tool?

    Thanks.

  • Create Dockerfile

    Create Dockerfile

    I created the lcvpn docker to build & run

    docker build  -t segator/lcvpn .
    docker run -d --name lcvpn  -v /my/lcvpn.conf:/config/lcvpn.conf  -p 25001:25001/udp segator/lcvp
    
Related tags
⛵ EdgeVPN: the immutable, decentralized, statically built VPN. NO central server!

⛵ EdgeVPN Fully Decentralized. Immutable. Portable. Easy to use Statically compiled VPN Usage Generate a config: ./edgevpn -g > config.yaml Run it on

Jan 3, 2023
SonicWall VPN-SSL Exploit* using Golang
SonicWall VPN-SSL Exploit* using Golang

goshock SonicWall VPN-SSL Exploit* using Golang ( * and other targets vulnerable to shellshock ).

Jul 6, 2022
A fork of the simple WireGuard VPN server GUI community maintained
A fork of the simple WireGuard VPN server GUI community maintained

Subspace - A simple WireGuard VPN server GUI Subspace - A simple WireGuard VPN server GUI Slack Screenshots Features Contributing Setup 1. Get a serve

Dec 25, 2022
Smart VPN client

Smart VPN client Performs all the standard functions of a VPN client, i.e. manages a connection to a VPN headend. The "smart" functionality includes:

Sep 2, 2022
Standalone client for proxies of Opera VPN

opera-proxy Standalone Opera VPN client. Younger brother of hola-proxy. Just run it and it'll start a plain HTTP proxy server forwarding traffic throu

Jan 9, 2023
SplitVPN - Split Internet and VPN routing

SplitVPN - Split Internet and VPN routing

Jul 15, 2022
A Lightweight VPN Built on top of Libp2p for Truly Distributed Networks.
A Lightweight VPN Built on top of Libp2p for Truly Distributed Networks.

Hyprspace A Lightweight VPN Built on top of Libp2p for Truly Distributed Networks. demo.mp4 Table of Contents A Bit of Backstory Use Cases A Digital N

Dec 29, 2022
A Wireguard VPN Server Manager and API to add and remove clients

Wireguard Manager And API A manager and API to add, remove clients as well as other features such as an auto reapplier which deletes and adds back a c

Dec 22, 2022
Terraform Provider for Pritunl VPN Server
 Terraform Provider for Pritunl VPN Server

Terraform Provider for Pritunl VPN Server Website: https://www.terraform.io Pritunl VPN Server: https://pritunl.com/ Provider: disc/pritunl Requiremen

Dec 24, 2022
CLI to drive SAML based auth for Global Protect VPN

GlobalProtect VPN Helper This tool is a CLI friendly tool used to perform POST based SAML authentication for GlobalProtect VPN. It displays a browser

Aug 28, 2022
A VPN Proxy Helper

VPN Proxy Helper Sometimes, VPN clients do not change the routing table of the computer but it still exists the VPN interface. Sometimes, you don't wa

Aug 19, 2022
IP2Proxy Go package allows users to query an IP address to determine if it was being used as open proxy, web proxy, VPN anonymizer and TOR exits.

IP2Proxy Go Package This package allows user to query an IP address if it was being used as VPN anonymizer, open proxies, web proxies, Tor exits, data

Sep 15, 2022
A memory-safe SSH server, focused on listening only on VPN networks such as Tailscale

Features Is tested to work with SCP Integrates well with systemd Quickstart Download binary for your architecture. We only support Linux. If you don't

Jun 10, 2022
KeeneticRouteToVpn is simple app updating Keenetic Router rules for some hosts to go through VPN interface.

KeeneticRouteToVpn KeeneticRouteToVpn is simple app updating Keenetic Router rules for some hosts to go through VPN interface. It has defaults values

Oct 8, 2022
Renloi: a decentralized finance network for golang

Intro to Renloi A digital decentralized version of cash will allow extremely fas

Jun 9, 2022
Hummingbard is an experimental client for building decentralized communities on top of Matrix.

Hummingbard is an experimental client for building decentralized communities on top of Matrix.

Oct 11, 2022
A decentralized P2P networking stack written in Go.

noise noise is an opinionated, easy-to-use P2P network stack for decentralized applications, and cryptographic protocols written in Go. noise is made

Dec 29, 2022
Decentralized Chat ( 去中心化的聊天系统 )

dchat Introduce dchat (Decentralized Chat) 一款去中心化的聊天系统。 Features 轻量级 Unix指令交互 去中心化 断线重连 支持集群 分布式ID Start Install go get -u github.com/awesome-cmd/dcha

Jul 2, 2022
A modular is an opinionated, easy-to-use P2P network stack for decentralized applications written in Go.

xlibp2p xlibp2p is an opinionated, easy-to-use P2P network stack for decentralized applications written in Go. xlibp2p is made to be minimal, robust,

Nov 9, 2022