Autentifikace pomocí Nginx reverse proxy a Azure AD OAuth (Docker + OPNsense certifikát) – Kompletní návod

SEO optimalizovaný návod – V tomto článku najdete kompletní krok‑za‑krokem postup, jak nastavit autentifikaci pro webové aplikace pomocí Nginx reverse proxy a Azure Active Directory OAuth 2.0 v Dockeru a zároveň automaticky stáhnout TLS certifikát z OPNsense. Tento průvodce je určen pro vývojáře a administrátory, kteří potřebují bezpečné a škálovatelné řešení.

1. Registrace aplikace v Azure AD

  • Otevřete Azure PortalAzure Active DirectoryApp registrationsNew registration.
  • Zadejte název aplikace (např. MyNginxOAuth) a nastavte Redirect URI na https://your-domain.com/oauth2/callback.
  • Po vytvoření získáte Client ID a Tenant ID. V sekci Certificates & secrets vytvořte nový client secret a uložte si hodnotu.

2. Dockerizace Nginx s Lua a OpenID Connect

Vytvoříme vlastní Docker image, který obsahuje:

  • Nginx s lua-nginx-module pro spuštění Lua skriptů.
  • Knihovnu lua-resty-openidc pro OIDC integraci.
# Dockerfile
FROM nginx:latest

# Instalace Lua, nginx‑lua‑module a lua‑resty‑openidc
RUN apt-get update && apt-get install -y \
    libnginx-mod-http-lua \
    lua5.3 \
    luarocks && \
    luarocks install lua-resty-openidc && \
    rm -rf /var/lib/apt/lists/*

# Kopírování konfiguračního souboru
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

Uložte tento Dockerfile a vytvořte soubor nginx.conf dle následující šablony.

nginx.conf – OIDC nastavení a TLS

worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    lua_shared_dict discovery 1m;
    lua_shared_dict jwks 1m;
    lua_shared_dict sessions 10m;

    server {
        listen 80;
        server_name your-domain.com;

        # Proxy na backend (upravit dle potřeby)
        location / {
            access_by_lua_block {
                local opts = {
                    discovery = "https://login.microsoftonline.com//v2.0/.well-known/openid-configuration",
                    client_id = "",
                    client_secret = "",
                    redirect_uri = "https://your-domain.com/oauth2/callback",
                    scope = "openid email profile",
                    iat_slack = 600,
                    session_secret = "a-very-secret-string",
                    redirect_after_logout_uri = "https://your-domain.com/",
                }
                local res, err = require("resty.openidc").authenticate(opts)
                if err then
                    ngx.status = 302
                    ngx.header["Location"] = "/login"
                    ngx.exit(ngx.HTTP_TEMPORARY_REDIRECT)
                end
                -- Uživatelská identita předána backendu
                ngx.req.set_header("X-Remote-User", res.id_token.sub)
            }
            proxy_pass http://backend_upstream;
        }
    }

    # TLS terminace – certifikát bude stažen z OPNsense (viz sekce 3)
    server {
        listen 443 ssl;
        server_name your-domain.com;
        ssl_certificate /etc/nginx/ssl/opnsense.crt;
        ssl_certificate_key /etc/nginx/ssl/opnsense.key;
        include /etc/nginx/conf.d/ssl_params.conf; # doporučené parametry SSL

        location / {
            access_by_lua_block {
                local opts = {
                    discovery = "https://login.microsoftonline.com//v2.0/.well-known/openid-configuration",
                    client_id = "",
                    client_secret = "",
                    redirect_uri = "https://your-domain.com/oauth2/callback",
                    scope = "openid email profile",
                    iat_slack = 600,
                    session_secret = "a-very-secret-string",
                    redirect_after_logout_uri = "https://your-domain.com/",
                }
                local res, err = require("resty.openidc").authenticate(opts)
                if err then
                    ngx.status = 302
                    ngx.header["Location"] = "/login"
                    ngx.exit(ngx.HTTP_TEMPORARY_REDIRECT)
                end
                ngx.req.set_header("X-Remote-User", res.id_token.sub)
            }
            proxy_pass http://backend_upstream;
        }
    }
}

3. Stahování TLS certifikátu z OPNsense (automatizované)

OPNsense nabízí REST API pro export certifikátů. Stačí jeden curl příkaz, který získá certifikát (a volitelně i soukromý klíč) a uloží jej do /etc/nginx/ssl uvnitř kontejneru.

# Předpoklad: máte API token a tajný klíč
API_KEY="your_opnsense_api_key"
API_SECRET="your_opnsense_api_secret"
OPNSENSE_HOST="https://opnsense.yourdomain.com"
CERT_ID="1"   # ID certifikátu (z UI → System → Trust → Authorities)

# Export certifikátu (PEM)
curl -k -u "$API_KEY:$API_SECRET" \
     "$OPNSENSE_HOST/api/services/ca/ca/export/$CERT_ID" \
     -o /etc/nginx/ssl/opnsense.crt

# Volitelně export privátního klíče (pokud máte povolení)
curl -k -u "$API_KEY:$API_SECRET" \
     "$OPNSENSE_HOST/api/services/ca/ca/exportkey/$CERT_ID" \
     -o /etc/nginx/ssl/opnsense.key

Ujistěte se, že adresář /etc/nginx/ssl je svazkem připojeným k Dockeru (např. -v /host/ssl:/etc/nginx/ssl).

4. Vytvoření a spuštění Docker kontejneru

# 1. Sestavte image
docker build -t nginx-azure-oidc .

# 2. Spusťte kontejner (připojte svazek s certifikátem a nastavte proměnné)
docker run -d \
  -p 80:80 -p 443:443 \
  -v /path/to/ssl:/etc/nginx/ssl \
  -e TENANT_ID="" \
  -e CLIENT_ID="" \
  -e CLIENT_SECRET="" \
  nginx-azure-oidc

5. Testování a ladění

  • Otevřete https://your-domain.com – mělo by vás přesměrovat na přihlašovací obrazovku Azure AD.
  • Po úspěšném přihlášení Nginx předá hlavičku X-Remote-User vašemu backendu.
  • Kontrolujte logy Nginx (/var/log/nginx/error.log) pro případné OIDC chyby.
  • Ověřte, že TLS certifikát je správně načten a platný (příkaz openssl s_client -connect your-domain.com:443 -servername your-domain.com).

 

Napsat komentář