# Tailscale funnel

[TOC]

# Overview
Tailscale Funnel is an excellent, free way to bypass CGNAT and expose a local service to the public internet. It handles the reverse proxying, TLS certificate provisioning (via Let's Encrypt), and public DNS routing for you.

# Steps

## Phase 1: Prepare the Proxmox LXC (Enable TUN)

1. SSH into your **Proxmox Host** (do not enter the container yet).
2. Open the configuration file for your LXC container (ID 101):
    ```bash
    nano /etc/pve/lxc/101.conf
    ```

3. Update lxc container configuration file: add the following two lines to the bottom of the file. This passes the `tun` device from the host to the container (if you are on an older Proxmox 6 setup, use `cgroup` instead of `cgroup2`):
    ```text
    lxc.cgroup2.devices.allow: c 10:200 rwm
    lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
    ```

    

4. Save and exit (`Ctrl+X`, `Y`, `Enter`), then restart the container to apply the changes:
    ```bash
    pct reboot 101
    ```


## Phase 2: Install and Authenticate Tailscale

1. Enter your LXC container's console:
    ```bash
    pct enter 101
    ```

2. Install Tailscale using their automated script:
    ```bash
    curl -fsSL https://tailscale.com/install.sh | sh
    ```

3. Start Tailscale:
    ```bash
    tailscale up
    ```

4. Click the link provided in the terminal to authenticate the BookStack node to your Tailscale account.


## Phase 3: Enable Funnel in your Tailscale Admin Console

Tailscale disables public Funnels by default for security. You must authorize it in your Tailnet settings.

1. Go to the [Tailscale Admin Console](https://login.tailscale.com/admin) in your web browser.
2. Go to the **DNS** tab and ensure both **MagicDNS** and **HTTPS Certificates** are enabled.
3. Go to the **Access Controls** tab. Scroll down to the `"nodeAttrs"` section (or add it if it's missing) and grant the `funnel` attribute to your devices. It should look like this:
    ```json
    "nodeAttrs": [
        {
            "target": ["autogroup:member"],
            "attr":   ["funnel"]
        }
    ],
    ```

4. Save the Access Controls.

## Phase 4: Start the Tailscale Funnel

Back in your LXC container's terminal:

1. Determine the local port BookStack is running on (typically `80` if served via Nginx/Apache without local SSL).
2. Route public internet traffic to that local port, running the process in the background (`--bg`):
    ```bash
    tailscale funnel --bg 80
    ```

3. Check the status of your Funnel to get your new public web address:
    ```bash
    tailscale funnel status
    ```

> [!NOTE]
> You will see an output with a URL like: `https://your-node.tailnet-name.ts.net`.


## Phase 5: Update BookStack's Configuration

BookStack uses absolute URLs for CSS, images, and internal links. If you don't update BookStack to recognize its new public URL, the site will look broken and you won't be able to log in.

1. Navigate to your BookStack directory inside the container (usually `/var/www/bookstack` or `/opt/bookstack`).
2. Edit the `.env` configuration file:
    ```bash
    nano .env
    ```

3. Find the `APP_URL` variable and update it to exactly match your new Tailscale URL (make sure it starts with `https://` and has no trailing slash):
    ```text
    APP_URL=https://your-node.tailnet-name.ts.net
    ```

4. Save and exit, then clear BookStack's cache to force the changes:
    ```bash
    php artisan config:clear
    php artisan cache:clear
    ```

> [!TIP]
> For a visual walkthrough of the container preparation steps, [Configuring Tailscale on an unprivileged Proxmox LXC](https://www.youtube.com/watch?v=JC63OGSzTQI) explains how the TUN device passthrough works under the hood.

# FAQ

## Customize tailscale funnel subdomain
You cannot change the subdomain inside Tailscale Funnel dynamically. Tailscale automatically generates the Funnel URL using the exact hostname of the machine (or LXC container) and your unique Tailscale network name (tailnet).

To change docker to something else (e.g., app.bee-custom.ts.net), you must change the hostname of the LXC container itself: 

1. Log into your Proxmox Host (root@nuc).
1. Run this command to change the hostname (replace 100 with your container ID):

    ```bash  
    pct set 100 --hostname your-new-name
    ```  
    
1. Restart the container for Tailscale to pick up the new name:

    ```bash
    pct reboot 100
    ```

## Running Multiple Funnels on the Same Machine
Tailscale allows you to route to multiple internal services on the same machine using two different methods 

### Method 1: Use Different Public Ports (Easiest)
Tailscale Funnel supports traffic incoming on ports 443, 8443, and 10000. You can run up to 3 distinct funnels simultaneously by mapping them to different public ports: [1, 8] 

* Service 1 (Port 443 -> local 9000):
    ```bash
    tailscale funnel --bg --https=443 9000
    ```
    
* Service 2 (Port 8443 -> local 9001):

    ```bash
    tailscale funnel --bg --https=8443 9001
    ```
    
* Service 3 (Port 10000 -> local 9002):

    ```bash
    tailscale funnel --bg --https=10000 9002
    ```

### Method 2: Use URL Paths (Best for Keeping Port 443) [6] 
If you want everything on standard HTTPS (port 443), you can route multiple services using distinct URL sub-paths instead of port numbers:

```bash
tailscale funnel --bg --set-path=/app1 127.0.0.1:9000
tailscale funnel --bg --set-path=/app2 127.0.0.1:9001
```

> [!NOTE]
> Ensure your web applications can handle sub-paths; some web apps assume they are always running at the root / path.