Error when trying to enable encryption in transit & start the Yugabyte on the 1st node

  1. In secure cluster, gflags related to YCQL and YSQL authentication are enabled by default. It also enables encryption in transit between server to server and client-server communication.

In insecure cluster, gflags related to authentication and TLS will be not be set. Apps and tools can connect to the cluster without password authentication on plain text.

  1. Following docs explains details regarding mtls - TLS and authentication | YugabyteDB Docs

To use TLS with both password authentication and client certificate verification, you can set the ysql_hba_conf_csv flag as follows:

hostssl all all all md5 clientcert=verify-full

Hi @nmalladi Thanks, I’m trying to set TLS without authentication & have specified ysql_hba_conf_csv & ysql_enable_auth accordingly but it is still asking for the password

NON-PROD:!:_aws-us-west-2a-ybdb1d-crdb-01:/home/crdbadmin> cat yugabyte_start.conf
{
"data_dir": "/crdb/data/yugabyte",
"log_dir": "/crdb/log/yugabyte",
"ysql_port": 9090,
"ycql_port": 9091,
"master_rpc_port": 9092,
"tserver_rpc_port": 9093,
"master_webserver_port": 9094,
"tserver_webserver_port": 9095,
"ysql_metric_port": 9096,
"yugabyted_ui_port":9097,
"ysql_enable_auth": false,
"certs_dir": "/home/crdbadmin/ybdb1d/certs",
"ca_cert_file_path": "/home/crdbadmin/ybdb1d/certs",
"secure": true,
"insecure": false,
"ysql_hba_conf_csv": "hostssl all all all trust clientcert=verify-full",
"backup_daemon": true
}
+---------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                  yugabyted                                                                  |
+---------------------------------------------------------------------------------------------------------------------------------------------+
| Status              : Running.                                                                                                              |
| YSQL Status         : Ready                                                                                                                 |
| Replication Factor  : 1                                                                                                                     |
| Security Features   : Encryption-in-transit, Password Authentication                                                                        |
| YugabyteDB UI       : http://aws-us-west-2a-ybdb1d-crdb-01.g.apple.com:9097                                                                 |
| JDBC                : jdbc:postgresql://aws-us-west-2a-ybdb1d-crdb-01.g.apple.com:9090/yugabyte?user=yugabyte&password=<DB_PASSWORD>        |
| YSQL                : bin/ysqlsh -h aws-us-west-2a-ybdb1d-crdb-01.g.apple.com -p 9090 -U yugabyte -d yugabyte                               |
| YCQL                : bin/ycqlsh aws-us-west-2a-ybdb1d-crdb-01.g.apple.com 9091 -u cassandra --ssl                                          |
| Data Dir            : /crdb/data/yugabyte                                                                                                   |
| Log Dir             : /crdb/log/yugabyte                                                                                                    |
| Universe UUID       : 961f29fb-573b-474a-870c-f93c6db38a1a                                                                                  |
+---------------------------------------------------------------------------------------------------------------------------------------------+

Hi @vineet2k1 , enabling the secure flag forces TLS as well as password authentication.
We don’t recommend using TLS without authentication. Can you tell us a bit about you usecase and the requirement to use TLS without authentication.

If you want to use this method, you’ll need to use the insecure flag while explicitly setting the correct gFlags for master and tserver processes. Here is doc link explaining the security related gFlags for master and tserver: Enable encryption in transit | YugabyteDB Docs

Config file:

    "master_rpc_port": 9092,
    "tserver_rpc_port": 9093,
    "master_webserver_port": 9094,
    "tserver_webserver_port": 9095,
    "ysql_port": 9090,
    "ycql_port": 9091,
    "ysql_metric_port": 9096,
    "ycql_metric_port": 12000,
    "cloud_provider": "aws",
    "cloud_region": "us-west-2",
    "cloud_zone": "us-west-2a",
    "insecure": false,
    "dns_enabled": true,
    "master_flags": "certs_dir=/home/gargsans/server_certs,allow_insecure_connections=false,use_node_to_node_encryption=true",
    "tserver_flags": "certs_dir=/home/gargsans/server_certs,allow_insecure_connections=false,use_node_to_node_encryption=true,use_client_to_server_encryption=true,ysql_hba_conf_csv={hostssl all all all trust clientcert=verify-full}"

