Reverse-Proxy

From FlowerHouseWiki
Reverse-Proxy-LXC
Reverse proxy.png

Network


IP: 192.168.88.3
MAC: 56:59:71:B1:85:BC

System


OS: Debian Bullseye
Files: x
RAM: 1024MB
Cores: 1
Privileged: No

The ReverseProxy is reachable under 192.168.88.3 which is located in the ServerVLAN.

Every incoming packages from outside are forwarded to this IP.

The ReverseProxy also forces outside connections to use HTTPS/SSL and will provide a SSL-Certificate.

Previously Nginx Proxy Manager and Authelia was used for ReverseProxy: Guide

Now Caddy2 is used for the ReverseProxy, because it's more stable and integrated

Caddy Installation

Download Caddy2 with Security Plugin

Copy binary to directory

mv ./caddy_linux_amd64_custom /usr/bin/caddy

Create user and group

addgroup caddy
adduser --system caddy
adduser caddy caddy

Set permissions for binary

chown caddy:caddy /usr/bin/caddy
chmod 770 /usr/bin/caddy

Create caddy file

nano /home/caddy/Caddyfile

In my installation I separated many config files for better overview:

/home/caddy/
├─ Caddyfile
├─ auth/
│  ├─ local/
│  │  ├─ users.json
├─ lxc/
│  ├─ 101_adguard
│  ├─ 102_reverse_proxy
│  ├─ ...
├─ security
├─ vm/
│  ├─ 200_truenas
│  ├─ 201_home_assitant
│  ├─ ...

"Caddyfile" containts general caddy configuration, for example general security configuraton which can be individually imported

# ============ SECURITY HEADER SNIPPET ============
(security_header) {
        header {
                Permissions-Policy interest-cohort=()
                Strict-Transport-Security max-age=31536000
                X-Content-Type-Options nosniff
                Referrer-Policy no-referrer-when-downgrade
        }
}

# Strict content policy
(content_policy) {
        header {
                # For older browser, newer ones use frame ancestors
                # SAMEORIGIN = self, DENY = none
                X-Frame-Options DENY
                Content-Security-Policy "
            default-src 'none';
            style-src 'self';
            script-src 'self';
            font-src 'self';
            img-src 'self';
            form-action 'self';
            connect-src 'self';
            frame-ancestors 'none';
            object-src 'none';"
        }
}

# Content policy - allow inline
(content_policy_inline) {
        header {
                X-Frame-Options DENY
                Content-Security-Policy "
                    default-src 'none';
                    style-src 'unsafe-inline' 'self';
                    script-src 'self';
                    font-src 'self';
                    img-src 'self';
                    form-action 'self';
                    connect-src 'self';
                    frame-ancestors 'none';
                    object-src 'none';"
        }
}

# ============ IMPORT CADDY FILES ============
# Settings for authentication portal
import ./security

# Network (ProxMox, Router,...)
import ./network

# LXCs
import ./lxc/101_adguard
import ./lxc/102_reverse_proxy
import ./lxc/103_dashboard
import ./lxc/104_database
import ./lxc/105_chat_matrix
import ./lxc/106_vaultwarden
import ./lxc/107_mediawiki
import ./lxc/108_nextcloud
import ./lxc/109_jellyfin
import ./lxc/110_jupyter
import ./lxc/111_heater
import ./lxc/112_partdb
import ./lxc/113_vikunja
import ./lxc/114_unifi

# VMs
import ./vm/200_truenas
import ./vm/201_home_assistant

"security" contains configuration for the auth portal (security plugin)

# =========== AUTH-PORTAL SETTINGS ===========
{
        # Global security setting
        order authenticate before respond
        order authorize before reverse_proxy

        # Configure how to handle login credentials
        # With this config they are stored locally in users.json
        security {
                local identity store localdb {
                        realm local
                        path /home/caddy/auth/local/users.json
                }

                # Configure the authentication portal
                authentication portal myportal {
                        # Key handling settings
                        # Stay logged in for 12h
                        crypto default token lifetime 43200
                        crypto key sign-verify {env.JWT_SHARED_KEY}

                        # Identity providers
                        enable identity store localdb

                        # Cooke settigs
                        cookie domain flowerhouse.at

                        # Links shown in authentication portal
                        ui {
                                links {
                                        # ICONS: https://icons8.com/line-awesome
                                        "My Identity" "/whoami" icon "las la-user"
                                        "Portal Settings" "/settings" icon "las la-c>
                                }
                        }

                        # Configure how to handle local user
                        transform user {
                                # Check with identity provider "local"
                                match origin local

                                # Add user role
                                action add role authp/user

                                # Force Multi-Factor Authentication
                                require mfa
                        }
                }

                # Create admin policy
                authorization policy admins_policy {
                        set auth url https://auth.flowerhouse.at
                        allow roles authp/admin authp/user
                        crypto key verify {env.JWT_SHARED_KEY}
                }
        }
}

"users.json" is created by the security plugin an contains the local users

"lxc/" contains proxy config for every ProxMox LXC, for example:

# =========== LXC 101 - AdGuard ===========
dns.flowerhouse.at {
        # Import security and privacy headers
        import security_header
        import content_policy

        # Use auth portal for security
        authorize with admins_policy

        reverse_proxy http://192.168.88.4:80
}

"vm/" contains proxy config for every ProxMox VM, for example:

# =========== VM 200 - TrueNAS ===========
nas.flowerhouse.at {
        # Import security and privacy headers
        import security_header
        import content_policy

        # Additional content policy
        header Access-Control-Allow-Origin: https://nas.flowerhouse.at https://nas.f>
        header Access-Control-Allow-Methods: GET
        #header Access-Control-Allow-Credentials: true    

        # Use auth portal for security
        authorize with admins_policy

        # WebUI
        reverse_proxy http://192.168.88.5:80
}

Set permissions for config files

chown -R caddy:caddy /home/caddy
chmod -R 770 /home/caddy

Create systemd file

nano /etc/systemd/system/caddy.service

Add content:

# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /home/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /home/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

Reload daemon and start

systemctl daemon-reload
systemctl start caddy
systemctl status caddy

Enable start at boot

systemctl enable --now caddy

Update Caddy

Download Caddy2 with Security Plugin

Enable root-ssh:

nano /etc/ssh/sshd_config

Change following line:

#PermitRootLogin prohibit-password -> PermitRootLogin yes

Restart ssh-service:

service sshd restart

Move binary to directory

mv ./caddy_linux_amd64_custom /usr/bin/caddy

Set permissions for binary

chown caddy:caddy /usr/bin/caddy
chmod 770 /usr/bin/caddy

Restart Caddy

systemctl restart caddy
systemctl status caddy