From c90e14a1ac5de284755ab316b37ed7186f3c7385 Mon Sep 17 00:00:00 2001 From: Jianhui Zhao Date: Fri, 1 Aug 2025 12:16:17 +0800 Subject: [PATCH] Reintroduce TLS support for device listener preserve client IP visibility Previously, TLS termination was moved to nginx for better separation of concerns. However, this introduced an issue with the new device IP display feature: - With nginx reverse proxying, all device connections appear to originate from 127.0.0.1 - The actual device IP addresses were masked by the proxy layer - This prevented accurate IP-based device identification and reporting Signed-off-by: Jianhui Zhao --- config.go | 8 ++++++++ device.go | 32 +++++++++++++++++++++++++++++++- main.go | 12 ++++++++++++ rttys.conf | 5 +++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/config.go b/config.go index 73d1a42..b6480e7 100644 --- a/config.go +++ b/config.go @@ -47,6 +47,10 @@ type Config struct { AllowOrigins bool PprofAddr string + + SslCert string + SslKey string + CaCert string } func (cfg *Config) Parse(c *cli.Command) error { @@ -78,6 +82,10 @@ func (cfg *Config) Parse(c *cli.Command) error { "allow-origins": &cfg.AllowOrigins, "pprof": &cfg.PprofAddr, + + "sslcert": &cfg.SslCert, + "sslkey": &cfg.SslKey, + "cacert": &cfg.CaCert, } for name, opt := range fields { diff --git a/device.go b/device.go index 696380c..78b0a24 100644 --- a/device.go +++ b/device.go @@ -28,11 +28,14 @@ import ( "bufio" "bytes" "context" + "crypto/tls" + "crypto/x509" "encoding/binary" "fmt" "io" "net" "net/http" + "os" "strings" "sync" "time" @@ -154,7 +157,34 @@ func (srv *RttyServer) ListenDevices() { } defer ln.Close() - log.Info().Msgf("Listen devices on: %s", ln.Addr().(*net.TCPAddr)) + if cfg.SslCert != "" && cfg.SslKey != "" { + cert, err := tls.LoadX509KeyPair(cfg.SslCert, cfg.SslKey) + if err != nil { + log.Fatal().Msg(err.Error()) + } + + config := &tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + } + + if cfg.CaCert != "" { + caCert, err := os.ReadFile(cfg.CaCert) + if err != nil { + log.Fatal().Msg(err.Error()) + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + config.ClientCAs = caCertPool + config.ClientAuth = tls.RequireAndVerifyClientCert + } + + ln = tls.NewListener(ln, config) + + log.Info().Msgf("Listen devices on: %s SSL on", ln.Addr().(*net.TCPAddr)) + } else { + log.Info().Msgf("Listen devices on: %s SSL off", ln.Addr().(*net.TCPAddr)) + } for { conn, err := ln.Accept() diff --git a/main.go b/main.go index 466adb9..c4c8e4c 100644 --- a/main.go +++ b/main.go @@ -118,6 +118,18 @@ func main() { Aliases: []string{"V"}, Usage: "more detailed log output", }, + &cli.StringFlag{ + Name: "sslcert", + Usage: "SSL/TLS certificate for device", + }, + &cli.StringFlag{ + Name: "sslkey", + Usage: "SSL/TLS private key for device", + }, + &cli.StringFlag{ + Name: "cacert", + Usage: "CA certificate to verify devices (mTLS)", + }, }, Action: cmdAction, } diff --git a/rttys.conf b/rttys.conf index 2c331d0..7d660ec 100644 --- a/rttys.conf +++ b/rttys.conf @@ -38,3 +38,8 @@ # CORS support (allow all origins for cross-domain requests) #allow-origins: false + +# SSL/TLS for listen device +#sslcert: +#sslkey: +#cacert: