Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server,cli/demo: make the SQL and HTTP listeners configurable #64571

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pkg/base/test_server_args.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ type TestServerArgs struct {
TenantAddr *string
// HTTPAddr (if nonempty) is the HTTP address to use for the test server.
HTTPAddr string
// HTTPAdvertiseAddr (if nonempty) is the advertised HTTP address to use.
HTTPAdvertiseAddr string

// DisableTLSForHTTP if set, disables TLS for the HTTP interface.
DisableTLSForHTTP bool

Expand Down
46 changes: 46 additions & 0 deletions pkg/cli/cliflags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1125,13 +1125,59 @@ There should be as many TCP ports available as the value of --nodes
starting at the specified value.`,
}

DemoSQLAddr = FlagInfo{
Name: "sql-addr",
Description: `The network address for demo nodes
to listen for connection requests from SQL clients.
The port number must not be included.`,
}

DemoHTTPPort = FlagInfo{
Name: "http-port",
Description: `First port number for HTTP servers.
There should be as many TCP ports available as the value of --nodes
starting at the specified value.`,
}

DemoHTTPAddr = FlagInfo{
Name: "http-addr",
Description: `The network address for demo nodes
to listen for connection requests from HTTP clients.
The port number must not be included.

Attention: if using --secure-http=false with a non-default
--http-addr, the resulting configuration may expose an unsecured
HTTP service over a shared network, resulting in possible
remote access to the local machine.`,
}

DemoHTTPAdvertiseAddr = FlagInfo{
Name: "http-advertise-addr",
Description: `The address to include in the web UI URL
displayed upon server startup and \demo ls. It is also
the address embedded in the server TLS certificate as
Common Name (CN) when the HTTPS console is enabled with
--secure-http.
The port number should be included; add :0 after the network
address to reuse the same HTTP port as each simulated node.

The default is the same as --http-addr.`,
}

DemoSecureHTTP = FlagInfo{
Name: "secure-http",
Description: `If set, enable TLS for accessing the web UI.
This causes the demo nodes to use a self-signed
TLS certificate for the HTTP port.
Use --http-advertise-addr to control the network
address listed as Common Name (CN) in the TLS certificate.

Attention: if using --secure-http=false with a non-default
--http-addr, the resulting configuration may expose an unsecured
HTTP service over a shared network, resulting in possible
remote access to the local machine.`,
}

DemoNodes = FlagInfo{
Name: "nodes",
Description: `How many in-memory nodes to create for the demo.`,
Expand Down
9 changes: 9 additions & 0 deletions pkg/cli/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,11 @@ var demoCtx struct {
insecure bool
sqlPort int
httpPort int

sqlAddr string
httpAddr string
httpAdvertiseAddr string
secureHTTP bool
}

// setDemoContextDefaults set the default values in demoCtx. This
Expand All @@ -584,6 +589,10 @@ func setDemoContextDefaults() {
demoCtx.insecure = false
demoCtx.sqlPort, _ = strconv.Atoi(base.DefaultPort)
demoCtx.httpPort, _ = strconv.Atoi(base.DefaultHTTPPort)
demoCtx.sqlAddr = "127.0.0.1"
demoCtx.httpAddr = "127.0.0.1"
demoCtx.httpAdvertiseAddr = ""
demoCtx.secureHTTP = false
}

// stmtDiagCtx captures the command-line parameters of the 'statement-diag'
Expand Down
25 changes: 25 additions & 0 deletions pkg/cli/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,31 @@ func checkDemoConfiguration(
gen = defaultGenerator
}

// Since --insecure disables all security controls, --secure-http would
// not work properly. Better prevent the combination altogether.
if demoCtx.insecure && demoCtx.secureHTTP {
return nil, errors.New("cannot enable HTTPS in insecure mode")
}

fs := flagSetForCmd(cmd)

// Ensure that an explicit --http-addr is always combined with
// and explicit --secure-http.
if fs.Lookup(cliflags.DemoHTTPAddr.Name).Changed &&
!fs.Lookup(cliflags.DemoSecureHTTP.Name).Changed {
return nil, errors.WithHintf(
errors.Newf("using --%[1]s requires either --%[2]s=true or --%[2]s=false",
cliflags.DemoHTTPAddr.Name, cliflags.DemoSecureHTTP.Name),
"Note that --%[2]s=false with a non-default --%[1]s can result in undesired network accesses.",
cliflags.DemoHTTPAddr.Name, cliflags.DemoSecureHTTP.Name)
}

// If --http-advertise-addr was not specified, fall back
// to the http addr.
if !fs.Lookup(cliflags.DemoHTTPAdvertiseAddr.Name).Changed {
demoCtx.httpAdvertiseAddr = demoCtx.httpAddr + ":0"
}

// Make sure that the user didn't request a workload and an empty database.
if demoCtx.runWorkload && demoCtx.noExampleDatabase {
return nil, errors.New("cannot run a workload when generation of the example database is disabled")
Expand Down
55 changes: 46 additions & 9 deletions pkg/cli/demo_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func (c *transientCluster) checkConfigAndSetupLogging(
}

if !demoCtx.insecure {
if err := generateCerts(c.demoDir); err != nil {
if err := generateCerts(c.demoDir, demoCtx.secureHTTP, demoCtx.httpAdvertiseAddr); err != nil {
return err
}
}
Expand Down Expand Up @@ -560,11 +560,15 @@ func testServerArgsForTransientCluster(
storeSpec.StickyInMemoryEngineID = fmt.Sprintf("demo-node%d", nodeID)

args := base.TestServerArgs{
SocketFile: sock.filename(),
PartOfCluster: true,
Stopper: stop.NewStopper(),
JoinAddr: joinAddr,
DisableTLSForHTTP: true,
SocketFile: sock.filename(),
PartOfCluster: true,
Stopper: stop.NewStopper(),
JoinAddr: joinAddr,

SQLAddr: demoCtx.sqlAddr + ":0", // The port number may be overridden below.
HTTPAddr: demoCtx.httpAddr + ":0", // The port number may be overridden below.
HTTPAdvertiseAddr: demoCtx.httpAdvertiseAddr,

StoreSpecs: []base.StoreSpec{storeSpec},
SQLMemoryPoolSize: demoCtx.sqlPoolMemorySize,
CacheSize: demoCtx.cacheSize,
Expand All @@ -580,19 +584,27 @@ func testServerArgsForTransientCluster(
},
}

if !demoCtx.secureHTTP {
args.DisableTLSForHTTP = true
}

if !testingForceRandomizeDemoPorts {
// Unit tests can be run with multiple processes side-by-side with
// `make stress`. This is bound to not work with fixed ports.
sqlPort := sqlBasePort + int(nodeID) - 1
if sqlBasePort == 0 {
// In case the user specified zero explicitly, this is an
// instruction to revert to automatic allocation.
sqlPort = 0
}
httpPort := httpBasePort + int(nodeID) - 1
if httpBasePort == 0 {
// In case the user specified zero explicitly, this is an
// instruction to revert to automatic allocation.
httpPort = 0
}
args.SQLAddr = fmt.Sprintf(":%d", sqlPort)
args.HTTPAddr = fmt.Sprintf(":%d", httpPort)
args.SQLAddr = fmt.Sprintf("%s:%d", demoCtx.sqlAddr, sqlPort)
args.HTTPAddr = fmt.Sprintf("%s:%d", demoCtx.httpAddr, httpPort)
}

if demoCtx.localities != nil {
Expand Down Expand Up @@ -846,7 +858,32 @@ This server is running at increased risk of memory-related failures.`,
}

