Non-Interactive SSL Certificate Request Generation with OpenSSL Command Line Parameters


1 views

When automating server deployment or building management tools, interactive prompts become a significant obstacle. The standard OpenSSL certificate signing request (CSR) generation process requires manual input for Distinguished Name (DN) fields, making scripted implementations challenging.

OpenSSL supports non-interactive CSR generation through configuration files. Here's how to implement it:

$ cat > csr_config.cnf << 'EOF'
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext

[dn]
C = US
ST = New Sweden
L = Stockholm
O = Scandinavian Ventures, Inc.
CN = foobar.com
emailAddress = gustav@foobar.com

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = foobar.com
DNS.2 = www.foobar.com
EOF

With the configuration file prepared, generate both private key and CSR in one command:

$ openssl req -new -nodes -keyout foobar.com.key -out foobar.com.csr -config csr_config.cnf

For different use cases, consider these modifications:

# With password-protected private key:
$ openssl req -new -newkey rsa:2048 -keyout secure.key -out request.csr \
-config csr_config.cnf -passout pass:YourStrongPassword

# For wildcard certificates:
[alt_names]
DNS.1 = *.foobar.com

Always validate your output:

$ openssl req -in foobar.com.csr -noout -text

For quick testing without config files (not recommended for production):

$ openssl req -new -newkey rsa:2048 -nodes -keyout test.key -out test.csr \
-subj "/C=US/ST=California/L=San Francisco/O=Your Org/CN=test.com"

When automating server deployments or building CLI tools, the standard interactive OpenSSL certificate signing request (CSR) generation process becomes problematic. The typical workflow forces manual input of DN (Distinguished Name) fields, making it unsuitable for scripting scenarios.

OpenSSL provides the -subj flag to specify all DN fields in a single command. The format follows:

openssl req -new -newkey rsa:2048 -nodes -sha256 \
  -keyout domain.key -out domain.csr \
  -subj "/C=US/ST=California/L=San Francisco/O=My Company/CN=example.com"

For complete non-interactive generation, combine with these parameters:

openssl req -new -newkey rsa:4096 -nodes -sha512 \
  -keyout secure.key -out request.csr \
  -subj "/C=US/ST=New York/L=New York/O=Tech Corp/OU=DevOps/CN=api.example.com/emailAddress=admin@example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.com" \
  -config <(printf "[req]\ndistinguished_name = req_distinguished_name\nreq_extensions = v3_req\n[req_distinguished_name]\n[v3_req]\nsubjectAltName = @alt_names\n[alt_names]\nDNS.1 = example.com\nDNS.2 = www.example.com")

For maximum flexibility with SANs (Subject Alternative Names) and other extensions:

# Create openssl.cnf
cat << EOF > openssl.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext

[dn]
C = US
ST = California
L = San Francisco
O = My Org
CN = example.com

[req_ext]
subjectAltName = @alt_names

[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
EOF

# Generate CSR
openssl req -new -config openssl.cnf -keyout domain.key -out domain.csr

1. Always verify generated CSRs with:
openssl req -in domain.csr -noout -text
2. For different OpenSSL versions (1.0.x vs 1.1.x), syntax for extensions varies
3. Consider using Let's Encrypt's certbot for automated certificate management

For complex automation scenarios, consider:
- cfssl from Cloudflare
- step-cli from Smallstep
- mkcert for local development certificates