Skip to content

server: add basic TLS support to tenant HTTP server #69723

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

Merged
merged 1 commit into from
Sep 10, 2021

Conversation

dhartunian
Copy link
Collaborator

@dhartunian dhartunian commented Sep 1, 2021

Previously, the tenant HTTP server only served non-TLS connections by
default. This change will use the TLS config when it's present and serve
the HTTP server over TLS on the tenant. As on dedicated nodes, the
configuration will pick up the optional UI cert or the node cert as a
fallback.

This change also adds TLS to all other HTTP servers on the tenant server
including the _status/vars endpoint and pprof endpoints.

Resolves #69927

Release justification: fixing high-priority bug in existing
functionality.

Release note (security update): sql tenant servers will now use a TLS
certificate for their HTTP server when it's present. Previously this
server never used TLS.

@dhartunian dhartunian requested review from chrisseto and a team September 1, 2021 23:46
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@dhartunian dhartunian requested a review from knz September 1, 2021 23:52
Copy link
Contributor

@chrisseto chrisseto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @knz)

Copy link
Contributor

@knz knz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @dhartunian)


pkg/server/tenant.go, line 191 at r1 (raw file):

	// Additionally, all tenant HTTPS access will be via proxy.
	// TODO(davidh): Use a UI certificate here instead of node cert.
	serverTLSConfig, err := args.rpcContext.GetServerTLSConfig()

I think most unit tests expect to use the UI certs. It will make your life more complicated to make this choice here.

Copy link
Collaborator Author

@dhartunian dhartunian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @knz)


pkg/server/tenant.go, line 191 at r1 (raw file):

Previously, knz (kena) wrote…

I think most unit tests expect to use the UI certs. It will make your life more complicated to make this choice here.

Good call. I modified the logic in GetUIServerTLSConfig instead.

@dhartunian dhartunian requested a review from knz September 9, 2021 18:51
Copy link
Contributor

@knz knz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 2 of 4 files at r2, 3 of 3 files at r4, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @dhartunian)


pkg/rpc/tls.go, line 205 at r4 (raw file):

// config. When called on a tenant instance, will fall back to returning
// the server TLS config for the node if the UI Server Config cannot be
// found. This choice was made to allow for simpler configuration

simpler simpler


pkg/rpc/tls.go, line 224 at r4 (raw file):

	tlsCfg, err := cm.GetUIServerTLSConfig()
	if tlsCfg == nil && ctx.tenID != roachpb.SystemTenantID {
		ctx := context.Background()

sorry can you spell out for me why you need this fallback? It looks to me that the remainder of the PR is sufficient to resolve the linked issue, without this fallback.

Copy link
Collaborator Author

@dhartunian dhartunian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @chrisseto and @knz)


pkg/rpc/tls.go, line 205 at r4 (raw file):

Previously, knz (kena) wrote…

simpler simpler

done.


pkg/rpc/tls.go, line 224 at r4 (raw file):

Previously, knz (kena) wrote…

sorry can you spell out for me why you need this fallback? It looks to me that the remainder of the PR is sufficient to resolve the linked issue, without this fallback.

The fallback was requested from @chrisseto because we do not currently generate any UI certs for tenants and doing so would require many more changes on the Intrusion side. Since the UI/HTTP will never be accessed directly from the public internet and only via our own proxy, it seems reasonable to use the node server cert so we could support TLS between the proxy and the tenant.

Copy link
Collaborator Author

@dhartunian dhartunian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @chrisseto and @knz)


pkg/rpc/tls.go, line 224 at r4 (raw file):

Previously, dhartunian (David Hartunian) wrote…

The fallback was requested from @chrisseto because we do not currently generate any UI certs for tenants and doing so would require many more changes on the Intrusion side. Since the UI/HTTP will never be accessed directly from the public internet and only via our own proxy, it seems reasonable to use the node server cert so we could support TLS between the proxy and the tenant.

Actually, I now realize there is already a fallback elsewhere in the code. Let me test without the fallback, I think you're correct @knz.

// getUICertLocked returns the UI certificate if present, otherwise returns
// the node certificate.
// cm.mu must be held.
func (cm *CertificateManager) getUICertLocked() (*CertInfo, error) {
if cm.uiCert == nil {
// No UI certificate: use node certificate.
return cm.getNodeCertLocked()
}
if err := checkCertIsValid(cm.uiCert); err != nil {
return nil, makeError(err, "problem with UI certificate")
}
return cm.uiCert, nil
}

Copy link
Collaborator Author

@dhartunian dhartunian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @chrisseto and @knz)


pkg/rpc/tls.go, line 224 at r4 (raw file):

Previously, dhartunian (David Hartunian) wrote…

Actually, I now realize there is already a fallback elsewhere in the code. Let me test without the fallback, I think you're correct @knz.

// getUICertLocked returns the UI certificate if present, otherwise returns
// the node certificate.
// cm.mu must be held.
func (cm *CertificateManager) getUICertLocked() (*CertInfo, error) {
if cm.uiCert == nil {
// No UI certificate: use node certificate.
return cm.getNodeCertLocked()
}
if err := checkCertIsValid(cm.uiCert); err != nil {
return nil, makeError(err, "problem with UI certificate")
}
return cm.uiCert, nil
}

I confirmed that the fallback is unnecessary, the node cert will be used automatically since the UI cert is already optional. Thanks for the nudge @knz, all modifications to tls.go and its test have been removed from this PR.

Copy link
Contributor

@knz knz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm: thank you!

Reviewed 2 of 2 files at r6, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (and 1 stale) (waiting on @chrisseto and @knz)

@dhartunian
Copy link
Collaborator Author

TFTR!

bors r=knz,chrisseto

@craig
Copy link
Contributor

craig bot commented Sep 10, 2021

Build failed:

@dhartunian
Copy link
Collaborator Author

bors r-

Previously, the tenant HTTP server only served non-TLS connections by
default. This change will use the TLS config when it's present and serve
the HTTP server over TLS on the tenant. As on dedicated nodes, the
configuration will pick up the optional UI cert or the node cert as a
fallback.

This change also adds TLS to all other HTTP servers on the tenant server
including the `_status/vars` endpoint and `pprof` endpoints.

Resolves cockroachdb#69927

Release justification: fixing high-priority bug in existing
functionality.

Release note (security update): sql tenant servers will now use a TLS
certificate for their HTTP server when it's present. Previously this
server never used TLS.
@dhartunian
Copy link
Collaborator Author

bors r=knz,chrisseto

@craig
Copy link
Contributor

craig bot commented Sep 10, 2021

Build succeeded:

@craig craig bot merged commit 0e3c319 into cockroachdb:master Sep 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use HTTPS for Tenant Pod UI endpoints
4 participants