ysql_hba_conf_csv is not a flag of yugabyted you’ll need to set the it inside the tserver_flags. Any CSV value flag needs to be enclosed inside curly braces: yugabyted reference | YugabyteDB Docs

Start the node:

./yugabyted start --base_dir ~/yb-cluster/node1 --config ~/ybd.conf --advertise_address dev-server-sgarg.us-west1-b.c.yugabyte.internal

Since the hba_conf was set to clientcert=verify-full, you’ll need to use a set of client certificates with ysqlsh.

./ysqlsh -h dev-server-sgarg.us-west1-b.c.yugabyte.internal -U yugabyte "sslcert=/home/gargsans/client_certs/client_yugabyte.crt sslkey=/home/gargsans/client_certs/client_yugabyte.key sslrootcert=/home/gargsans/client_certs/ca.crt" -p 9090

ysqlsh (15.2-YB-2.25.0.0-b0)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

yugabyte=#

The client certs needs to be created using the same root-ca which was used to create the server certs along with the CN as the username of the ysqlsh. In the provided the example, the client certs were created using CN yugabyte

Thank you @Sanskar_Garg will try it, the objective behind it is, the TLS will take care of the transit encryption & for authentication we are using certs anyways, so that way we are secured & can get benefit of mTLS as well, Thx.

HI @Sanskar_Garg i tied but not working, below is the command Im running:

$HOME/yb_open_binaries/yugabyte-2.25.0.0/bin/ysqlsh -h $(hostname) -U yugabyte -p 9090 "sslcert=/home/crdbadmin/ybdb1d/certs/client.node.crt sslkey=/home/crdbadmin/ybdb1d/certs/client.node.key sslrootcert=/home/crdbadmin/ybdb1d/certs/ca-client.crt"

Error:

y=/home/crdbadmin/ybdb1d/certs/client.node.key sslrootcert=/home/crdbadmin/ybdb1d/certs/ca-client.crt"n/ysqlsh -h $(hostname) -U yugabyte -p 9090 "sslcert=/home/crdbadmin/ybdb1d/certs/client.node.crt sslkey
ysqlsh: error: connection to server at "aws-us-west-2a-ybdb1d-crdb-01.g.apple.com" (100.76.212.207), port 9090 failed: FATAL:  "trust" authentication failed for user "yugabyte"
connection to server at "aws-us-west-2a-ybdb1d-crdb-01.g.apple.com" (100.76.212.207), port 9090 failed: FATAL:  no pg_hba.conf entry for host "100.76.212.207", user "yugabyte", database "yugabyte", no encryption

I see that the authentication is failing for the user yugabyte.
Can you confirm once that the certs:

  1. Were created using the same root-ca that was used to create the server certs
  2. the client certs has CN set as yugabyte (ysqlsh username)
  3. the sslrootcert is the same ca.crt as the one used in server certs.

HI @Sanskar_Garg Im working on it, will update once done, Thx.

Hi @Sanskar_Garg im trying to create like below, even when defining insecure as FALSE after creating the cluster in the conf file is shows insecure TRUE only

$HOME/yb_open_binaries/yugabyte-2.25.0.0/bin/yugabyted start \
--config $HOME/yugabyte_start_mtls.conf \
--advertise_address=$(hostname) \
--cloud_location=$(get_aws_region_az) \
--base_dir=$HOME/yb_open_binaries \
--fault_tolerance=region

}NON-PROD:!:_aws-us-west-2a-ybdb1d-crdb-01:/home/crdbadmin> cat $HOME/yugabyte_start_mtls.conf
{
"data_dir": "/crdb/data/yugabyte",
"log_dir": "/crdb/log/yugabyte",
"ysql_port": 9090,
"ycql_port": 9097,
"master_rpc_port": 9092,
"tserver_rpc_port": 9093,
"master_webserver_port": 9094,
"tserver_webserver_port": 9095,
"ysql_metric_port": 9096,
"yugabyted_ui_port":9091,
"backup_daemon": true,
"insecure": false,
"master_flags": "certs_dir=/home/crdbadmin/ybdb1d/certs,allow_insecure_connections=false,use_node_to_node_encryption=true",
"tserver_flags": "certs_dir=/home/crdbadmin/ybdb1d/certs,allow_insecure_connections=false,use_node_to_node_encryption=true,use_client_to_server_encryption=true,ysql_hba_conf_csv={hostssl all all all trust clientcert=verify-ca}"
}

