Guide to Secure Connection to CB‐Spider RDBMS - cloud-barista/cb-spider GitHub Wiki

Guide to Secure Connection to CB-Spider RDBMS

Language: English | 한국어

Overview

  • CSP RDBMS instances provided by CB-Spider vary by CSP in whether TLS (SSL) is supported at all, and whether it's enforced (require_secure_transport).
  • This guide explains how to use CB-Spider's Secure Transport status API to obtain a target instance's TLS status and CA certificate, then connect securely with the mysql CLI or an application driver (e.g. Go).
  • For the full verification results and underlying mechanics across all 9 CSPs, see the rdbms-mysql-test/tls-test README — this guide is the practical, usage-oriented counterpart to that document.

Why this matters

  • Connecting in plaintext (tls=false) to an instance with require_secure_transport=ON is rejected outright.
  • Conversely, even on an instance where it's OFF, connecting over TLS is safer — but depending on client settings, it's common to end up "encrypted but unverified" (vulnerable to MITM).
  • Some CSPs' auto-generated certificates have no Subject Alternative Name (SAN) at all (OpenStack, NHN), making full identity (hostname) verification structurally impossible — even then, there's a way to connect safely using chain-only verification.

require_secure_transport Availability and CB-Spider's Approach

  • When require_secure_transport=ON, clients cannot connect in plaintext at all — TLS is enforced.
  • Whether the CSP exposes this setting to users at all — let alone makes it changeable — varies by CSP and by engine version. Only some of the CSPs CB-Spider supports expose it:
    • IBM: Doesn't expose this setting at all — it's always fixed at require_secure_transport=ON.
    • AWS: Defaults to OFF, but certain engine versions (e.g. MariaDB 11.8) default to ON.
    • Alibaba, Tencent: The default deployment doesn't offer TLS at all — you must connect in plaintext.
    • A CSP's default deployment policy, or its per-engine-version policy, can change over time.
  • For this reason, CB-Spider does not provide an API to set (change) require_secure_transport or other TLS-related settings — it only provides an API to query a target instance's TLS-related information.
  • Users are expected to check the current status via that query API first, and then choose the connection method that fits (see Client Connection Options below).

Secure Transport Status API

CB-Spider provides an API that checks a target RDBMS instance's TLS configuration via standard SQL, and separately captures its CA certificate through a live TLS handshake.

GET /spider/rdbms/{Name}/secure-transport?ConnectionName={ConnectionName}
X-Master-User-Password: {Password}

MasterUserPassword is passed via the X-Master-User-Password HTTP header rather than a URL query parameter, to avoid it being logged in plaintext by proxies, web servers, or APM tools that record request URLs.

Response Fields

Field Description
Engine One of mysql, mariadb, postgres
RequireSecureTransport (MySQL/MariaDB) the require_secure_transport value — ON / OFF
Enforced (PostgreSQL) whether every matching pg_hba_file_rules TCP rule requires SSL
Rules (PostgreSQL) the raw pg_hba_file_rules rows the verdict was derived from
TLSInUse Whether this diagnostic connection itself was actually established over TLS (empirical) — false if the instance doesn't support TLS at all
TLSCipher Negotiated cipher suite when TLSInUse=true (e.g. ECDHE-RSA-AES128-GCM-SHA256, TLS_AES_256_GCM_SHA384)
CACertificate The server certificate captured via a live TLS handshake — includes PEM, Subject, Issuer, NotAfter, IsSelfSigned
CACertificateError Reason the CA capture failed despite TLSInUse=true
RecommendedSSLMode The strongest SSL mode the client can actually use — DISABLED (TLS unsupported) / VERIFY_CA (TLS supported but the server certificate has no SAN) / VERIFY_IDENTITY (TLS supported and SAN present). Empty string if the CA capture itself failed (see CACertificateError)

CACertificate.PEM is the top-of-chain certificate the server presents — for some CSPs this is an intermediate CA rather than the ultimate self-signed root (distinguished by IsSelfSigned). Either way, it's usable as-is for a client's --ssl-ca / sslrootcert.

RecommendedSSLMode maps 1:1 to the --ssl-mode values in the Client Connection Options table below — use it directly and you can skip working out which mode fits from that table.

Example Call

curl -u admin:your-secure-password -sX GET \
  "http://localhost:1024/spider/rdbms/cb-spider-mysql-test/secure-transport?ConnectionName=aws-config01" \
  -H "X-Master-User-Password: Password123!" | jq

Example response (AWS, TLS in use)

{
  "Engine": "mysql",
  "RequireSecureTransport": "OFF",
  "TLSInUse": true,
  "TLSCipher": "ECDHE-RSA-AES128-GCM-SHA256",
  "CACertificate": {
    "PEM": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n",
    "Subject": "CN=Amazon RDS us-east-1 CA 2019",
    "Issuer": "CN=Amazon RDS Root 2019",
    "NotAfter": "2039-08-22T17:08:50Z",
    "IsSelfSigned": false
  },
  "RecommendedSSLMode": "VERIFY_IDENTITY"
}

