Websocket: add option to disable TLS

The new option Websocket.NoTLS would have to be set to true
to disable the server check that enforces TLS configuration.

Resolves #1529

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
This commit is contained in:
Ivan Kozlovic
2020-07-29 17:33:02 -06:00
parent 6e1a892740
commit 20a67a5be8
3 changed files with 22 additions and 11 deletions

View File

@@ -281,6 +281,15 @@ type WebsocketOpts struct {
// Timeout for the authentication process.
AuthTimeout float64
// By default the server will enforce the use of TLS. If no TLS configuration
// is provided, you need to explicitly set NoTLS to true to allow the server
// to start without TLS configuration. Note that if a TLS configuration is
// present, this boolean is ignored and the server will run the Websocket
// server with that TLS configuration.
// Running without TLS is less secure since Websocket clients that use bearer
// tokens will send them in clear. So this should not be used in production.
NoTLS bool
// TLS configuration is required.
TLSConfig *tls.Config
// If true, map certificate values for authentication purposes.
@@ -3070,6 +3079,8 @@ func parseWebsocket(v interface{}, o *Options, errors *[]error, warnings *[]erro
o.Websocket.Host = mv.(string)
case "advertise":
o.Websocket.Advertise = mv.(string)
case "no_tls":
o.Websocket.NoTLS = mv.(bool)
case "tls":
tc, err := parseTLS(tk)
if err != nil {

View File

@@ -1229,9 +1229,6 @@ func TestAcceptError(t *testing.T) {
}
func TestAcceptLoopsDoNotLeaveOpenedConn(t *testing.T) {
testWebsocketAllowNonTLS = true
defer func() { testWebsocketAllowNonTLS = false }()
for _, test := range []struct {
name string
url func(o *Options) (string, int)
@@ -1258,6 +1255,7 @@ func TestAcceptLoopsDoNotLeaveOpenedConn(t *testing.T) {
o.Websocket.Host = "127.0.0.1"
o.Websocket.Port = -1
o.Websocket.HandshakeTimeout = 1
o.Websocket.NoTLS = true
s := RunServer(o)
defer s.Shutdown()
@@ -1321,9 +1319,6 @@ func TestAcceptLoopsDoNotLeaveOpenedConn(t *testing.T) {
}
func TestServerShutdownDuringStart(t *testing.T) {
testWebsocketAllowNonTLS = true
defer func() { testWebsocketAllowNonTLS = false }()
o := DefaultOptions()
o.DisableShortFirstPing = true
o.Accounts = []*Account{NewAccount("$SYS")}
@@ -1339,6 +1334,7 @@ func TestServerShutdownDuringStart(t *testing.T) {
o.Websocket.Host = "127.0.0.1"
o.Websocket.Port = -1
o.Websocket.HandshakeTimeout = 1
o.Websocket.NoTLS = true
// We are going to test that if the server is shutdown
// while Start() runs (in this case, before), we don't

View File

@@ -82,9 +82,6 @@ var decompressorPool sync.Pool
// From https://tools.ietf.org/html/rfc6455#section-1.3
var wsGUID = []byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
// Can be set for tests
var testWebsocketAllowNonTLS = false
type websocket struct {
frames net.Buffers
fs int64
@@ -734,8 +731,8 @@ func validateWebsocketOptions(o *Options) error {
if wo.Port == 0 {
return nil
}
// Enforce TLS...
if !testWebsocketAllowNonTLS && wo.TLSConfig == nil {
// Enforce TLS... unless NoTLS is set to true.
if wo.TLSConfig == nil && !wo.NoTLS {
return errors.New("websocket requires TLS configuration")
}
// Make sure that allowed origins, if specified, can be parsed.
@@ -840,6 +837,10 @@ func (s *Server) startWebsocketServer() {
s.mu.Unlock()
return
}
// Do not check o.NoTLS here. If a TLS configuration is available, use it,
// regardless of NoTLS. If we don't have a TLS config, it means that the
// user has configured NoTLS because otherwise the server would have failed
// to start due to options validation.
if o.TLSConfig != nil {
proto = "wss"
config := o.TLSConfig.Clone()
@@ -854,6 +855,9 @@ func (s *Server) startWebsocketServer() {
return
}
s.Noticef("Listening for websocket clients on %s://%s:%d", proto, o.Host, port)
if proto == "ws" {
s.Warnf("Websocket not configured with TLS. DO NOT USE IN PRODUCTION!")
}
s.websocket.tls = proto == "wss"
if port == 0 {