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

VPN improvements #356

Merged
merged 71 commits into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
9221ab3
Add passcode to config generation
Darkren Apr 30, 2020
bf3c651
FUlly add passcode
Darkren Apr 30, 2020
c9ac661
Fix `String` for `HandshakeStatus`
Darkren Apr 30, 2020
8de36e6
Add debug log
Darkren Apr 30, 2020
d5a53b0
Fix passcode passing to the server
Darkren Apr 30, 2020
edddef5
Remove debug log
Darkren Apr 30, 2020
7ffaa13
Make lintr happy
Darkren Apr 30, 2020
9ad76c9
Remove redundant logs
Darkren May 1, 2020
3520b80
Add RPC calls to change passcode and PK for VPN apps
Darkren May 1, 2020
a49778a
Make linter happy
Darkren May 1, 2020
fe810c4
Add `README.md` for VPN client
Darkren May 4, 2020
bffe337
Add `README.md` for VPN server, fix client's one a bit
Darkren May 4, 2020
53deb0a
Make default network gateway detection work via `ip r` for Linux systems
Darkren May 4, 2020
a33d0a0
Fix default network gateway detection
Darkren May 4, 2020
8f6a3f6
Fix it once again
Darkren May 4, 2020
249e20b
Make TUN setup go via `ip` for Linux systems
Darkren May 4, 2020
253ca86
Fix Linux code
Darkren May 4, 2020
460be43
Try to fix
Darkren May 4, 2020
7768f2a
Make all routing be done via 'ip` for Linux systems
Darkren May 4, 2020
446b17b
Remove some duplicate code
Darkren May 4, 2020
1f87aae
Substitute logrus sys log hook with our wrapper
Darkren May 5, 2020
da60cdf
Implement `DefaultNetworkGateway` for Windows
Darkren May 5, 2020
9ec65d2
Finish TUN setup for Windows
Darkren May 6, 2020
37ad9b2
Fix sys log build for Windows
Darkren May 6, 2020
8aac4ea
Merge branch 'feature/vpn-improvements' of https://github.com/Darkren…
Darkren May 6, 2020
ee66dc1
Refactor all os-related funcs
Darkren May 6, 2020
6153391
Fix `DefaultNetworkInterface` for Linux systems
Darkren May 6, 2020
932d4df
Add routing commands for Windows
Darkren May 6, 2020
4f397ae
Merge branch 'feature/vpn-improvements' of https://github.com/Darkren…
Darkren May 6, 2020
1bdbb57
Remove dmsgpty config generation for Windows subsystems
Darkren May 6, 2020
08f6822
Remove dmsgpty references from visor package
Darkren May 6, 2020
20e16a3
Let it be built for Windows systems
Darkren May 6, 2020
3825d18
Fix dmsgpty setup for Windows
Darkren May 6, 2020
18a8c95
Fix it once again
Darkren May 6, 2020
3be46ce
Try to use TAP server side for Windows clients
Darkren May 10, 2020
707b6dd
Fix
Darkren May 10, 2020
d72d3dc
Fix
Darkren May 10, 2020
5df97df
Fix
Darkren May 10, 2020
6f6539a
Fix
Darkren May 10, 2020
ed482b7
Fix
Darkren May 10, 2020
c64169e
Start integrating wintun
Darkren May 12, 2020
6d52894
Udate vendor
Darkren May 12, 2020
eefecd8
Revert testing changes
Darkren May 12, 2020
a34de8f
Finish wintun integration
Darkren May 12, 2020
e8ceecc
Add a bit TODOs
Darkren May 12, 2020
d9db49c
Refactor VPN part
Darkren May 12, 2020
6d72de1
Refactor main CMDs and syslog
Darkren May 13, 2020
3b80055
Refactor hypervisor
Darkren May 13, 2020
24d09ea
Refactor visor
Darkren May 13, 2020
b83cc10
Make linter happy
Darkren May 13, 2020
d19959b
Update vendor
Darkren May 13, 2020
2965a61
Try to integrate noise
Darkren May 13, 2020
98cf951
Add more logging
Darkren May 13, 2020
7256fce
Improve logging
Darkren May 14, 2020
8172ee2
Fix
Darkren May 14, 2020
84630de
Fix
Darkren May 14, 2020
ac33837
Fix
Darkren May 14, 2020
126b36c
Pass PK and SK as binary args
Darkren May 14, 2020
dc69941
Add noise handshake
Darkren May 14, 2020
0376dfb
Refactor encryption
Darkren May 14, 2020
336714a
Merge branch 'develop' of github.com:SkycoinProject/skywire-mainnet i…
Darkren May 18, 2020
ef4516e
Fix VPN envs
Darkren May 18, 2020
ca4d96e
Remove panic
Darkren May 19, 2020
e80813a
Make linter happier
Darkren May 19, 2020
a66b6ef
Add Windows info to README
Darkren May 20, 2020
6b7fe69
Exclude dmsgpty config generation for Windows systems
Darkren May 21, 2020
90a96f4
Disallow socket files removal for Windows systems
Darkren May 21, 2020
7851388
Add an ability to derive PK out of SK for noise creds
Darkren May 21, 2020
46c9f9f
Refactor a bit
Darkren May 21, 2020
dd1966c
Refactor, make VPN server autostart velue false by default
Darkren May 21, 2020
8057e79
Merge branch 'develop' of github.com:SkycoinProject/skywire-mainnet i…
Darkren May 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions cmd/apps/vpn-client/vpn-client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,10 @@ var (
r = netutil.NewRetrier(log, serverDialInitBO, serverDialMaxBO, 0, 1)
)

