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 thenginxsystem user. - A hardened
/etc/nginx/nginx.confwithserver_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_statushealth endpoint at/nginx_status, bound to127.0.0.1. - A commented reverse-proxy
locationblock, ready for you to point at an upstream. nginx.serviceandfreenginx-firstboot.servicesystemd 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.
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.
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 StandardOpen 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 TcpVerify 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:*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 -tThe 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.
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.
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.confTo serve your own static site, replace the contents of /var/www/html, then test and reload:
sudo nginx -t sudo systemctl reload nginxReverse-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 nginxInstall 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 nginxFor 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