TLS
AD CS
Certificate issuance under Microsoft's manual PKI hellscape
Add CA cert to Ubuntu trust store
# Copy the Root CA to ... MUST have extension: *.crt
sudo lime-DC1-CA.cer /usr/local/share/ca-certificates/lime-DC1-CA.crt
# Update the OS trust store
sudo update-ca-certificates
# Verify : flag --ca-native to use host's native trust store
curl --ca-native https://e2e.kube.lime.lan/foo/hostname
By default, the AD CS role of Windows Server 2019 provides only RSA type TLS certificates.
We successfully obtained a TLS certificate for web server usage
from AD CS web form of its Certificate Server
lime-DC1-CA
at https://dc1.lime.lan/certsrv/
The server responds with two (end-entity and full-chain) certificates,
both in PKCS#7 format (.p7b
),
and so must be converted to PEM for use in most servers.
Their odd format is useful only at Microsoft IIS and other legacy
or non-standard servers such as Apache Tomcat.
certnew.p7b
# Convert certificate from PKCS#7 (.p7b) to PEM format cn=kube.lime.lan openssl pkcs7 -print_certs -in certnew.p7b -out $cn.crt # Parse the certificate openssl x509 -noout -subject -issuer -startdate -enddate -ext subjectAltName -in $cn.crt
subject=C = US, ST = MD, L = AAC, O = DisselTree, OU = ops, CN = kube.lime.lan, emailAddress = admin@lime.lan issuer=DC = lan, DC = lime, CN = lime-DC1-CA notBefore=Jan 25 14:32:36 2025 GMT notAfter=Jan 25 14:32:36 2027 GMT X509v3 Subject Alternative Name: DNS:kube.lime.lan, DNS:*.kube.lime.lan
CSR
AD CS requires CSR in PKCS#10/#7 (New/Renew) format.
OpenSSL generates the request (*.csr
) in that format by default.
Regarding Windows Server 2019 and prior, AD CS offers only RSA-based certificates unless that role is configured otherwise, which is a non-trivial task that nearly no organization performs.
domain=lime.lan
cn=kube.$domain
TLS_CN=$cn
TLS_O="K8s on $domain"
TLS_OU=$domain
## Create the configuration file (CNF) : See man config
## See: man openssl-req : CONFIGURATION FILE FORMAT section
## https://www.openssl.org/docs/man1.0.2/man1/openssl-req.html
cat <<EOH |tee $cn.cnf
[ req ]
prompt = no # Disable interactive prompts.
default_bits = 2048 # Key size for RSA keys. Ignored for Ed25519.
default_md = sha256 # Hashing algorithm.
distinguished_name = req_distinguished_name
req_extensions = v3_req # Extensions to include in the request.
[ req_distinguished_name ]
CN = ${TLS_CN:-p.gotham.gov} # Common Name
O = ${TLS_O:-Penguin Inc} # Organization name
OU = ${TLS_OU:-gotham.gov} # Organizational Unit name
#L = ${TLS_L:-Gotham} # Locality name
#ST = ${TLS_ST:-NY} # State or Province
C = ${TLS_C:-US} # Country
emailAddress = admin@$root
[ v3_req ]
subjectAltName = @alt_names
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
[ alt_names ]
DNS.1 = $cn
DNS.2 = *.$cn # Wildcard. CA must allow, else declare each subdomain.
EOH
# RSA (Use only this if the certificate server is AD CS)
openssl req -new -noenc -config $cn.cnf -extensions v3_req -newkey rsa:2048 -keyout $cn.key -out $cn.csr
# ED25519
openssl req -new -noenc -config $cn.cnf -extensions v3_req -newkey ed25519 -keyout $cn.key -out $cn.csr
# ECDSA (NIST P-256 curve)
openssl req -new -noenc -config $cn.cnf -extensions v3_req -newkey ec:<(openssl ecparam -name prime256v1 -genkey) -keyout $cn.key -out $cn.csr
Automated TLS Management (Enterprise Grade)
- cert-manager
- Private Issuers (Backends):
- Smallstep
step-ca
An online CA for secure, automated X.509 and SSH certificate management. It's the server counterpart tostep
CLI. Run step-ca (internal ACME) +step-issuer
or usecert-manager
’s ACME issuer pointed atstep-ca
. Provides air-gapped ACME + tight Kubernetes integration.- Generate TLS certificates for private infrastructure using the ACME protocol.
- Automate TLS certificate renewal.
- Add Automated Certificate Management Environment (ACME) support to a legacy subordinate CA.
- Issue short-lived SSH certificates via OAuth OIDC single sign on.
- Issue customized X.509 and SSH certificates.
- Hashicorp Vault PKI | OpenBao PKI
- Venafi TLS Protect for Kubernetes (the commercial successor to Jetstack Secure): central policy/visibility across clusters and CAs (public or private). If you want enterprise governance and inventory at scale, this is the “batteries-included” option.
- Smallstep
Recommendations
Per environment:
- Air-gapped / Regulated:
cert-manager + Vault PKI (or step-ca if you want ACME everywhere). Both are proven, policy-driven, and keep keys/CAs entirely under your control. - Large enterprise needing fleet-wide governance:
Venafi TLS Protect for Kubernetes integrated with cert-manager (or Venafi issuer) for policy, workflows, and inventory. - AWS-only edge:
ACM + AWS Load Balancer Controller for public ingress, optionally cert-manager + Vault/step-ca for internal services and mTLS.
ACME
Automated Certificate Management Environment (ACME)
An ACME server is a trusted CA endpoint that issues certs after validating the client requestor has domain control.
- Origin: ACME is an IETF standard (RFC 8555) created by the Let's Encrypt project to automate the issuance of publicly trusted TLS certificates.
- Purpose: Automates domain-validated (DV) certificate requests and renewals from a Certificate Authority (CA).
- Focus:
- Primarily for internet-facing services.
- Proves control of DNS names via challenges
(HTTP-01, DNS-01, TLS-ALPN-01) to prove the requestor has domain control. - Result: an X.509 certificate signed by a public CA.
- Private/Internal ACME Servers
- Smallstep Certificates (open-source & enterprise versions)
- HashiCorp Vault (with ACME support)
- Boulder (OSS version of Let's Encrypt's CA software).