Skip to content

Commit

Permalink
#17216 - zCli for macos
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-hajek committed Jul 10, 2020
1 parent b9226c4 commit ed4b4d8
Show file tree
Hide file tree
Showing 16 changed files with 240 additions and 56 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
zcli.config.yml
zcli.config.yml
zcli.data
7 changes: 5 additions & 2 deletions cmd/di.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ func createSudoers() *sudoers.Handler {
}

func createStorage() (*storage.Handler, error) {
tempDir := os.TempDir()
currentDir, err := os.Getwd()
if err != nil {
return nil, err
}

return storage.New(
storage.Config{
FilePath: path.Join(tempDir, "zcli.data"),
FilePath: path.Join(currentDir, "zcli.data"),
},
)
}
Expand Down
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/zerops-io/zcli
go 1.14

require (
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/golang/protobuf v1.4.2
github.com/google/uuid v1.1.1
Expand All @@ -15,10 +14,8 @@ require (
github.com/spf13/cobra v1.0.0
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.6.3
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 // indirect
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 // indirect
golang.org/x/text v0.3.2 // indirect
google.golang.org/grpc v1.21.0
gopkg.in/ini.v1 v1.55.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)
7 changes: 3 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
git.vsh-labs.cz/cml/nest v0.0.30 h1:/D9n9dVd3bAbOU+4wJecOc7wBHBnOAc2JY9yp60rVN8=
git.vsh-labs.cz/cml/nest v0.0.30/go.mod h1:thiWZ8/Nx6YndGNrdgx7ReczCGiKI4buH1EM3hQ6ll4=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
Expand All @@ -23,8 +21,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
Expand Down Expand Up @@ -95,9 +91,11 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
Expand Down Expand Up @@ -219,6 +217,7 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ=
gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
6 changes: 5 additions & 1 deletion src/command/startVpn/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ func (h *Handler) Run(ctx context.Context, config RunConfig) error {
return err
}

h.logger.Info("\nclient is connected \n")
if h.isVpnAlive() {
h.logger.Info("\nvpn connection is established\n")
} else {
return errors.New("vpn is not connected")
}

h.storage.Data.ProjectId = project.GetId()
err = h.storage.Save()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// +build linux

package startVpn

import (
Expand Down
19 changes: 19 additions & 0 deletions src/command/startVpn/handler_clean_linux_macos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// +build darwin

package startVpn

import "os/exec"

func (h *Handler) cleanVpn() error {

var err error

cmd := "ps aux | grep wireguard | grep -v grep | awk '{print $2}' | xargs sudo kill"

_, err = h.sudoers.RunCommand(exec.Command("bash", "-c", cmd))
if err != nil {
return err
}

return nil
}
2 changes: 1 addition & 1 deletion src/command/startVpn/handler_isVpnAlive.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func (h *Handler) isVpnAlive() bool {
}

for i := 0; i < 3; i++ {
_, err := exec.Command("ping", h.storage.Data.ServerIp, "-c", "1", "-W", "1").Output()
_, err := exec.Command("ping6", h.storage.Data.ServerIp, "-c", "1").Output()
if err != nil {
continue
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// +build linux

package startVpn

import (
Expand All @@ -9,9 +11,7 @@ import (
"strconv"

"github.com/google/uuid"

"github.com/zerops-io/zcli/src/service/sudoers"

"github.com/zerops-io/zcli/src/zeropsVpnProtocol"
)

Expand Down
98 changes: 98 additions & 0 deletions src/command/startVpn/handler_setVpn_macos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// +build darwin

package startVpn

import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"regexp"
"strconv"

"github.com/zerops-io/zcli/src/service/sudoers"

"github.com/google/uuid"
"github.com/zerops-io/zcli/src/zeropsVpnProtocol"
)

func (h *Handler) setVpn(selectedVpnAddress, privateKey string, response *zeropsVpnProtocol.StartVpnResponse) error {
var err error

output, err := h.sudoers.RunCommand(exec.Command("wireguard-go", "utun"))
if err != nil {
return err
}

re := regexp.MustCompile(`INFO: \((.*)\)`)
submatches := re.FindSubmatch(output)
if len(submatches) != 2 {
return errors.New("vpn interface not found")
}

interfaceName := string(submatches[1])

{
privateKeyName := uuid.New().String()
tempPrivateKeyFile := path.Join(os.TempDir(), privateKeyName)

fmt.Println(tempPrivateKeyFile)
err = ioutil.WriteFile(tempPrivateKeyFile, []byte(privateKey), 0755)
if err != nil {
return err
}
_, err = h.sudoers.RunCommand(exec.Command("wg", "set", interfaceName, "private-key", tempPrivateKeyFile))
if err != nil {
return err
}
err = os.Remove(tempPrivateKeyFile)
if err != nil {
return err
}
}

_, err = h.sudoers.RunCommand(exec.Command("wg", "set", interfaceName, "listen-port", wireguardPort))
if err != nil {
return err
}

clientIp := zeropsVpnProtocol.FromProtoIP(response.GetVpn().GetAssignedClientIp())
serverIp := zeropsVpnProtocol.FromProtoIP(response.GetVpn().GetServerIp())
vpnRange := zeropsVpnProtocol.FromProtoIPRange(response.GetVpn().GetVpnIpRange())

args := []string{
"set", interfaceName,
"peer", response.GetVpn().GetServerPublicKey(),
"allowed-ips", vpnRange.String(),
"endpoint", selectedVpnAddress + ":" + strconv.Itoa(int(response.GetVpn().GetPort())),
"persistent-keepalive", "25",
}
_, err = h.sudoers.RunCommand(exec.Command("wg", args...))
if err != nil {
if !errors.Is(err, sudoers.IpAlreadySetErr) {
panic(err)
}
}

_, err = h.sudoers.RunCommand(exec.Command("ifconfig", interfaceName, "inet6", clientIp.String(), "mtu", "1420"))
if err != nil {
return err
}

_, err = h.sudoers.RunCommand(exec.Command("route", "add", "-inet6", vpnRange.String(), serverIp.String()))
if err != nil {
return err
}

h.logger.Debug("assigned client address: " + clientIp.String())
h.logger.Debug("assigned vpn server: " + selectedVpnAddress + ":" + strconv.Itoa(int(response.GetVpn().GetPort())))
h.logger.Debug("server public key: " + response.GetVpn().GetServerPublicKey())
h.logger.Debug("serverIp address: " + serverIp.String())
h.logger.Debug("vpnRange: " + vpnRange.String())

h.storage.Data.ServerIp = serverIp.String()

return nil
}
13 changes: 5 additions & 8 deletions src/command/stopVpn/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ package stopVpn

import (
"context"
"errors"
"os/exec"

"github.com/zerops-io/zcli/src/service/storage"

"github.com/zerops-io/zcli/src/service/logger"
"github.com/zerops-io/zcli/src/service/storage"
"github.com/zerops-io/zcli/src/service/sudoers"
)

Expand Down Expand Up @@ -40,11 +37,9 @@ func New(

func (h *Handler) Run(_ context.Context, _ RunConfig) error {

_, err := h.sudoers.RunCommand(exec.Command("ip", "link", "del", "dev", "wg0"))
err := h.cleanVpn()
if err != nil {
if !errors.Is(err, sudoers.CannotFindDeviceErr) {
return err
}
return err
}

h.storage.Data.ProjectId = ""
Expand All @@ -54,5 +49,7 @@ func (h *Handler) Run(_ context.Context, _ RunConfig) error {
return err
}

h.logger.Info("\nvpn connection was closed\n")

return nil
}
24 changes: 24 additions & 0 deletions src/command/stopVpn/handler_clean_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// +build linux

package stopVpn

import (
"errors"
"os/exec"

"github.com/zerops-io/zcli/src/service/sudoers"
)

func (h *Handler) cleanVpn() error {

var err error

_, err = h.sudoers.RunCommand(exec.Command("ip", "link", "del", "dev", "wg0"))
if err != nil {
if !errors.Is(err, sudoers.CannotFindDeviceErr) {
return err
}
}

return nil
}
19 changes: 19 additions & 0 deletions src/command/stopVpn/handler_clean_linux_macos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// +build darwin

package stopVpn

import "os/exec"

func (h *Handler) cleanVpn() error {

var err error

cmd := "ps aux | grep wireguard | grep -v grep | awk '{print $2}' | xargs sudo kill"

_, err = h.sudoers.RunCommand(exec.Command("bash", "-c", cmd))
if err != nil {
return err
}

return nil
}
40 changes: 40 additions & 0 deletions src/helpers/cmdRunner/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package cmdRunner

import (
"bytes"
"errors"
"os/exec"
"strings"
)

var IpAlreadySetErr = errors.New("RTNETLINK answers: File exists")
var CannotFindDeviceErr = errors.New(`Cannot find device "wg0"`)
var OperationNotPermitted = errors.New(`Operation not permitted`)

func Run(cmd *exec.Cmd) ([]byte, error) {
output := &bytes.Buffer{}
errOutput := &bytes.Buffer{}
cmd.Stdout = output
cmd.Stderr = errOutput

if err := cmd.Run(); err != nil {


if errOutput.Len() > 0 {
errOutputString := string(errOutput.Bytes()[0 : errOutput.Len()-1])

if strings.Contains(errOutputString, OperationNotPermitted.Error()) {
return nil, OperationNotPermitted
}

for _, e := range []error{IpAlreadySetErr, CannotFindDeviceErr} {
if errOutputString == e.Error() {
return nil, e
}
}
}
return nil, err
}

return output.Bytes(), nil
}
2 changes: 1 addition & 1 deletion src/service/certReader/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func New(config Config) (h *Handler, err error) {

tokens := strings.Split(config.Token, ";")
if len(tokens) != 3 {
return h, errors.New("wrong token")
return h, errors.New("invalid credentials, try `login` command")
}

if h.CaData, err = readData(tokens[0]); err != nil {
Expand Down
Loading

0 comments on commit ed4b4d8

Please sign in to comment.