Rework the Serveex intro page and fix icon colors

This commit is contained in:
Djeex
2026-09-04 16:33:37 +02:00
parent a7b3880088
commit 1337fae991
7 changed files with 237 additions and 82 deletions
@@ -1,278 +0,0 @@
---
title: Wireguard
description: Install and configure WireGuard VPN to securely access your homelab from anywhere and connect all your devices to your private network.
---
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
## Introduction
Using a VPN allows remote access to a servers local resources without exposing them to the internet. Its a clean and secure way to access services like SSH without exposing the port publicly. With a VPN, you can securely connect to your network from anywhere and make devices on different networks communicate.
Here we will use [Wireguard](https://www.wireguard.com/), a secure and high-performance VPN server, using containers:
- [wg-easy](https://github.com/wg-easy/wg-easy) as the server, providing a very simple web UI to manage connections and download config files (including QR codes for phones)
- [Wireguard](https://docs.linuxserver.io/images/docker-wireguard/?h=wireguard) as the client for Linux systems
Clients are also available for Windows, macOS, iOS, and Android.
The concept:
- On the internet, anyone can reach any internet box and thus any exposed server.
- Your server is on your local network. It is accessible only locally unless services are explicitly exposed (as we did with Dockge). To access non-exposed resources, you must be on the same local network.
- We want to securely access these unexposed services (like SSH) from anywhere.
- We also want to connect services between servers, like linking two Dockge instances securely.
To achieve this, well create a **Virtual Private Network** (VPN), i.e., a secure tunnel that only connected machines can use. Theyll appear to be on the same private network.
Additionally, you can add your phone, laptop, or other devices to the VPN and securely access your server resources wherever you are.
![picture](/img/serveex/vpn.svg)
In this diagram, machine 1 is part of two networks:
- Its local network (devices behind the same router, e.g. `192.168.x.x` machines 1 and 2)
- The VPN network (VPN devices with a second IP, e.g. `10.8.x.x` machines 1 and 4)
You *can* allow VPN clients to share access to their local networks, but we wont do that here for security and subnet conflict reasons (e.g., if two remote machines use the same local IP like `192.168.1.1`).
So only VPN-connected devices can communicate with each other on the VPN, not with other local devices outside the VPN.
## Server Setup
::note
📋 **Pre-flight Checklist:**
- Ensure port `51820 UDP` is free on your server and correctly forwarded from your router (`51820 UDP -> Server`).
- Ensure port `51821 TCP` is free for the web UI.
::
::warning
__Warning__: If your IP is not static, use a Dynamic DNS service ([DynDNS](https://en.wikipedia.org/wiki/Dynamic_DNS)). If your ISP uses [CGNAT](https://en.wikipedia.org/wiki/Carrier-grade_NAT), youll need to use an external VPS and connect your local server as a client.
::
### Folder Structure
::file-tree
---
tree:
/:
- docker:
- wg-easy:
- config:
- etc_wireguard/
- compose.yaml
- .env
---
::
::steps{level="3"}
### Deploy the stack
Open Dockge, click **Compose**, and name the stack `wg_easy`.
Copy the following configuration:
```yaml [compose.yaml]
---
services:
wg-easy:
environment:
- INSECURE=true
image: ghcr.io/wg-easy/wg-easy:15
container_name: wg-easy
networks:
wg:
ipv4_address: 10.42.42.42
ipv6_address: fdcc:ad94:bacf:61a3::2a
volumes:
- ./etc_wireguard:/etc/wireguard
- /lib/modules:/lib/modules:ro
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
restart: unless-stopped
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv6.conf.all.forwarding=1
- net.ipv6.conf.default.forwarding=1
networks:
wg:
driver: bridge
enable_ipv6: true
ipam:
driver: default
config:
- subnet: 10.42.42.0/24
- subnet: fdcc:ad94:bacf:61a3::/64
```
::tip{icon=""}
✨ **Tip:**
- You can customize WireGuard and web UI ports.
- Add a Watchtower label for automatic updates:
```yaml [compose.yaml]
---
services:
wg-easy:
# ...
labels:
- com.centurylinklabs.watchtower.enable=true
```
::
Deploy the stack and access the local web UI at `http://server-ip:51821`.
::caution
If the deployment fails, check your firewall rules.
::
### Create your account
Once connected, follow the web UI instructions to:
- Create your admin account and password.
- Set the host field (use your public IP or domain name).
### Configure the tunnel
Then go to *Administrator → Admin Panel → Config*:
- Change `Allowed IPs` from `0.0.0.0/24` to `10.8.0.0/24` for **split tunneling**.
- Remove IPv6 (it often causes unnecessary issues).
### Done !
::
### Retrieve Configuration Files
To configure clients:
::steps{level="4"}
#### Access the web UI
Go to `http://server-ip:51821`.
#### Create a new client
#### Edit the client
Add `10.8.0.0/24` to `Server Allowed IPs`.
#### (Optional) Set Persistent Keep Alive
Set it to `25` if its a permanently connected client.
#### Save and rename the file
Save, download, and rename the file to `wg0.conf` (or `wg1.conf`, etc.)
#### Done !
::
## Client Server Setup
::note
We assume the client server runs Linux with Docker installed.
::
### Folder Structure
::file-tree
---
tree:
/:
- docker:
- wireguard:
- config:
- wg_confs/
- compose.yaml
---
::
::steps{level="3"}
### Create the folder
```bash [Terminal]
sudo mkdir -p /docker/wireguard/config/wg_confs
```
::tip{icon=""}
✨ **Tip:** You can use [File Browser Quantum](/serveex/files/file-browser-quantum) instead of the terminal to edit and upload files.
::
### Create the wg0.conf file
```bash [Terminal]
sudo nano /docker/wireguard/config/wg_confs/wg0.conf
```
Paste the downloaded configuration, then save with :kbd{value="Ctrl+O"}, :kbd{value="Enter"}, and exit with :kbd{value="Ctrl+X"}.
::tip{icon=""}
✨ **Alternative method:** Transfer the file via SFTP and move it:
```bash [Terminal]
sudo cp ~/wg0.conf /docker/wireguard/config/wg_confs
```
::
### Create the compose file
Create the `compose.yaml` file in `/docker/wireguard`:
```yaml [compose.yaml]
---
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
container_name: wireguard
network_mode: host
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- TZ=Europe/Paris
volumes:
- /docker/wireguard/config:/config
- /lib/modules:/lib/modules
restart: unless-stopped
```
### Start the container
```bash [Terminal]
cd /docker/wireguard
sudo docker compose up -d
```
### Done !
::
::note
Repeat this setup for each client.
::
## Other Devices
- **Mobile:** Install WireGuard and scan the QR code via the web UI (`http://server-ip:51821`)
- **Desktop:** Install the WireGuard client and import the downloaded config file.
::warning
**Note:** If the client machine is on the same local network as the server, edit the `wg0.conf` file to use the local server IP:
`Endpoint = server-local-ip:51820`
::
And heres the final setup overview:
![picture](/img/serveex/wireguard.svg)
@@ -10,16 +10,11 @@ description: Install TinyAuth, a lightweight forward-auth proxy, and pair it wit
![tinyauth](/img/serveex/tinyauth.png)
It supports a simple local username/password login out of the box, and can also delegate login to an external OIDC provider. Here we'll use [Pocket ID](/serveex/security/pocket-id), so anyone visiting a protected app first authenticates with a passkey via Pocket ID, then gets forwarded through.
It supports a simple local username/password login out of the box, which is what we'll set up here. It can also delegate login to an external OIDC provider like [Pocket ID](/serveex/security/pocket-id) instead, so anyone visiting a protected app authenticates with a passkey via Pocket ID and then gets forwarded through: install Pocket ID afterwards and follow [its guide](/serveex/security/pocket-id#connecting-pocket-id-to-tinyauth) to connect the two.
- [TinyAuth documentation](https://tinyauth.app/docs)
- [TinyAuth on GitHub](https://github.com/tinyauthapp/tinyauth)
::note
This guide assumes you've already installed [Pocket ID](/serveex/security/pocket-id). You can skip the Pocket ID sections below and use TinyAuth with just a local username/password instead.
::
## Installation
::file-tree
@@ -103,6 +98,42 @@ Deploy the stack. The local interface is available at `http://yourserverip:3000`
### Done !
::
## Enabling Two-Factor Authentication
TinyAuth can require a TOTP code from an authenticator app (Google Authenticator, Aegis...) alongside the local password, per user. This is a property of the user entry itself, not a toggle in the web UI.
::steps{level="3"}
### Generate a TOTP secret
```bash [Terminal]
sudo docker run -i -t --rm ghcr.io/tinyauthapp/tinyauth:v5 totp generate --interactive
```
Enter the `username:hash` pair you generated during installation. TinyAuth prints a QR code to scan with your authenticator app, then outputs the updated login string as `username:hash:secret`.
::note
Both `docker run` and `docker exec` need the `-it` flags here: the command is interactive and renders the QR code in the terminal, which needs a TTY (and a wide enough window) to display correctly.
::
### Update your environment variable
Replace that user's entry in `TINYAUTH_AUTH_USERS` with the new `username:hash:secret` string, then redeploy the stack.
::tip{icon=""}
__Tip:__ Verify the flow works before relying on it:
```bash [Terminal]
sudo docker run -i -t --rm ghcr.io/tinyauthapp/tinyauth:v5 user verify --interactive
```
It re-prompts for the username, password, and current 6-digit code.
::
### Done !
::
From now on, that user needs both their password and a valid code from their authenticator app to log in.
## Exposing TinyAuth with Swag
TinyAuth needs its own subdomain: it's the page users land on before being forwarded to the app they actually want.
@@ -192,56 +223,6 @@ __If it fails:__ check your firewall rules.
### Done !
::
## Connecting TinyAuth to Pocket ID
::steps{level="3"}
### Register TinyAuth as an OIDC client
First, [register TinyAuth as an OIDC client in Pocket ID](/serveex/security/pocket-id#registering-an-oidc-client), using this callback URL:
```text
https://tinyauth.mydomain.com/api/oauth/callback/pocketid
```
### Add the Pocket ID provider
Copy the __Client ID__ and __Client Secret__ Pocket ID gives you, then edit TinyAuth's `.env` file:
```bash [Terminal]
sudo nano /docker/tinyauth/.env
```
Add the following:
```properties [.env]
TINYAUTH_OAUTH_PROVIDERS_POCKETID_NAME=Pocket ID
TINYAUTH_OAUTH_PROVIDERS_POCKETID_CLIENTID=
TINYAUTH_OAUTH_PROVIDERS_POCKETID_CLIENTSECRET=
TINYAUTH_OAUTH_PROVIDERS_POCKETID_AUTHURL=https://id.mydomain.com/authorize
TINYAUTH_OAUTH_PROVIDERS_POCKETID_TOKENURL=https://id.mydomain.com/api/oidc/token
TINYAUTH_OAUTH_PROVIDERS_POCKETID_USERINFOURL=https://id.mydomain.com/api/oidc/userinfo
TINYAUTH_OAUTH_PROVIDERS_POCKETID_REDIRECTURL=https://tinyauth.mydomain.com/api/oauth/callback/pocketid
TINYAUTH_OAUTH_PROVIDERS_POCKETID_SCOPES=openid email profile
```
| Variable | Value |
|----------|-------|
| `CLIENTID`{lang=properties} | The client ID copied from Pocket ID |
| `CLIENTSECRET`{lang=properties} | The client secret copied from Pocket ID |
| `AUTHURL` / `TOKENURL` / `USERINFOURL`{lang=properties} | Pocket ID's public URL, with the paths shown above |
Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.
### Redeploy the stack
Redeploy the TinyAuth stack. On your next visit to `https://tinyauth.mydomain.com`, you'll see a "Login with Pocket ID" option alongside the local login form.
::tip{icon=""}
✨ To skip straight to Pocket ID and hide the local login form, add `TINYAUTH_OAUTH_AUTOREDIRECT=pocketid` to the same `.env` file.
::
### Done !
::
## Protecting an app via reverse proxy
Swag doesn't ship a ready-made include file for TinyAuth, so we'll add the forward-auth check directly to the app's own `*.subdomain.conf`. We'll use Dockge as an example.
@@ -226,4 +226,56 @@ Save, then copy the generated __Client ID__ and __Client Secret__. You'll need t
### Done !
::
Pocket ID is ready to act as your OIDC provider. Head to the [TinyAuth guide](/serveex/security/tinyauth) to use it as a forward-auth login page for the rest of your apps.
## Connecting Pocket ID to TinyAuth
[TinyAuth](/serveex/security/tinyauth) can delegate its login to Pocket ID instead of (or alongside) its local username/password, so anyone visiting a protected app authenticates with a passkey and gets forwarded through.
::steps{level="3"}
### Register TinyAuth as an OIDC client
[Register an OIDC client](#registering-an-oidc-client) named `TinyAuth`, using this callback URL:
```text
https://tinyauth.mydomain.com/api/oauth/callback/pocketid
```
### Add the Pocket ID provider in TinyAuth
Copy the __Client ID__ and __Client Secret__ Pocket ID gives you, then edit TinyAuth's `.env` file:
```bash [Terminal]
sudo nano /docker/tinyauth/.env
```
Add the following:
```properties [.env]
TINYAUTH_OAUTH_PROVIDERS_POCKETID_NAME=Pocket ID
TINYAUTH_OAUTH_PROVIDERS_POCKETID_CLIENTID=
TINYAUTH_OAUTH_PROVIDERS_POCKETID_CLIENTSECRET=
TINYAUTH_OAUTH_PROVIDERS_POCKETID_AUTHURL=https://id.mydomain.com/authorize
TINYAUTH_OAUTH_PROVIDERS_POCKETID_TOKENURL=https://id.mydomain.com/api/oidc/token
TINYAUTH_OAUTH_PROVIDERS_POCKETID_USERINFOURL=https://id.mydomain.com/api/oidc/userinfo
TINYAUTH_OAUTH_PROVIDERS_POCKETID_REDIRECTURL=https://tinyauth.mydomain.com/api/oauth/callback/pocketid
TINYAUTH_OAUTH_PROVIDERS_POCKETID_SCOPES=openid email profile
```
| Variable | Value |
|----------|-------|
| `CLIENTID`{lang=properties} | The client ID copied from Pocket ID |
| `CLIENTSECRET`{lang=properties} | The client secret copied from Pocket ID |
| `AUTHURL` / `TOKENURL` / `USERINFOURL`{lang=properties} | Pocket ID's public URL, with the paths shown above |
Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.
### Redeploy the stack
Redeploy the TinyAuth stack. On your next visit to `https://tinyauth.mydomain.com`, you'll see a "Login with Pocket ID" option alongside the local login form.
::tip{icon=""}
✨ To skip straight to Pocket ID and hide the local login form, add `TINYAUTH_OAUTH_AUTOREDIRECT=pocketid` to the same `.env` file.
::
### Done !
::
That's it! TinyAuth now offers passwordless login via Pocket ID for every app it protects.