Question about Authelia configuration

1. The problem I’m having:

Hey, it’s me again, the guy with the strange questions. :sweat_smile:

I am templating the Authelia integration example for the opnsense plugin of Caddy. I am trying to fit things into the existing logic, and I want to know if the resulting Caddyfile of my template would work, or not. The caddyfile validation says it’s okay, but I’m unsure since I don’t have any experience with forward_auth.

My main question is, are the additional empty handle allowed, or do they have to be removed (because if the forward_auth is successful, it won’t “break out” of the handle to go to the next one.)

Thank you a lot.

2. Error messages and/or full log output:

I don't have any errors.

3. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

4. How I installed and ran Caddy:

a. System environment:

FreeBSD 13.2

b. Command:

service caddy start

c. Service/unit/compose file:

#!/bin/sh

# PROVIDE: caddy
# REQUIRE: LOGIN DAEMON NETWORKING
# KEYWORD: shutdown

# To enable caddy:
#
# - Edit %%PREVIX%%/etc/caddy/Caddyfile
#   See https://caddyserver.com/docs/
# - Run 'service enable caddy'
#
# Note while Caddy currently defaults to running as root:wheel, it is strongly
# recommended to run the server as an unprivileged user, such as www:www.
#
# - Use security/portacl-rc to enable privileged port binding:
#
#   # pkg install security/portacl-rc
#   # sysrc portacl_users+=www
#   # sysrc portacl_user_www_tcp="http https"
#   # sysrc portacl_user_www_udp="https"
#   # service portacl enable
#   # service portacl start
#
# - Configure caddy to run as www:www
#
#   # sysrc caddy_user=www caddy_group=www
#
# - Note if Caddy has been started as root previously, files in
#   /var/log/caddy, /var/db/caddy, and /var/run/caddy may require their ownership
#   changing manually.

# Optional settings:
# caddy_command (string):     Full path to the caddy binary
# caddy_config (string):      Full path to caddy config file
#                             (/usr/local/etc/caddy/Caddyfile)
# caddy_adapter (string):     Config adapter type (caddyfile)
# caddy_admin (string):       Default administration endpoint
#                             (unix//var/run/caddy/caddy.sock)
# caddy_directory (string):   Root for caddy storage (ACME certs, etc.)
#                             (/var/db/caddy)
# caddy_extra_flags (string): Extra flags passed to caddy start
# caddy_logdir (string):      Where caddy logs are stored
#                             (/var/log/caddy)
# caddy_logfile (string):     Location of process log (${caddy_logdir}/caddy.log)
#                             This is for startup/shutdown/error messages.
#                             To create an access log, see:
#                             https://caddyserver.com/docs/caddyfile/directives/log
# caddy_user (user):          User to run caddy (root)
# caddy_group (group):        Group to run caddy (wheel)
#
# This script will honor XDG_CONFIG_HOME/XDG_DATA_HOME. Caddy will create a
# .../caddy subdir in each of those. By default, they are subdirs of /var/db/caddy.
# See https://caddyserver.com/docs/conventions#data-directory

. /etc/rc.subr

name=caddy
rcvar=caddy_enable
desc="Powerful, enterprise-ready, open source web server with automatic HTTPS written in Go"

load_rc_config $name

# Defaults
: ${caddy_enable:=NO}
: ${caddy_adapter:=caddyfile}
: ${caddy_config:="/usr/local/etc/${name}/Caddyfile"}
: ${caddy_admin:="unix//var/run/${name}/${name}.sock"}
: ${caddy_command:="/usr/local/bin/${name}"}
: ${caddy_directory:="/var/db/${name}"}
: ${caddy_extra_flags:=""}
: ${caddy_logdir:="/var/log/${name}"}
: ${caddy_logfile:="${caddy_logdir}/${name}.log"}
: ${caddy_user:="root"}
: ${caddy_group:="wheel"}

# Config and base directories
: ${XDG_CONFIG_HOME:="${caddy_directory}/config"}
: ${XDG_DATA_HOME:="${caddy_directory}/data"}
export XDG_CONFIG_HOME XDG_DATA_HOME

# Default admin interface
export CADDY_ADMIN="${caddy_admin}"

