Skip to content

Commit

Permalink
pgwire, ccl: add support for LDAP server authentication
Browse files Browse the repository at this point in the history
informs #125087
fixes #124307
fixes #125076
fixes #125080
Epic CRDB-33829

Release note(enterprise, security): We will be adding a new authentication
mechanism `authLDAP` to connect to AD servers over LDAPs. Example hba conf entry
for this auth method:
```
 # TYPE    DATABASE      USER           ADDRESS             METHOD             OPTIONS
 # Allow all users to connect to using LDAP authentication with search and bind
   host    all           all            all                 ldap               ldapserver=ldap.example.com ldapport=636 "ldapbasedn=ou=users,dc=example,dc=com" "ldapbinddn=cn=readonly,dc=example,dc=com" ldapbindpasswd=readonly_password ldapsearchattribute=uid "ldapsearchfilter=(memberof=cn=cockroachdb_users,ou=groups,dc=example,dc=com)"
 # Fallback to password authentication for the root user
   host    all           root           0.0.0.0/0          password
```
Example to use for azure AD server:
```
SET cluster setting server.host_based_authentication.configuration = 'host    all           all            all                 ldap ldapserver=azure.dev ldapport=636 "ldapbasedn=OU=AADDC Users,DC=azure,DC=dev" "ldapbinddn=CN=Some User,OU=AADDC Users,DC=azure,DC=dev" ldapbindpasswd=my_pwd ldapsearchattribute=sAMAccountName "ldapsearchfilter=(memberOf=CN=azure-dev-domain-sync-users,OU=AADDC Users,DC=crlcloud,DC=dev)"
host    all           root           0.0.0.0/0          password';
```

We also add the following cluster settings:
1. `server.ldap_authentication.domain_ca` to allow operators to set a custom CA
for their domain (i.e. `example.com`).
2. `server.ldap_authentication.client.tls_certificate` and
`server.ldap_authentication.client.tls_key` to allow operators to set the client
certificate and key for establishing mTLS connection with LDAP server.

Post configuration users should be able to authenticate to LDAP server if:
1. The distinguished name corresponding to their sql username exists (we search
for the sql username using `ldapbinddn` and `ldapbindpasswd` in the `ldapbasedn`
domain with filter set to `ldapsearchfilter` and `ldapsearchattribute` key
having value sql username in db connection string) and we retrieve the DN.
2. Their bind attempt is successful with LDAP server using the retrieved DN and
provided ldap password in db connection string.

Example DB client sql login commands. Note `LDAP_SEARCH_VAL` and `SQL_USERNAME`
are same. In case of azure `LDAP_SEARCH_VAL` will be value for `sAMAccountName`:
1.
```
cockroach sql --url "postgresql://{LDAP_SEARCH_VAL}:{LDAP_PASSWORD}@{CLUSTER_HOST}:26257" --certs-dir={CLUSTER_CERT_DIR}
```
2.
```
export PGPASSWORD='LDAP_PASSWORD'
cockroach sql --certs-dir=certs --url "postgresql://{LDAP_SEARCH_VAL}@{CLUSTER_HOST}:26257"
```
  • Loading branch information
