diff --git a/Makefile b/Makefile index 93f32aa..04b9e76 100644 --- a/Makefile +++ b/Makefile @@ -28,9 +28,6 @@ run-server: build run-client: build connet --config examples/minimal.toml -run-sws: - static-web-server --port 8081 --root . --directory-listing - .PHONY: update-go update-nix update-go: diff --git a/README.md b/README.md index 8787950..c005e4e 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ status-addr = "127.0.0.1:19182" # at what address this client listens for status [client.destinations.serviceX] addr = "localhost:3000" # where this destination connects to, required route = "any" # what kind of routes to use, `any` will use both `direct` and `relay` +file-server-root = "." # run a file server at current directory, on localhost:3000 address [client.destinations.serviceY] addr = "192.168.1.100:8000" # multiple destinations can be defined, they are matched by name at the server @@ -383,6 +384,8 @@ by adding account management and it is one of the easiest way to start. ### v0.5.0 - [x] Stateless reset key for the server - [x] Name access restrictions for clients + - [x] File http server + - [ ] Gen config ## Future diff --git a/cmd/connet/main.go b/cmd/connet/main.go index ead9a83..b846043 100644 --- a/cmd/connet/main.go +++ b/cmd/connet/main.go @@ -16,12 +16,14 @@ import ( "github.com/connet-dev/connet" "github.com/connet-dev/connet/control" "github.com/connet-dev/connet/model" + "github.com/connet-dev/connet/netc" "github.com/connet-dev/connet/relay" "github.com/connet-dev/connet/restr" "github.com/connet-dev/connet/selfhosted" "github.com/klev-dev/kleverr" "github.com/pelletier/go-toml/v2" "github.com/spf13/cobra" + "golang.org/x/sync/errgroup" ) type Config struct { @@ -45,11 +47,17 @@ type ClientConfig struct { DirectAddr string `toml:"direct-addr"` StatusAddr string `toml:"status-addr"` - Destinations map[string]ForwardConfig `toml:"destinations"` - Sources map[string]ForwardConfig `toml:"sources"` + Destinations map[string]DestinationConfig `toml:"destinations"` + Sources map[string]SourceConfig `toml:"sources"` } -type ForwardConfig struct { +type DestinationConfig struct { + Addr string `toml:"addr"` + Route string `toml:"route"` + FileServerRoot string `toml:"file-server-root"` +} + +type SourceConfig struct { Addr string `toml:"addr"` Route string `toml:"route"` } @@ -162,13 +170,14 @@ func rootCmd() *cobra.Command { cmd.Flags().StringVar(&flagsConfig.Client.StatusAddr, "status-addr", "", "status server address to listen") var dstName string - var dstCfg ForwardConfig + var dstCfg DestinationConfig cmd.Flags().StringVar(&dstName, "dst-name", "", "destination name") cmd.Flags().StringVar(&dstCfg.Addr, "dst-addr", "", "destination address") + cmd.Flags().StringVar(&dstCfg.FileServerRoot, "dst-file-server-root", "", "destination file server root directory") cmd.Flags().StringVar(&dstCfg.Route, "dst-route", "", "destination route") var srcName string - var srcCfg ForwardConfig + var srcCfg SourceConfig cmd.Flags().StringVar(&srcName, "src-name", "", "source name") cmd.Flags().StringVar(&srcCfg.Addr, "src-addr", "", "source address") cmd.Flags().StringVar(&srcCfg.Route, "src-route", "", "source route") @@ -180,10 +189,10 @@ func rootCmd() *cobra.Command { } if dstName != "" { - flagsConfig.Client.Destinations = map[string]ForwardConfig{dstName: dstCfg} + flagsConfig.Client.Destinations = map[string]DestinationConfig{dstName: dstCfg} } if srcName != "" { - flagsConfig.Client.Sources = map[string]ForwardConfig{srcName: srcCfg} + flagsConfig.Client.Sources = map[string]SourceConfig{srcName: srcCfg} } cfg.merge(flagsConfig) @@ -440,11 +449,15 @@ func clientRun(ctx context.Context, cfg ClientConfig, logger *slog.Logger) error opts = append(opts, connet.ClientStatusAddress(cfg.StatusAddr)) } + var srvs []*netc.FileServer for name, fc := range cfg.Destinations { route, err := parseRouteOption(fc.Route) if err != nil { return err } + if fc.FileServerRoot != "" { + srvs = append(srvs, &netc.FileServer{Addr: fc.Addr, Root: fc.FileServerRoot}) + } opts = append(opts, connet.ClientDestination(name, fc.Addr, route)) } for name, fc := range cfg.Sources { @@ -461,6 +474,15 @@ func clientRun(ctx context.Context, cfg ClientConfig, logger *slog.Logger) error if err != nil { return err } + if len(srvs) > 0 { + g, ctx := errgroup.WithContext(ctx) + for _, srv := range srvs { + g.Go(func() error { return srv.Run(ctx) }) + } + + g.Go(func() error { return cl.Run(ctx) }) + return g.Wait() + } return cl.Run(ctx) } @@ -770,16 +792,16 @@ func (c *ClientConfig) merge(o ClientConfig) { for k, v := range o.Destinations { if c.Destinations == nil { - c.Destinations = map[string]ForwardConfig{} + c.Destinations = map[string]DestinationConfig{} } - c.Destinations[k] = mergeForwardConfig(c.Destinations[k], v) + c.Destinations[k] = mergeDestinationConfig(c.Destinations[k], v) } for k, v := range o.Sources { if c.Sources == nil { - c.Sources = map[string]ForwardConfig{} + c.Sources = map[string]SourceConfig{} } - c.Sources[k] = mergeForwardConfig(c.Sources[k], v) + c.Sources[k] = mergeSourceConfig(c.Sources[k], v) } } @@ -833,8 +855,16 @@ func (c *RelayConfig) merge(o RelayConfig) { c.StoreDir = override(c.StoreDir, o.StoreDir) } -func mergeForwardConfig(c, o ForwardConfig) ForwardConfig { - return ForwardConfig{ +func mergeDestinationConfig(c, o DestinationConfig) DestinationConfig { + return DestinationConfig{ + Addr: override(c.Addr, o.Addr), + FileServerRoot: override(c.FileServerRoot, o.FileServerRoot), + Route: override(c.Route, o.Route), + } +} + +func mergeSourceConfig(c, o SourceConfig) SourceConfig { + return SourceConfig{ Addr: override(c.Addr, o.Addr), Route: override(c.Route, o.Route), } diff --git a/examples/client-destination.toml b/examples/client-destination.toml index ffb4242..02945d9 100644 --- a/examples/client-destination.toml +++ b/examples/client-destination.toml @@ -3,7 +3,7 @@ log-level = "debug" [client] token-file = "examples/client-token.secret" server-cas = ".direnv/minica.pem" -direct-addr = ":19193" [client.destinations.sws] addr = ":8081" +file-server-root = "." diff --git a/examples/client-source.toml b/examples/client-source.toml index c4e886c..87b8ff6 100644 --- a/examples/client-source.toml +++ b/examples/client-source.toml @@ -3,7 +3,7 @@ log-level = "debug" [client] token-file = "examples/client-token.secret" server-cas = ".direnv/minica.pem" -direct-addr = ":19194" +direct-addr = ":19193" [client.sources.sws] addr = ":9999" diff --git a/examples/minimal.toml b/examples/minimal.toml index 99da56d..9adebac 100644 --- a/examples/minimal.toml +++ b/examples/minimal.toml @@ -6,6 +6,7 @@ server-cas = ".direnv/minica.pem" [client.destinations.sws] addr = ":8081" +file-server-root = "." [client.sources.sws] addr = ":9999" diff --git a/examples/routes.toml b/examples/routes.toml index 9e90371..d5c4d01 100644 --- a/examples/routes.toml +++ b/examples/routes.toml @@ -12,6 +12,7 @@ server-cas = ".direnv/minica.pem" [client.destinations.sws-direct] addr = ":8081" route = "direct" +file-server-root = "." [client.sources.sws-direct] addr = ":9999" diff --git a/flake.nix b/flake.nix index b5c1de0..b6e7199 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,6 @@ protoc-gen-go process-compose skopeo - static-web-server (pkgs.writeShellScriptBin "gen-local-certs" '' set -euo pipefail cd .direnv diff --git a/netc/file_server.go b/netc/file_server.go new file mode 100644 index 0000000..ceb8726 --- /dev/null +++ b/netc/file_server.go @@ -0,0 +1,28 @@ +package netc + +import ( + "context" + "net/http" +) + +type FileServer struct { + Addr string + Root string +} + +func (f *FileServer) Run(ctx context.Context) error { + mux := http.NewServeMux() + mux.Handle("/", http.FileServer(http.Dir(f.Root))) + + srv := &http.Server{ + Addr: f.Addr, + Handler: mux, + } + + go func() { + <-ctx.Done() + srv.Close() + }() + + return srv.ListenAndServe() +} diff --git a/process-compose.yaml b/process-compose.yaml index 4b66e4f..1965ece 100644 --- a/process-compose.yaml +++ b/process-compose.yaml @@ -34,5 +34,3 @@ processes: condition: process_started client-dst: condition: process_started - upstream: - command: static-web-server --port 8081 --root . --directory-listing diff --git a/selfhosted/clients.go b/selfhosted/clients.go index eb4b458..6e5f84e 100644 --- a/selfhosted/clients.go +++ b/selfhosted/clients.go @@ -24,7 +24,7 @@ func NewClientAuthenticatorRestricted(tokens []string, iprestr []restr.IP, namer switch { case len(namerestr) == 0: - iprestr = make([]restr.IP, len(tokens)) + namerestr = make([]restr.Name, len(tokens)) case len(namerestr) != len(tokens): return nil, kleverr.Newf("expected equal number of tokens and token name restrictions") }