Example response (OpenStack/NHN — TLS supported but the server certificate has no SAN)

{
  "Engine": "mysql",
  "RequireSecureTransport": "OFF",
  "TLSInUse": true,
  "TLSCipher": "ECDHE-RSA-AES256-GCM-SHA384",
  "CACertificate": {
    "PEM": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n",
    "Subject": "CN=MySQL_Server_8.0_Auto_Generated_CA_Certificate",
    "Issuer": "CN=MySQL_Server_8.0_Auto_Generated_CA_Certificate",
    "NotAfter": "2034-01-01T00:00:00Z",
    "IsSelfSigned": true
  },
  "RecommendedSSLMode": "VERIFY_CA"
}

Saving the CA Certificate to a File

curl -u admin:your-secure-password -sX GET \
  "http://localhost:1024/spider/rdbms/cb-spider-mysql-test/secure-transport?ConnectionName=aws-config01" \
  -H "X-Master-User-Password: Password123!" \
  | jq -r '.CACertificate.PEM' > rds-ca.pem

Flow

sequenceDiagram
    participant Client
    participant Spider as CB-Spider Server
    participant DB as RDBMS Instance (CSP)

    Client->>Spider: GET /rdbms/{Name}/secure-transport
    Spider->>DB: SQL connection (SHOW VARIABLES LIKE 'require_secure_transport')
    DB-->>Spider: require_secure_transport value
    Spider->>DB: Separate TLS handshake (for certificate capture)
    DB-->>Spider: Server certificate chain
    Note over Spider: Check the server (leaf) certificate's SAN<br/>→ determine RecommendedSSLMode
    Spider-->>Client: RequireSecureTransport, TLSInUse, TLSCipher, CACertificate(PEM), RecommendedSSLMode
    Note over Client: Save as rds-ca.pem,<br/>then use RecommendedSSLMode as --ssl-mode
Loading

Client Connection Options

Once you have the CA certificate, connect from the client (mysql CLI, application driver) using one of the following, weakest to strongest security:

You don't have to work out which mode fits — just use the secure-transport response's RecommendedSSLMode value directly as --ssl-mode (DISABLED/VERIFY_CA/VERIFY_IDENTITY).

Option mysql CLI Description Recommendation
Plaintext --ssl-mode=DISABLED No encryption. Rejected outright if RequireSecureTransport=ON ❌ Not recommended
Encryption only --ssl-mode=REQUIRED Encrypted, but no certificate verification at all — vulnerable to MITM ⚠️ Dev/test only
Chain verification --ssl-mode=VERIFY_CA --ssl-ca=rds-ca.pem Encrypted + CA trust chain verified. Hostname is not checked ✅ Safe even against SAN-less certificates
Full verification --ssl-mode=VERIFY_IDENTITY --ssl-ca=rds-ca.pem Encrypted + chain verified + hostname (SAN) verified — the safest ✅ Top recommendation

VERIFY_IDENTITY doesn't always work — OpenStack Trove and NHN Cloud RDS use MySQL's own auto-generated certificate, which has no SAN, so VERIFY_IDENTITY fails structurally (a limitation of the server certificate itself, not the client). VERIFY_CA is the safest option that's actually usable there. See CSP-Specific Notes below for details.

go-sql-driver/mysql (Go) Example

import (
    "crypto/tls"
    "crypto/x509"
    "database/sql"
    "github.com/go-sql-driver/mysql"
)

// Full verification (VERIFY_IDENTITY equivalent)
caPool := x509.NewCertPool()
caPool.AppendCertsFromPEM(caCertPEM) // CACertificate.PEM from the secure-transport API
cfg := mysql.NewConfig()
cfg.User, cfg.Passwd = "myadmin", "Password123!"
cfg.Net, cfg.Addr = "tcp", "cb-spider-mysql-test.xxx.rds.amazonaws.com:3306"
cfg.TLS = &tls.Config{RootCAs: caPool, ServerName: "cb-spider-mysql-test.xxx.rds.amazonaws.com"}
connector, _ := mysql.NewConnector(cfg)
db := sql.OpenDB(connector)
// Chain verification only (VERIFY_CA equivalent) — safe even against SAN-less certificates
cfg.TLS = &tls.Config{
    InsecureSkipVerify: true, // disables Go's default verification so we can verify manually below
    VerifyPeerCertificate: func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
        cert, err := x509.ParseCertificate(rawCerts[0])
        if err != nil {
            return err
        }
        _, err = cert.Verify(x509.VerifyOptions{Roots: caPool}) // DNSName omitted = no hostname check
        return err
    },
}