command="${caddy_command}"
pidfile="/var/run/${name}/${name}.pid"

required_files="${caddy_config} ${caddy_command}"

start_precmd="caddy_precmd"
start_cmd="caddy_start"
stop_precmd="caddy_prestop"

# JSON is the native format, so there is no "adapter" for it
if [ "${caddy_adapter}" = "json" ]; then
    caddy_flags="--config ${caddy_config}"
else
    caddy_flags="--config ${caddy_config} --adapter ${caddy_adapter}"
fi

# Extra Commands
extra_commands="configtest reload reloadssl"
configtest_cmd="caddy_execute validate ${caddy_flags}"
reload_cmd="caddy_execute reload ${caddy_flags}"
reloadssl_cmd="caddy_execute reload --force ${caddy_flags}"

caddy_execute()
{
    /usr/bin/su -m "${caddy_user}" -c "${caddy_command} $*"
}

caddy_precmd()
{
    # Create required directories and set permissions
    /usr/bin/install -d -m 755 -o "${caddy_user}" -g "${caddy_group}" ${caddy_directory}
    /usr/bin/install -d -m 700 -o "${caddy_user}" -g "${caddy_group}" ${caddy_directory}/config
    /usr/bin/install -d -m 700 -o "${caddy_user}" -g "${caddy_group}" ${caddy_directory}/data
    /usr/bin/install -d -m 755 -o "${caddy_user}" -g "${caddy_group}" ${caddy_logdir}
    /usr/bin/install -d -m 700 -o "${caddy_user}" -g "${caddy_group}" /var/run/caddy
    if [ -e ${caddy_logfile} ]; then
        /bin/chmod 644 ${caddy_logfile}
        /usr/sbin/chown "${caddy_user}:${caddy_group}" ${caddy_logfile}
    else
        /usr/bin/install -m 644 -o "${caddy_user}" -g "${caddy_group}" /dev/null ${caddy_logfile}
    fi
}

caddy_start()
{
    echo -n "Starting caddy... "
    /usr/bin/su -m ${caddy_user} -c "${caddy_command} start ${caddy_flags} \
        ${caddy_extra_flags} --pidfile ${pidfile}" >> ${caddy_logfile} 2>&1
    if [ $? -eq 0 ] && ps -ax -o pid | grep -q "$(cat ${pidfile})"; then
        echo "done"
        echo "Log: ${caddy_logfile}"
    else
        echo "Error: Caddy failed to start"
        echo "Check the caddy log: ${caddy_logfile}"
    fi
}

caddy_prestop()
{
    local result

    echo -n "Stopping caddy... "

    result="$(caddy_execute stop ${caddy_flags} 2>&1)"
    if [ ${?} -eq 0 ]; then
        echo "done"
        exit 0
    else
        if echo "${result}" | grep -q -e "connection refused" \
            -e "connect: no such file or directory"; then

            echo "admin interface unavailable; using pidfile"
            return 0
        else
            echo "Error: Unable to stop caddy"
            echo "Check the caddy log: ${caddy_logfile}"
            return 1
        fi
    fi
}

run_rc_command "$1"

d. My complete Caddy config:

# Global Options
{
        log {
                output net unixgram//var/caddy/var/run/log {
                }
                format json {
                        time_format rfc3339
                }
        }

        import /usr/local/etc/caddy/caddy.d/*.global
}
# Reverse Proxy Domain: "388cc0a7-efc5-44b4-81d6-5757aa85a5ad"
app1.example.com {
        handle {
                forward_auth authelia:9091 {
                        uri /api/verify?rd=https://auth.example.com

                        copy_headers {
                                Remote-Email
                                Remote-Groups
                                Remote-Name
                                Remote-User
                        }
                }
        }

        handle {
                reverse_proxy app1:8080 {
                }
        }
}
# Reverse Proxy Domain: "3adc1fb4-67bf-45ce-bd9a-dba74aff4fda"
auth.example.com {
        handle {
                reverse_proxy authelia:9091 {
                }
        }
}

5. Links to relevant resources:

I should have read the Authelia docs too. It makes it pretty clear how it has to look like when handles for subpaths are involved.

Classic example of rtfm for me. XD

1 Like