194 lines
5.7 KiB
Plaintext
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
|
|
}
|