Deployment guide

freenginx

Overview

freenginx is a community-driven fork of the nginx HTTP server, reverse proxy and load balancer, maintained by Maxim Dounin. It keeps the nginx configuration language and behaviour, so everything you know about nginx.conf, server blocks and location blocks applies unchanged.

This guide covers deploying and configuring freenginx on Ubuntu 24.04 on Azure from the SecureAnyCloud Azure Marketplace image. The image ships freenginx 1.30.1 (the current stable line), compiled from the official source tarball with SSL, HTTP/2, real-IP, gzip-static, stub-status and sub-filter modules and hardened compiler flags.

The image boots with a production configuration rather than a bare default. The server version is hidden (server_tokens off), only TLS 1.2 and 1.3 are accepted, HTTP/2 is on, gzip is enabled and common security headers are set. HTTPS works out of the box because each VM generates its own self-signed certificate, private key and Diffie-Hellman parameters at first boot. Nothing secret is baked into the image.

What you get:

  • freenginx 1.30.1 compiled from source to /usr/sbin/nginx, running as the nginx system user.
  • A hardened /etc/nginx/nginx.conf with server_tokens off, gzip, TLS 1.2/1.3 and session hardening.
  • A default site at /etc/nginx/conf.d/default.conf that serves the SecureAnyCloud landing page on TCP 80 and TCP 443.
  • A document root at /var/www/html.
  • A per-VM self-signed TLS certificate, key and DH parameters, generated at first boot in /etc/nginx/ssl/ and never shipped in the image.
  • A local-only stub_status health endpoint at /nginx_status, bound to 127.0.0.1.
  • A commented reverse-proxy location block, ready for you to point at an upstream.
  • nginx.service and freenginx-firstboot.service systemd units that start automatically on boot.
  • Listeners on TCP 80 (HTTP) and TCP 443 (HTTP/2 + TLS).
  • An Ubuntu 24.04 LTS base with the latest security patches applied at build time and unattended-upgrades enabled.
  • The Azure Linux Agent for cloud integration and SSH key injection.
  • 24/7 SecureAnyCloud support with a 24 hour response SLA.

Prerequisites

  • An active Azure subscription.
  • A subscription to the freenginx on Ubuntu 24.04 listing on Azure Marketplace.
  • An SSH public key for VM authentication.
  • A virtual network and subnet in the target region.
  • Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for typical web and reverse-proxy traffic. freenginx is efficient and has a small memory footprint, so scale up only for very high request rates or large reverse-proxy fleets.
1

Deploy from the Azure Portal

In the Azure Portal, open Marketplace, search for freenginx, select the SecureAnyCloud publisher entry, and choose Create.

On the Networking tab, attach a network security group. Allow inbound TCP 22 from your management IP range, and allow TCP 80 and TCP 443 from the client networks that should reach your site.

Choose Review + create, wait for validation, then choose Create. Deployment takes around two minutes.

2

Deploy from the Azure CLI

RG="freenginx-prod" LOCATION="eastus" VM_NAME="freenginx-01" ADMIN_USER="azureuser" IMAGE_URN="sac1647283583153:freenginx-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:freenginx-ubuntu-24-04:default:latest
az vm create \
  --resource-group "$RG" \
  --name "$VM_NAME" \
  --image "$IMAGE_URN" \
  --size Standard_B2s \
  --admin-username "$ADMIN_USER" \
  --ssh-key-values "$SSH_KEY" \
  --public-ip-sku Standard

Open the web ports on the VM's network security group. Adjust the source ranges to your own networks:

az network nsg rule create --resource-group "$RG" --nsg-name "${VM_NAME}NSG" \
  --name allow-http --priority 1001 --destination-port-ranges 80 --access Allow --protocol Tcp
az network nsg rule create --resource-group "$RG" --nsg-name "${VM_NAME}NSG" \
  --name allow-https --priority 1002 --destination-port-ranges 443 --access Allow --protocol Tcp
3

Verify the service is running

Connect to the VM over SSH and confirm that freenginx is active, enabled at boot and listening on TCP 80 and 443. freenginx-firstboot.service generates the self-signed certificate and DH parameters once, at first boot.

systemctl status nginx --no-pager nginx -v ss -tln | grep -E ':80 |:443 '

