Categories
Apache IdP Keycloak Shibboleth SingleSignOn SSO Webserver

Apache SAML SSO using mellon (example: open-webui)

This short post is about how to run the open-webui docker container with an apache based reversed proxy (handling the SSL termination and authentication with mod-auth-mellon).

In the following example the open-webui docker container is listening on localhost only, port 8009 (s. variable definition at the beginning of the apache2 config):

Define SERVERNAME open-webui.mydomain.de
Define BACKEND_HOST localhost
Define BACKEND_PORT 8009

<VirtualHost *:443>
        ServerName ${SERVERNAME}
        ServerAdmin webmaster@mydomain.de
        DocumentRoot /var/www/html

        ErrorLog ${APACHE_LOG_DIR}/${SERVERNAME}-error.log
        CustomLog ${APACHE_LOG_DIR}/${SERVERNAME}-access.log combined

        SSLEngine on
        SSLCertificateKeyFile   /etc/letsencrypt/live/${SERVERNAME}/privkey.pem
        SSLCertificateFile      /etc/letsencrypt/live/${SERVERNAME}/fullchain.pem

        ProxyPreserveHost On
        ProxyRequests off
        ProxyPass         /  http://${BACKEND_HOST}:${BACKEND_PORT}/ nocanon upgrade=websocket timeout=3600
        ProxyPassReverse  /  http://${BACKEND_HOST}:${BACKEND_PORT}/

        RequestHeader setifempty "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
        RequestHeader setifempty "X-Forwarded-Host" %{THE_HOST}e

        AllowEncodedSlashes NoDecode

        LogLevel mod_auth_mellon.c:debug

        <Location />
                # Module mod_auth_mellon.c
                MellonEnable "auth"
                MellonSecureCookie secure
                MellonCookiePath /
                MellonEndpointPath "/mellon"
                MellonDefaultLoginPath "/"
                MellonSessionLength 86400
                MellonNoCookieErrorPage "https://www.mydomain.de/no_cookie.html"
                MellonSPMetadataFile /etc/apache2/mellon/https_${SERVERNAME}.xml
                MellonOrganizationName "My Domain"
                MellonOrganizationDisplayName "en" "My Domain"
                MellonSPPrivateKeyFile /etc/apache2/mellon/https_${SERVERNAME}.key
                MellonSPCertFile /etc/apache2/mellon/https_${SERVERNAME}.cert
                MellonIdPMetadataFile /etc/apache2/mellon/keycloak-metadata.xml
                MellonRedirectDomains [self]
        </Location>

        #MellonDiagnosticsEnable On
        #MellonDiagnosticsFile /var/log/apache2/mellon_diagnostics.log

        RequestHeader setifempty "X-Real-IP" expr=%{REMOTE_ADDR}

        RequestHeader set "X-Forwarded-Email" %{MELLON_email}e "expr=-n %{env:MELLON_email}"
        RequestHeader set "X-Forwarded-Username" %{MELLON_username}e "expr=-n %{env:MELLON_username}"
        RequestHeader set "X-Forwarded-Displayname" %{MELLON_displayname}e "expr=-n %{env:MELLON_displayname}"


</VirtualHost>

In order to use the above config some modules need to be enabled: mod-auth-mellon for SAML authentication and mod-headers in order to set extra HTTP headers (username and email) for open-webui backend:

linux # apt install libapache2-mod-auth-mellon
linux # a2enmod auth_mellon
linux # a2enmod headers
linux # systemctl reload apache2

Next thing: we need some certificates and a basic SAML service provider (SP) config. This can be created using the tool mellon_create_metadata(.sh) shipped with the module. This tool takes to opions: the SP identifier (usually just the base URL of your host) and the mellon endpoint (s. apache config, MellonEndpointPath):

linux # mellon_create_metadata https://www.mydomain.de/saml https://www.mydomain.de/saml/mellon
Output files:
Private key: https_www.mydomain.de_saml.key
Certificate: https_www.mydomain.de_saml.cert
Metadata: https_www.mydomain.de_saml.xml
Host: www.mydomain.de

Endpoints:
SingleLogoutService: https://www.mydomain.de/saml/mellon/logout
AssertionConsumerService: https://www.mydomain.de/saml/mellon/postResponse

As seen by the output above, this will create 3 files: a certificate (and matching key) and a XML file containing the SP config. The later one will be required by your Identity Provider (IdP) in order to accept requests from you Service Provider (SP).

And for the final part: The open-webui docker config is quite easy: just set the WEBUI_AUTH_TRUSTED_* variables to the ones set in your apache config (s. “RequestHeader set” lines):

# https://docs.openwebui.com/getting-started/env-configuration#webui_auth_trusted_email_header
WEBUI_AUTH_TRUSTED_EMAIL_HEADER=X-Forwarded-Email
# https://docs.openwebui.com/getting-started/env-configuration#webui_auth_trusted_name_header
WEBUI_AUTH_TRUSTED_NAME_HEADER=X-Forwarded-User

Leave a Reply

Your email address will not be published. Required fields are marked *