diff --git a/server/cmd/dcrdex/config.go b/server/cmd/dcrdex/config.go index c6353d33d3..a6385ead72 100644 --- a/server/cmd/dcrdex/config.go +++ b/server/cmd/dcrdex/config.go @@ -86,6 +86,7 @@ type dexConf struct { DEXPrivKeyPath string RPCCert string RPCKey string + NoTLS bool RPCListen []string HiddenService string BroadcastTimeout time.Duration @@ -117,6 +118,7 @@ type flagsData struct { RPCCert string `long:"rpccert" description:"RPC server TLS certificate file."` RPCKey string `long:"rpckey" description:"RPC server TLS private key file."` RPCListen []string `long:"rpclisten" description:"IP addresses on which the RPC server should listen for incoming connections."` + NoTLS bool `long:"notls" description:"Run without TLS encryption."` AltDNSNames []string `long:"altdnsnames" description:"A list of hostnames to include in the RPC certificate (X509v3 Subject Alternative Name)."` HiddenService string `long:"hiddenservice" description:"A host:port on which the RPC server should listen for incoming hidden service connections. No TLS is used for these connections."` @@ -542,6 +544,7 @@ func loadConfig() (*dexConf, *procOpts, error) { DEXPrivKeyPath: cfg.DEXPrivKeyPath, RPCCert: cfg.RPCCert, RPCKey: cfg.RPCKey, + NoTLS: cfg.NoTLS, RPCListen: RPCListen, HiddenService: HiddenService, BroadcastTimeout: cfg.BroadcastTimeout, diff --git a/server/cmd/dcrdex/main.go b/server/cmd/dcrdex/main.go index 2ee769d1f4..d108c22d20 100644 --- a/server/cmd/dcrdex/main.go +++ b/server/cmd/dcrdex/main.go @@ -144,6 +144,7 @@ func mainCore(ctx context.Context) error { DEXPrivKey: privKey, CommsCfg: &dexsrv.RPCConfig{ RPCCert: cfg.RPCCert, + NoTLS: cfg.NoTLS, RPCKey: cfg.RPCKey, ListenAddrs: cfg.RPCListen, AltDNSNames: cfg.AltDNSNames, diff --git a/server/comms/server.go b/server/comms/server.go index fccba94da3..802b9482b6 100644 --- a/server/comms/server.go +++ b/server/comms/server.go @@ -179,6 +179,7 @@ type RPCConfig struct { // generated and saved to these locations. RPCKey string RPCCert string + NoTLS bool // AltDNSNames specifies allowable request addresses for an auto-generated // TLS keypair. Changing AltDNSNames does not force the keypair to be // regenerated. To regenerate, delete or move the old files. @@ -287,22 +288,30 @@ type Server struct { // is not provided as part of the RPCConfig. The server also maintains a // IP-based quarantine to short-circuit to an error response for misbehaving // clients, if necessary. -func NewServer(cfg *RPCConfig) (*Server, error) { - // Find or create the key pair. - keyExists := dex.FileExists(cfg.RPCKey) - certExists := dex.FileExists(cfg.RPCCert) - if certExists == !keyExists { - return nil, fmt.Errorf("missing cert pair file") - } - if !keyExists && !certExists { - err := genCertPair(cfg.RPCCert, cfg.RPCKey, cfg.AltDNSNames) +func NewServer(cfg *RPCConfig) (_ *Server, err error) { + + var tlsConfig *tls.Config + if !cfg.NoTLS { + // Prepare the TLS configuration. + keyExists := dex.FileExists(cfg.RPCKey) + certExists := dex.FileExists(cfg.RPCCert) + if certExists == !keyExists { + return nil, fmt.Errorf("missing cert pair file") + } + if !keyExists && !certExists { + err := genCertPair(cfg.RPCCert, cfg.RPCKey, cfg.AltDNSNames) + if err != nil { + return nil, err + } + } + keypair, err := tls.LoadX509KeyPair(cfg.RPCCert, cfg.RPCKey) if err != nil { return nil, err } - } - keypair, err := tls.LoadX509KeyPair(cfg.RPCCert, cfg.RPCKey) - if err != nil { - return nil, err + tlsConfig = &tls.Config{ + Certificates: []tls.Certificate{keypair}, // TODO: multiple key pairs for virtual hosting + MinVersion: tls.VersionTLS12, + } } // Start with the hidden service listener, if specified. @@ -331,29 +340,34 @@ func NewServer(cfg *RPCConfig) (*Server, error) { } } - // Prepare the TLS configuration. - tlsConfig := tls.Config{ - Certificates: []tls.Certificate{keypair}, // TODO: multiple key pairs for virtual hosting - MinVersion: tls.VersionTLS12, - } // Parse the specified listen addresses and create the []net.Listener. ipv4ListenAddrs, ipv6ListenAddrs, _, err := parseListeners(cfg.ListenAddrs) if err != nil { return nil, err } - for _, addr := range ipv4ListenAddrs { - listener, err := tls.Listen("tcp4", addr, &tlsConfig) + parseListener := func(network, addr string) (err error) { + var listener net.Listener + if cfg.NoTLS { + listener, err = net.Listen(network, addr) + } else { + listener, err = tls.Listen(network, addr, tlsConfig) + } if err != nil { - return nil, fmt.Errorf("cannot listen on %s: %w", addr, err) + return fmt.Errorf("cannot listen on %s: %w", addr, err) } listeners = append(listeners, listener) + return nil + } + + for _, addr := range ipv4ListenAddrs { + if err := parseListener("tcp4", addr); err != nil { + return nil, err + } } for _, addr := range ipv6ListenAddrs { - listener, err := tls.Listen("tcp6", addr, &tlsConfig) - if err != nil { - return nil, fmt.Errorf("cannot listen on %s: %w", addr, err) + if err := parseListener("tcp6", addr); err != nil { + return nil, err } - listeners = append(listeners, listener) } if len(listeners) == 0 { return nil, fmt.Errorf("RPCS: No valid listen address")