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

release-21.2: pgwire: Add dynamic user identity mapping #74459

Merged
merged 1 commit into from
Jan 5, 2022
Merged

release-21.2: pgwire: Add dynamic user identity mapping #74459

merged 1 commit into from
Jan 5, 2022

Conversation

bobvawter
Copy link
Member

@bobvawter bobvawter commented Jan 5, 2022

Backport 1/1 commits from #70269.

Release justification: A customer who currently uses --cert-principal-map to interoperate with their internal Certificate Authority requirements must restart the cluster any time they want to add a new SQL user.

/cc @cockroachdb/release


This commit adds support for mapping incoming system identities (e.g.: GSSAPI
or X.509 principals) to database usernames. The implementation follows in the
same pattern as the HBA configuration. Namely, there is a new cluster setting
server.identity_map.configuration which contains data compatible with the
pg_ident.conf file.

When a new connection is made, the relevant HBA configuration line is selected
and the "map" option is used to select an identity-map ruleset. The system
identity is mapped to a database username and authentication proceeds using the
HBA entry method.

CockroachDB explicitly disallows the use of the "map" entry with the "password"
HBA method. When using the "cert-password" method, an identity mapping is
applied only for incoming connections that present a client certificate;
password-based connections will not be subject to any identity remapping.

The root user is never subject to identity remapping and cannot be locked out
by a bad identity-map configuration. The effective HBA configuration always has
a system-defined rule that matches the root user as the first rule. This
baked-in rule does not contain a "map" option, thus bypassing the mapper code
entirely.

Users must already have access to the ADMIN role in order to change cluster
settings, so this change does not, in and of itself, present
privilege-escalation concerns. Futhermore, if the identity mapping results in
the "root", "node", or other reserved usernames, an error will be returned to
the client.

For pedantry's sake, the term "identity" is preferred over "username" within
the code, since not all identities are necessarily what would be considered
usernames.

Fixes: #47196

See also: https://www.postgresql.org/docs/13/auth-username-maps.html

Release note (security update): The server.identity_map.configuration cluster
setting allows a pg_ident.conf file to be uploaded to support dynamically
remapping system identities (e.g.: Kerberos or X.509 principals) to database
usernames. This supports use-cases where X.509 certificates must conform to
organizational standards that mandate the use of Common Names that are not
valid SQL usernames (e.g.: CN=carl@example.com => carl). Mapping rules that
result in the root, node, or other reserved usernames will result in an error
when the client attempts to connect.

Release note (security update): The client_authentication_info structured log
message provides a new "SystemIdentity" field with the client-provided system
identity. The existing "User" field will be populated after any Host-Based
Authentication rules have been selected and applied, which may include a
system-identity to database-username mapping.

Release note (security update): GSSAPI-based authentication can now use either
the HBA "map" option or "include_realm=0" to map the incoming princpal to a
database username. Existing configurations will operate unchanged, however
operators are encouraged to migrate from "include_realm=0" to "map" to avoid
ambiguity in deployments where multiple realms are present.

Release note (security update): Incoming system identities are normalized to
lower-case before they are evaluated against any active identity-mapping HBA
configuration. For example, an incoming GSSAPI principal "carl@EXAMPLE.COM"
would only be matched by rules such as "example carl@example.com carl" or
"example /^(.*)@example.com$ \1".

@bobvawter bobvawter requested review from knz and a team January 5, 2022 16:29
@bobvawter bobvawter requested a review from a team as a code owner January 5, 2022 16:29
@blathers-crl
Copy link

blathers-crl bot commented Jan 5, 2022

Thanks for opening a backport.

Please check the backport criteria before merging:

  • Patches should only be created for serious issues or test-only changes.
  • Patches should not break backwards-compatibility.
  • Patches should change as little code as possible.
  • Patches should not change on-disk formats or node communication protocols.
  • Patches should not add new functionality.
  • Patches must not add, edit, or otherwise modify cluster versions; or add version gates.
If some of the basic criteria cannot be satisfied, ensure that the exceptional criteria are satisfied within.
  • There is a high priority need for the functionality that cannot wait until the next release and is difficult to address in another way.
  • The new functionality is additive-only and only runs for clusters which have specifically “opted in” to it (e.g. by a cluster setting).
  • New code is protected by a conditional check that is trivial to verify and ensures that it only runs for opt-in clusters.
  • The PM and TL on the team that owns the changed code have signed off that the change obeys the above rules.