// generateCerts generates some temporary certificates for cockroach demo.
func generateCerts(certsDir string) (err error) {
func generateCerts(certsDir string, generateHTTPCerts bool, httpAdvAddr string) (err error) {
if generateHTTPCerts {
uicaKeyPath := filepath.Join(certsDir, security.EmbeddedUICAKey)
// Create a CA-Key for the UI certificates.
if err := security.CreateUICAPair(
certsDir,
uicaKeyPath,
defaultKeySize,
defaultCALifetime,
false, /* allowKeyReuse */
false, /*overwrite */
); err != nil {
return err
}
// Generate a certificate for the demo nodes's HTTP interface.
if err := security.CreateUIPair(
certsDir,
uicaKeyPath,
defaultKeySize,
defaultCertLifetime,
false, /* overwrite */
[]string{httpAdvAddr},
); err != nil {
return err
}
}
caKeyPath := filepath.Join(certsDir, security.EmbeddedCAKey)
// Create a CA-Key.
if err := security.CreateCAPair(
Expand Down
5 changes: 5 additions & 0 deletions pkg/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,11 @@ func init() {

intFlag(f, &demoCtx.sqlPort, cliflags.DemoSQLPort)
intFlag(f, &demoCtx.httpPort, cliflags.DemoHTTPPort)

stringFlag(f, &demoCtx.sqlAddr, cliflags.DemoSQLAddr)
stringFlag(f, &demoCtx.httpAddr, cliflags.DemoHTTPAddr)
stringFlag(f, &demoCtx.httpAdvertiseAddr, cliflags.DemoHTTPAdvertiseAddr)
boolFlag(f, &demoCtx.secureHTTP, cliflags.DemoSecureHTTP)
}

// statement-diag command.
Expand Down
3 changes: 3 additions & 0 deletions pkg/server/testserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ func makeTestConfigFromParams(params base.TestServerArgs) Config {
if params.HTTPAddr != "" {
cfg.HTTPAddr = params.HTTPAddr
}
if params.HTTPAdvertiseAddr != "" {
cfg.HTTPAdvertiseAddr = params.HTTPAdvertiseAddr
}
cfg.DisableTLSForHTTP = params.DisableTLSForHTTP
if params.DisableWebSessionAuthentication {
cfg.EnableWebSessionAuthentication = false
Expand Down