go-sql-driver/mysql has no built-in DSN option equivalent to VERIFY_CA (a PR proposing a tls-verify=ca parameter was closed without merging — go-sql-driver/mysql#1742). Implementing it directly with a VerifyPeerCertificate callback, as above, is the standard workaround.


Quick Start

1. Check TLS Status and CA

export SPIDER_URL=http://localhost:1024
export SPIDER_AUTH=admin:change-your-password

curl -u $SPIDER_AUTH -s "$SPIDER_URL/spider/rdbms/cb-spider-mysql-test/secure-transport?ConnectionName=aws-config01" \
  -H "X-Master-User-Password: Password123!" \
  | tee secure-transport.json | jq '{RequireSecureTransport, TLSInUse, TLSCipher, RecommendedSSLMode}'

jq -r '.CACertificate.PEM' secure-transport.json > rds-ca.pem
SSL_MODE=$(jq -r '.RecommendedSSLMode' secure-transport.json)

2. Look Up the Endpoint

curl -u $SPIDER_AUTH -s "$SPIDER_URL/spider/rdbms/cb-spider-mysql-test?ConnectionName=aws-config01" \
  | jq -r '.Endpoint'

3. Connect with the mysql CLI (using RecommendedSSLMode as-is)

mysql -h <Endpoint host> -P 3306 -u myadmin -p \
  --ssl-mode=$SSL_MODE --ssl-ca=rds-ca.pem

If RecommendedSSLMode came back as VERIFY_CA, the server certificate has no SAN (OpenStack/NHN, etc.) — trying VERIFY_IDENTITY will always fail with x509: certificate is not valid for any names..., so just use VERIFY_CA as given. See the Client Connection Options table above for details.


Checking via AdminWeb

  • AdminWeb's RDBMS management page shows the require_secure_transport ON/OFF badge directly in the instance list, and hovering over the badge shows RecommendedSSLMode as a tooltip.
  • Clicking Details opens an overlay showing TLSInUse, TLSCipher, Recommended SSL Mode (color-coded: gray = DISABLED, orange = VERIFY_CA, green = VERIFY_IDENTITY), PostgreSQL's pg_hba rules, and the CA certificate itself (PEM, Subject/Issuer, self-signed status) — all copyable. When it's VERIFY_CA, a note also explains that VERIFY_IDENTITY will always fail due to the missing SAN.

CSP-Specific Notes

CSP Observed require_secure_transport default TLS supported RecommendedSSLMode Notes
AWS, GCP, Azure, IBM OFF (AWS/GCP) / ON (Azure/IBM) Yes VERIFY_IDENTITY Certificate has a SAN — full verification works
OpenStack, NHN OFF Yes VERIFY_CA Certificate has no SAN — only chain verification works
Alibaba, Tencent, NCP OFF No DISABLED The instance itself doesn't have TLS turned on (Alibaba/Tencent can be enabled separately via the CSP console/API)

NCP's default private endpoint isn't reachable from outside its VPC right after instance creation — enabling a public IP in the NCP console is required, and it takes about 5 minutes to become reachable afterward. Even once reachable, the instance itself still doesn't support TLS.

  • OpenStack Trove / NHN Cloud RDS: Both use MySQL's own auto-generated certificate, which has no SAN extension. VERIFY_IDENTITY fails structurally (x509: certificate is not valid for any names...), but VERIFY_CA works fine — the secure-transport API detects this and reports RecommendedSSLMode: "VERIFY_CA" directly, so you don't have to hit the error yourself to find out.
  • GCP Cloud SQL: When Endpoint is an IP address, the certificate has no IP SAN, but it does have a DNS SAN (N-<uuid>.<region>.sql.goog) — when using VERIFY_IDENTITY, point the hostname verification target at that DNS SAN instead of the IP.
  • Alibaba/Tencent/NCP: The instance itself doesn't support TLS. Alibaba's rds.ModifyDBInstanceSSL and Tencent's cdb.OpenSSL CSP-native APIs can enable it (CB-Spider doesn't currently use this capability); whether NCP's API offers an equivalent hasn't been confirmed.

For the full verification results and rationale across all 9 CSPs, see the Known Caveats section of the tls-test README.


Security Notes

  • Avoid --ssl-mode=REQUIRED (encryption only, no verification) in production — it's vulnerable to MITM attacks.
  • CACertificate.PEM is captured live on every call, so its value can change if the instance's certificate is rotated — if your application caches the CA, re-check it periodically.
  • MasterUserPassword is passed via the X-Master-User-Password header rather than a URL query parameter, so it won't appear in plaintext in access logs — but still only call this API over a trusted network path to the CB-Spider server (e.g. a TLS-protected management channel).

⚠️ **GitHub.com Fallback** ⚠️