NON-PROD:!:_aws-us-west-2a-ybdb1d-crdb-01:/home/crdbadmin> cat yb_open_binaries/conf/yugabyted.conf
{
    "data_dir": "/crdb/data/yugabyte",
    "additional_data_dir": "",
    "log_dir": "/crdb/log/yugabyte",
    "gen_certs_dir": "/home/crdbadmin/yb_open_binaries/generated_certs",
    "master_rpc_port": 9092,
    "tserver_rpc_port": 9093,
    "master_webserver_port": 9094,
    "tserver_webserver_port": 9095,
    "ysql_port": 9090,
    "ycql_port": 9097,
    "ysql_metric_port": 9096,
    "ycql_metric_port": 12000,
    "advertise_address": "aws-us-west-2a-ybdb1d-crdb-01.g.apple.com",
    "webserver_port": 7200,
    "yugabyted_ui_port": 9091,
    "universe_uuid": "96233345-3c83-4bd8-be60-ea552b357d6d",
    "node_uuid": "ed6d4b6a-a931-4c8c-8aa1-67439da92715",
    "tserver_uuid": "c757c909f8694fd08333e07922dd09b3",
    "master_uuid": "3bcc86a135a548bf8674557a6c014e0b",
    "placement_uuid": "198d02d8-b9fb-4830-b2bb-15b1e0c0b51f",
    "polling_interval": "5",
    "callhome": true,
    "master_flags": "certs_dir=/home/crdbadmin/ybdb1d/certs,allow_insecure_connections=false,use_node_to_node_encryption=true",
    "tserver_flags": "certs_dir=/home/crdbadmin/ybdb1d/certs,allow_insecure_connections=false,use_node_to_node_encryption=true,use_client_to_server_encryption=true,ysql_hba_conf_csv={hostssl all all all trust clientcert=verify-ca}",
    "join": "",
    "ysql_enable_auth": false,
    "use_cassandra_authentication": false,
    "cloud_provider": "aws",
    "cloud_region": "us-west-2",
    "cloud_zone": "us-west-2a",
    "fault_tolerance": "region",
    "secure": false,
    "insecure": true,
    "certs_dir": "/home/crdbadmin/yb_open_binaries/certs",
    "ca_cert_file_path": "",
    "database_password": null,
    "current_masters": "aws-us-west-2a-ybdb1d-crdb-01.g.apple.com:9092",
    "ui": true,
    "backup_daemon": true,
    "dns_enabled": true,
    "read_replica": false,
    "cluster_member": true
}

+----------------------------------------------------------------------------------------------------------------------------------------+
|                                                               yugabyted                                                                |
+----------------------------------------------------------------------------------------------------------------------------------------+
| Status              : Running.                                                                                                         |
| YSQL Status         : Ready                                                                                                            |
| Replication Factor  : 1                                                                                                                |
| YugabyteDB UI       : http://aws-us-west-2a-ybdb1d-crdb-01.g.apple.com:9091                                                            |
| JDBC                : jdbc:postgresql://aws-us-west-2a-ybdb1d-crdb-01.g.apple.com:9090/yugabyte?user=yugabyte&password=yugabyte        |
| YSQL                : bin/ysqlsh -h aws-us-west-2a-ybdb1d-crdb-01.g.apple.com -p 9090 -U yugabyte -d yugabyte                          |
| YCQL                : bin/ycqlsh aws-us-west-2a-ybdb1d-crdb-01.g.apple.com 9097 -u cassandra                                           |
| Data Dir            : /crdb/data/yugabyte                                                                                              |
| Log Dir             : /crdb/log/yugabyte                                                                                               |
| Universe UUID       : 96233345-3c83-4bd8-be60-ea552b357d6d                                                                             |
+----------------------------------------------------------------------------------------------------------------------------------------+

