2025-10-07 10:59:52 +01:00

194 lines
5.7 KiB
Plaintext

#!/usr/bin/env nu
# Generate TLS certificates for OCI registry
export def main [
--registry-type: string = "zot" # zot, harbor, distribution
--domain: string = "localhost"
--days: int = 365
] {
print "🔒 Generating TLS certificates..."
print $" Registry type: ($registry_type)"
print $" Domain: ($domain)"
print $" Validity: ($days) days\n"
let base_path = match $registry_type {
"zot" => "./zot/certs"
"harbor" => "./harbor/certs"
"distribution" => "./distribution/certs"
_ => {
error make {msg: $"Unknown registry type: ($registry_type)"}
}
}
# Create certs directory
mkdir $base_path
# Generate CA key and certificate
print "📝 Generating CA certificate..."
generate-ca $base_path $domain $days
# Generate server key and certificate
print "📝 Generating server certificate..."
generate-server-cert $base_path $domain $days
# Generate client certificates (optional)
print "📝 Generating client certificate..."
generate-client-cert $base_path $domain $days
print "\n✅ Certificates generated successfully!"
print $"\n📂 Certificate files in: ($base_path)"
print " ca.crt - CA certificate"
print " ca.key - CA private key"
print " server.crt - Server certificate"
print " server.key - Server private key"
print " client.crt - Client certificate"
print " client.key - Client private key"
print "\n📋 Next steps:"
print "1. Trust the CA certificate on your system:"
print $" - macOS: sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ($base_path)/ca.crt"
print $" - Linux: sudo cp ($base_path)/ca.crt /usr/local/share/ca-certificates/ && sudo update-ca-certificates"
print "2. Restart the registry service"
print "3. Test with: docker login --tls-verify https://($domain):5000"
}
def generate-ca [base_path: string, domain: string, days: int] {
# Generate CA private key
^openssl genrsa -out $"($base_path)/ca.key" 4096
# Generate CA certificate
^openssl req -new -x509 \
-key $"($base_path)/ca.key" \
-out $"($base_path)/ca.crt" \
-days $days \
-subj $"/C=US/ST=State/L=City/O=Provisioning/OU=CA/CN=($domain)-CA"
print $" ✓ CA certificate created: ($base_path)/ca.crt"
}
def generate-server-cert [base_path: string, domain: string, days: int] {
# Generate server private key
^openssl genrsa -out $"($base_path)/server.key" 4096
# Generate server CSR
^openssl req -new \
-key $"($base_path)/server.key" \
-out $"($base_path)/server.csr" \
-subj $"/C=US/ST=State/L=City/O=Provisioning/OU=Registry/CN=($domain)"
# Create SAN config
let san_config = $"($base_path)/san.cnf"
$"[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = State
L = City
O = Provisioning
OU = Registry
CN = ($domain)
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = ($domain)
DNS.2 = localhost
DNS.3 = *.($domain)
IP.1 = 127.0.0.1
IP.2 = 0.0.0.0" | save -f $san_config
# Sign server certificate with CA
^openssl x509 -req \
-in $"($base_path)/server.csr" \
-CA $"($base_path)/ca.crt" \
-CAkey $"($base_path)/ca.key" \
-CAcreateserial \
-out $"($base_path)/server.crt" \
-days $days \
-extensions v3_req \
-extfile $san_config
# Cleanup
rm $"($base_path)/server.csr"
rm $san_config
print $" ✓ Server certificate created: ($base_path)/server.crt"
}
def generate-client-cert [base_path: string, domain: string, days: int] {
# Generate client private key
^openssl genrsa -out $"($base_path)/client.key" 4096
# Generate client CSR
^openssl req -new \
-key $"($base_path)/client.key" \
-out $"($base_path)/client.csr" \
-subj $"/C=US/ST=State/L=City/O=Provisioning/OU=Client/CN=provisioning-client"
# Sign client certificate with CA
^openssl x509 -req \
-in $"($base_path)/client.csr" \
-CA $"($base_path)/ca.crt" \
-CAkey $"($base_path)/ca.key" \
-CAcreateserial \
-out $"($base_path)/client.crt" \
-days $days
# Cleanup
rm $"($base_path)/client.csr"
print $" ✓ Client certificate created: ($base_path)/client.crt"
}
# Verify certificates
export def "certs verify" [
--registry-type: string = "zot"
] {
let base_path = match $registry_type {
"zot" => "./zot/certs"
"harbor" => "./harbor/certs"
"distribution" => "./distribution/certs"
_ => {
error make {msg: $"Unknown registry type: ($registry_type)"}
}
}
print "🔍 Verifying certificates...\n"
# Verify CA
print "CA Certificate:"
^openssl x509 -in $"($base_path)/ca.crt" -noout -text | grep -E "Subject:|Issuer:|Not After"
# Verify server cert
print "\nServer Certificate:"
^openssl x509 -in $"($base_path)/server.crt" -noout -text | grep -E "Subject:|Issuer:|Not After|DNS:"
# Verify server cert against CA
print "\nVerifying server cert against CA:"
let verify = (^openssl verify -CAfile $"($base_path)/ca.crt" $"($base_path)/server.crt" | complete)
if $verify.exit_code == 0 {
print "✅ Server certificate valid"
} else {
print "❌ Server certificate invalid"
}
}
# Show certificate info
export def "certs info" [
cert_file: string
] {
if not ($cert_file | path exists) {
error make {msg: $"Certificate file not found: ($cert_file)"}
}
^openssl x509 -in $cert_file -noout -text
}