Expected output:

● nginx.service - freenginx - high performance web server (sac) Loaded: loaded (/etc/systemd/system/nginx.service; enabled; preset: enabled) Active: active (running) nginx version: freenginx/1.30.1 LISTEN 0 511 0.0.0.0:80 0.0.0.0:* LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
4

Review the build configuration

The image is compiled from the official freenginx source tarball. Inspect the exact modules and compiler flags used in the build, and confirm that the running configuration passes a syntax test:

nginx -V nginx -t

The build includes the SSL, HTTP/2, real-IP, stub-status, gzip-static and sub-filter modules, with stack-protector and RELRO hardening flags. nginx -t reports the configuration syntax is OK.

5

Confirm the hardened defaults and TLS

Check that the server version is hidden, the security headers are present, the per-VM self-signed certificate is in place and HTTP/2 is negotiated on TCP 443:

curl -sI http://localhost/ | grep -iE '^HTTP|^Server:|^X-|^Referrer' echo | openssl s_client -connect 127.0.0.1:443 2>/dev/null | openssl x509 -noout -subject -issuer -dates
curl -skI --http2 https://localhost/ | grep -iE '^HTTP|^strict-transport'

Server: freenginx appears with no version number (server_tokens off). The X-Content-Type-Options, X-Frame-Options and Referrer-Policy headers are set, and the certificate is this VM's own self-signed certificate. HTTP/2 200 confirms that HTTP/2 is active, with HSTS on HTTPS.

The default landing page is served from /var/www/html over both HTTP and HTTPS.

6

Serve your own website

Copy your files into the document root, or edit the default site. The document root is /var/www/html:

ls -la /var/www/html/ cat /etc/nginx/conf.d/default.conf

To serve your own static site, replace the contents of /var/www/html, then test and reload:

sudo nginx -t sudo systemctl reload nginx
7

Reverse-proxy an upstream application

freenginx works as a reverse proxy and load balancer. The default site ships a commented location /app/ block. Uncomment it in /etc/nginx/conf.d/default.conf and point proxy_pass at your backend:

location /app/ { proxy_pass http://127.0.0.1:8080/; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }

To load-balance across several backends, declare an upstream block and proxy to it:

upstream app_pool { server 10.0.0.4:8080; server 10.0.0.5:8080; } server { listen 80; location / { proxy_pass http://app_pool; } }

After you edit any configuration, validate it before you reload. A reload never drops live connections:

sudo nginx -t sudo systemctl reload nginx
8

Install a real TLS certificate

The image ships with a per-VM self-signed certificate, so HTTPS works immediately. To serve a certificate that browsers trust, replace the two files referenced by the default :443 server block, then reload:

  • /etc/nginx/ssl/sac.crt: your certificate (full chain).
  • /etc/nginx/ssl/sac.key: your private key.
ssl_certificate /etc/nginx/ssl/sac.crt; ssl_certificate_key /etc/nginx/ssl/sac.key;

Copy your certificate and key over those paths, and keep the key readable only by root. Then test and reload:

sudo nginx -t sudo systemctl reload nginx

For automated Let's Encrypt certificates, install certbot with the nginx plugin (sudo apt-get install -y python3-certbot-nginx). Then run sudo certbot --nginx -d your-domain.example. Certbot rewrites the certificate paths for you and installs a renewal timer.

Security notes

No baked secret. Every VM generates its own TLS private key, certificate and DH parameters at first boot in /etc/nginx/ssl/. The private key is mode 0600 root:root. No two instances share a key, and nothing secret ships in the image.

Version hidden. server_tokens off means responses carry a bare Server: freenginx header with no version, which reduces fingerprinting.

TLS 1.2 and 1.3 only. Session tickets are disabled, and HSTS is set on HTTPS responses.

Local-only status. The stub_status metrics endpoint at /nginx_status is restricted to 127.0.0.1.

Patched at build time. Unattended-upgrades stays enabled, so the VM keeps receiving OS security updates.

Support

  • Documentation and guides: secureanycloud.com
  • Email support: sales@secureanycloud.com (24/7, 24 hour response SLA)
  • freenginx project: freenginx.org

Deploy on Azure

Launch freenginx on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure