-
Notifications
You must be signed in to change notification settings - Fork 30
feat: Update TLS validation to use both SAN and CN fields. #979
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
Conversation
3b282f0 to
07ca9f7
Compare
07ca9f7 to
c132292
Compare
|
/gcbrun |
jackwotherspoon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we please make the description of this PR more clear on what this is solving, I thought we went forward with our previous PR for TLS validation because no more customers should require this CN validation when they have DNS names, now it seems like we are falling back to CN validation even with a DNS name present?
internal/cloudsql/tls_verify.go
Outdated
| // verifyPeerCertificateFunc creates a VerifyPeerCertificate func that | ||
| // verifies that the peer certificate is in the cert pool. We need to define | ||
| // our own because CloudSQL instances use the instance name (e.g., | ||
| // my-project:my-instance) instead of a valid domain name for the certificate's | ||
| // Common Name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these comments are out of date...
d7f512a to
6b1443a
Compare
internal/cloudsql/instance.go
Outdated
| Certificates: []tls.Certificate{c.ClientCertificate}, | ||
| RootCAs: pool, | ||
| MinVersion: tls.VersionTLS13, | ||
| // We need to set InsecureSkipVerify to true due to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should update this comment.
Historically, Cloud SQL server certificates had my-instance:my-project in the common name, which broke TLS validation and required InsecureSkipVerify being set to true. There are still instances in the Cloud SQL fleet with those certificates. So this comment is still correct for those instances. It's worth explaining why we need it for all instances now (plus any future work to improve the situation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the comment here and on the verifyPeerCertificateFunc() in tls_verify.go to provide a better explanation.
eddfae8 to
3db5f73
Compare
3db5f73 to
3713046
Compare
jackwotherspoon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM ✅ Very nice comments and description 👏
This updates the logic used by the connector to validate server certificates. When connecting to the instance, the connector's TLS validator will first check the SAN field, and then if that fails check the CN field in the certificate for the instance name. This will enable the connector to work smoothly with both legacy and newer instances. To summarize the deviations from standard TLS hostname verification: Historically, Cloud SQL creates server certificates with the instance name in the Subject.CN field in the format "my-project:my-instance". The connector is expected to check that the instance name that the connector was configured to dial matches the server certificate Subject.CN field. Thus, the Subject.CN field for most Cloud SQL instances does not contain a well-formed DNS Name. This breaks standard TLS hostname verification. Also, there are times when the instance metadata reports that an instance has a DNS name, but that DNS name does not yet appear in the SAN records of the server certificate. The client should fall back to validating the hostname using the instance name in the Subject.CN field. See also: GoogleCloudPlatform/cloud-sql-go-connector#979
This updates the logic used by the connector to validate server certificates. When connecting to the instance, the connector's TLS validator will first check the SAN field, and then if that fails check the CN field in the certificate for the instance name. This will enable the connector to work smoothly with both legacy and newer instances. To summarize the deviations from standard TLS hostname verification: Historically, Cloud SQL creates server certificates with the instance name in the Subject.CN field in the format "my-project:my-instance". The connector is expected to check that the instance name that the connector was configured to dial matches the server certificate Subject.CN field. Thus, the Subject.CN field for most Cloud SQL instances does not contain a well-formed DNS Name. This breaks standard TLS hostname verification. Also, there are times when the instance metadata reports that an instance has a DNS name, but that DNS name does not yet appear in the SAN records of the server certificate. The client should fall back to validating the hostname using the instance name in the Subject.CN field. See also: GoogleCloudPlatform/cloud-sql-go-connector#979
This updates the logic used by the connector to validate server certificates.
When connecting to the instance, the connector's TLS validator will first check the SAN field,
and then if that fails check the CN field in the certificate for the instance name. This will enable
the connector to work smoothly with both legacy and newer instances.
In the Go TLS library, the only way to replace the TLS hostname verification check is to
set
TLSConfig.InsecureSkipVerify = true, and then replace the entire TLS verificationfunction by setting
TLSConfig.VerifyPeerCertificate.To summarize the deviations from standard TLS hostname verification:
Historically, Cloud SQL creates server certificates with the instance name in the Subject.CN field in
the format "my-project:my-instance". The connector is expected to check that the instance name
that the connector was configured to dial matches the server certificate Subject.CN field. Thus,
the Subject.CN field for most Cloud SQL instances does not contain a well-formed DNS Name. This
breaks standard TLS hostname verification.
Also, there are times when the instance metadata reports that an instance has a DNS name, but
that DNS name does not yet appear in the SAN records of the server certificate. The client should
fall back to use the instance name in the Subject.CN field to validate the server certificate's identity.