Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I wrote this bit of code to get the Common Name of the subject field in the SSL certificate for a given domain:

$ echo -e "GET / HTTP/1.1\nEOT" | openssl s_client -connect google.com:443 2>&1 | grep subject subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com

However, this only gives me the “subject” value. Alternative CNs may be listed in the “Subject Alternative Name” field. For example:

So, how can I get the value of the Subject Alternative Name field in Bash?

share|improve this question
up vote 4 down vote accepted

This might not work under every circumstance, but try

openssl s_client -connect google.com:443 2>&1 | openssl x509 -text | grep DNS
share|improve this answer
Thanks so much! openssl x509 -text is what I was looking for. I guess I was Googling for the wrong keywords. – Mathias Bynens Mar 7 '13 at 14:28

Here's a version that will work in every circumstance (and strips leading space):

openssl s_client -connect google.com:443 2>&1 | openssl x509 -text |
  sed -nr '/^ {12}X509v3 Subject Alternative Name/{n;s/^ *//p}'
share|improve this answer
Can you be more specific about what kind of issues this works around (that the other answer doesn’t)? Thanks! – Mathias Bynens Aug 8 '14 at 13:44
Unlike the other answer, this doesn't inadvertently include other fields that contain "DNS" (such as what you could encounter running the other answer for the certificate of a service that provides DNS). – Stuart P. Bentley Aug 8 '14 at 21:20

What @stuart-p-bentley wrote got me thinking and I came up with this way of getting a comma delimited list of "Subject Alternative Names" using openssl, awk and tr. The sed line in his answer does not work on FreeBSD per example.

openssl s_client -connect google.com:443 2>&1 | openssl x509 -text | awk '/X509v3 Subject Alternative Name/ {getline;gsub(/ /, "", $0); print}' | tr -d "DNS:"

Here is what you get with google.com

share|improve this answer
tr -d "DNS:" is not a good solution to get all the domains in the SAN, as the SAN field may contain other kinds of values than DNS, such as IP addresses. I don't know how you'd do it with awk, but sed -nr '/^ {12}X509v3 Subject Alternative Name/{n; s/(^|,) *DNS:/,/g; s/(^|,) [^,]*//gp}' is how I did it with sed here. – Stuart P. Bentley Oct 15 '14 at 6:25
The equivalent awk translation would probably be awk '/^ {12}X509v3 Subject Alternative Name/ {getline; gsub(/(^|,) *DNS:/, ",", $0); gsub(/(^|,) [^,]*/, "", $0); print}', though I don't know why that would be any better than using sed (I can't see why the sed wouldn't work on FreeBSD, unless you need to use -nE instead of -nr due to being on an old version). – Stuart P. Bentley Oct 15 '14 at 6:37
Another reason tr -d "DNS:" is not a good solution is because tr -d deletes sets of characters, not strings. You might as well do tr -d ":A-Z". (While you're at it, throw out the gsub(/ /, "", $0); and add spaces to the set for deletion. Or just do all your deletion in the awk command in the first place, where you can do it with strings and patterns - at which point you reach my previous comment's code.) – Stuart P. Bentley Jun 1 '15 at 9:12
(The code referenced at the end of my first comment has moved to github.com/plushu/plushu-app-nginx-servers/blob/master/hooks/… .) – Stuart P. Bentley Jun 1 '15 at 9:14

Also use the switch

-certopt no_pubkey,no_sigdump,no_validity,no_serial,no_header,no_issuer,no_version,no_aux,no_signame,no_subject
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.