Skip to content

Instantly share code, notes, and snippets.

@schtobia
Last active August 22, 2023 11:18
Show Gist options
  • Save schtobia/302cd39c0332240163f6 to your computer and use it in GitHub Desktop.
Save schtobia/302cd39c0332240163f6 to your computer and use it in GitHub Desktop.
CN-based client authentification with nginx. This emulates Apache's SSLRequire (%{SSL_CLIENT_S_DN_CN} in {"Really Me"})
map $ssl_client_s_dn $ssl_client_s_dn_cn {
default "";
~/CN=(?<CN>[^/]+) $CN;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
server_name foo.bar.com;
if ($scheme = http) {
return 301 https://$server_name$request_uri;
}
ssl_certificate /etc/ssl/$server_name;
ssl_certificate_key /some/where/private;
ssl_client_certificate /the/root/of/all/client/cas.pem
ssl_verify_depth 3;
ssl_verify_client optional;
location ~ ^/safe {
if ($ssl_client_verify != SUCCESS) {
return 401;
}
if ($ssl_client_s_dn_cn !~ "Really Me") {
return 401;
}
}
}
@maresb
Copy link

maresb commented Aug 13, 2019

Since nginx release 1.11.6, the formatting of $ssl_client_s_dn has changed to use commas instead of slashes.

In this case, the following line should work:

~(^|,)CN=(?<CN>[^,]+) $CN;

(Note the two cases that CN= could occur either at the beginning of the line or following a , character.)

@arpan57
Copy link

arpan57 commented Feb 14, 2022

Hi @schtobia ,

Awesome example.
I am trying similar thing but I get the value of $ssl_client_s_dn as blank in nginx when I connect to nginx via curl ( I am passing valid key and the cert as well as capath) Do you know where I might be going wrong?
I have added a question in more details here : https://serverfault.com/questions/1093641/rejecting-connections-based-on-a-pattern-in-nginx

Thanks,
Arpan

@schtobia
Copy link
Author

Hi @arpan57,

I'm sorry, i didn't look into nginx for quite some time - I move my entire frontend to traefik.

@arpan57
Copy link

arpan57 commented Feb 15, 2022

hi @schtobia ,
Thank you for the quick response.

I managed to fix it. Posting solution here just in case it could aid someone.

In my configurations missing bit was ssl_verify_client optional; until we specify I learnt that unless we mention ssl_verify_client on or optional, the $ssl_client_s_dn variable is not set. It will keep printing blank.
A bit strange that nginx logs didn't say it, I had to figure it out by trial and error.
Hindsight it makes sense that without enabling client verification, what server will do with the client client subject DN.

Regards,
Arpan

@schtobia
Copy link
Author

Thanks for the follow-up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment