From 0f9d824e6b516a9bafabeb6d115bf466f3708edf Mon Sep 17 00:00:00 2001 From: MohammadReza Palide Date: Tue, 19 Apr 2022 04:41:45 +0430 Subject: [PATCH 1/7] add -netifc parameter to vpn-server --- cmd/apps/vpn-server/vpn-server.go | 6 +++-- .../commands/config/update/root.go | 1 + .../commands/config/update/update.go | 4 ++++ internal/vpn/server.go | 24 ++++++++++++++++--- internal/vpn/server_config.go | 5 ++-- pkg/visor/api.go | 22 +++++++++++++++++ pkg/visor/hypervisor.go | 10 +++++++- pkg/visor/rpc.go | 13 ++++++++++ pkg/visor/rpc_client.go | 23 ++++++++++++++++++ 9 files changed, 100 insertions(+), 8 deletions(-) diff --git a/cmd/apps/vpn-server/vpn-server.go b/cmd/apps/vpn-server/vpn-server.go index 54066cffe..a47ea1d88 100644 --- a/cmd/apps/vpn-server/vpn-server.go +++ b/cmd/apps/vpn-server/vpn-server.go @@ -30,6 +30,7 @@ var ( localPKStr = flag.String("pk", "", "Local PubKey") localSKStr = flag.String("sk", "", "Local SecKey") passcode = flag.String("passcode", "", "Passcode to authenticate connecting users") + networkIfc = flag.String("netifc", "", "Default network interface for multiple available interfaces") secure = flag.Bool("secure", true, "Forbid connections from clients to server local network") ) @@ -73,8 +74,9 @@ func main() { log.Infof("Got app listener, bound to %d", vpnPort) srvCfg := vpn.ServerConfig{ - Passcode: *passcode, - Secure: *secure, + Passcode: *passcode, + Secure: *secure, + NetworkInteface: *networkIfc, } srv, err := vpn.NewServer(srvCfg, log) if err != nil { diff --git a/cmd/skywire-cli/commands/config/update/root.go b/cmd/skywire-cli/commands/config/update/root.go index 834648c38..64dadc031 100644 --- a/cmd/skywire-cli/commands/config/update/root.go +++ b/cmd/skywire-cli/commands/config/update/root.go @@ -30,6 +30,7 @@ var ( addVPNServerPasscode string setVPNServerSecure string setVPNServerAutostart string + setVPNServerNetIfc string resetVPNServer bool addSkysocksClientSrv string resetSkysocksClient bool diff --git a/cmd/skywire-cli/commands/config/update/update.go b/cmd/skywire-cli/commands/config/update/update.go index 814689292..6ce085336 100644 --- a/cmd/skywire-cli/commands/config/update/update.go +++ b/cmd/skywire-cli/commands/config/update/update.go @@ -43,6 +43,7 @@ func init() { vpnServerUpdateCmd.Flags().StringVarP(&addVPNServerPasscode, "passwd", "s", "", "add passcode to vpn-server") vpnServerUpdateCmd.Flags().StringVar(&setVPNServerSecure, "secure", "", "change secure mode status of vpn-server") vpnServerUpdateCmd.Flags().StringVar(&setVPNServerAutostart, "autostart", "", "change autostart of vpn-server") + vpnServerUpdateCmd.Flags().StringVar(&setVPNServerNetIfc, "netifc", "", "set default network interface") vpnServerUpdateCmd.Flags().BoolVarP(&resetVPNServer, "reset", "r", false, "reset vpn-server configurations") } @@ -200,6 +201,9 @@ var vpnServerUpdateCmd = &cobra.Command{ if addVPNServerPasscode != "" { changeAppsConfig(conf, "vpn-server", "--passcode", addVPNServerPasscode) } + if setVPNServerNetIfc != "" { + changeAppsConfig(conf, "vpn-server", "-netifc", setVPNServerNetIfc) + } switch setVPNServerSecure { case "true": changeAppsConfig(conf, "vpn-server", "--secure", setVPNServerSecure) diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 7b994aa01..ca43bd74e 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net" + "strings" "sync" "github.com/sirupsen/logrus" @@ -29,15 +30,24 @@ type Server struct { // NewServer creates VPN server instance. func NewServer(cfg ServerConfig, l logrus.FieldLogger) (*Server, error) { + var defaultNetworkIfc string s := &Server{ cfg: cfg, log: l, ipGen: NewIPGenerator(), } + if cfg.NetworkInteface == "" { + defaultNetworkIfc, err := netutil.DefaultNetworkInterface() + if err != nil { + return nil, fmt.Errorf("error getting default network interface: %w", err) + } - defaultNetworkIfc, err := netutil.DefaultNetworkInterface() - if err != nil { - return nil, fmt.Errorf("error getting default network interface: %w", err) + netIfcs, isMultiple := s.checkingNetworkInterface(defaultNetworkIfc) + if isMultiple { + return nil, fmt.Errorf("multiple default network interface detected, please set once in setting or be single: %v", netIfcs) + } + } else { + defaultNetworkIfc = cfg.NetworkInteface } l.Infof("Got default network interface: %s", defaultNetworkIfc) @@ -316,3 +326,11 @@ func (s *Server) sendServerErrHello(conn net.Conn, status HandshakeStatus) { s.log.WithError(err).Errorln("Error sending server hello") } } + +func (s *Server) checkingNetworkInterface(defaultNetworkInterface string) ([]string, bool) { + networkInterfaces := strings.Split(defaultNetworkInterface, "\n") + if len(networkInterfaces) > 1 { + return networkInterfaces, true + } + return []string{}, false +} diff --git a/internal/vpn/server_config.go b/internal/vpn/server_config.go index b95476598..a656bd87f 100644 --- a/internal/vpn/server_config.go +++ b/internal/vpn/server_config.go @@ -2,6 +2,7 @@ package vpn // ServerConfig is a configuration for VPN server. type ServerConfig struct { - Passcode string - Secure bool + Passcode string + Secure bool + NetworkInteface string } diff --git a/pkg/visor/api.go b/pkg/visor/api.go index 9164eab4e..0bbbe560b 100644 --- a/pkg/visor/api.go +++ b/pkg/visor/api.go @@ -47,6 +47,7 @@ type API interface { SetAppPK(appName string, pk cipher.PubKey) error SetAppSecure(appName string, isSecure bool) error SetAppKillswitch(appName string, killswitch bool) error + SetAppNetworkInterface(appName string, netifc string) error LogsSince(timestamp time.Time, appName string) ([]string, error) GetAppStats(appName string) (appserver.AppStats, error) GetAppError(appName string) (string, error) @@ -411,6 +412,27 @@ func (v *Visor) SetAppPassword(appName, password string) error { return nil } +// SetAppNetworkInterface implements API. +func (v *Visor) SetAppNetworkInterface(appName, netifc string) error { + if skyenv.VPNServerName != appName { + return fmt.Errorf("app %s is not allowed to set network interface", appName) + } + + v.log.Infof("Changing %s network interface to %q", appName, netifc) + + const ( + netifcArgName = "-netifc" + ) + + if err := v.conf.UpdateAppArg(v.appL, appName, netifcArgName, netifc); err != nil { + return err + } + + v.log.Infof("Updated %v network interface", appName) + + return nil +} + // SetAppKillswitch implements API. func (v *Visor) SetAppKillswitch(appName string, killswitch bool) error { if appName != skyenv.VPNClientName { diff --git a/pkg/visor/hypervisor.go b/pkg/visor/hypervisor.go index cbc747cee..057d1c557 100644 --- a/pkg/visor/hypervisor.go +++ b/pkg/visor/hypervisor.go @@ -604,13 +604,14 @@ func (hv *Hypervisor) putApp() http.HandlerFunc { Secure *bool `json:"secure,omitempty"` Status *int `json:"status,omitempty"` Passcode *string `json:"passcode,omitempty"` + NetIfc *string `json:"netifc,omitempty"` PK *cipher.PubKey `json:"pk,omitempty"` } shouldRestartApp := func(r req) bool { // we restart the app if one of these fields was changed return r.Killswitch != nil || r.Secure != nil || r.Passcode != nil || - r.PK != nil + r.PK != nil || r.NetIfc != nil } var reqBody req @@ -661,6 +662,13 @@ func (hv *Hypervisor) putApp() http.HandlerFunc { } } + if reqBody.NetIfc != nil { + if err := ctx.API.SetAppNetworkInterface(ctx.App.Name, *reqBody.NetIfc); err != nil { + httputil.WriteJSON(w, r, http.StatusInternalServerError, err) + return + } + } + if shouldRestartApp(reqBody) { if err := ctx.API.RestartApp(ctx.App.Name); err != nil { httputil.WriteJSON(w, r, http.StatusInternalServerError, err) diff --git a/pkg/visor/rpc.go b/pkg/visor/rpc.go index 5e4f3d363..f12d6a20b 100644 --- a/pkg/visor/rpc.go +++ b/pkg/visor/rpc.go @@ -253,6 +253,19 @@ func (r *RPC) SetAppPassword(in *SetAppPasswordIn, _ *struct{}) (err error) { return r.visor.SetAppPassword(in.AppName, in.Password) } +// SetAppNetworkInterfaceIn is input for SetAppNetworkInterface. +type SetAppNetworkInterfaceIn struct { + AppName string + NetIfc string +} + +// SetAppNetworkInterface sets network interface for the app. +func (r *RPC) SetAppNetworkInterface(in *SetAppNetworkInterfaceIn, _ *struct{}) (err error) { + defer rpcutil.LogCall(r.log, "SetAppNetworkInterface", in)(nil, &err) + + return r.visor.SetAppNetworkInterface(in.AppName, in.NetIfc) +} + // SetAppPKIn is input for SetAppPK. type SetAppPKIn struct { AppName string diff --git a/pkg/visor/rpc_client.go b/pkg/visor/rpc_client.go index 0534b4dba..3b85a5b14 100644 --- a/pkg/visor/rpc_client.go +++ b/pkg/visor/rpc_client.go @@ -190,6 +190,14 @@ func (rc *rpcClient) SetAppKillswitch(appName string, killswitch bool) error { }, &struct{}{}) } +// SetAppKillswitch implements API. +func (rc *rpcClient) SetAppNetworkInterface(appName, netifc string) error { + return rc.Call("SetAppNetworkInterface", &SetAppNetworkInterfaceIn{ + AppName: appName, + NetIfc: netifc, + }, &struct{}{}) +} + // SetAppSecure implements API. func (rc *rpcClient) SetAppSecure(appName string, isSecure bool) error { return rc.Call("SetAppSecure", &SetAppBoolIn{ @@ -743,6 +751,21 @@ func (mc *mockRPCClient) SetAppPassword(string, string) error { }) } +// SetAppPassword implements API. +func (mc *mockRPCClient) SetAppNetworkInterface(string, string) error { + return mc.do(true, func() error { + const vpnServerName = "vpn-server" + + for i := range mc.o.Apps { + if mc.o.Apps[i].Name == vpnServerName { + return nil + } + } + + return fmt.Errorf("app of name '%s' does not exist", vpnServerName) + }) +} + // SetAppPK implements API. func (mc *mockRPCClient) SetAppPK(string, cipher.PubKey) error { return mc.do(true, func() error { From dcb10d432d95a4acec59c11c8ef96af2f238a228 Mon Sep 17 00:00:00 2001 From: MohammadReza Palide Date: Tue, 19 Apr 2022 15:12:09 +0430 Subject: [PATCH 2/7] fix little bug --- internal/vpn/server.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/vpn/server.go b/internal/vpn/server.go index ca43bd74e..87a4321e6 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -36,16 +36,17 @@ func NewServer(cfg ServerConfig, l logrus.FieldLogger) (*Server, error) { log: l, ipGen: NewIPGenerator(), } + if cfg.NetworkInteface == "" { - defaultNetworkIfc, err := netutil.DefaultNetworkInterface() + defaultNetworkIfcs, err := netutil.DefaultNetworkInterface() if err != nil { return nil, fmt.Errorf("error getting default network interface: %w", err) } - - netIfcs, isMultiple := s.checkingNetworkInterface(defaultNetworkIfc) + netIfcs, isMultiple := s.checkingNetworkInterface(defaultNetworkIfcs) if isMultiple { return nil, fmt.Errorf("multiple default network interface detected, please set once in setting or be single: %v", netIfcs) } + defaultNetworkIfc = defaultNetworkIfcs } else { defaultNetworkIfc = cfg.NetworkInteface } From 8c45e47312caeff8a9d901913c3659581eaf9069 Mon Sep 17 00:00:00 2001 From: MohammadReza Palide Date: Thu, 21 Apr 2022 06:10:40 +0430 Subject: [PATCH 3/7] fix jdknives review --- cmd/apps/vpn-server/vpn-server.go | 6 +++--- internal/vpn/server.go | 12 ++++++------ internal/vpn/server_config.go | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cmd/apps/vpn-server/vpn-server.go b/cmd/apps/vpn-server/vpn-server.go index a47ea1d88..5fae705be 100644 --- a/cmd/apps/vpn-server/vpn-server.go +++ b/cmd/apps/vpn-server/vpn-server.go @@ -74,9 +74,9 @@ func main() { log.Infof("Got app listener, bound to %d", vpnPort) srvCfg := vpn.ServerConfig{ - Passcode: *passcode, - Secure: *secure, - NetworkInteface: *networkIfc, + Passcode: *passcode, + Secure: *secure, + NetworkInterface: *networkIfc, } srv, err := vpn.NewServer(srvCfg, log) if err != nil { diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 87a4321e6..6aae31415 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -37,18 +37,18 @@ func NewServer(cfg ServerConfig, l logrus.FieldLogger) (*Server, error) { ipGen: NewIPGenerator(), } - if cfg.NetworkInteface == "" { + if cfg.NetworkInterface == "" { defaultNetworkIfcs, err := netutil.DefaultNetworkInterface() if err != nil { return nil, fmt.Errorf("error getting default network interface: %w", err) } - netIfcs, isMultiple := s.checkingNetworkInterface(defaultNetworkIfcs) - if isMultiple { - return nil, fmt.Errorf("multiple default network interface detected, please set once in setting or be single: %v", netIfcs) + ifcs, hasMultiple := s.hasMutipleNetworkInterfaces(defaultNetworkIfcs) + if hasMultiple { + return nil, fmt.Errorf("multiple default network interfaces detected...set a default one for VPN server or remove one: %v", ifcs) } defaultNetworkIfc = defaultNetworkIfcs } else { - defaultNetworkIfc = cfg.NetworkInteface + defaultNetworkIfc = cfg.NetworkInterface } l.Infof("Got default network interface: %s", defaultNetworkIfc) @@ -328,7 +328,7 @@ func (s *Server) sendServerErrHello(conn net.Conn, status HandshakeStatus) { } } -func (s *Server) checkingNetworkInterface(defaultNetworkInterface string) ([]string, bool) { +func (s *Server) hasMutipleNetworkInterfaces(defaultNetworkInterface string) ([]string, bool) { networkInterfaces := strings.Split(defaultNetworkInterface, "\n") if len(networkInterfaces) > 1 { return networkInterfaces, true diff --git a/internal/vpn/server_config.go b/internal/vpn/server_config.go index a656bd87f..d85554910 100644 --- a/internal/vpn/server_config.go +++ b/internal/vpn/server_config.go @@ -2,7 +2,7 @@ package vpn // ServerConfig is a configuration for VPN server. type ServerConfig struct { - Passcode string - Secure bool - NetworkInteface string + Passcode string + Secure bool + NetworkInterface string } From 7ba988e4ef1cd83d4a91f5a4456f92326afa79e0 Mon Sep 17 00:00:00 2001 From: MohammadReza Palide Date: Fri, 22 Apr 2022 16:53:17 +0430 Subject: [PATCH 4/7] fix some issues | add ifc validation --- .../commands/config/update/update.go | 2 +- internal/vpn/server.go | 29 +++++++++++++------ pkg/visor/api.go | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/cmd/skywire-cli/commands/config/update/update.go b/cmd/skywire-cli/commands/config/update/update.go index 6ce085336..9af44decd 100644 --- a/cmd/skywire-cli/commands/config/update/update.go +++ b/cmd/skywire-cli/commands/config/update/update.go @@ -202,7 +202,7 @@ var vpnServerUpdateCmd = &cobra.Command{ changeAppsConfig(conf, "vpn-server", "--passcode", addVPNServerPasscode) } if setVPNServerNetIfc != "" { - changeAppsConfig(conf, "vpn-server", "-netifc", setVPNServerNetIfc) + changeAppsConfig(conf, "vpn-server", "--netifc", setVPNServerNetIfc) } switch setVPNServerSecure { case "true": diff --git a/internal/vpn/server.go b/internal/vpn/server.go index 6aae31415..758a103c4 100644 --- a/internal/vpn/server.go +++ b/internal/vpn/server.go @@ -37,18 +37,20 @@ func NewServer(cfg ServerConfig, l logrus.FieldLogger) (*Server, error) { ipGen: NewIPGenerator(), } - if cfg.NetworkInterface == "" { - defaultNetworkIfcs, err := netutil.DefaultNetworkInterface() - if err != nil { - return nil, fmt.Errorf("error getting default network interface: %w", err) - } - ifcs, hasMultiple := s.hasMutipleNetworkInterfaces(defaultNetworkIfcs) - if hasMultiple { + defaultNetworkIfcs, err := netutil.DefaultNetworkInterface() + if err != nil { + return nil, fmt.Errorf("error getting default network interface: %w", err) + } + ifcs, hasMultiple := s.hasMutipleNetworkInterfaces(defaultNetworkIfcs) + if hasMultiple { + if cfg.NetworkInterface == "" { return nil, fmt.Errorf("multiple default network interfaces detected...set a default one for VPN server or remove one: %v", ifcs) + } else if !s.validateInterface(ifcs, cfg.NetworkInterface) { + return nil, fmt.Errorf("network interface value in config is not in default network interfaces detected: %v", ifcs) } - defaultNetworkIfc = defaultNetworkIfcs - } else { defaultNetworkIfc = cfg.NetworkInterface + } else { + defaultNetworkIfc = defaultNetworkIfcs } l.Infof("Got default network interface: %s", defaultNetworkIfc) @@ -335,3 +337,12 @@ func (s *Server) hasMutipleNetworkInterfaces(defaultNetworkInterface string) ([] } return []string{}, false } + +func (s *Server) validateInterface(ifcs []string, selectedIfc string) bool { + for _, ifc := range ifcs { + if ifc == selectedIfc { + return true + } + } + return false +} diff --git a/pkg/visor/api.go b/pkg/visor/api.go index 0bbbe560b..70639408c 100644 --- a/pkg/visor/api.go +++ b/pkg/visor/api.go @@ -421,7 +421,7 @@ func (v *Visor) SetAppNetworkInterface(appName, netifc string) error { v.log.Infof("Changing %s network interface to %q", appName, netifc) const ( - netifcArgName = "-netifc" + netifcArgName = "--netifc" ) if err := v.conf.UpdateAppArg(v.appL, appName, netifcArgName, netifc); err != nil { From 1c2b24e00936888125557e5dc5fa47ff4761a730 Mon Sep 17 00:00:00 2001 From: MohammadReza Palide Date: Mon, 25 Apr 2022 15:56:38 +0430 Subject: [PATCH 5/7] add build-systray to linux job of appveyor --- .appveyor.yml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 5da83f125..46e639210 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -41,12 +41,30 @@ environment: appveyor_build_worker_image: ubuntu2004 for: - - # Linux and MacOS + - # Linux + skip_tags: true + matrix: + only: + - job_name: Linux + + install: + - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.44.2 + - sudo apt-get install gcc libgtk-3-dev libayatana-appindicator3-dev + - make dep + - sh: ci_scripts/create-ip-aliases.sh + + before_build: + - make check + + build_script: + - make build + - make build-systray + + - # MacOS skip_tags: true matrix: only: - job_name: Linux - - job_name: MacOS install: - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.44.2 From 12c80bf86ef09c658640357548cd461e74b71522 Mon Sep 17 00:00:00 2001 From: MohammadReza Palide Date: Mon, 25 Apr 2022 15:59:39 +0430 Subject: [PATCH 6/7] change checkroot to isroot --- internal/gui/gui.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/gui/gui.go b/internal/gui/gui.go index 9f7783153..3a8967d0d 100644 --- a/internal/gui/gui.go +++ b/internal/gui/gui.go @@ -138,7 +138,7 @@ func initAdvancedButton(conf *visorconfig.V1) { // if it's not installed via package, hide the uninstall button initUninstallBtn() //hide the buttons which could launch the browser if the process is run as root - if checkRoot() { + if isRoot() { mAdvancedButton.Hide() mOpenHypervisor.Hide() return @@ -178,7 +178,7 @@ func initAdvancedButton(conf *visorconfig.V1) { func initOpenVPNLinkBtn(vc *visorconfig.V1) { mVPNLink = systray.AddMenuItem("Open VPN UI", "Open VPN UI in browser") - if checkRoot() { + if isRoot() { mVPNLink.Hide() return } From 47b7facb1979ced457e20a50226b58c6ff676541 Mon Sep 17 00:00:00 2001 From: MohammadReza Palide Date: Mon, 25 Apr 2022 16:02:56 +0430 Subject: [PATCH 7/7] add -y to install packages --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor.yml b/.appveyor.yml index 46e639210..f05939ff6 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -49,7 +49,7 @@ for: install: - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.44.2 - - sudo apt-get install gcc libgtk-3-dev libayatana-appindicator3-dev + - sudo apt-get install gcc libgtk-3-dev libayatana-appindicator3-dev -y - make dep - sh: ci_scripts/create-ip-aliases.sh