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