diff --git a/.goreleaser.yaml b/.goreleaser.yaml index f9fe15f1f..49faae1f4 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -85,6 +85,52 @@ nfpms: postinstall: "release_files/post_install.sh" preremove: "release_files/pre_remove.sh" dockers: + - image_templates: + - wiretrustee/wiretrustee:{{ .Version }}-amd64 + ids: + - wiretrustee + goarch: amd64 + use: buildx + dockerfile: client/Dockerfile + build_flag_templates: + - "--platform=linux/amd64" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=maintainer=wiretrustee@wiretrustee.com" + - image_templates: + - wiretrustee/wiretrustee:{{ .Version }}-arm64v8 + ids: + - wiretrustee + goarch: arm64 + use: buildx + dockerfile: client/Dockerfile + build_flag_templates: + - "--platform=linux/arm64" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=maintainer=wiretrustee@wiretrustee.com" + - image_templates: + - wiretrustee/wiretrustee:{{ .Version }}-arm + ids: + - wiretrustee + goarch: arm + goarm: 6 + use: buildx + dockerfile: client/Dockerfile + build_flag_templates: + - "--platform=linux/arm" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=maintainer=wiretrustee@wiretrustee.com" - image_templates: - wiretrustee/signal:{{ .Version }}-amd64 ids: @@ -225,6 +271,18 @@ dockers: - "--label=org.opencontainers.image.version={{.Version}}" - "--label=maintainer=wiretrustee@wiretrustee.com" docker_manifests: + - name_template: wiretrustee/wiretrustee:{{ .Version }} + image_templates: + - wiretrustee/wiretrustee:{{ .Version }}-arm64v8 + - wiretrustee/wiretrustee:{{ .Version }}-arm + - wiretrustee/wiretrustee:{{ .Version }}-amd64 + + - name_template: wiretrustee/wiretrustee:latest + image_templates: + - wiretrustee/wiretrustee:{{ .Version }}-arm64v8 + - wiretrustee/wiretrustee:{{ .Version }}-arm + - wiretrustee/wiretrustee:{{ .Version }}-amd64 + - name_template: wiretrustee/signal:{{ .Version }} image_templates: - wiretrustee/signal:{{ .Version }}-arm64v8 diff --git a/README.md b/README.md index 21f67fdd3..910ba703b 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,11 @@ For **Windows** systems, start powershell as administrator and: ```shell wiretrustee up --setup-key ``` +For **Docker**, you can run with the following command: +```shell +docker run --network host --privileged --rm -d -e WT_SETUP_KEY= -v wiretrustee-client:/etc/wiretrustee wiretrustee/wiretrustee: +``` +> TAG > 0.3.0 version Alternatively, if you are hosting your own Management Service provide `--management-url` property pointing to your Management Service: ```shell diff --git a/client/Dockerfile b/client/Dockerfile new file mode 100644 index 000000000..45e36df09 --- /dev/null +++ b/client/Dockerfile @@ -0,0 +1,4 @@ +FROM gcr.io/distroless/base:debug +ENV WT_LOG_FILE=console +ENTRYPOINT [ "/go/bin/wiretrustee","up"] +COPY wiretrustee /go/bin/wiretrustee \ No newline at end of file diff --git a/client/cmd/login.go b/client/cmd/login.go index f3c27dce8..53759456b 100644 --- a/client/cmd/login.go +++ b/client/cmd/login.go @@ -18,12 +18,12 @@ import ( ) var ( - setupKey string - loginCmd = &cobra.Command{ Use: "login", Short: "login to the Wiretrustee Management Service (first run)", RunE: func(cmd *cobra.Command, args []string) error { + SetFlagsFromEnvVars() + err := util.InitLog(logLevel, logFile) if err != nil { log.Errorf("failed initializing log %v", err) @@ -151,6 +151,3 @@ func promptPeerSetupKey() (string, error) { return "", s.Err() } - -//func init() { -//} diff --git a/client/cmd/root.go b/client/cmd/root.go index 2c8368cb4..d1693818f 100644 --- a/client/cmd/root.go +++ b/client/cmd/root.go @@ -4,19 +4,15 @@ import ( "fmt" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/spf13/pflag" "github.com/wiretrustee/wiretrustee/client/internal" "os" "os/signal" "runtime" + "strings" "syscall" ) -const ( - // ExitSetupFailed defines exit code - ExitSetupFailed = 1 - DefaultConfigPath = "" -) - var ( configPath string defaultConfigPath string @@ -24,6 +20,7 @@ var ( defaultLogFile string logFile string managementURL string + setupKey string rootCmd = &cobra.Command{ Use: "wiretrustee", Short: "", @@ -75,3 +72,28 @@ func SetupCloseHandler() { } }() } + +// SetFlagsFromEnvVars reads and updates flag values from environment variables with prefix WT_ +func SetFlagsFromEnvVars() { + flags := rootCmd.PersistentFlags() + flags.VisitAll(func(f *pflag.Flag) { + + envVar := FlagNameToEnvVar(f.Name) + + if value, present := os.LookupEnv(envVar); present { + err := flags.Set(f.Name, value) + if err != nil { + log.Infof("unable to configure flag %s using variable %s, err: %v", f.Name, envVar, err) + } + } + }) +} + +// FlagNameToEnvVar converts flag name to environment var name adding a prefix, +// replacing dashes and making all uppercase (e.g. setup-keys is converted to WT_SETUP_KEYS) +func FlagNameToEnvVar(f string) string { + prefix := "WT_" + parsed := strings.ReplaceAll(f, "-", "_") + upper := strings.ToUpper(parsed) + return prefix + upper +} diff --git a/client/cmd/service.go b/client/cmd/service.go index 2a60c31fe..0ec4199ed 100644 --- a/client/cmd/service.go +++ b/client/cmd/service.go @@ -34,6 +34,3 @@ var ( Short: "manages wiretrustee service", } ) - -func init() { -} diff --git a/client/cmd/service_controller.go b/client/cmd/service_controller.go index 82873fcab..b64da710c 100644 --- a/client/cmd/service_controller.go +++ b/client/cmd/service_controller.go @@ -8,7 +8,7 @@ import ( "time" ) -func (p *program) Start(s service.Service) error { +func (p *program) Start(service.Service) error { // Start should not block. Do the actual work async. log.Info("starting service") //nolint @@ -22,7 +22,7 @@ func (p *program) Start(s service.Service) error { return nil } -func (p *program) Stop(s service.Service) error { +func (p *program) Stop(service.Service) error { go func() { stopCh <- 1 }() @@ -41,6 +41,7 @@ var ( Use: "run", Short: "runs wiretrustee as service", Run: func(cmd *cobra.Command, args []string) { + SetFlagsFromEnvVars() err := util.InitLog(logLevel, logFile) if err != nil { @@ -75,6 +76,8 @@ var ( Use: "start", Short: "starts wiretrustee service", RunE: func(cmd *cobra.Command, args []string) error { + SetFlagsFromEnvVars() + err := util.InitLog(logLevel, logFile) if err != nil { log.Errorf("failed initializing log %v", err) @@ -101,6 +104,8 @@ var ( Use: "stop", Short: "stops wiretrustee service", Run: func(cmd *cobra.Command, args []string) { + SetFlagsFromEnvVars() + err := util.InitLog(logLevel, logFile) if err != nil { log.Errorf("failed initializing log %v", err) @@ -125,6 +130,8 @@ var ( Use: "restart", Short: "restarts wiretrustee service", Run: func(cmd *cobra.Command, args []string) { + SetFlagsFromEnvVars() + err := util.InitLog(logLevel, logFile) if err != nil { log.Errorf("failed initializing log %v", err) @@ -143,6 +150,3 @@ var ( }, } ) - -func init() { -} diff --git a/client/cmd/service_installer.go b/client/cmd/service_installer.go index 49331dd65..f5939a7d8 100644 --- a/client/cmd/service_installer.go +++ b/client/cmd/service_installer.go @@ -10,6 +10,7 @@ var ( Use: "install", Short: "installs wiretrustee service", RunE: func(cmd *cobra.Command, args []string) error { + SetFlagsFromEnvVars() svcConfig := newSVCConfig() @@ -49,6 +50,7 @@ var ( Use: "uninstall", Short: "uninstalls wiretrustee service from system", Run: func(cmd *cobra.Command, args []string) { + SetFlagsFromEnvVars() s, err := newSVC(&program{}, newSVCConfig()) if err != nil { @@ -65,6 +67,3 @@ var ( }, } ) - -func init() { -} diff --git a/client/cmd/up.go b/client/cmd/up.go index cc7667d9b..a5fdc72f4 100644 --- a/client/cmd/up.go +++ b/client/cmd/up.go @@ -21,7 +21,7 @@ var ( Use: "up", Short: "install, login and start wiretrustee client", RunE: func(cmd *cobra.Command, args []string) error { - + SetFlagsFromEnvVars() err := loginCmd.RunE(cmd, args) if err != nil { return err diff --git a/client/installer.nsis b/client/installer.nsis index 721742b7f..9064fa9a4 100644 --- a/client/installer.nsis +++ b/client/installer.nsis @@ -106,6 +106,7 @@ SectionEnd Section Uninstall ${INSTALL_TYPE} +Exec '"$INSTDIR\${MAIN_APP_EXE}" service stop' Exec '"$INSTDIR\${MAIN_APP_EXE}" service uninstall' # wait the service uninstall take unblock the executable Sleep 3000 diff --git a/client/internal/connection.go b/client/internal/connection.go index ed3dfc057..0a2662aed 100644 --- a/client/internal/connection.go +++ b/client/internal/connection.go @@ -138,12 +138,18 @@ func (conn *Connection) Open(timeout time.Duration) error { return !ok }, }) - conn.agent = a - if err != nil { return err } + conn.agent = a + defer func() { + err := conn.agent.Close() + if err != nil { + return + } + }() + err = conn.listenOnLocalCandidates() if err != nil { return err diff --git a/client/internal/engine.go b/client/internal/engine.go index 1f4e65064..8588fe676 100644 --- a/client/internal/engine.go +++ b/client/internal/engine.go @@ -148,6 +148,11 @@ func (e *Engine) initializePeer(peer Peer) { }, e.ctx) operation := func() error { + + if e.signal.GetStatus() != signal.StreamConnected { + return fmt.Errorf("not opening connection to peer because Signal is unavailable") + } + _, err := e.openPeerConnection(e.wgPort, e.config.WgPrivateKey, peer) e.peerMux.Lock() defer e.peerMux.Unlock() @@ -157,7 +162,7 @@ func (e *Engine) initializePeer(peer Peer) { } if err != nil { - log.Infof("retrying connection because of error: %s", err.Error()) + log.Debugf("retrying connection because of error: %s", err.Error()) return err } return nil diff --git a/go.mod b/go.mod index 8e843885f..20809ccb0 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/rs/cors v1.8.0 github.com/sirupsen/logrus v1.7.0 github.com/spf13/cobra v1.1.3 + github.com/spf13/pflag v1.0.5 github.com/vishvananda/netlink v1.1.0 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 diff --git a/signal/client/client.go b/signal/client/client.go index 5378b1625..f227846b3 100644 --- a/signal/client/client.go +++ b/signal/client/client.go @@ -10,6 +10,12 @@ import ( // A set of tools to exchange connection details (Wireguard endpoints) with the remote peer. +// Status is the status of the client +type Status string + +const StreamConnected Status = "Connected" +const StreamDisconnected Status = "Disconnected" + // Client is an interface describing Signal client type Client interface { // Receive handles incoming messages from the Signal service @@ -21,6 +27,7 @@ type Client interface { SendToStream(msg *proto.EncryptedMessage) error // WaitStreamConnected blocks until client is connected to the Signal stream WaitStreamConnected() + GetStatus() Status } // decryptMessage decrypts the body of the msg using Wireguard private key and Remote peer's public key diff --git a/signal/client/client_test.go b/signal/client/client_test.go index 19c49a6a4..d57ee9f59 100644 --- a/signal/client/client_test.go +++ b/signal/client/client_test.go @@ -37,7 +37,7 @@ var _ = Describe("Client", func() { }) Describe("Exchanging messages", func() { - Context("between streamConnected peers", func() { + Context("between connected peers", func() { It("should be successful", func() { var msgReceived sync.WaitGroup