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: fix the advisory certificate check #39166

Merged
merged 1 commit into from
Jul 30, 2019
Merged

Conversation

knz
Copy link
Contributor

@knz knz commented Jul 30, 2019

Fixes #32539.

(context: cockroach start performs some advisory checks on the
certificates prior to starting up, to inform the user upfront if the
cert configuration is suspicious. These checks are complementary to
the actual security validation performed in the go std lib.)

Prior to this patch, the advisory cert validation was performing
checks on both the addres given to --listen and that given to
--advertise (either explicitly, or implicitly when derived from
--listen).

This was problematic because the listen address is really irrelevant
to security validation. What matters for node cert validation is that
the advertised address is present. So this patch removes the check on
the listen addr (recommended by @mberhault).

Additionally this patch also enhances the check on the advertise addr:
if a host name is given to --advertise-addr (either explicitly, or
implicitly as derived from --listen-addr), and the name is not
present in the cert, the validation is considered to pass if the
resolved address for the given name is present int he cert.

Release note (cli change): The advisory/informative check performed by
cockroach start on the validity of addresses contained in the node
certificate is relaxed to focus on the advertised node address, and to
tolerate cases when the cert contains an IP address but a hostname is
specified as advertised address.

@knz knz requested a review from mberhault July 30, 2019 12:58
@knz knz requested a review from a team as a code owner July 30, 2019 12:58
@knz knz requested a review from a team July 30, 2019 12:58
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@knz knz force-pushed the 20190730-cert branch from 4d685dc to 8c6af98 Compare July 30, 2019 12:59
notifyFunc := func(msg, host string) {
if buf.Len() > 0 {
buf.WriteString(" and ")
host, _, _ := net.SplitHostPort(cfg.AdvertiseAddr)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason you're ignoring the returned error? Have there been valid addresses we failed on?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm assuming here ValidateAddrs() has been called already. If the syntax was not correct that would have failed before. Do you think I should still check here with a panic("call ValidateAddrs first")?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm fine leaving it out, mostly curious.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok added the panic

@knz knz force-pushed the 20190730-cert branch from 8c6af98 to 9b12be8 Compare July 30, 2019 14:40
(context: `cockroach start` performs some advisory checks on the
certificates prior to starting up, to inform the user upfront if the
cert configuration is suspicious. These checks are complementary to
the actual security validation performed in the go std lib.)

Prior to this patch, the advisory cert validation was performing
checks on both the addres given to `--listen` and that given to
`--advertise` (either explicitly, or implicitly when derived from
`--listen`).

This was problematic because the listen address is really irrelevant
to security validation. What matters for node cert validation is that
the advertised address is present. So this patch removes the check on
the listen addr (recommended by @mberhault).

Additionally this patch also enhances the check on the advertise addr:
if a host name is given to `--advertise-addr` (either explicitly, or
implicitly as derived from `--listen-addr`), and the name is not
present in the cert, the validation is considered to pass if the
resolved address for the given name is present int he cert.

Release note (cli change): The advisory/informative check performed by
`cockroach start` on the validity of addresses contained in the node
certificate is relaxed to focus on the advertised node address, and to
tolerate cases when the cert contains an IP address but a hostname is
specified as advertised address.
@knz knz force-pushed the 20190730-cert branch from 9b12be8 to 0819797 Compare July 30, 2019 15:45
@knz
Copy link
Contributor Author

knz commented Jul 30, 2019

TFYR

bors r+

craig bot pushed a commit that referenced this pull request Jul 30, 2019
39148: importccl: Modify row_id generation for IMPORT from CSV. r=adityamaru27 a=adityamaru27

This change was motivated by a bug in which consecutive IMPORT INTO
queries into a table without an explicit PK, and from unique data
sources would overwrite instead of appending data.
This is because row_id generation was based on fileIndex and
rowNum which created colliding PKs across query runs.

To fix this we add the timestamp at which IMPORT INTO is run
at a 10-microsecond granularity to the rowNum.

39166: server: fix the advisory certificate check r=knz a=knz

Fixes #32539.

(context: `cockroach start` performs some advisory checks on the
certificates prior to starting up, to inform the user upfront if the
cert configuration is suspicious. These checks are complementary to
the actual security validation performed in the go std lib.)

Prior to this patch, the advisory cert validation was performing
checks on both the addres given to `--listen` and that given to
`--advertise` (either explicitly, or implicitly when derived from
`--listen`).

This was problematic because the listen address is really irrelevant
to security validation. What matters for node cert validation is that
the advertised address is present. So this patch removes the check on
the listen addr (recommended by @mberhault).

Additionally this patch also enhances the check on the advertise addr:
if a host name is given to `--advertise-addr` (either explicitly, or
implicitly as derived from `--listen-addr`), and the name is not
present in the cert, the validation is considered to pass if the
resolved address for the given name is present int he cert.

Release note (cli change): The advisory/informative check performed by
`cockroach start` on the validity of addresses contained in the node
certificate is relaxed to focus on the advertised node address, and to
tolerate cases when the cert contains an IP address but a hostname is
specified as advertised address.

Co-authored-by: Aditya Maru <[email protected]>
Co-authored-by: Raphael 'kena' Poss <[email protected]>
@craig
Copy link
Contributor

craig bot commented Jul 30, 2019

Build succeeded

@craig craig bot merged commit 0819797 into cockroachdb:master Jul 30, 2019
@knz knz deleted the 20190730-cert branch July 30, 2019 16:40
Copy link
Contributor

@bdarnell bdarnell 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 (waiting on @knz and @mberhault)


pkg/base/addr_validation.go, line 287 at r2 (raw file):

		}
		if err := cert.VerifyHostname(host); err != nil {
			// The hostname itself is not in the cert. Is the numeric address in the cert?

Does it work to advertise a name but only have an IP address in the cert? I don't think it does. If it does work, that would be a security problem since DNS is insecure (it's not actually a security hole in this method since it's just advisory and the real check is in crypto/tls, but it's also not doing anything useful to manually resolve the IP address and compare it to the cert as far as I can tell.

@knz
Copy link
Contributor Author

knz commented Jul 30, 2019

Ben do you have any idea where to look in the go stdlib to check what you say?

@bdarnell
Copy link
Contributor

Grep for ResolveIP in crypto/tls?

But it may be more straightforward to just write a test and see what happens: advertise localhost but only put 127.0.0.1 in the certificate. I believe that will pass this check but fail in actual usage.

@knz
Copy link
Contributor Author

knz commented Jul 30, 2019

Does it work to advertise a name but only have an IP address in the cert?

I looked into this further: yes it works. The situation(problem?) is that it's possible for a node A to advertise some hostname HA, but use A's numeric address when connecting from B (e.g. start B with --join=<Aaddr>)

In that case, B will check A's identity based on Aaddr not HA.

Because of that situation, I think it's OK to (advisorily) verify that A's numeric address is in the cert if the hostname isn't.

We could (but currently don't) validate inside the crdb protocol that the address given on B's --join matches the advertised address on A. If we did that, we would be in the simple situation you describe.

What do you think?

@bdarnell
Copy link
Contributor

This is why it's sometimes useful to have un-advertised IPs/hostnames in the cert. But that doesn't make it OK to omit the advertised hostname from the cert. In some cases the advertised address will be used, and the connection will fail unless that address is in the cert. It's possible that the cluster will still work (if there are enough nodes using the correct join address that everything can become fully connected), but I think we should still disallow advertising addresses that are not present in the cert.

@knz
Copy link
Contributor Author

knz commented Jul 30, 2019

Fixin in #39179

craig bot pushed a commit that referenced this pull request Jul 30, 2019
39179: server: simplify the advisory cert check r=knz a=knz

Tweak to the previous commit (#39166) around this code, as requested by
@bdarnell, see discussion here:
#39166 (review)

Co-authored-by: Raphael 'kena' Poss <[email protected]>
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.

cli/start: certificate error if no IP in cert (--listen translates hostname to addr and addr not in cert)
4 participants