souravcrl committed Jul 10, 2024
1 parent 8ff7cd0 commit c888ed6
Show file tree
Hide file tree
Showing 15 changed files with 1,089 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@
/pkg/ccl/jwtauthccl/ @cockroachdb/cloud-identity
#!/pkg/ccl/kvccl/ @cockroachdb/kv-noreview
/pkg/ccl/kvccl/kvtenantccl/ @cockroachdb/server-prs
/pkg/ccl/ldapccl/ @cockroachdb/prodsec
#!/pkg/ccl/upgradeccl/ @cockroachdb/release-eng-prs @cockroachdb/upgrade-prs
#!/pkg/ccl/logictestccl/ @cockroachdb/sql-queries-noreview
#!/pkg/ccl/sqlitelogictestccl/ @cockroachdb/sql-queries-noreview
Expand Down
3 changes: 3 additions & 0 deletions docs/generated/settings/settings-for-tenants.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ server.hsts.enabled boolean false if true, HSTS headers will be sent along with
server.http.base_path string / path to redirect the user to upon succcessful login application
server.identity_map.configuration string system-identity to database-username mappings application
server.jwt_authentication.issuer_custom_ca string sets the custom root CA for verifying certificates while fetching JWKS from the JWT issuer application
server.ldap_authentication.client.tls_certificate string sets the client certificate for establishing mTLS connection with LDAP server application
server.ldap_authentication.client.tls_key string sets the client key for establishing mTLS connection with LDAP server application
server.ldap_authentication.domain.custom_ca string sets the custom root CA for verifying domain certificates when establishing connection with LDAP server application
server.log_gc.max_deletions_per_cycle integer 1000 the maximum number of entries to delete on each purge of log-like system tables application
server.log_gc.period duration 1h0m0s the period at which log-like system tables are checked for old entries application
server.max_connections_per_gateway integer -1 the maximum number of SQL connections per gateway allowed at a given time (note: this will only limit future connection attempts and will not affect already established connections). Negative values result in unlimited number of connections. Superusers are not affected by this limit. application
Expand Down
3 changes: 3 additions & 0 deletions docs/generated/settings/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@
<tr><td><div id="setting-server-http-base-path" class="anchored"><code>server.http.base_path</code></div></td><td>string</td><td><code>/</code></td><td>path to redirect the user to upon succcessful login</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
<tr><td><div id="setting-server-identity-map-configuration" class="anchored"><code>server.identity_map.configuration</code></div></td><td>string</td><td><code></code></td><td>system-identity to database-username mappings</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
<tr><td><div id="setting-server-jwt-authentication-issuer-custom-ca" class="anchored"><code>server.jwt_authentication.issuer_custom_ca</code></div></td><td>string</td><td><code></code></td><td>sets the custom root CA for verifying certificates while fetching JWKS from the JWT issuer</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
<tr><td><div id="setting-server-ldap-authentication-client-tls-certificate" class="anchored"><code>server.ldap_authentication.client.tls_certificate</code></div></td><td>string</td><td><code></code></td><td>sets the client certificate for establishing mTLS connection with LDAP server</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
<tr><td><div id="setting-server-ldap-authentication-client-tls-key" class="anchored"><code>server.ldap_authentication.client.tls_key</code></div></td><td>string</td><td><code></code></td><td>sets the client key for establishing mTLS connection with LDAP server</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
<tr><td><div id="setting-server-ldap-authentication-domain-custom-ca" class="anchored"><code>server.ldap_authentication.domain.custom_ca</code></div></td><td>string</td><td><code></code></td><td>sets the custom root CA for verifying domain certificates when establishing connection with LDAP server</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
<tr><td><div id="setting-server-log-gc-max-deletions-per-cycle" class="anchored"><code>server.log_gc.max_deletions_per_cycle</code></div></td><td>integer</td><td><code>1000</code></td><td>the maximum number of entries to delete on each purge of log-like system tables</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
<tr><td><div id="setting-server-log-gc-period" class="anchored"><code>server.log_gc.period</code></div></td><td>duration</td><td><code>1h0m0s</code></td><td>the period at which log-like system tables are checked for old entries</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
<tr><td><div id="setting-server-max-connections-per-gateway" class="anchored"><code>server.max_connections_per_gateway</code></div></td><td>integer</td><td><code>-1</code></td><td>the maximum number of SQL connections per gateway allowed at a given time (note: this will only limit future connection attempts and will not affect already established connections). Negative values result in unlimited number of connections. Superusers are not affected by this limit.</td><td>Serverless/Dedicated/Self-Hosted</td></tr>
Expand Down
3 changes: 3 additions & 0 deletions pkg/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ ALL_TESTS = [
"//pkg/ccl/kvccl/kvfollowerreadsccl:kvfollowerreadsccl_test",
"//pkg/ccl/kvccl/kvtenantccl/upgradeccl:upgradeccl_test",
"//pkg/ccl/kvccl/kvtenantccl/upgradeinterlockccl:upgradeinterlockccl_test",
"//pkg/ccl/ldapccl:ldapccl_test",
"//pkg/ccl/logictestccl/tests/3node-tenant-multiregion:3node-tenant-multiregion_test",
"//pkg/ccl/logictestccl/tests/3node-tenant:3node-tenant_test",
"//pkg/ccl/logictestccl/tests/5node:5node_test",
Expand Down Expand Up @@ -898,6 +899,8 @@ GO_TARGETS = [
"//pkg/ccl/kvccl/kvtenantccl/upgradeinterlockccl:upgradeinterlockccl_test",
"//pkg/ccl/kvccl/kvtenantccl:kvtenantccl",
"//pkg/ccl/kvccl:kvccl",
"//pkg/ccl/ldapccl:ldapccl",
"//pkg/ccl/ldapccl:ldapccl_test",
"//pkg/ccl/logictestccl/tests/3node-tenant-multiregion:3node-tenant-multiregion_test",
"//pkg/ccl/logictestccl/tests/3node-tenant:3node-tenant_test",
"//pkg/ccl/logictestccl/tests/5node:5node_test",
Expand Down
1 change: 1 addition & 0 deletions pkg/ccl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ go_library(
"//pkg/ccl/jwtauthccl",
"//pkg/ccl/kvccl",
"//pkg/ccl/kvccl/kvtenantccl",
"//pkg/ccl/ldapccl",
"//pkg/ccl/multiregionccl",
"//pkg/ccl/multitenantccl",
"//pkg/ccl/oidcccl",
Expand Down
1 change: 1 addition & 0 deletions pkg/ccl/ccl_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
_ "github.com/cockroachdb/cockroach/pkg/ccl/jwtauthccl"
_ "github.com/cockroachdb/cockroach/pkg/ccl/kvccl"
_ "github.com/cockroachdb/cockroach/pkg/ccl/kvccl/kvtenantccl"
_ "github.com/cockroachdb/cockroach/pkg/ccl/ldapccl"
_ "github.com/cockroachdb/cockroach/pkg/ccl/multiregionccl"
_ "github.com/cockroachdb/cockroach/pkg/ccl/multitenantccl"
_ "github.com/cockroachdb/cockroach/pkg/ccl/oidcccl"
Expand Down
62 changes: 62 additions & 0 deletions pkg/ccl/ldapccl/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "ldapccl",
srcs = [
"authentication_ldap.go",
"ldap_util.go",
"settings.go",
],
importpath = "github.com/cockroachdb/cockroach/pkg/ccl/ldapccl",
visibility = ["//visibility:public"],
deps = [
"//pkg/ccl/utilccl",
"//pkg/clusterversion",
"//pkg/security",
"//pkg/security/username",
"//pkg/server/telemetry",
"//pkg/settings",
"//pkg/settings/cluster",
"//pkg/sql/pgwire",
"//pkg/sql/pgwire/hba",
"//pkg/sql/pgwire/identmap",
"//pkg/sql/pgwire/pgcode",
"//pkg/sql/pgwire/pgerror",
"//pkg/util/log",
"//pkg/util/syncutil",
"//pkg/util/uuid",
"@com_github_cockroachdb_errors//:errors",
"@com_github_go_ldap_ldap_v3//:ldap",
],
)

go_test(
name = "ldapccl_test",
size = "small",
srcs = [
"authentication_ldap_test.go",
"main_test.go",
"settings_test.go",
],
data = glob(["testdata/**"]),
embed = [":ldapccl"],
deps = [
"//pkg/base",
"//pkg/ccl",
"//pkg/security/certnames",
"//pkg/security/securityassets",
"//pkg/security/securitytest",
"//pkg/security/username",
"//pkg/server",
"//pkg/sql/pgwire/hba",
"//pkg/testutils",
"//pkg/testutils/serverutils",
"//pkg/testutils/testcluster",
"//pkg/util/leaktest",
"//pkg/util/log",
"//pkg/util/randutil",
"@com_github_cockroachdb_errors//:errors",
"@com_github_go_ldap_ldap_v3//:ldap",
"@com_github_stretchr_testify//require",
],
)
Loading

0 comments on commit c888ed6

Please sign in to comment.