Add a brief release justification to the body of your PR to justify this backport.

Some other things to consider:

  • What did we do to ensure that a user that doesn’t know & care about this backport, has no idea that it happened?
  • Will this work in a cluster of mixed patch versions? Did we test that?
  • If a user upgrades a patch version, uses this feature, and then downgrades, what happens?

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@bobvawter
Copy link
Member Author

@knz, old nodes will just ignore the map= option:

demo@127.0.0.1:26257/movr> select version();
                                        version
----------------------------------------------------------------------------------------
  CockroachDB CCL v21.2.2 (x86_64-apple-darwin19, built 2021/12/01 14:38:36, go1.16.6)
(1 row)

demo@127.0.0.1:26257/movr> set cluster setting server.host_based_authentication.configuration = 'host all all all cert-password map=testing';
SET CLUSTER SETTING

demo@127.0.0.1:26257/movr> show cluster setting server.host_based_authentication.configuration;
  server.host_based_authentication.configuration
--------------------------------------------------
  host all all all cert-password map=testing
(1 row)

This commit adds support for mapping incoming system identities (e.g.: GSSAPI
or X.509 principals) to database usernames. The implementation follows in the
same pattern as the HBA configuration. Namely, there is a new cluster setting
server.identity_map.configuration which contains data compatible with the
pg_ident.conf file.

When a new connection is made, the relevant HBA configuration line is selected
and the "map" option is used to select an identity-map ruleset. The system
identity is mapped to a database username and authentication proceeds using the
HBA entry method.

CockroachDB explicitly disallows the use of the "map" entry with the "password"
HBA method. When using the "cert-password" method, an identity mapping is
applied only for incoming connections that present a client certificate;
password-based connections will not be subject to any identity remapping.

The root user is never subject to identity remapping and cannot be locked out
by a bad identity-map configuration. The effective HBA configuration always has
a system-defined rule that matches the root user as the first rule. This
baked-in rule does not contain a "map" option, thus bypassing the mapper code
entirely.

Users must already have access to the ADMIN role in order to change cluster
settings, so this change does not, in and of itself, present
privilege-escalation concerns. Futhermore, if the identity mapping results in
the "root", "node", or other reserved usernames, an error will be returned to
the client.

For pedantry's sake, the term "identity" is preferred over "username" within
the code, since not all identities are necessarily what would be considered
usernames.

Fixes: #47196

See also: https://www.postgresql.org/docs/13/auth-username-maps.html

Release note (security update): The server.identity_map.configuration cluster
setting allows a pg_ident.conf file to be uploaded to support dynamically
remapping system identities (e.g.: Kerberos or X.509 principals) to database
usernames. This supports use-cases where X.509 certificates must conform to
organizational standards that mandate the use of Common Names that are not
valid SQL usernames (e.g.: CN=carl@example.com => carl). Mapping rules that
result in the root, node, or other reserved usernames will result in an error
when the client attempts to connect.

Release note (security update): The client_authentication_info structured log
message provides a new "SystemIdentity" field with the client-provided system
identity. The existing "User" field will be populated after any Host-Based
Authentication rules have been selected and applied, which may include a
system-identity to database-username mapping.

Release note (security update): GSSAPI-based authentication can now use either
the HBA "map" option or "include_realm=0" to map the incoming princpal to a
database username. Existing configurations will operate unchanged, however
operators are encouraged to migrate from "include_realm=0" to "map" to avoid
ambiguity in deployments where multiple realms are present.

Release note (security update): Incoming system identities are normalized to
lower-case before they are evaluated against any active identity-mapping HBA
configuration. For example, an incoming GSSAPI principal "carl@EXAMPLE.COM"
would only be matched by rules such as "example carl@example.com carl" or
"example /^(.*)@example.com$ \1".
@bobvawter
Copy link
Member Author

The test failure is because SQLUsername.IsReserved() doesn't check for the node user in the 21.2 branch. I have tweaked the check in role_mapper.go to test for the node user as is done for the root user.

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:

Also we've discussed this internally and I believe @aaron-crl and @abhinavg6 are on board too.

Reviewed 29 of 29 files at r1, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @bobvawter)

@abhinavg6
Copy link
Contributor

Yep, approved for the backport from PM perspective as it's a separate cluster setting (so isolated), and it's a painful experience for the customer to onboard new SQL users without it.

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.

4 participants