Skip to content

Target types

A target is something on a server that uses the certificate. One variable, <SERVER>_TARGETS, says what is there, so normal servers and Kubernetes nodes are configured the same way:

WEB_PROD_TARGETS=nginx,minio      # a VM with nginx and MinIO
K8S_PROD_TARGETS=k8s            # a Kubernetes node
DB_PROD_TARGETS=files              # just place the files
Type Files Health check Reload
nginx _CERT (full chain), _KEY service active, nginx -t nginx -t && systemctl reload nginx
apache _CERT, _KEY, optional _CHAIN service active, apachectl configtest configtest + reload apache2/httpd
haproxy _PEM (chain + key in one file) service active, haproxy -c haproxy -c + reload
minio _CERT (public.crt), _KEY (private.key) systemctl is-active $SERVICE systemctl restart $SERVICE
postgres _CERT, _KEY service active systemctl reload $SERVICE
k8s _CERT, _KEY (staging copies on the node, created if missing) API readyz + rollout status update secrets, then rollout restart (below)
files any of _CERT, _KEY, _CHAIN, _PEM — —

sslsync targets prints the same table, with every setting.

Common target settings

Setting Description
_<TARGET>_TYPE when the name is not a type: TARGETS=nginx,api + API_TYPE=minio (two MinIOs, etc.)
_<TARGET>_CREATE true: create missing files and folders (default only for k8s)
_<TARGET>_OWNER owner of created files, e.g. root:ssl-cert
_<TARGET>_KEY_MODE permissions the private key must have, e.g. 0600 (default for k8s). Unset: only access for other users is removed. Group-readable keys such as 0640 root:ssl-cert keep working
_<TARGET>_RELOAD replace the default reload; none = no reload
_<TARGET>_ROLLBACK command after the old files are restored (default: reload again)
_<TARGET>_HEALTH replace the default health check; none = none
_<TARGET>_<FILE>_CONTENT what a file gets: fullchain, leaf, chain, key, pem
_<TARGET>_SERVICE systemd unit (minio, postgres)

Kubernetes (k8s)

Setting Description
_K8S_CERT, _K8S_KEY where the files are placed on the node (the source for the secrets)
_K8S_TLS_SECRETS kubernetes.io/tls secret names; updated in every namespace that has them
_K8S_OPAQUE_SECRETS name:certkey:keykey, e.g. minio-tls:public.crt:private.key
_K8S_RESTART namespace/kind/name list, restarted and awaited after the update
_K8S_KUBECTL default kubectl (e.g. k3s kubectl)

How it works: before the update, every affected secret is exported to /root/ssl-secret-backup/<stamp>/. The secrets are then updated, and the workloads restarted and awaited. A failed rollout, health check or VERIFY re-applies the saved secrets and restarts again. The state phase compares the certificate in each secret with the file, so an interrupted run is completed next time.

Updating a secret in every namespace that has it matters: copies of the same TLS secret often exist in more namespaces than a runbook lists (ingress, ArgoCD, dashboards, monitoring …). Updating only some of them leaves the rest on the old certificate.

Choosing VERIFY

List every port a client connects to: web, admin panels, the MinIO API and console, NodePorts. Verification compares the exact certificate bytes, so it catches: - a service that was not reloaded - a port served by another process you did not know about - a load balancer or ingress in front that still has the old cert

A server without VERIFY is never checked end-to-end. Add it unless there is truly no TLS port (files targets).