How do I use SANs with openSSL instead of common name?
Asked Answered
A

4

50

After upgrading a system (kubernetes) that uses golang 1.15.0-rc.1, I am stuck on this error message:

"x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0". 

The only place I am using common name (that I know of) is when I generate the private key for my service openssl req -new -key certs/foo-bar.pem -subj "/CN=foobar.mydomain.svc" -out certs/foo-bar.csr -config certs/foo-bar_config.txt.

How can I convert this command to use SANs instead?

Anarthrous answered 13/11, 2020 at 1:24 Comment(1)
I should clarify, I understand what the difference between the two is, but I can't figure out from googling/reading articles what the syntax is to implement the switch.Anarthrous
G
48

You may need the -addext flag.

For example:

openssl req -new -key certs/foo-bar.pem \
    -subj "/CN=foobar.mydomain.svc" \
    -addext "subjectAltName = DNS:foobar.mydomain.svc" \
    -out certs/foo-bar.csr \
    -config certs/foo-bar_config.txt

Got the answer from here: https://security.stackexchange.com/questions/74345/provide-subjectaltname-to-openssl-directly-on-the-command-line

Genitor answered 14/1, 2021 at 0:13 Comment(4)
Only freaking way I had to make the SAN thing work. Security by sorcery! 1. SAN env var : didn't work 2. /etc/ssl/openssl.cnf -> subjectAltName=${ENV::SAN} : didn'twork The command to make it work (OpenSSL 1.1.1f, but trust me, your openssl won't do the same) was: openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt -subj "/CN=localhost" -addext "subjectAltName = DNS:localhost" Now the example posener.github.io/http2 works for me without GODEBUG=x509ignoreCN=0, self-signed, no "State or province", no nothing. Take that!Gobbledegook
OpenSSL 1.0.2k-fips complains about an unknown option -addext. Not claiming that version is new, but it seems the current one for CentOS 7.Slime
Found out missing part from the recommendations and accepted answer: you also need to copy extensions from cert req into final certificate. For doing that consider to use option -copy_extensions copyallCampanology
When using OpenSSL to generate a certificate signing request (CSR) and subsequently a certificate (CRT), the Subject Alternative Names (SANs) are not automatically copied from the CSR to the final CRT because OpenSSL requires explicit configuration to include SANs in the final certificate. This behavior ensures that the SANs are only added if they are explicitly requested and properly authorized, preventing unintended security issues. So there several ways: a.) Use ` -copy_extensions copyall` during signing the csr (with care)! b.) Explicit set c.) maybe more .. ?Addieaddiego
A
37

Solution

I explained totally.

This solution works for me. At first you must have a CA and then sign your server cert by CA. I create a CA and server cert and finally sign server cert by command bellow.(change your desired -subj and CN)

In your situation you should pass the subjectAltName when you signing server cert in latest command line below.

openssl genrsa -out ca.key 2048
openssl req -new -x509 -days 365 -key ca.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=Acme Root CA" -out ca.crt

openssl req -newkey rsa:2048 -nodes -keyout server.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=*.example.com" -out server.csr
openssl x509 -req -extfile <(printf "subjectAltName=DNS:example.com,DNS:www.example.com") -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt

After run this command you can use certs (server.crt,servert.key) in kubernetes secret for ingress.

Amarelle answered 7/4, 2021 at 5:35 Comment(4)
This worked with OpenSSL 1.0.2k-fips (which doesn't support the -addext option)Cateyed
On ubuntu 20.04, openssl version OpenSSL 1.1.1f 31 Mar 2020, in bash -extfile < ( .. syntax does not work. I just created $ echo "subjectAltName=DNS:some.host" > altsubj.ext $ openssl x509 -req -extfile altsubj.ext ... Then it worked fine.Psf
thanks for this batteries-included answer without any blurry parts. much better than https://mcmap.net/q/355656/-failed-to-connect-to-a-server-with-golang-due-x509-certificate-relies-on-legacy-common-name-field of #68197002 (which is unrelated to MongoDB btw)Siobhan
TIL: 1) SANs(extensions) aren't copied over from the CSR. 2) You can skip writing out to a file: -extfile <(printf "subjectAltName=DNS:example.com,DNS:www.example.com") . You can use /dev/stdout to pipe the CSR to cert signing openssl req ... -out /dev/stdout | openssl x509 ... . Remove the -in server.csr from the last command.Benuecongo
D
3

I think this blog post will help you, Know about SAN Certificate and How to Create With OpenSSL. Otherwise you could made what is suggested by the error message, and set GODEBUG="x509ignoreCN=0" as a environment variable.

Delrio answered 16/11, 2020 at 7:5 Comment(4)
I just add GODEBUG=x509ignoreCN=0 as an environment variable and the error message remains the same.Brady
For me it works, but it's just a docker swarm usecase. Not at first, because the env variable was not on the right placeAquanaut
Thanks for this hint. The error message does not say it should be an environment variable. And the recommended "see docker run --help" does not either...Slime
GODEBUG="x509ignoreCN=0" flag deprecated in go 1.17Flaxseed
V
1

I run on redhat 8.4 using environment varialbe, it works for me

export GODEBUG="x509ignoreCN=0"
podman login repo.example.com:5000

Username: registryuser Password: Login Succeeded!

Vestige answered 20/9, 2021 at 19:32 Comment(1)
That's not solution. It's hidding problems...Prig

© 2022 - 2024 — McMap. All rights reserved.