How to Set Up Authelia Single Sign-On (SSO) and 2FA with Nginx on Ubuntu VPS

Why Self-Hosted Web Portals Need Centralized Zero-Trust 2FA

As you self-host multiple internal web applications on your Linux VPS (such as Uptime Kuma, Glances, Portainer, MinIO Console, Traefik Dashboard, or phpMyAdmin), each platform features its own separate authentication mechanism—or worse, lacks native Two-Factor Authentication (2FA) support. Managing fragmented passwords across dozens of admin dashboards creates immense security vulnerability.


⚡ Executive Summary & Key Takeaways

Verified Guide
  • Core Architecture: Production setup of Authelia Single Sign-On (SSO) and 2FA with Nginx on Ubuntu VPS engineered for maximum throughput and minimal memory footprint.
  • Deployment Speed: Fast-track setup under 5–10 minutes with isolated daemon processes and secure system permissions.
  • Security Hardening: Configured with dedicated system users, UFW network rules, and automated SSL/TLS termination.
  • Cost & Sovereignty: 100% open-source self-hosting on Linux VPS, eliminating expensive recurring SaaS subscriptions.

🎯 Difficulty: Intermediate
⚡ Est. Execution: 10–15 Mins
⏱️ 6 min read (1,058 words)

🔄 Verified September 2026 Edition

🐧 Target Environment: Ubuntu 24.04 / 22.04 LTS • Debian 12 • AlmaLinux 9
🛡️ Reviewed by: Senior Linux Systems Architect

Authelia is an open-source, lightweight authentication and authorization server that integrates seamlessly with Nginx using the auth_request forward-authentication module. Authelia acts as a fortress gatekeeper in front of all your subdomains: unauthenticated visitors are automatically redirected to a sleek Single Sign-On (SSO) portal requiring a primary password and secondary 2FA (TOTP authenticator app, WebAuthn YubiKey, or Duo push) before Nginx permits traffic through.

In this cybersecurity tutorial, we will configure Authelia on Ubuntu 24.04/22.04 LTS using Docker Compose, secure private subdomains via Nginx auth_request, and configure TOTP Two-Factor Authentication.

Step 1: Installing Docker and Creating Project Directory

# Install Docker and prerequisite utilities
sudo apt update && sudo apt install -y curl nginx certbot python3-certbot-nginx
curl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable --now docker

# Create project directory
sudo mkdir -p /var/www/authelia
sudo chown -R $USER:$USER /var/www/authelia
cd /var/www/authelia

Zero Server Overhead

Prefer Not to Manage Commands via Terminal?

Deploy high-speed hosting with CpanelFree $0 Free Web Hosting. Enjoy authentic cPanel, unmetered NVMe SSD storage, PHP 8.3, and automatic SSL without server maintenance.

Step 2: Writing Production Authelia Configuration

Create configuration directory and file /var/www/authelia/configuration.yml:

server:
  host: 0.0.0.0
  port: 9091

log:
  level: info

jwt_secret: "YourUltraSecureJwtSecretKeyAtLeast32Chars!"
default_redirection_url: "https://auth.example.com"

totp:
  issuer: "CpanelFree Cloud"

authentication_backend:
  file:
    path: /config/users_database.yml

access_control:
  default_policy: deny
  rules:
    # Require Two-Factor Authentication for all internal dashboards
    - domain: "*.example.com"
      policy: two_factor

session:
  name: authelia_session
  domain: example.com
  secret: "AnotherUltraSecureSessionSecretKey32Chars!"
  expiration: 3600 # 1 hour

storage:
  local:
    path: /config/db.sqlite3

notifier:
  filesystem:
    filename: /config/notification.txt

Step 3: Creating Users Database with Password Hashes

Generate a secure Argon2id password hash using Docker:

# Generate Argon2 password hash
docker run authelia/authelia:latest authelia crypto hash generate argon2 --password "StrongUserPassword2026!"

Create /var/www/authelia/users_database.yml:

users:
  admin:
    displayname: "Administrator"
    password: "$argon2id$v=19$m=65536,t=3,p=4$..."
    email: "[email protected]"
    groups:
      - admins

Step 4: Launching Authelia Container Stack

Create /var/www/authelia/docker-compose.yml:

