-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pgwire: accept non-TLS client conns safely in secure mode
This change makes it possible for a DBA / system administrator to reconfigure individual nodes *in a secure cluster* to accept SQL client sessions over TCP without mandating a TLS handshake. Authentication remains mandatory as per the HBA rules. Motivation: we have at least two high-profile customers who keep their nodes and client apps in a private secure network (with network-level encryption / privacy) and who experience client-side TLS as unnecessary and expensive friction. Why this does not impair security: - authentication remains mandatory (as per the HBA rules). - the feature is opt-in: the operator must set a command-line flag (`--accept-sql-without-tls`), which is not enabled by default. - there is an interlock: the user must both set up the flag and set log-in passwords for their SQL users (by default, users get created without a password and thus cannot log in without client certs). - for now, node-node connections still require TLS. For contex, the default HBA configuration is the following: ``` host all root all cert-password # fixed rule host all all all cert-password # built-in CockroachDB default local all all password # built-in CockroachDB default ``` The directive `host` covers both TLS and non-TLS incoming TCP connections (`local` is for the unix socket). The method `cert-password` means "client cert or password": without a cert, the password is mandatory. As previously, the user can further secure the configuration by restricting non-TLS connections to just a subnetwork, for example: ``` hostnossl all all 10.0.0.0/8 password # accept non-TLS auth on the 10/8 network. hostnossl all all all reject # refuse non-TLS conns from other nets. hostssl all all all cert-password # accept certs or passwords over TLS local all all password ``` Note that this change is limited to the server side: CockroachDB's own `cockroach` CLI commands do not yet know how to connect to a CockroachDB server without TLS; such connections are only supported from `psql` or SQL client drivers in apps. Release justification: fixes for high-priority or high-severity bugs in existing functionality Release note (security update): A new experimental flag `--accept-sql-without-tls` has been introduced for `cockroach start` and `start-single-node`: when specified, a secure node will also accept secure SQL connections without TLS. When this flag is enabled: - Node-to-node connections still use TLS: the server must still be started with `--certs-dir` and valid TLS cert configuration for nodes. - Client authentication (spoof protection) and authorization (access control and privilege escalation prevention) is performed by CockroachDB as usual, subject to the HBA configuration (for authn) and SQL privileges (for authz). - Transport-level security (integrity and confidentiality) for client connections must then be provided by the operator outside of CockroachDB -- for example, by using a private network or VPN dedicated to CockroachDB and its client app(s). - The flag only applies to the SQL interface. TLS is still required for the HTTP endpoint (unless `--unencrypted-localhost-http` is passed) and for the RPC endpoint. To introduce this feature into an existing cluster, proceed as follows: 1. ensure the cluster ugprade is finalized. 2. set up the HBA configuration to reject `hostnossl` connections for any network other than the one that has been secured. 3. add the command-line flag and restart the nodes. Note that even when the flag is supplied, clients can still negotiate TLS and present a valid TLS certificate to identify themselves (at least under the default HBA configuration). Finally, this flag is experimental and its ergonomics will likely change in a later version.
- Loading branch information
Showing
12 changed files
with
189 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#!/usr/bin/env bash | ||
|
||
CERTS_DIR=${CERTS_DIR:-/certs} | ||
crdb=$1 | ||
trap "set -x; killall cockroach cockroachshort || true" EXIT HUP | ||
|
||
set -euo pipefail | ||
|
||
# Disable automatic network access by psql. | ||
unset PGHOST | ||
unset PGPORT | ||
# Use root access. | ||
export PGUSER=root | ||
|
||
set +x | ||
echo "Testing non-TLS TCP connection via secure server." | ||
set -x | ||
|
||
# Start a server in secure mode and allow non-TLS SQL clients. | ||
"$crdb" start-single-node --background \ | ||
--certs-dir="$CERTS_DIR" --socket-dir=/tmp \ | ||
--accept-sql-without-tls \ | ||
--listen-addr=:12345 | ||
|
||
# Wait for server ready; also create a user that can log in. | ||
"$crdb" sql --certs-dir="$CERTS_DIR" -e "create user foo with password 'pass'" -p 12345 | ||
|
||
# verify that psql can connect to the server without TLS but auth | ||
# fails if they present the wrong password. | ||
(env PGPASSWORD=wrongpass psql 'postgres://foo@localhost:12345?sslmode=disable' -c "select 1" 2>&1 || true) | grep "password authentication failed" | ||
|
||
# now verify that psql can connect to the server without TLS with | ||
# the proper password. | ||
env PGPASSWORD=pass psql 'postgres://foo@localhost:12345?sslmode=disable' -c "select 1" | grep "1 row" | ||
|
||
set +x | ||
# Done. | ||
"$crdb" quit --certs-dir="$CERTS_DIR" -p 12345 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
config secure | ||
---- | ||
|
||
# By default, neither root nor testuser can connect without TLS. | ||
|
||
connect user=root sslmode=disable | ||
---- | ||
ERROR: node is running secure mode, SSL connection required (SQLSTATE 08P01) | ||
|
||
connect user=testuser sslmode=disable | ||
---- | ||
ERROR: node is running secure mode, SSL connection required (SQLSTATE 08P01) | ||
|
||
# Enable non-TLS secure connections. | ||
allow_non_tls | ||
---- | ||
|
||
# Since root and testuser do not have a password, they stil | ||
# cannot log in. | ||
|
||
connect user=root sslmode=disable | ||
---- | ||
ERROR: password authentication failed for user root | ||
|
||
connect user=testuser sslmode=disable | ||
---- | ||
ERROR: password authentication failed for user testuser | ||
|
||
# set the password for testuser. | ||
sql | ||
ALTER USER testuser WITH PASSWORD 'abc' | ||
---- | ||
ok | ||
|
||
# Now testuser can log in. | ||
|
||
connect password=abc user=testuser sslmode=disable | ||
---- | ||
ok defaultdb | ||
|
||
# Now disable all non-TLS conns via HBA. | ||
set_hba | ||
hostnossl all all all reject | ||
host all all all cert-password | ||
local all all password | ||
---- | ||
# Active authentication configuration on this node: | ||
# Original configuration: | ||
# host all root all cert-password # CockroachDB mandatory rule | ||
# hostnossl all all all reject | ||
# host all all all cert-password | ||
# local all all password | ||
# | ||
# Interpreted configuration: | ||
# TYPE DATABASE USER ADDRESS METHOD OPTIONS | ||
host all root all cert-password | ||
hostnossl all all all reject | ||
host all all all cert-password | ||
local all all password | ||
|
||
# Now testuser cannot log in any more (rejected by HBA). | ||
|
||
connect password=abc user=testuser sslmode=disable | ||
---- | ||
ERROR: authentication rejected by configuration | ||
|