From 7bc89769515c8a9fa3308f7cd88816c9261d7e8a Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Wed, 30 Aug 2023 13:46:51 -0400 Subject: [PATCH] private sharing; caddy (#392); sdk refactor --- cmd/zrok/sharePrivate.go | 180 ++++++++++++++++--------------------- cmd/zrok/sharePublic.go | 14 +-- cmd/zrok/shareReserved.go | 2 +- endpoints/proxy/backend.go | 6 +- 4 files changed, 90 insertions(+), 112 deletions(-) diff --git a/cmd/zrok/sharePrivate.go b/cmd/zrok/sharePrivate.go index bb37a7c1..96196404 100644 --- a/cmd/zrok/sharePrivate.go +++ b/cmd/zrok/sharePrivate.go @@ -3,24 +3,18 @@ package main import ( "fmt" tea "github.com/charmbracelet/bubbletea" - "github.com/go-openapi/runtime" - httptransport "github.com/go-openapi/runtime/client" "github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/endpoints/proxy" "github.com/openziti/zrok/endpoints/tcpTunnel" "github.com/openziti/zrok/endpoints/udpTunnel" "github.com/openziti/zrok/environment" - "github.com/openziti/zrok/rest_client_zrok" - "github.com/openziti/zrok/rest_client_zrok/share" - "github.com/openziti/zrok/rest_model_zrok" + "github.com/openziti/zrok/environment/env_core" "github.com/openziti/zrok/sdk" "github.com/openziti/zrok/tui" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "os" "os/signal" - "strings" "syscall" ) @@ -44,7 +38,7 @@ func newSharePrivateCommand() *sharePrivateCommand { } command := &sharePrivateCommand{cmd: cmd} cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (,...") - cmd.Flags().StringVar(&command.backendMode, "backend-mode", "proxy", "The backend mode {proxy, web, tcpTunnel, udpTunnel}") + cmd.Flags().StringVar(&command.backendMode, "backend-mode", "proxy", "The backend mode {proxy, web, tcpTunnel, udpTunnel, caddy}") cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless") cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for ") cmd.Run = command.run @@ -74,11 +68,14 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { case "udpTunnel": target = args[0] + case "caddy": + target = args[0] + default: tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel}", cmd.backendMode), nil) } - env, err := environment.LoadRoot() + root, err := environment.LoadRoot() if err != nil { if !panicInstead { tui.Error("unable to load environment", err) @@ -86,11 +83,11 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { panic(err) } - if !env.IsEnabled() { + if !root.IsEnabled() { tui.Error("unable to load environment; did you 'zrok enable'?", nil) } - zif, err := env.ZitiIdentityNamed(env.EnvironmentIdentityName()) + zif, err := root.ZitiIdentityNamed(root.EnvironmentIdentityName()) if err != nil { if !panicInstead { tui.Error("unable to load ziti identity configuration", err) @@ -98,36 +95,13 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { panic(err) } - zrok, err := env.Client() - if err != nil { - if !panicInstead { - tui.Error("unable to create zrok client", err) - } - panic(err) + req := &sdk.ShareRequest{ + BackendMode: sdk.BackendMode(cmd.backendMode), + ShareMode: sdk.PrivateShareMode, + Auth: cmd.basicAuth, + Target: target, } - - auth := httptransport.APIKeyAuth("X-TOKEN", "header", env.Environment().Token) - req := share.NewShareParams() - req.Body = &rest_model_zrok.ShareRequest{ - EnvZID: env.Environment().ZitiIdentity, - ShareMode: string(sdk.PrivateShareMode), - BackendMode: cmd.backendMode, - BackendProxyEndpoint: target, - AuthScheme: string(sdk.None), - } - if len(cmd.basicAuth) > 0 { - logrus.Infof("configuring basic auth") - req.Body.AuthScheme = string(sdk.Basic) - for _, pair := range cmd.basicAuth { - tokens := strings.Split(pair, ":") - if len(tokens) == 2 { - req.Body.AuthUsers = append(req.Body.AuthUsers, &rest_model_zrok.AuthUser{Username: strings.TrimSpace(tokens[0]), Password: strings.TrimSpace(tokens[1])}) - } else { - panic(errors.Errorf("invalid username:password pair '%v'", pair)) - } - } - } - resp, err := zrok.Share.Share(req, auth) + shr, err := sdk.CreateShare(root, req) if err != nil { if !panicInstead { tui.Error("unable to create share", err) @@ -135,8 +109,8 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { panic(err) } - shareDescription := fmt.Sprintf("access your share with: %v", tui.Code.Render(fmt.Sprintf("zrok access private %v", resp.Payload.ShrToken))) - mdl := newShareModel(resp.Payload.ShrToken, []string{shareDescription}, sdk.PrivateShareMode, sdk.BackendMode(cmd.backendMode)) + shareDescription := fmt.Sprintf("access your share with: %v", tui.Code.Render(fmt.Sprintf("zrok access private %v", shr.Token))) + mdl := newShareModel(shr.Token, []string{shareDescription}, sdk.PrivateShareMode, sdk.BackendMode(cmd.backendMode)) if !cmd.headless { proxy.SetCaddyLoggingWriter(mdl) } @@ -145,36 +119,45 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { <-c - cmd.destroy(env.Environment().ZitiIdentity, resp.Payload.ShrToken, zrok, auth) + cmd.shutdown(root, shr) os.Exit(0) }() - requestsChan := make(chan *endpoints.Request, 1024) + requests := make(chan *endpoints.Request, 1024) + switch cmd.backendMode { case "proxy": cfg := &proxy.BackendConfig{ IdentityPath: zif, EndpointAddress: target, - ShrToken: resp.Payload.ShrToken, + ShrToken: shr.Token, Insecure: cmd.insecure, - RequestsChan: requestsChan, + Requests: requests, } - _, err = cmd.proxyBackendMode(cfg) + + be, err := proxy.NewBackend(cfg) if err != nil { if !panicInstead { - tui.Error("unable to create proxy backend handler", err) + tui.Error("error creating proxy backend", err) } panic(err) } + go func() { + if err := be.Run(); err != nil { + logrus.Errorf("error running http proxy backend: %v", err) + } + }() + case "web": cfg := &proxy.CaddyWebBackendConfig{ IdentityPath: zif, WebRoot: target, - ShrToken: resp.Payload.ShrToken, - Requests: requestsChan, + ShrToken: shr.Token, + Requests: requests, } - _, err = cmd.webBackendMode(cfg) + + be, err := proxy.NewCaddyWebBackend(cfg) if err != nil { if !panicInstead { tui.Error("unable to create web backend handler", err) @@ -182,13 +165,20 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { panic(err) } + go func() { + if err := be.Run(); err != nil { + logrus.Errorf("error running http web backend: %v", err) + } + }() + case "tcpTunnel": cfg := &tcpTunnel.BackendConfig{ IdentityPath: zif, EndpointAddress: target, - ShrToken: resp.Payload.ShrToken, - RequestsChan: requestsChan, + ShrToken: shr.Token, + RequestsChan: requests, } + be, err := tcpTunnel.NewBackend(cfg) if err != nil { if !panicInstead { @@ -196,6 +186,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { } panic(err) } + go func() { if err := be.Run(); err != nil { logrus.Errorf("error running tcpTunnel backend: %v", err) @@ -206,9 +197,10 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { cfg := &udpTunnel.BackendConfig{ IdentityPath: zif, EndpointAddress: target, - ShrToken: resp.Payload.ShrToken, - RequestsChan: requestsChan, + ShrToken: shr.Token, + RequestsChan: requests, } + be, err := udpTunnel.NewBackend(cfg) if err != nil { if !panicInstead { @@ -216,21 +208,43 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { } panic(err) } + go func() { if err := be.Run(); err != nil { logrus.Errorf("error running udpTunnel backend: %v", err) } }() + case "caddy": + cfg := &proxy.CaddyfileBackendConfig{ + CaddyfilePath: target, + Shr: shr, + Requests: requests, + } + + be, err := proxy.NewCaddyfileBackend(cfg) + if err != nil { + if !panicInstead { + tui.Error("unable to create caddy backend", err) + } + panic(err) + } + + go func() { + if err := be.Run(); err != nil { + logrus.Errorf("error running caddy backend: %v", err) + } + }() + default: tui.Error("invalid backend mode", nil) } if cmd.headless { - logrus.Infof("allow other to access your share with the following command:\nzrok access private %v", resp.Payload.ShrToken) + logrus.Infof("allow other to access your share with the following command:\nzrok access private %v", shr.Token) for { select { - case req := <-requestsChan: + case req := <-requests: logrus.Infof("%v -> %v %v", req.RemoteAddr, req.Method, req.Path) } } @@ -243,7 +257,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { go func() { for { select { - case req := <-requestsChan: + case req := <-requests: prg.Send(req) } } @@ -253,51 +267,15 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { tui.Error("An error occurred", err) } - close(requestsChan) - cmd.destroy(env.Environment().ZitiIdentity, resp.Payload.ShrToken, zrok, auth) + close(requests) + cmd.shutdown(root, shr) } } -func (cmd *sharePrivateCommand) proxyBackendMode(cfg *proxy.BackendConfig) (endpoints.RequestHandler, error) { - be, err := proxy.NewBackend(cfg) - if err != nil { - return nil, errors.Wrap(err, "error creating http proxy backend") - } - - go func() { - if err := be.Run(); err != nil { - logrus.Errorf("error running http proxy backend: %v", err) - } - }() - - return be, nil -} - -func (cmd *sharePrivateCommand) webBackendMode(cfg *proxy.CaddyWebBackendConfig) (endpoints.RequestHandler, error) { - be, err := proxy.NewCaddyWebBackend(cfg) - if err != nil { - return nil, errors.Wrap(err, "error creating http web backend") - } - - go func() { - if err := be.Run(); err != nil { - logrus.Errorf("error running http web backend: %v", err) - } - }() - - return be, nil -} - -func (cmd *sharePrivateCommand) destroy(id string, shrToken string, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) { - logrus.Debugf("shutting down '%v'", shrToken) - req := share.NewUnshareParams() - req.Body = &rest_model_zrok.UnshareRequest{ - EnvZID: id, - ShrToken: shrToken, - } - if _, err := zrok.Share.Unshare(req, auth); err == nil { - logrus.Debugf("shutdown complete") - } else { - logrus.Errorf("error shutting down: %v", err) +func (cmd *sharePrivateCommand) shutdown(root env_core.Root, shr *sdk.Share) { + logrus.Debugf("shutting down '%v'", shr.Token) + if err := sdk.DeleteShare(root, shr); err != nil { + logrus.Errorf("error shutting down '%v': %v", shr.Token, err) } + logrus.Debugf("shutdown complete") } diff --git a/cmd/zrok/sharePublic.go b/cmd/zrok/sharePublic.go index ae80ea9a..4ffcb1ab 100644 --- a/cmd/zrok/sharePublic.go +++ b/cmd/zrok/sharePublic.go @@ -71,7 +71,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web}", cmd.backendMode), nil) } - env, err := environment.LoadRoot() + root, err := environment.LoadRoot() if err != nil { if !panicInstead { tui.Error("unable to load environment", err) @@ -79,11 +79,11 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { panic(err) } - if !env.IsEnabled() { + if !root.IsEnabled() { tui.Error("unable to load environment; did you 'zrok enable'?", nil) } - zif, err := env.ZitiIdentityNamed(env.EnvironmentIdentityName()) + zif, err := root.ZitiIdentityNamed(root.EnvironmentIdentityName()) if err != nil { if !panicInstead { tui.Error("unable to access ziti identity file", err) @@ -98,7 +98,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { Auth: cmd.basicAuth, Target: target, } - shr, err := sdk.CreateShare(env, req) + shr, err := sdk.CreateShare(root, req) if err != nil { if !panicInstead { tui.Error("unable to create share", err) @@ -115,7 +115,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { <-c - cmd.shutdown(env, shr) + cmd.shutdown(root, shr) os.Exit(0) }() @@ -128,7 +128,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { EndpointAddress: target, ShrToken: shr.Token, Insecure: cmd.insecure, - RequestsChan: requests, + Requests: requests, } be, err := proxy.NewBackend(cfg) @@ -220,7 +220,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { } close(requests) - cmd.shutdown(env, shr) + cmd.shutdown(root, shr) } } diff --git a/cmd/zrok/shareReserved.go b/cmd/zrok/shareReserved.go index 5059b872..d4c2c694 100644 --- a/cmd/zrok/shareReserved.go +++ b/cmd/zrok/shareReserved.go @@ -127,7 +127,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { EndpointAddress: target, ShrToken: shrToken, Insecure: cmd.insecure, - RequestsChan: requestsChan, + Requests: requestsChan, } _, err := cmd.proxyBackendMode(cfg) if err != nil { diff --git a/endpoints/proxy/backend.go b/endpoints/proxy/backend.go index 133d831d..8b8b62e1 100644 --- a/endpoints/proxy/backend.go +++ b/endpoints/proxy/backend.go @@ -20,7 +20,7 @@ type BackendConfig struct { EndpointAddress string ShrToken string Insecure bool - RequestsChan chan *endpoints.Request + Requests chan *endpoints.Request } type Backend struct { @@ -88,8 +88,8 @@ func newReverseProxy(cfg *BackendConfig) (*httputil.ReverseProxy, error) { proxy.Transport = tpt director := proxy.Director proxy.Director = func(req *http.Request) { - if cfg.RequestsChan != nil { - cfg.RequestsChan <- &endpoints.Request{ + if cfg.Requests != nil { + cfg.Requests <- &endpoints.Request{ Stamp: time.Now(), RemoteAddr: fmt.Sprintf("%v", req.Header["X-Real-Ip"]), Method: req.Method,