Hi @Sanskar_Garg @nmalladi can you please help with. We are trying to get it all resolved so can go ahead with other parts of the POC, Thanks.

Hi @vineet2k1

The behaviour of --secure and --insecure flag is mutually exclusive. By default yugabyted node will set the flag --insecure to true , value of this flag cannot be updated by the user by design. If you want to set the --insecure to false, you will have to use the --secure flag when starting the yugabyted node. This will set the --insecure to fasle.

Internally we have bunch of logic which is driven by the --secure and --insecure flags on yugabyted start.

Ok @nmalladi it’s little confusing for sure :slight_smile: My ask is to set the cluster mTLS enabled so exactly what shall I set for below 2 setups:

  1. mTLS without authentication.
  2. mTLS with authentication.

As @Sanskar_Garg had mentioned in his earlier response, these configurations will enable mtls on the cluster. However, yugabyted conf will have the --insecure as true as tls configurations were directly getting passed using gflags.

Got it, We can try to make it better. From a yugabyted perspective, we support only two options: --secure or --insecure [both TLS and authentication].

  • Insecure cluster
yugabyted start 

or

yugabyted start --insecure
  • Both the above commands start an insecure cluster
  • by default, we set --insecure to true
  • Secure cluster
yugabyted start --secure
  • This enables both password and TLS authentication
  • This sets the --insecure flag to false
  1. mTLS without authentication: This is something we don’t support with yugabyted natively and as we mentioned you’re trying out a custom solution.

wondering whether the steps sent here worked for you?

I’m able to start the Leader node, when starting the follower getting below error:

–Conf file:

[crdbadmin@aws-us-west-2c-ybdb1d-crdb-02 ~]$ cat yugabyte_start_mtls.conf
{
"data_dir": "/crdb/data/yugabyte",
"log_dir": "/crdb/log/yugabyte",
"ysql_port": 9090,
"ycql_port": 9097,
"master_rpc_port": 9092,
"tserver_rpc_port": 9093,
"master_webserver_port": 9094,
"tserver_webserver_port": 9095,
"ysql_metric_port": 9096,
"yugabyted_ui_port":9091,
"backup_daemon": true,
"insecure": false,
"master_flags": "certs_dir=/home/crdbadmin/ybdb1d/certs,allow_insecure_connections=false,use_node_to_node_encryption=true",
"tserver_flags": "certs_dir=/home/crdbadmin/ybdb1d/certs,allow_insecure_connections=false,use_node_to_node_encryption=true,use_client_to_server_encryption=true,ysql_hba_conf_csv={hostssl all all all trust clientcert=verify-ca}"
}
[crdbadmin@aws-us-west-2c-ybdb1d-crdb-02 ~]$ $HOME/yb_open_binaries/yugabyte-2.25.0.0/bin/yugabyted start \
> --config $HOME/yugabyte_start_mtls.conf \
> --advertise_address=$(hostname) \
> --join aws-us-west-2a-ybdb1d-crdb-01.g.apple.com \
> --cloud_location=$(get_aws_region_az) \
> --base_dir=$HOME/yb_open_binaries \
> --fault_tolerance=region
Fetching configs from join IP...
ERROR: The node whose IP was provided in --join flag has SSL/TLS enabled. Cannot join a secure and an insecure node.
[crdbadmin@aws-us-west-2c-ybdb1d-crdb-02 ~]$ ls -l /home/crdbadmin/ybdb1d/certs
total 104
-rw-r--r--. 1 crdbadmin dba 2891 Feb 22 00:24 ca-client.crt
-rw-r--r--. 1 crdbadmin dba 2875 Feb 22 00:24 ca.crt
-rw-------. 1 crdbadmin dba 2891 Feb 22 00:24 ca.root.crt
-rw-------. 1 crdbadmin dba 2891 Feb 22 00:24 ca.root.crt_bkp
-rw-r--r--. 1 crdbadmin dba 1700 Feb 22 00:24 client.node.crt
-rw-r--r--. 1 crdbadmin dba 1679 Feb 22 00:24 client.node.key
-rw-r--r--. 1 crdbadmin dba 1854 Feb 22 00:24 client.nodekey.pem
-rw-r--r--. 1 crdbadmin dba  883 Feb 22 00:24 client.node.unsigned.csr
-rw-r--r--. 1 crdbadmin dba 4591 Feb 22 00:24 client.root.crt
-rw-r--r--. 1 crdbadmin dba 1679 Feb 22 00:24 client.root.key
-rw-r--r--. 1 crdbadmin dba 1854 Feb 22 00:24 client.rootkey.pem
-rw-r--r--. 1 crdbadmin dba  883 Feb 22 00:24 client.root.unsigned.csr
-rw-------. 1 crdbadmin dba 1679 Feb 22 00:24 client.yugabyte.key
-rw-------. 1 crdbadmin dba 1679 Feb 22 00:24 client.yugabyte.key_bkp
-rw-r--r--. 1 crdbadmin dba 5733 Feb 22 00:24 node.aws-us-west-2c-ybdb1d-crdb-02.g.apple.com.crt
-r--------. 1 crdbadmin dba 1679 Feb 22 00:24 node.aws-us-west-2c-ybdb1d-crdb-02.g.apple.com.key
-rw-r--r--. 1 crdbadmin dba 5733 Feb 22 00:24 node.crt
-r--------. 1 crdbadmin dba 1679 Feb 22 00:24 node.key
-rw-r--r--. 1 crdbadmin dba 1854 Feb 22 00:24 serverkey.pem
-rw-r--r--. 1 crdbadmin dba  784 Feb 22 00:24 ybdb.ybdb1d.corp.apple.com.cnf
-rw-r--r--. 1 crdbadmin dba 1700 Feb 22 00:24 ybdb.ybdb1d.corp.apple.com.csr
-rw-------. 1 crdbadmin dba 2439 Feb 22 00:24 yugabyte.cert.crt
-rw-------. 1 crdbadmin dba 1708 Feb 22 00:24 yugabyte.cert.crt_bkp

