Nginx Reverse Proxy with TLS Encryption

  • Application Security
  • APPSEC01: Secure all client to service communication with TLS
  • APPSEC02: Secure inter service communication with TLS

Certificate Generation process

  • You create a certificate signing request on your severer
  • You forwarded the request to a registration authority
  • The registry authority checks the claim that you are the owner of the server, and sends an ok to a certificate authority
  • The certificate authority generates the certificate and the private key
  • The certificate is forwarded to a validation authority
  • The certificate and the private key will be sent to you
  • You install the certificate on your server

Creating Certificates with OpenSSL

openssl req -new -x509 -days 90 -newkey rsa:4096 -sha512 -nodes -out admantium.cert -keyout admantium.key
  • req: Make a new certificate request
  • x509: Create the certificate in X509 format
  • days: Set the viability period of this certificate
  • newkey: Generate a new key using 4096bit RSA
  • sha512: Use SHA-512 as the message digest algorithm
  • nodes: Do not require a password for the key file (ONLY ok for self-signed certificates)
  • out: Path and filename where the certificates should be saved
  • keyout: Path and filename where the certificate should be saved
server {
server_name prometheus.infra;
listen 443 ssl;
ssl_certificate /etc/nginx/certs/admantium.cert;
ssl_certificate_key /etc/nginx/certs/admantium.key;
  • listen 443 ssl: Listen on port 443 for incoming TLS connection
  • ssl_certificate: Path and filename of the certificate
  • ssl_certificate_key: Path and filename of the certificate key
http {
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
  • ssl_protocols: The supported protocols - only use TLS1.2 and TLS1.3 since older versions have security weaknesses
  • ssl_ciphers: With this list you control the available encryption methods that Nginx and the client can use for exchanging data, select only strong ciphers
  • ssl_prefer_server_ciphers: A flag that specifies to use the offered ciphers, not those that the client offers.

Testing the Connection

Configure DNSmasq


Critical Review

  • Static configuration: The configuration is determined when I configure Nginx by running an Ansible script. When a new service starts, I need to modify the Nginx configuration. If an existing service stops, Nginx will show an error. However, when the service comes back, which is the default behavior of the job scheduler Nomad, the Consul DNS resolution points to the new space.
  • No dynamic ports: The open source version of Nginx cannot parse DNS SRV records to determine the dynamic ports of a service — this feature is available only on the paid version Nginx Plus. For now, I configure the all Services that are run with Nomad to use static ports. Then, in the Nginx configuration, I can refer to these static ports. This works for now. If the demand to oversee a high amount of services with dynamic ports arises, I could either use the Consul Template extension, a daemon with the task to watch variables and writes config files when they change, or I go back to a zero-conf router like Traeffik or Fabio.



  1. See also this cookbook-style article for quickly to apply examples.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store