Security

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

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

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.

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

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.

Fortress-Grade Identity Security on CpanelFree

Protect your infrastructure with zero-trust Single Sign-On, dedicated NVMe servers, and 100% free hosting and VPS options.

Get Free Cloud Hosting Today →

Deploy Fast, Reliable Web Hosting on CpanelFree

Get genuine cPanel control, unmetered NVMe SSD storage, and free AutoSSL at $0 cost forever.

Claim Free Hosting Account

About the author

Blog

DevOps architect and Linux sysadmin specializing in server hardening, OpenLiteSpeed performance optimization, and free cloud hosting infrastructure.

Leave a Comment