38

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?

425nesp
  • 6,936
  • 9
  • 50
  • 61
EMC
  • 1,560
  • 2
  • 17
  • 31
  • 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. – EMC Nov 16 '20 at 22:05

4 Answers4

34

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

425nesp
  • 6,936
  • 9
  • 50
  • 61
  • 2
    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 https://posener.github.io/http2/ works for me without `GODEBUG=x509ignoreCN=0`, self-signed, no "State or province", no nothing. Take that! – Riccardo Manfrin May 04 '21 at 20:58
  • 2
    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. – Queeg Aug 23 '21 at 21:44
  • 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 copyall – Павел Jul 18 '23 at 10:29
28

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.

Mohammad Ravanbakhsh
  • 2,244
  • 1
  • 15
  • 26
  • This worked with OpenSSL 1.0.2k-fips (which doesn't support the -addext option) – Rob Nov 15 '21 at 02:36
  • 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. – Madars Vi Dec 14 '21 at 21:56
  • thanks for this batteries-included answer without any blurry parts. much better than https://stackoverflow.com/a/68196866/589493 of https://stackoverflow.com/questions/68196502/failed-to-connect-to-a-server-with-golang-due-x509-certificate-relies-on-legacy (which is unrelated to MongoDB btw) – Tchakabam Jan 20 '23 at 00:53
  • 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. – jhr Feb 25 '23 at 07:33
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.

Gealber
  • 463
  • 5
  • 13
  • 11
    I just add GODEBUG=x509ignoreCN=0 as an environment variable and the error message remains the same. – Rafael Reyes Dec 20 '20 at 05:46
  • For me it works, but it's just a docker swarm usecase. Not at first, because the env variable was not on the right place – Ser Aug 17 '21 at 11:12
  • 1
    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... – Queeg Aug 23 '21 at 21:28
  • GODEBUG="x509ignoreCN=0" flag deprecated in go 1.17 – Vladimir Dec 24 '21 at 07:38
2

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!