wip: some progress on markdown; cleaning up code using html-react-parser and its dependencies
This commit is contained in:
202
dummies/test1.md
202
dummies/test1.md
@@ -1,15 +1,201 @@
|
||||
# Post Title
|
||||
# Nginx + SSL Client Certificate Verification: Manage access to a site
|
||||
|
||||
## Introduction
|
||||
Access control is a fundamental part of security. Most entities rely on
|
||||
the combination of username and password, sometimes with additional multi-factor authentication
|
||||
to improve security. Some entities also use the SSL client certificate verification to manage access
|
||||
to specific resources. One of the use cases where SSL client certificate verification fits perfectly is
|
||||
managing access to internet-facing development or staging servers. In this post, I'll share how
|
||||
to set up the certificates and configure nginx to verify users based on their certificates.
|
||||
|
||||
Hi there! Do you see me?
|
||||
## Preparing the certificates
|
||||
|
||||
```go
|
||||
import "fmt"
|
||||
There are two certificates we are going to create. The first one is the root
|
||||
certificate. It will be placed in the Nginx server. The second one is the client certificate. It will
|
||||
be installed in the client machine/browsers.
|
||||
|
||||
func main() {
|
||||
fmt.Println("hello world")
|
||||
### Root CA
|
||||
|
||||
For generating a root CA, execute these two steps:
|
||||
|
||||
#### Generate RSA Key
|
||||
|
||||
```sh
|
||||
openssl genrsa -aes256 -out ca.key 4096
|
||||
```
|
||||
|
||||
#### Create Root CA file
|
||||
|
||||
```sh
|
||||
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
|
||||
```
|
||||
|
||||
### Setup CA configuration
|
||||
|
||||
This is an optional step, but if you want to be able to revoke access you previously granted, you need to do this step.
|
||||
Create a file named ca.cnf in the same directory as the ca.key and ca.crt.
|
||||
|
||||
```ini
|
||||
[ ca ]
|
||||
default_ca = gca
|
||||
|
||||
[ crl_ext ]
|
||||
authorityKeyIdentifier=keyid:always
|
||||
|
||||
[ gca ]
|
||||
dir = ./
|
||||
new_certs_dir = $dir
|
||||
unique_subject = no
|
||||
certificate = $dir/ca.crt
|
||||
database = $dir/certindex
|
||||
private_key = $dir/ca.key
|
||||
serial = $dir/certserial
|
||||
default_days = 365
|
||||
default_md = sha256
|
||||
policy = gca_policy
|
||||
x509_extensions = gca_extensions
|
||||
crlnumber = $dir/crlnumber
|
||||
default_crl_days = 365
|
||||
|
||||
[ gca_policy ]
|
||||
commonName = supplied
|
||||
stateOrProvinceName = supplied
|
||||
countryName = optional
|
||||
emailAddress = optional
|
||||
organizationName = supplied
|
||||
organizationUnitName = optional
|
||||
|
||||
[ gca_extensions ]
|
||||
basicConstraints = CA:false
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always
|
||||
keyUsage = digitalSignature,keyEncipherment
|
||||
extendedKeyUsage = serverAuth
|
||||
crlDistributionPoints = URI:http://example.com/root.crl
|
||||
subjectAltName = @alt_names
|
||||
|
||||
[ alt_names ]
|
||||
DNS.1 = example.com
|
||||
DNS.2 = *.example.com
|
||||
```
|
||||
|
||||
Initialize an empty file for the CA database.
|
||||
|
||||
```sh
|
||||
touch certindex
|
||||
```
|
||||
|
||||
Initialize value for certserial and crlnumber
|
||||
|
||||
```sh
|
||||
echo 01 > certserial
|
||||
echo 01 > crlnumber
|
||||
```
|
||||
|
||||
### User Certificates
|
||||
|
||||
#### Generate the user RSA key
|
||||
|
||||
```sh
|
||||
openssl genrsa -aes256 -out client01/user.key 4096
|
||||
```
|
||||
|
||||
#### Create Certificate-Signing Request (CSR)
|
||||
|
||||
```sh
|
||||
openssl req -new -key client01/user.key -out client01/user.csr
|
||||
```
|
||||
|
||||
#### Sign the CSR
|
||||
|
||||
If you did the setup CA configuration step, sign the CSR file by running this command.
|
||||
|
||||
```sh
|
||||
openssl ca -config ca.cnf -in client01/user.csr -out client01/user.crt
|
||||
```
|
||||
|
||||
If you skipped the setup CA configuration step, sign the CSR file by running this command.
|
||||
|
||||
```sh
|
||||
openssl x509 -req -days 365 -in client01/user.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client01/user.crt
|
||||
```
|
||||
|
||||
#### Convert the crt file to pfx/p12 file
|
||||
|
||||
Most of the time, browsers/client machines only accept a certificate in the pfx format. Run this
|
||||
command to convert the crt file to the pfx/p12 format
|
||||
|
||||
```sh
|
||||
openssl pkcs12 -export -out client01/user.pfx -inkey client01/user.key -in client01/user.crt -certfile ca.crt
|
||||
```
|
||||
|
||||
You'll be prompted to enter an export password. You must input the exact password when adding
|
||||
the certificate to a browser.
|
||||
|
||||
---
|
||||
|
||||
## Setting up nginx with client certificates verification
|
||||
|
||||
Add these lines to a server block in your nginx configuration
|
||||
|
||||
```nginx
|
||||
ssl_client_certificate /path/to/client/verfication/ca.crt;
|
||||
ssl_verify_client optional;
|
||||
ssl_verify_depth 2;
|
||||
```
|
||||
|
||||
You can do location-based access control. Location-based here refers to a location block in your
|
||||
nginx configuration, for example:
|
||||
|
||||
```nginx
|
||||
location /private {
|
||||
if ($ssl_client_verify != SUCCESS) { # add this condition
|
||||
return 403; # to make nginx return 403
|
||||
} # when the client has no valid certificate
|
||||
|
||||
....
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Here is a complete example of a server block in the nginx configuration
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
|
||||
server_name www.example.com;
|
||||
ssl_certificate /path/to/your/https/certificate.pem;
|
||||
ssl_certificate_key /path/to/your/https/private-key.pem;
|
||||
include snippets/ssl-params.conf;
|
||||
|
||||
# the folowing three lines make nginx verify client certificate
|
||||
ssl_client_certificate /path/to/client/verification/ca.crt;
|
||||
ssl_verify_client optional;
|
||||
ssl_verify_depth 2;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
location / {
|
||||
if ($ssl_client_verify != SUCCESS) { # add this condition
|
||||
return 403; # to make nginx return 403
|
||||
} # when the client has no valid certificate
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
That's the `hello world` code!
|
||||
---
|
||||
|
||||
## Adding the User Certificates to the client machine/browsers
|
||||
|
||||
Most browsers have a search feature on their setting page. Just search for certificates. It will show you the setting
|
||||
for certificate management.
|
||||
|
||||
### Google Chrome (and Chromium-based browsers)
|
||||
|
||||
Google Chrome and most Chromium-based (e.g., Vivaldi, Microsoft Edge) browsers installed on Windows or Mac rely on
|
||||
the operating system key management. So when you open the setting for certificate management, an external window
|
||||
will open.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user