Ahh, Looks like we have validations that don’t support this way of deploying multi-node clusters with yuagbyted. cc @Sanskar_Garg. I’ll open a feature request to support TLS without authentication in yugabyted.

Let me see if there are any other ways of doing mtls without enabling authentication in ybd. Otherwise, we will have to fall back on using yb-master and yb-tserver CLI and follow these steps - Enable encryption in transit | YugabyteDB Docs

Thanks,
Nikhil

Ok @nmalladi this is really important for our setup, expedite help is really appreciated. Also, so if we setup with “mTLS with authentication” what shall we change in below:

{
"data_dir": "/crdb/data/yugabyte",
"log_dir": "/crdb/log/yugabyte",
"ysql_port": 9090,
"ycql_port": 9097,
"master_rpc_port": 9092,
"tserver_rpc_port": 9093,
"master_webserver_port": 9094,
"tserver_webserver_port": 9095,
"ysql_metric_port": 9096,
"yugabyted_ui_port":9091,
"backup_daemon": true,
"insecure": false,
"master_flags": "certs_dir=/home/crdbadmin/ybdb1d/certs,allow_insecure_connections=false,use_node_to_node_encryption=true",
"tserver_flags": "certs_dir=/home/crdbadmin/ybdb1d/certs,allow_insecure_connections=false,use_node_to_node_encryption=true,use_client_to_server_encryption=true,ysql_hba_conf_csv={hostssl all all all trust clientcert=verify-ca}"
}

@vineet2k1

For multi-node, mTLS is not supported natively with yugabyted. You’ll need to use yb-master and yb-tserver CLI for setting up the cluster. We’re working on an approach to enable mTLS without a password using yugabyted, one of us will share the steps by tomorrow.

Thanks,
Nikhil

Hi @vineet2k1 , as @nmalladi mentioned, yugabyted doesn’t have native support for enabling mTLS. Let’s break down the issues you have faced and then the solution for it.

Issues:

  • When you were trying to start a node with --secure flag and mTLS enabled, it failed. This is because enabling mTLS means client_certs are required to connect to ysqlsh and when yugabyted tries to update the password (since --secure flag was used), it fails.
  • A workaround here was to not use secure flag and just enable mTLS by explicitly specifying the required gFlags. This would work for single node. But when trying to start a 2nd node , it would fail as yugabyted doesn’t allow a node without --secure flag to join to a node with gFlags, for enabling TLS, set.

Solution:

Requirements:

Following set of certificates:

  • Server Certs: ca.crt, node.<node_hostname>.crt, node.<node_hostname>.key
  • Client Certs: ca.crt, <client_name>.crt, <client_name>.key

Please ensure that the ca.crt is same for both set of certs and same set of root-ca certificates were used to create both server and client certs.

Now to tackle the 2nd issue, we’ll first start all the nodes in a normal TLS fashion with the server certs.

Your yugabyte_start_mtls.conf would look like:

{
    "data_dir": "/crdb/data/yugabyte",
    "log_dir": "/crdb/log/yugabyte",
    "ysql_port": 9090,
    "ycql_port": 9097,
    "master_rpc_port": 9092,
    "tserver_rpc_port": 9093,
    "master_webserver_port": 9094,
    "tserver_webserver_port": 9095,
    "ysql_metric_port": 9096,
    "yugabyted_ui_port": 9091,
    "backup_daemon": true,
    "certs_dir": "/home/crdbadmin/ybdb1d/certs"
}

Start the 1st node using:

$HOME/yb_open_binaries/yugabyte-2.25.0.0/bin/yugabyted start \
 --secure \
 --config $HOME/yugabyte_start_mtls.conf \
 --advertise_address=$(hostname) \
 --cloud_location=$(get_aws_region_az) \
 --base_dir=$HOME/yb_open_binaries \
 --fault_tolerance=region

This will start a node with only TLS enabled. The --secure flag will take care of setting the required gFlags, so no need to explicitly set them.

Add more nodes to it:

$HOME/yb_open_binaries/yugabyte-2.25.0.0/bin/yugabyted start \
 --secure \
 --config $HOME/yugabyte_start_mtls.conf \
 --advertise_address=$(hostname) \
 --join aws-us-west-2a-ybdb1d-crdb-01.g.apple.com \
 --cloud_location=$(get_aws_region_az) \
 --base_dir=$HOME/yb_open_binaries \
 --fault_tolerance=region

Once all the nodes are started, we’ll now restart the nodes (in sequential manner) while enabling mTLS.

Stop the node:

$HOME/yb_open_binaries/yugabyte-2.25.0.0/bin/yugabyted stop \
  --base_dir=$HOME/yb_open_binaries

Restart the node with mTLS enabled:

$HOME/yb_open_binaries/yugabyte-2.25.0.0/bin/yugabyted start \
  --base_dir=$HOME/yb_open_binaries \
  --tserver_flags="ysql_hba_conf_csv={hostssl all all all trust clientcert=verify-full}"

Once all the nodes are restarted, you can connect to ysqlsh using the command:

./ysqlsh -h $(hostname) -p 9090 -U yugabyte \
"sslcert=/home/crdbadmin/ybdb1d/certs/<client_name>.crt sslkey=/home/crdbadmin/ybdb1d/certs/<client_name>.key sslrootcert=/home/crdbadmin/ybdb1d/certs/ca.crt sslmode=verify-full"

A little about sslmode and clientcert:

  • When specifying clientcert(specified in hba_conf) as verify-ca, the server will verify the client certs but only checks whether the client certs has been signed by the same root-ca or not whereas verify-full will ensure server checks the clients certs for correct signature as well as the username is stored in the client certificates.
    If using verify-full please ensure that the client-certs have CN set as the username (yugabyte in the above example).
  • Similarly using verify-ca as sslmode(specified while running ysqlsh) will ensure client only checks for correct signature of the server certs, whereas verify-full mode will ensure that the hostname is the same as the one stored in server certs.

Enabling vs Disabling Password authentication:

Password authentication can toggled by either using trust(disable) or md5(enable) in the hba_conf while restarting the nodes.
Please note that the password was updated by yugabyted during the initial start of the 1st node. A credentials file would have been created and stored in node 1.
If you decide to enable password authentication with mTLS, please use the generated password.

Please let us know if you face any issues with this deployment.

Thank you @Sanskar_Garg will try it & will update.

Also @Sanskar_Garg when we did the same mTLS without authentication in YBA setup, it worked fine.