From 57e14bf4895afe19dac2eba72aaf7d519f2c1520 Mon Sep 17 00:00:00 2001 From: leandrofars Date: Tue, 16 Apr 2024 13:46:57 -0300 Subject: [PATCH] feat: websockets with tls --- .../mtp/ws-adapter/cmd/ws-adapter/main.go | 9 ++++++++- .../mtp/ws-adapter/internal/bridge/bridge.go | 16 ++++++++-------- .../mtp/ws-adapter/internal/config/config.go | 10 ++++++++++ .../services/mtp/ws/internal/config/config.go | 18 +++++++++++++++++- backend/services/mtp/ws/internal/ws/ws.go | 10 +++++++--- 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/backend/services/mtp/ws-adapter/cmd/ws-adapter/main.go b/backend/services/mtp/ws-adapter/cmd/ws-adapter/main.go index ba0c588..9c6e989 100644 --- a/backend/services/mtp/ws-adapter/cmd/ws-adapter/main.go +++ b/backend/services/mtp/ws-adapter/cmd/ws-adapter/main.go @@ -21,7 +21,14 @@ func main() { kv, publisher, subscriber := nats.StartNatsClient(c.Nats) bridge := bridge.NewBridge(publisher, subscriber, c.Ws.Ctx, c.Ws, kv) - bridge.StartBridge() + + if !c.Ws.NoTls { + bridge.StartBridge(c.Ws.Port, false) + } + + if c.Ws.TlsEnable { + bridge.StartBridge(c.Ws.TlsPort, true) + } <-done diff --git a/backend/services/mtp/ws-adapter/internal/bridge/bridge.go b/backend/services/mtp/ws-adapter/internal/bridge/bridge.go index 6d2f236..360d1c9 100644 --- a/backend/services/mtp/ws-adapter/internal/bridge/bridge.go +++ b/backend/services/mtp/ws-adapter/internal/bridge/bridge.go @@ -69,11 +69,11 @@ func NewBridge(p Publisher, s Subscriber, ctx context.Context, w config.Ws, kv j } } -func (b *Bridge) StartBridge() { +func (b *Bridge) StartBridge(port string, tls bool) { - go func() { + go func(port string, tls bool) { for { - url := b.urlBuild() + url := b.urlBuild(tls, port) dialer := b.newDialer() wc, _, err := dialer.Dial(url, nil) if err != nil { @@ -89,7 +89,7 @@ func (b *Bridge) StartBridge() { if err != nil { if websocket.IsCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { log.Printf("websocket error: %v", err) - b.StartBridge() + b.StartBridge(port, tls) return } log.Println("websocket unexpected error:", err) @@ -130,7 +130,7 @@ func (b *Bridge) StartBridge() { }(wc) break } - }() + }(port, tls) } func (b *Bridge) subscribe(wc *websocket.Conn) { @@ -224,13 +224,13 @@ func (b *Bridge) statusMsgHandler(wsMsg []byte) { b.Pub(NATS_WS_SUBJECT_PREFIX+deviceStatus.Eid+".status", []byte(deviceStatus.Status)) } -func (b *Bridge) urlBuild() string { +func (b *Bridge) urlBuild(tls bool, port string) string { prefix := "ws://" - if b.Ws.TlsEnable { + if tls { prefix = "wss://" } - wsUrl := prefix + b.Ws.Addr + b.Ws.Port + b.Ws.Route + wsUrl := prefix + b.Ws.Addr + port + b.Ws.Route token, _ := b.kv.Get(b.Ctx, "oktopusController") diff --git a/backend/services/mtp/ws-adapter/internal/config/config.go b/backend/services/mtp/ws-adapter/internal/config/config.go index eb4c026..c78e4dd 100644 --- a/backend/services/mtp/ws-adapter/internal/config/config.go +++ b/backend/services/mtp/ws-adapter/internal/config/config.go @@ -25,7 +25,9 @@ type Ws struct { Port string Route string TlsEnable bool + TlsPort string SkipTlsVerify bool + NoTls bool Ctx context.Context } @@ -44,6 +46,8 @@ func NewConfig() *Config { wsAuthEnable := flag.Bool("ws_auth_enable", lookupEnvOrBool("WS_AUTH_ENABLE", false), "enable authentication for websocket server") wsAddr := flag.String("ws_addr", lookupEnvOrString("WS_ADDR", "localhost"), "websocket server address (domain or ip)") wsPort := flag.String("ws_port", lookupEnvOrString("WS_PORT", ":8080"), "websocket server port") + wsTlsPort := flag.String("ws_tls_port", lookupEnvOrString("WS_TLS_PORT", ":8081"), "websocket tls server port") + wsNoTls := flag.Bool("ws_no_tls", lookupEnvOrBool("WS_NO_TLS", false), "connects to websocket server without tls") wsRoute := flag.String("ws_route", lookupEnvOrString("WS_ROUTE", "/ws/controller"), "websocket server route") wsTlsEnable := flag.Bool("ws_tls_enable", lookupEnvOrBool("WS_TLS_ENABLE", false), "access websocket via tls protocol (wss)") wsSkipTlsVerify := flag.Bool("ws_skip_tls_verify", lookupEnvOrBool("WS_SKIP_TLS_VERIFY", false), "skip tls verification for websocket server") @@ -56,6 +60,10 @@ func NewConfig() *Config { os.Exit(0) } + if *wsNoTls && !*wsTlsEnable { + log.Fatalf("You must configure at least one connection to the websocket server") + } + ctx := context.TODO() return &Config{ @@ -73,6 +81,8 @@ func NewConfig() *Config { TlsEnable: *wsTlsEnable, SkipTlsVerify: *wsSkipTlsVerify, Ctx: ctx, + TlsPort: *wsTlsPort, + NoTls: *wsNoTls, }, } } diff --git a/backend/services/mtp/ws/internal/config/config.go b/backend/services/mtp/ws/internal/config/config.go index 840c0e6..f79f176 100644 --- a/backend/services/mtp/ws/internal/config/config.go +++ b/backend/services/mtp/ws/internal/config/config.go @@ -16,6 +16,10 @@ type Config struct { Auth bool // server auth enable/disable ControllerEID string // controller endpoint id Tls bool // enable/diable websockets server tls + TlsPort string + NoTls bool + FullChain string + PrivateKey string Nats Nats } @@ -47,7 +51,11 @@ func NewConfig() Config { flPort := flag.String("port", lookupEnvOrString("SERVER_PORT", ":8080"), "Server port") flAuth := flag.Bool("auth", lookupEnvOrBool("SERVER_AUTH_ENABLE", false), "Server auth enable/disable") flControllerEid := flag.String("controller-eid", lookupEnvOrString("CONTROLLER_EID", "oktopusController"), "Controller eid") - flTls := flag.Bool("tls", lookupEnvOrBool("SERVER_TLS_ENABLE", false), "Enable/diable websockets server tls") + flTls := flag.Bool("tls", lookupEnvOrBool("SERVER_TLS_ENABLE", false), "Enable/disable websockets server tls") + flTlsPort := flag.String("tls_port", lookupEnvOrString("SERVER_TLS_PORT", ":8081"), "Server Port to use if TLS is enabled") + flNoTls := flag.Bool("no_tls", lookupEnvOrBool("SERVER_NO_TLS", false), "Disable/enable websockets serevr without tls") + flFullchain := flag.String("fullchain_path", lookupEnvOrString("FULL_CHAIN_PATH", "cert.pem"), "Fullchain file path") + flPrivKey := flag.String("privkey_path", lookupEnvOrString("PRIVATE_KEY_PATH", "key.pem"), "Private key file path") flHelp := flag.Bool("help", false, "Help") flag.Parse() /* -------------------------------------------------------------------------- */ @@ -57,13 +65,21 @@ func NewConfig() Config { os.Exit(0) } + if *flNoTls && !*flTls { + log.Fatalf("You must at least choose one between tls and no_tls configs") + } + ctx := context.TODO() return Config{ Port: *flPort, + TlsPort: *flTlsPort, + NoTls: *flNoTls, Auth: *flAuth, ControllerEID: *flControllerEid, Tls: *flTls, + FullChain: *flFullchain, + PrivateKey: *flPrivKey, Nats: Nats{ Url: *natsUrl, Name: *natsName, diff --git a/backend/services/mtp/ws/internal/ws/ws.go b/backend/services/mtp/ws/internal/ws/ws.go index d08ef44..264344a 100644 --- a/backend/services/mtp/ws/internal/ws/ws.go +++ b/backend/services/mtp/ws/internal/ws/ws.go @@ -30,12 +30,16 @@ func StartNewServer(c config.Config, kv jetstream.KeyValue) { go func() { if c.Tls { - log.Println("Websockets server running with TLS") - err := http.ListenAndServeTLS(c.Port, "cert.pem", "key.pem", r) + log.Println("Websockets server running with TLS at port", c.TlsPort) + err := http.ListenAndServeTLS(c.TlsPort, c.FullChain, c.PrivateKey, r) if err != nil { log.Fatal("ListenAndServeTLS: ", err) } - } else { + } + }() + + go func() { + if !c.NoTls { log.Println("Websockets server running at port", c.Port) err := http.ListenAndServe(c.Port, r) if err != nil {