Enforce mTLS on private-admin Traefik routes
This commit is contained in:
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
TRAEFIK_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
CA_DIR="${TRAEFIK_ROOT}/certs/ca"
|
||||
|
||||
CA_KEY="${CA_DIR}/clients-ca.key"
|
||||
CA_CERT="${CA_DIR}/clients-ca.crt"
|
||||
CA_SERIAL="${CA_DIR}/clients-ca.srl"
|
||||
|
||||
DAYS="${DAYS:-3650}"
|
||||
SUBJECT="${SUBJECT:-/CN=Traefik Private Admin Client CA/O=Homelab}"
|
||||
|
||||
mkdir -p "${CA_DIR}"
|
||||
chmod 700 "${CA_DIR}"
|
||||
|
||||
if [[ -f "${CA_KEY}" || -f "${CA_CERT}" ]]; then
|
||||
echo "Refusing to overwrite existing CA material in ${CA_DIR}."
|
||||
echo "Delete existing files first if you intentionally want to rotate the CA."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
openssl genrsa -out "${CA_KEY}" 4096
|
||||
chmod 600 "${CA_KEY}"
|
||||
|
||||
openssl req -x509 -new -nodes \
|
||||
-key "${CA_KEY}" \
|
||||
-sha256 \
|
||||
-days "${DAYS}" \
|
||||
-subj "${SUBJECT}" \
|
||||
-out "${CA_CERT}"
|
||||
chmod 644 "${CA_CERT}"
|
||||
|
||||
rm -f "${CA_SERIAL}"
|
||||
|
||||
echo "Created mTLS client CA: ${CA_CERT}"
|
||||
echo "Use issue-mtls-client-cert.sh to issue client certificates signed by this CA."
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: $0 <client-name> [days]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_NAME="$1"
|
||||
DAYS="${2:-825}"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
TRAEFIK_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
CA_DIR="${TRAEFIK_ROOT}/certs/ca"
|
||||
CLIENT_DIR="${TRAEFIK_ROOT}/certs/clients/${CLIENT_NAME}"
|
||||
|
||||
CA_KEY="${CA_DIR}/clients-ca.key"
|
||||
CA_CERT="${CA_DIR}/clients-ca.crt"
|
||||
CA_SERIAL="${CA_DIR}/clients-ca.srl"
|
||||
|
||||
CLIENT_KEY="${CLIENT_DIR}/${CLIENT_NAME}.key"
|
||||
CLIENT_CSR="${CLIENT_DIR}/${CLIENT_NAME}.csr"
|
||||
CLIENT_CERT="${CLIENT_DIR}/${CLIENT_NAME}.crt"
|
||||
CLIENT_P12="${CLIENT_DIR}/${CLIENT_NAME}.p12"
|
||||
OPENSSL_EXT="${CLIENT_DIR}/client.ext"
|
||||
|
||||
if [[ ! -f "${CA_KEY}" || ! -f "${CA_CERT}" ]]; then
|
||||
echo "Missing CA material. Run init-mtls-ca.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -d "${CLIENT_DIR}" ]]; then
|
||||
echo "Client directory already exists (${CLIENT_DIR}); refusing to overwrite."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "${CLIENT_DIR}"
|
||||
chmod 700 "${CLIENT_DIR}"
|
||||
|
||||
cat > "${OPENSSL_EXT}" <<EXT
|
||||
basicConstraints=CA:FALSE
|
||||
keyUsage = digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = clientAuth
|
||||
subjectAltName = DNS:${CLIENT_NAME}
|
||||
EXT
|
||||
|
||||
openssl genrsa -out "${CLIENT_KEY}" 2048
|
||||
chmod 600 "${CLIENT_KEY}"
|
||||
|
||||
openssl req -new -key "${CLIENT_KEY}" -subj "/CN=${CLIENT_NAME}" -out "${CLIENT_CSR}"
|
||||
|
||||
openssl x509 -req \
|
||||
-in "${CLIENT_CSR}" \
|
||||
-CA "${CA_CERT}" \
|
||||
-CAkey "${CA_KEY}" \
|
||||
-CAcreateserial \
|
||||
-out "${CLIENT_CERT}" \
|
||||
-days "${DAYS}" \
|
||||
-sha256 \
|
||||
-extfile "${OPENSSL_EXT}"
|
||||
chmod 644 "${CLIENT_CERT}"
|
||||
|
||||
openssl pkcs12 -export \
|
||||
-inkey "${CLIENT_KEY}" \
|
||||
-in "${CLIENT_CERT}" \
|
||||
-certfile "${CA_CERT}" \
|
||||
-name "${CLIENT_NAME}" \
|
||||
-out "${CLIENT_P12}"
|
||||
chmod 600 "${CLIENT_P12}"
|
||||
|
||||
rm -f "${CLIENT_CSR}" "${OPENSSL_EXT}"
|
||||
|
||||
echo "Issued client certificate for ${CLIENT_NAME}."
|
||||
echo "CRT: ${CLIENT_CERT}"
|
||||
echo "KEY: ${CLIENT_KEY}"
|
||||
echo "P12: ${CLIENT_P12}"
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: $0 <client-name>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_NAME="$1"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
TRAEFIK_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
CLIENT_DIR="${TRAEFIK_ROOT}/certs/clients/${CLIENT_NAME}"
|
||||
REVOKED_DIR="${TRAEFIK_ROOT}/certs/revoked"
|
||||
|
||||
if [[ ! -d "${CLIENT_DIR}" ]]; then
|
||||
echo "No certificate directory found for client '${CLIENT_NAME}'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "${REVOKED_DIR}"
|
||||
|
||||
STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
|
||||
mv "${CLIENT_DIR}" "${REVOKED_DIR}/${CLIENT_NAME}-${STAMP}"
|
||||
|
||||
echo "Moved client certificate material to ${REVOKED_DIR}/${CLIENT_NAME}-${STAMP}."
|
||||
echo "Note: Traefik clientAuth with a CA file does not enforce revocation lists by default."
|
||||
echo "For immediate hard revocation, rotate the client CA and re-issue trusted client certificates."
|
||||
Reference in New Issue
Block a user