Nginx can easily be configured to act as a reverse proxy in order to externaly expose on the same point different web services hosted internaly.
To restrict the access to the content hosted behind the proxy, it is possible to require the users to provide a personal certificate. Using this mechanism, you ensure only trusted users are allowed to access protected services.
This project provides all the tools needed to easily setup and configure the reverse proxy and the client certificates.
This project requires Docker and Docker-compose to be installed.
The docker-compose.yml file describes the architecture of the project.
Alternatively, you can use the provided files on a regular Nginx server to use the same mechanism without Docker.
Files:
The nginx/nginx.conf
file is configured to run Nginx using default configuration.
The nginx/fastcgi.conf
file is the default configuration for FastCGI.
The nginx/proxy.conf
file contains the parameters to optimize the proxy role of Nginx.
The nginx/ssl.conf
file is configured to use strong encryption protocols and ciphers. It also add security mechanisms through headers.
The nginx/conf.d/site.example.conf
is configured to listen on ports 80 and 443 and requires clients to use a certificate to authenticate themself. If a client is successfully authenticated, it is redirected to the webapp docker machine.
client [certificate] -> front [CA + proxy] -> webapp [website]
-
Go to
nginx/ssl
:$ cd nginx/ssl
-
Edit the
ca/ca.cnf
file to reflect your organization values in the[ ca_dn ]
part.- Create the certificate authority (CA):
$ ./create_ca.sh
. The filecreate_ca.sh
should then by set to mode 000 in order to avoid erasing the issued CA.
- Create the certificate authority (CA):
-
Edit the
tls/tls.tpl
file to reflect your organization subdomain values in the[ default ]
part.- Create a certificate for the front website
$ ./create_tls.sh site.example
. The DNS name of the website can differ but you have to edit the file generated innginx/conf.d
to match the actual name. Alternatively, you can buy a certificate from a recognized issuer or get one for free using Let's Encrypt.
- Create a certificate for the front website
-
Edit the
client/client.tpl
file to reflect organization values in the[ client_dn ]
part. You don't need to change the email address, this will be done by the script.- Create a client
$ ./create_client.sh firstname lastname client@site.example
The newly created certificate is located inclients/p12
and protected by a password added to theclients/passwords.txt
file.
- Create a client
-
Go to
nginx/conf.d
:$ cd ../conf.d
-
Open the
site.example.conf
to adjust the following parameters :- Change the
site.example
value afterserver_name
to match your website's URL (2 times). - Change the values after
ssl_certificate
andssl_certificate_key
to match your website's certificate. - Change the
http://protectedapp;
value afterproxy_pass
to match your docker application's name or its address (domain name or IP). - Optional: change the log's name after
access_log
.
- Change the
-
Optional: change the file's name, as long as its extension is ".conf".
In your browser, to go the settings -> certificate part. It can have different names, such as "manage certificates" or "view certificates".
This part has 4 sections: "Your certificates", "People", "Servers" and "Authorities".
In the "Your certificates", click "import" and select the .p12 file issued for you. The browser asks for a password which has been assigned during the certificate creation.
Optional: In the "Authorities", import the "ca.crt" certificate. Check "Trust this CA to identify websites". You don't have to do this if your website certificate has been issued by a recognized issuer.
Then, validate/exit the certificate manager part.
- In the root directory, where the "docker-compose.yml" is located, run
$ docker-compose up
. - Edit the
/etc/hosts
file using sudo$ sudo nano /etc/root
. Add the following new line:127.0.0.1 site.example
or whatever name you chose for your website. - Open you browser, go to https://site.example. The browser should ask for permissions to use your user certificate. Validate the request.
If your browser raises a TLS warning, ignore it and "accept the risk".
If everything went well, you should see a page displaying "NGINX" and various info such as "Server address" and "Server name".
To revoke a client, run $ ./revoke_client firstname lastname
and check the certificate has been moved to clients/revoked
.
Revoked files are visible by possessing a 200122103242Z,cessationOfOperation
string in the 3rd column of nginx/ssl/ca/ca.db
.
Users possessing revoked certificated can not authenticate themself anymore on the proxy.
Go to about:config
and set security.osclientcerts.autoload
to true
.
The password may be wrong. Check the associated password in passwords.txt
or regenerate a certificate.
You have not imported your certificate in your browser or the domain linked to the certificate is wrong.
Your certificate may be revoked. Check the revoked
folder.
Have you tried rebooting ?
Credits:
- Docker: https://www.docker.com/
- Docker-compose: https://docs.docker.com/compose/
- Nginx: https://www.nginx.com/
- OpenSSL https://www.openssl.org/
Coming later:
- LDAP based Two Factors Authentication
- Web interface to manage the PKI