mirror of
https://github.com/zhaojh329/rttys.git
synced 2026-02-27 09:53:21 +08:00
feat: mTLS support (#68)
Signed-off-by: Jiri Novotny <k4chn1k@gmail.com>
This commit is contained in:
committed by
Jianhui Zhao
parent
2d3f9cf6d8
commit
b7cc62b0e7
@@ -30,6 +30,7 @@ This is the server program of [rtty](https://github.com/zhaojh329/rtty)
|
||||
statik -src=frontend/dist
|
||||
|
||||
## Authorization
|
||||
### Token
|
||||
Generate a token
|
||||
|
||||
$ rttys token
|
||||
@@ -40,6 +41,11 @@ Use token
|
||||
|
||||
$ rttys run -t 34762d07637276694b938d23f10d7164
|
||||
|
||||
### mTLS
|
||||
You can enable mTLS by specifying device CA storage (valid file) in config file or from CLI (variable ssl-devs).
|
||||
Appending to CA storage is possible on-the-fly, you can reload CA certs by sendig SIGUSR1 signal.
|
||||
Device(s) without valid CA in storage will be disconnected in TLS handshake.
|
||||
|
||||
## Running as a Linux service
|
||||
Move the rttys binary into /usr/local/bin/
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"crypto/x509"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
@@ -32,6 +33,7 @@ type broker struct {
|
||||
userMessage chan *usrMessage
|
||||
cmdMessage chan []byte
|
||||
webMessage chan *webResp
|
||||
devCertPool *x509.CertPool
|
||||
}
|
||||
|
||||
func newBroker(cfg *config.Config) *broker {
|
||||
|
||||
2
build.sh
2
build.sh
@@ -5,7 +5,7 @@ GitCommit=$(git log --pretty=format:"%h" -1)
|
||||
BuildTime=$(date +%FT%T%z)
|
||||
|
||||
[ $# -lt 2 ] && {
|
||||
echo "Usage: $0 linux amb64"
|
||||
echo "Usage: $0 linux amd64"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ type Config struct {
|
||||
WebPort int
|
||||
SslCert string
|
||||
SslKey string
|
||||
SslDevices string
|
||||
HTTPUsername string
|
||||
HTTPPassword string
|
||||
Token string
|
||||
@@ -49,6 +50,7 @@ func Parse(c *cli.Context) *Config {
|
||||
WebRedirURL: c.String("web-redir-url"),
|
||||
SslCert: c.String("ssl-cert"),
|
||||
SslKey: c.String("ssl-key"),
|
||||
SslDevices: c.String("ssl-devs"),
|
||||
HTTPUsername: c.String("http-username"),
|
||||
HTTPPassword: c.String("http-password"),
|
||||
Token: c.String("token"),
|
||||
@@ -74,6 +76,7 @@ func Parse(c *cli.Context) *Config {
|
||||
getConfigOpt(yamlCfg, "web-redir-url", &cfg.WebRedirURL)
|
||||
getConfigOpt(yamlCfg, "ssl-cert", &cfg.SslCert)
|
||||
getConfigOpt(yamlCfg, "ssl-key", &cfg.SslKey)
|
||||
getConfigOpt(yamlCfg, "ssl-devs", &cfg.SslDevices)
|
||||
getConfigOpt(yamlCfg, "http-username", &cfg.HTTPUsername)
|
||||
getConfigOpt(yamlCfg, "http-password", &cfg.HTTPPassword)
|
||||
getConfigOpt(yamlCfg, "token", &cfg.Token)
|
||||
|
||||
14
device.go
14
device.go
@@ -6,8 +6,10 @@ import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -272,6 +274,18 @@ func listenDevice(br *broker) {
|
||||
tlsConfig.Time = time.Now
|
||||
tlsConfig.Rand = rand.Reader
|
||||
|
||||
caCert, err := ioutil.ReadFile(cfg.SslDevices)
|
||||
if err != nil {
|
||||
log.Warn().Msgf("mTLS not used: %s", err.Error())
|
||||
} else {
|
||||
br.devCertPool = x509.NewCertPool()
|
||||
br.devCertPool.AppendCertsFromPEM(caCert)
|
||||
|
||||
// Create the TLS Config with the CA pool and enable Client certificate validation
|
||||
tlsConfig.ClientCAs = br.devCertPool
|
||||
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||
}
|
||||
|
||||
ln = tls.NewListener(ln, tlsConfig)
|
||||
log.Info().Msgf("Listen device on: %s SSL on", cfg.AddrDev)
|
||||
} else {
|
||||
|
||||
30
main.go
30
main.go
@@ -3,7 +3,10 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"runtime"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/urfave/cli/v2"
|
||||
@@ -17,6 +20,8 @@ func runRttys(c *cli.Context) {
|
||||
rlog.SetPath(c.String("log"))
|
||||
|
||||
cfg := config.Parse(c)
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGUSR1)
|
||||
|
||||
if cfg.HTTPUsername == "" {
|
||||
fmt.Println("You must configure the http username by commandline or config file")
|
||||
@@ -46,6 +51,26 @@ func runRttys(c *cli.Context) {
|
||||
listenDeviceWeb(br)
|
||||
httpStart(br)
|
||||
|
||||
go func() {
|
||||
for {
|
||||
s := <-sigs
|
||||
switch s {
|
||||
case syscall.SIGUSR1:
|
||||
if br.devCertPool != nil {
|
||||
log.Info().Msg("Reload certs for mTLS")
|
||||
caCert, err := ioutil.ReadFile(cfg.SslDevices)
|
||||
if err != nil {
|
||||
log.Info().Msgf("mTLS update faled: %s", err.Error())
|
||||
} else {
|
||||
br.devCertPool.AppendCertsFromPEM(caCert)
|
||||
}
|
||||
} else {
|
||||
log.Warn().Msg("Reload certs failed: mTLS not used")
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
select {}
|
||||
}
|
||||
|
||||
@@ -105,6 +130,11 @@ func main() {
|
||||
Value: "",
|
||||
Usage: "ssl key file Path",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "ssl-devs",
|
||||
Value: "",
|
||||
Usage: "mtls CA storage in PEM file Path",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "http-username",
|
||||
Value: "",
|
||||
|
||||
Reference in New Issue
Block a user