var serverPKStr = flag.String("srv", "", "PubKey of the server to connect to")

func dialServer(appCl *app.Client, pk cipher.PubKey) (net.Conn, error) {
var conn net.Conn
err := r.Do(context.Background(), func() error {
var err error
conn, err = appCl.Dial(appnet.Addr{
Net: netType,
PubKey: pk,
Port: vpnPort,
})
return err
})
if err != nil {
return nil, err
}

return conn, nil
}
var (
serverPKStr = flag.String("srv", "", "PubKey of the server to connect to")
passcode = flag.String("passcode", "", "Passcode to authenticate connection")
)

func main() {
flag.Parse()
Expand Down Expand Up @@ -96,7 +81,10 @@ func main() {

log.Infof("Dialed %s", appConn.RemoteAddr())

vpnClient, err := vpn.NewClient(log, appConn)
vpnClientCfg := vpn.ClientConfig{
Passcode: *passcode,
}
vpnClient, err := vpn.NewClient(vpnClientCfg, log, appConn)
if err != nil {
log.WithError(err).Fatalln("Error creating VPN client")
}
Expand All @@ -116,3 +104,21 @@ func main() {
log.WithError(err).Fatalln("Error serving VPN")
}
}

func dialServer(appCl *app.Client, pk cipher.PubKey) (net.Conn, error) {
var conn net.Conn
err := r.Do(context.Background(), func() error {
var err error
conn, err = appCl.Dial(appnet.Addr{
Net: netType,
PubKey: pk,
Port: vpnPort,
})
return err
})
if err != nil {
return nil, err
}

return conn, nil
}
12 changes: 11 additions & 1 deletion cmd/apps/vpn-server/vpn-server.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"flag"
"fmt"
"os"
"os/signal"
Expand All @@ -25,7 +26,13 @@ var (
log = app.NewLogger(appName)
)

var (
passcode = flag.String("passcode", "", "Passcode to authenticate connecting users")
)

func main() {
flag.Parse()

appCfg, err := app.ClientConfigFromEnv()
if err != nil {
log.WithError(err).Errorln("Error getting app client config")
Expand Down Expand Up @@ -56,7 +63,10 @@ func main() {

log.Infof("Got app listener, bound to %d", vpnPort)

srv, err := vpn.NewServer(log)
srvCfg := vpn.ServerConfig{
Passcode: *passcode,
}
srv, err := vpn.NewServer(srvCfg, log)
if err != nil {
log.WithError(err).Fatalln("Error creating VPN server")
}
Expand Down
20 changes: 16 additions & 4 deletions cmd/skywire-cli/commands/visor/gen-config.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ func defaultConfig() *visor.Config {
defaultSkychatConfig(),
defaultSkysocksConfig(""),
defaultSkysocksClientConfig(),
defaultVPNServerConfig(),
defaultVPNClientConfig(),
defaultVPNServerConfig(""),
defaultVPNClientConfig(""),
}

conf.TrustedVisors = []cipher.PubKey{}
Expand Down Expand Up @@ -210,18 +210,30 @@ func defaultSkysocksClientConfig() visor.AppConfig {
}
}

func defaultVPNServerConfig() visor.AppConfig {
func defaultVPNServerConfig(passcode string) visor.AppConfig {
var args []string
if passcode != "" {
args = []string{"-passcode", passcode}
}

return visor.AppConfig{
App: skyenv.VPNServerName,
AutoStart: true,
Port: routing.Port(skyenv.VPNServerPort),
Args: args,
}
}

func defaultVPNClientConfig() visor.AppConfig {
func defaultVPNClientConfig(passcode string) visor.AppConfig {
var args []string
if passcode != "" {
args = []string{"-passcode", passcode}
}

return visor.AppConfig{
App: skyenv.VPNClientName,
AutoStart: false,
Port: routing.Port(skyenv.VPNClientPort),
Args: args,
}
}
7 changes: 5 additions & 2 deletions internal/vpn/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (

// Client is a VPN client.
type Client struct {
cfg ClientConfig
log *logging.MasterLogger
conn net.Conn
directIPs []net.IP
Expand All @@ -30,7 +31,7 @@ type Client struct {
}

// NewClient creates VPN client instance.
func NewClient(l *logging.MasterLogger, conn net.Conn) (*Client, error) {
func NewClient(cfg ClientConfig, l *logging.MasterLogger, conn net.Conn) (*Client, error) {
dmsgDiscIP, err := dmsgDiscIPFromEnv()
if err != nil {
return nil, fmt.Errorf("error getting Dmsg discovery IP: %w", err)
Expand Down Expand Up @@ -69,6 +70,7 @@ func NewClient(l *logging.MasterLogger, conn net.Conn) (*Client, error) {
l.Infof("Got default network gateway IP: %s", defaultGateway)

return &Client{
cfg: cfg,
log: l,
conn: conn,
directIPs: directIPs,
Expand All @@ -92,7 +94,7 @@ func (c *Client) Serve() error {
DeviceType: water.TUN,
})
if err != nil {
return fmt.Errorf("error allocating TUN interace: %w", err)
return fmt.Errorf("error allocating TUN interface: %w", err)
}
defer func() {
tunName := tun.Name()
Expand Down Expand Up @@ -275,6 +277,7 @@ func (c *Client) shakeHands() (TUNIP, TUNGateway net.IP, err error) {

cHello := ClientHello{
UnavailablePrivateIPs: unavailableIPs,
Passcode: c.cfg.Passcode,
}

c.log.Debugf("Sending client hello: %v", cHello)
Expand Down
6 changes: 6 additions & 0 deletions internal/vpn/client_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package vpn

// ClientConfig is a configuration for VPN client.
type ClientConfig struct {
Passcode string
}
1 change: 1 addition & 0 deletions internal/vpn/client_hello.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import "net"
// ClientHello is a message sent by client during the Client/Server handshake.
type ClientHello struct {
UnavailablePrivateIPs []net.IP `json:"unavailable_private_ips"`
Passcode string `json:"passcode"`
}
4 changes: 4 additions & 0 deletions internal/vpn/handshake_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const (
HandshakeNoFreeIPs
// HandshakeStatusInternalError is returned in all other cases when some server error occurred.
HandshakeStatusInternalError
// HandshakeStatusForbidden is returned if client had sent the wrong passcode.
HandshakeStatusForbidden
)

func (hs HandshakeStatus) String() string {
Expand All @@ -24,6 +26,8 @@ func (hs HandshakeStatus) String() string {
return "No free IPs left to serve"
case HandshakeStatusInternalError:
return "Internal server error"
case HandshakeStatusForbidden:
return "Forbidden"
default:
return "Unknown code"
}
Expand Down
13 changes: 12 additions & 1 deletion internal/vpn/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

// Server is a VPN server.
type Server struct {
cfg ServerConfig
lisMx sync.Mutex
lis net.Listener
log *logging.MasterLogger
Expand All @@ -24,7 +25,7 @@ type Server struct {
}

// NewServer creates VPN server instance.
func NewServer(l *logging.MasterLogger) (*Server, error) {
func NewServer(cfg ServerConfig, l *logging.MasterLogger) (*Server, error) {
defaultNetworkIfc, err := DefaultNetworkInterface()
if err != nil {
return nil, fmt.Errorf("error getting default network interface: %w", err)
Expand All @@ -45,6 +46,7 @@ func NewServer(l *logging.MasterLogger) (*Server, error) {
l.Infof("IPv4: %s, IPv6: %s", ipv4ForwardingVal, ipv6ForwardingVal)

return &Server{
cfg: cfg,
log: l,
ipGen: NewIPGenerator(),
defaultNetworkInterface: defaultNetworkIfc,
Expand Down Expand Up @@ -199,6 +201,15 @@ func (s *Server) shakeHands(conn net.Conn) (tunIP, tunGateway net.IP, err error)

var sHello ServerHello

if s.cfg.Passcode != "" && cHello.Passcode != s.cfg.Passcode {
sHello.Status = HandshakeStatusForbidden
if err := WriteJSON(conn, &sHello); err != nil {
s.log.WithError(err).Errorln("Error sending server hello")
}

return nil, nil, errors.New("got wrong passcode from client")
}

for _, ip := range cHello.UnavailablePrivateIPs {
if err := s.ipGen.Reserve(ip); err != nil {
// this happens only on malformed IP
Expand Down
6 changes: 6 additions & 0 deletions internal/vpn/server_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package vpn

// ServerConfig is a configuration for VPN server.
type ServerConfig struct {
Passcode string
}
16 changes: 4 additions & 12 deletions pkg/hypervisor/hypervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,22 +395,15 @@ func (hv *Hypervisor) putApp() http.HandlerFunc {
}
}

const (
skysocksName = "skysocks"
skysocksClientName = "skysocks-client"
)

if reqBody.Passcode != nil && ctx.App.App == skysocksName {
if err := ctx.RPC.SetSocksPassword(*reqBody.Passcode); err != nil {
if reqBody.Passcode != nil {
if err := ctx.RPC.SetAppPassword(ctx.App.App, *reqBody.Passcode); err != nil {
httputil.WriteJSON(w, r, http.StatusInternalServerError, err)
return
}
}

if reqBody.PK != nil && ctx.App.App == skysocksClientName {
log.Errorf("SETTING PK: %s", *reqBody.PK)
if err := ctx.RPC.SetSocksClientPK(*reqBody.PK); err != nil {
log.Errorf("ERROR SETTING PK")
if reqBody.PK != nil {
if err := ctx.RPC.SetAppPK(ctx.App.App, *reqBody.PK); err != nil {
httputil.WriteJSON(w, r, http.StatusInternalServerError, err)
return
}
Expand All @@ -425,7 +418,6 @@ func (hv *Hypervisor) putApp() http.HandlerFunc {
}
case statusStart:
if err := ctx.RPC.StartApp(ctx.App.App); err != nil {
log.Errorf("ERROR STARTING APP")
httputil.WriteJSON(w, r, http.StatusInternalServerError, err)
return
}
Expand Down
28 changes: 20 additions & 8 deletions pkg/visor/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,30 @@ func (r *RPC) SetAutoStart(in *SetAutoStartIn, _ *struct{}) (err error) {
return r.visor.setAutoStart(in.AppName, in.AutoStart)
}

// SetSocksPassword sets password for skysocks.
func (r *RPC) SetSocksPassword(in *string, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "SetSocksPassword", in)(nil, &err)
// SetAppPasswordIn is input for SetAppPassword.
type SetAppPasswordIn struct {
AppName string
Password string
}

// SetAppPassword sets password for the app.
func (r *RPC) SetAppPassword(in *SetAppPasswordIn, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "SetAppPassword", in)(nil, &err)

return r.visor.setAppPassword(in.AppName, in.Password)
}

return r.visor.setSocksPassword(*in)
// SetAppPKIn is input for SetAppPK.
type SetAppPKIn struct {
AppName string
PK cipher.PubKey
}

// SetSocksClientPK sets PK for skysocks-client.
func (r *RPC) SetSocksClientPK(in *cipher.PubKey, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "SetSocksClientPK", in)(nil, &err)
// SetAppPK sets PK for the app.
func (r *RPC) SetAppPK(in *SetAppPKIn, _ *struct{}) (err error) {
defer rpcutil.LogCall(r.log, "SetAppPK", in)(nil, &err)

return r.visor.setSocksClientPK(*in)
return r.visor.setAppPK(in.AppName, in.PK)
}

/*
Expand Down
30 changes: 18 additions & 12 deletions pkg/visor/rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ type RPCClient interface {
StartApp(appName string) error
StopApp(appName string) error
SetAutoStart(appName string, autostart bool) error
SetSocksPassword(password string) error
SetSocksClientPK(pk cipher.PubKey) error
SetAppPassword(appName, password string) error
SetAppPK(appName string, pk cipher.PubKey) error
LogsSince(timestamp time.Time, appName string) ([]string, error)

TransportTypes() ([]string, error)
Expand Down Expand Up @@ -157,14 +157,20 @@ func (rc *rpcClient) SetAutoStart(appName string, autostart bool) error {
}, &struct{}{})
}

// SetSocksPassword calls SetSocksPassword.
func (rc *rpcClient) SetSocksPassword(password string) error {
return rc.Call("SetSocksPassword", &password, &struct{}{})
// SetAppPassword calls SetAppPassword.
func (rc *rpcClient) SetAppPassword(appName, password string) error {
return rc.Call("SetAppPassword", &SetAppPasswordIn{
AppName: appName,
Password: password,
}, &struct{}{})
}

// SetSocksClientPK calls SetSocksClientPK.
func (rc *rpcClient) SetSocksClientPK(pk cipher.PubKey) error {
return rc.Call("SetSocksClientPK", &pk, &struct{}{})
// SetAppPK calls SetAppPK.
func (rc *rpcClient) SetAppPK(appName string, pk cipher.PubKey) error {
return rc.Call("SetSocksClientPK", &SetAppPKIn{
AppName: appName,
PK: pk,
}, &struct{}{})
}

// LogsSince calls LogsSince
Expand Down Expand Up @@ -481,8 +487,8 @@ func (mc *mockRPCClient) SetAutoStart(appName string, autostart bool) error {
})
}

// SetSocksPassword implements RPCClient.
func (mc *mockRPCClient) SetSocksPassword(string) error {
// SetAppPassword implements RPCClient.
func (mc *mockRPCClient) SetAppPassword(string, string) error {
return mc.do(true, func() error {
const socksName = "skysocks"

Expand All @@ -496,8 +502,8 @@ func (mc *mockRPCClient) SetSocksPassword(string) error {
})
}

// SetSocksClientPK implements RPCClient.
func (mc *mockRPCClient) SetSocksClientPK(cipher.PubKey) error {
// SetAppPK implements RPCClient.
func (mc *mockRPCClient) SetAppPK(string, cipher.PubKey) error {
return mc.do(true, func() error {
const socksName = "skysocks-client"

Expand Down
Loading