6
Network
alvis edited this page 2026-03-08 16:09:24 +00:00

Network

Netplan (bridge)

Edit /etc/netplan/50-cloud-init.yaml:

network:
  bridges:
    br0:
      interfaces: [enp4s0]
      dhcp4: true
  version: 2
sudo netplan apply

MAC address changes after bridge setup — router may assign a new IP. Interface name (enp4s0) may differ after hardware changes — check with ip link show.

Caddy (reverse proxy)

Install | Docs

Config: /etc/caddy/Caddyfile

haos.alogins.net {
    reverse_proxy http://192.168.1.141:8123 {
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
}

vi.alogins.net    { reverse_proxy localhost:2283 }
doc.alogins.net   { reverse_proxy localhost:11001 }
zb.alogins.net    { reverse_proxy localhost:81 }
git.alogins.net   { reverse_proxy localhost:3000 }
ai.alogins.net    { reverse_proxy localhost:3125 }
ntfy.alogins.net  { reverse_proxy localhost:8840 }
vw.alogins.net    { reverse_proxy localhost:8041 }

wiki.alogins.net {
    reverse_proxy localhost:8083 {
        header_up Host {http.request.host}
        header_up X-Forwarded-Proto {scheme}
        header_up X-Real-IP {remote_host}
    }
}

nn.alogins.net  { reverse_proxy localhost:5678 }
ds.alogins.net  { reverse_proxy localhost:3974 }

openpi.alogins.net {
    root * /home/alvis/tmp/files/pi05_droid
    file_server browse
}

# VPN proxy (3X-UI)
vui3.alogins.net {
    @xhttp { path /VLSpdG9k/xht* }
    handle @xhttp {
        reverse_proxy http://localhost:8445 {
            flush_interval -1
            header_up X-Real-IP {remote_host}
            transport http {
                read_timeout 0
                write_timeout 0
                dial_timeout 10s
            }
        }
    }
    reverse_proxy /gnYCNq4EbYukS5qtOe/* localhost:58959
    respond 401
}
vui4.alogins.net { reverse_proxy localhost:58959 }
sudo systemctl enable --now caddy

Hairpin NAT

The router does not support hairpin NAT — the server cannot reach its own public IP from within the LAN. Services that need to call back to a public domain from the host or from Docker containers must use local overrides.

Add to /etc/hosts on the host for any domain that needs to be reached locally:

# Loopback for self-hosted domains (hairpin NAT workaround)
127.0.0.1 docs.alogins.net
127.0.0.1 vw.alogins.net

For Docker containers, use extra_hosts in the compose file:

extra_hosts:
  - "docs.alogins.net:host-gateway"

Port forwarding requirements:

  • Ports 80 and 443 forwarded on the router (source and target, remote IP empty)
  • Port 10051 forwarded for Zabbix active agent connections

TLS debugging

curl -v http://yourdomain.net/.well-known/acme-challenge/test
# Expect HTTP 200

Pi-hole (DNS ad-blocking)

Pi-hole runs as a Docker container on a macvlan network, giving it its own IP on the LAN (192.168.1.2). This allows it to bind to port 53 without conflicting with the host.

Architecture

[LAN clients] → DNS → 192.168.1.2 (pihole, macvlan on br0)
                         ↓ (upstream)
                    8.8.8.8 / 1.1.1.1

The host (br0) and Pi-hole (macvlan-br0) are on the same physical network but cannot communicate directly due to macvlan isolation. The host uses its router as DNS instead.

Setup

cd ~/agap_git/pihole
docker compose up -d

Pi-hole data: /mnt/ssd/dbs/pihole Web UI: http://192.168.1.2/admin (password: set via FTLCONF_webserver_api_password)

Router config

Set the router's DNS server to 192.168.1.2 so all LAN clients use Pi-hole automatically.