Hostname Verification
Hostname verification ensures that the certificate presented by a peer matches the expected identity. Without hostname verification, an attacker with any valid certificate signed by a trusted CA could impersonate any node.
How Hostname Verification Works
Section titled “How Hostname Verification Works”During TLS handshake, the client performs these steps:
- Receive server certificate
- Validate certificate chain against truststore
- Verify hostname matches certificate identity
Step 3 is hostname verification. It compares the hostname used to connect against identities in the certificate.
Identity Matching
Section titled “Identity Matching”The verifier checks these certificate fields in order:
-
Subject Alternative Name (SAN) - Preferred method
- DNS names (e.g.,
cassandra-node-1.example.com) - IP addresses (e.g.,
10.0.1.1)
- DNS names (e.g.,
-
Common Name (CN) - Legacy fallback
- Only checked if no SAN extension exists
- Deprecated by RFC 6125
Subject Alternative Names (SAN)
Section titled “Subject Alternative Names (SAN)”SANs allow a single certificate to be valid for multiple identities.
SAN Types
Section titled “SAN Types”| Type | Format | Example |
|---|---|---|
| DNS | DNS:hostname | DNS:cassandra-node-1.example.com |
| IP | IP:address | IP:10.0.1.1 |
| URI | URI:identifier | URI:spiffe://cluster/node/1 |
email:address | email:admin@example.com |
Recommended SANs for Cassandra Nodes
Section titled “Recommended SANs for Cassandra Nodes”Include all identities that clients or other nodes might use to connect:
DNS.1 = cassandra-node-1DNS.2 = cassandra-node-1.example.comDNS.3 = cassandra-node-1.dc1.example.comIP.1 = 10.0.1.1IP.2 = 192.168.1.1Generating Certificates with SANs
Section titled “Generating Certificates with SANs”# Create SAN configuration filecat > san.cnf << EOF[req]distinguished_name = req_distinguished_namereq_extensions = v3_req
[req_distinguished_name]CN = cassandra-node-1
[v3_req]basicConstraints = CA:FALSEkeyUsage = digitalSignature, keyEnciphermentextendedKeyUsage = serverAuth, clientAuthsubjectAltName = @alt_names
[alt_names]DNS.1 = cassandra-node-1DNS.2 = cassandra-node-1.example.comDNS.3 = localhostIP.1 = 10.0.1.1IP.2 = 127.0.0.1EOF
# Generate CSR with SANsopenssl req -new \ -key node-key.pem \ -out node.csr \ -config san.cnf \ -subj "/CN=cassandra-node-1"
# Sign certificate preserving SANsopenssl x509 -req \ -in node.csr \ -CA ca-cert.pem \ -CAkey ca-key.pem \ -CAcreateserial \ -out node-cert.pem \ -days 365 \ -extensions v3_req \ -extfile san.cnfVerify SANs in Certificate
Section titled “Verify SANs in Certificate”# View SANsopenssl x509 -in node-cert.pem -noout -ext subjectAltName
# Output example:# X509v3 Subject Alternative Name:# DNS:cassandra-node-1, DNS:cassandra-node-1.example.com, IP Address:10.0.1.1Cassandra Configuration
Section titled “Cassandra Configuration”Enabling Hostname Verification (Cassandra 4.0+)
Section titled “Enabling Hostname Verification (Cassandra 4.0+)”# Internode encryptionserver_encryption_options: internode_encryption: all require_endpoint_verification: true # ... keystore and truststore settings
# Client encryptionclient_encryption_options: enabled: true require_endpoint_verification: true # ... keystore and truststore settingsConfiguration Parameters
Section titled “Configuration Parameters”| Parameter | Default | Description |
|---|---|---|
require_endpoint_verification | false | Enable hostname verification |
Pre-Cassandra 4.0
Section titled “Pre-Cassandra 4.0”Earlier versions do not support hostname verification natively. Options include:
- Upgrade to Cassandra 4.0+
- Rely on certificate chain validation only
- Implement custom SSL context factory
Wildcard Certificates
Section titled “Wildcard Certificates”Wildcard certificates match multiple hostnames with a single certificate.
Wildcard Rules
Section titled “Wildcard Rules”| Pattern | Matches | Does Not Match |
|---|---|---|
*.example.com | node1.example.com | node1.dc1.example.com |
*.example.com | node2.example.com | example.com |
Wildcards only match a single label (between dots).
Wildcard Certificate Generation
Section titled “Wildcard Certificate Generation”# Generate certificate with wildcard SANcat > wildcard-san.cnf << EOF[req]distinguished_name = req_distinguished_namereq_extensions = v3_req
[req_distinguished_name]CN = *.cassandra.example.com
[v3_req]basicConstraints = CA:FALSEkeyUsage = digitalSignature, keyEnciphermentextendedKeyUsage = serverAuthsubjectAltName = @alt_names
[alt_names]DNS.1 = *.cassandra.example.comDNS.2 = cassandra.example.comEOFWildcard Considerations
Section titled “Wildcard Considerations”Advantages:
- Simplified certificate management
- Single certificate for all nodes in a domain
Disadvantages:
- Compromised certificate affects all nodes
- Cannot use IP address SANs with wildcards
- May not meet compliance requirements
Recommendation: Use individual certificates per node in production environments.
Cloud and Kubernetes Environments
Section titled “Cloud and Kubernetes Environments”Dynamic IP Addresses
Section titled “Dynamic IP Addresses”Cloud instances may have changing IP addresses. Strategies:
- DNS-based identity: Use DNS names instead of IP addresses
- Service discovery: Configure clients to resolve hostnames dynamically
- IP SANs at provisioning: Generate certificates during instance creation
Kubernetes
Section titled “Kubernetes”Pods have multiple identities:
DNS.1 = pod-nameDNS.2 = pod-name.service-nameDNS.3 = pod-name.service-name.namespaceDNS.4 = pod-name.service-name.namespace.svc.cluster.localIP.1 = <pod-ip>Example: Kubernetes Certificate SANs
Section titled “Example: Kubernetes Certificate SANs”[alt_names]DNS.1 = cassandra-0DNS.2 = cassandra-0.cassandra-headlessDNS.3 = cassandra-0.cassandra-headless.defaultDNS.4 = cassandra-0.cassandra-headless.default.svc.cluster.localDNS.5 = *.cassandra-headless.default.svc.cluster.localTroubleshooting Hostname Verification
Section titled “Troubleshooting Hostname Verification”Common Errors
Section titled “Common Errors”Certificate does not match hostname:
javax.net.ssl.SSLPeerUnverifiedException: Hostname verification failedCauses:
- Certificate CN/SAN does not include the connection hostname
- Client connecting via IP but certificate only has DNS names
- DNS resolution returning unexpected hostname
Diagnostic Commands
Section titled “Diagnostic Commands”# Check what hostname the client is usingnslookup 10.0.1.1
# Verify certificate SANsopenssl x509 -in node-cert.pem -noout -ext subjectAltName
# Test TLS connection with hostnameopenssl s_client -connect cassandra-node-1.example.com:9042 \ -servername cassandra-node-1.example.com
# Test hostname verification explicitlyopenssl s_client -connect cassandra-node-1.example.com:9042 \ -verify_hostname cassandra-node-1.example.comResolution Steps
Section titled “Resolution Steps”- Identify the hostname used by connecting clients
- Verify that hostname exists in certificate SANs
- Regenerate certificate with correct SANs if needed
- Ensure DNS resolves correctly
Related Documentation
Section titled “Related Documentation”- Encryption Overview - Why encryption is essential
- Certificate Types - Certificate generation
- Cassandra Configuration - Full configuration reference
- Troubleshooting - Common issues and solutions