#!/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 }