services:
  authelia:
    image: authelia/authelia:latest
    container_name: authelia_sso
    restart: always
    ports:
      - "127.0.0.1:9091:9091"
    volumes:
      - ./:/config
    deploy:
      resources:
        limits:
          memory: 256M

Launch the container: docker compose up -d.

Step 5: Nginx Forward-Auth Integration & Subdomain Protection

Create the universal Authelia forward-auth snippet at /etc/nginx/snippets/authelia.conf:

location /authelia {
    internal;
    proxy_pass http://127.0.0.1:9091/api/verify;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    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;
}

Now, protect ANY internal subdomain (e.g. status.example.com or monitor.example.com) by adding two lines:

server {
    listen 80;
    server_name status.example.com;

    # Include Authelia 2FA gatekeeper
    include snippets/authelia.conf;
    auth_request /authelia;

    error_page 401 =302 https://auth.example.com/?rd=$scheme://$http_host$request_uri;

    location / {
        proxy_pass http://127.0.0.1:3001;
    }
}

Integrating Duo Push & WebAuthn YubiKey Hardware Keys

Authelia natively supports FIDO2 WebAuthn cryptographic hardware security keys (YubiKey, Google Titan) and Duo mobile push notifications for enterprise Two-Factor Authentication. Users can register their biometric TouchID, Windows Hello, or YubiKey directly within the Authelia self-service security portal.

Enforcing Granular Access Control Policies by User Group

Define role-based access rules in /var/www/authelia/configuration.yml so that only members of the admins group can access critical monitoring and database dashboards, while standard users access general internal tools with single-factor authentication:

access_control:
  default_policy: deny
  rules:
    # Restrict server monitoring dashboards to admins group only
    - domain: "monitor.example.com"
      subject: "group:admins"
      policy: two_factor

    # Allow general staff to access status portals with single-factor
    - domain: "status.example.com"
      subject: "group:staff"
      policy: one_factor

Enforcing OpenID Connect (OIDC) Identity Provider (IdP)

Authelia can function as a full OpenID Connect (OIDC) Identity Provider, allowing third-party applications (such as Grafana, Nextcloud, Forgejo, or Portainer) to delegate authentication to Authelia using OAuth2 tokens:

# Enable OpenID Connect in /var/www/authelia/configuration.yml
identity_providers:
  oidc:
    hmac_secret: "YourUltraSecureOidcHmacSecretKey32Chars!"
    issuer_private_key: |
      -----BEGIN RSA PRIVATE KEY-----
      ...
      -----END RSA PRIVATE KEY-----
    clients:
      - client_id: "grafana"
        client_name: "Grafana Monitoring Dashboard"
        client_secret: "$argon2id$v=19$m=65536,t=3,p=4$..."
        public: false
        authorization_policy: "two_factor"
        redirect_uris:
          - "https://monitor.example.com/login/generic_oauth"
        scopes:
          - "openid"
          - "profile"
          - "email"
          - "groups"

Authelia Security Hardening Checklist

  • Enforce Argon2id Hashing: Always use Argon2id with m=65536, t=3, p=4 parameters for resistant password storage against GPU cracking.
  • Enable Session Cookie Protection: Ensure same_site: "lax" and secure: true are active.

Protecting Multiple Subdomains with Authelia Regex Wildcards

Instead of manually writing separate server blocks for every internal tool, configure Nginx and Authelia with regex wildcard rules to secure all *.internal.example.com subdomains under a single unified Single Sign-On session:

# Authelia Wildcard Domain Rule (/var/www/authelia/configuration.yml)
access_control:
  default_policy: deny
  rules:
    - domain: "*.internal.example.com"
      policy: two_factor

Authelia Session Management & Redis Cluster Storage

For high-availability multi-node VPS clusters, replace local SQLite session storage with in-memory Redis clustering in configuration.yml to allow seamless failover across multiple Authelia instances without forcing users to re-authenticate.

🚀 Production Cloud Infrastructure

Deploy on High-Performance Cloud VPS with MeraHost

Need dedicated vCPU, root SSH access, pure NVMe SSD speeds, and 99.95% uptime SLA for your production stack? Launch with MeraHost — guaranteed price lock with zero renewal hikes.

Leave a Comment