Ultimate Tailscale Dropbox Setup

I have some clients who need a CCTV camera in a remote location and there isn’t a budget for any kind of infrastructure at the site and we want the recording to happen back at a central server.

So my solution is a raspberry pi zero with a PoE hat at the remote location sharing the entire network and giving a frigate instance access to the PoE camera via a tailscale network.

During my setting up and testing I thought it might be possible that the network IP details change or that this little tailscale relay unit needs to be deployed into a new network as a support unit, a network audit unit, a mail in/out support dropbox etc. So I made a little script and set of instructions for anyone who wants to make their own portable support box.
The script runs at system boot and checks the network connection details and updates the tailscale network with its local network which is rout able. This means you can plug this unit into any PoE port and within minutes it is providing full network access via a tailscale network.

I have been testing this setup with a cheap ($65 Australian) Annke PoE camera and if you manually set the cameras network settings so it can’t access the internet this is a great way to plumb it back into a frigate NVR system where it can be analysed for persons or objects.

This can be setup on a raspberry pi 3/4 as well ( I have done all my testing using a Raspberry pi 4 4Gb)

Possible uses are kinda endless, mail it to your parents to fix their network, mail or install at client locations for auditing, get arrested trying to hack your school/university!

Follow the instructions below on a Ubuntu Server 22.04
Feel free to give me feedback if you run into issues! :grinning:

sudo apt update && sudo apt upgrade -y

curl -fsSL https://tailscale.com/install.sh | sh

sudo reboot

sudo tailscale up
#here you will need to copy a link into your browser and log into tailscale


sudo nano /etc/sysctl.conf
#add the following to the file
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

sudo sysctl -p

sudo nano script.sh
#paste script into this file


This is the script

#!/bin/bash

# Get the primary network interface's IP address and subnet
PRIMARY_INTERFACE=$(ip route | grep '^default' | grep -oP '(?<=dev )(\S+)')

# Fetch IPv4 address
IPV4_ADDR=$(ip -4 addr show $PRIMARY_INTERFACE | grep 'inet\b' | awk '{print $2}' | head -n 1)

# Calculate the network address from the IPv4 address
IFS='.' read -ra ADDR <<< "$(echo $IPV4_ADDR | cut -d'/' -f1)"
NETMASK=$(echo $IPV4_ADDR | cut -d'/' -f2)
if [ "$NETMASK" == "24" ]; then
    NETWORK_ADDR="${ADDR[0]}.${ADDR[1]}.${ADDR[2]}.0/$NETMASK"
elif [ "$NETMASK" == "16" ]; then
    NETWORK_ADDR="${ADDR[0]}.${ADDR[1]}.0.0/$NETMASK"
elif [ "$NETMASK" == "8" ]; then
    NETWORK_ADDR="${ADDR[0]}.0.0.0/$NETMASK"
else
    echo "Netmask not supported by the script."
    exit 1
fi

# Check if IPv4 address is retrieved
if [ -z "$IPV4_ADDR" ]; then
    echo "No IPv4 address found on the interface $PRIMARY_INTERFACE."
    exit 1
fi

# Construct Tailscale command to advertise the IPv4 route
ADVERTISE_CMD="sudo tailscale up --accept-routes --advertise-routes=$NETWORK_ADDR"

# Execute Tailscale command
echo "Executing command: $ADVERTISE_CMD"
eval $ADVERTISE_CMD
sudo chmod +x script.sh

sudo nano /etc/systemd/system/myscript.service
#paste the following into file
#adjust the script.sh path as needed
[Unit]
Description=Run my script at startup

[Service]
Type=simple
ExecStart=/home/ubuntu/script.sh
Restart=on-abort

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload

sudo systemctl enable myscript.service

sudo systemctl start myscript.service

Finally, if you want to be able to get to the RTSP stream from a desktop running tailscale you will need to launch tailscale with the following argument (stop tailscale first if it is already running)

sudo tailscale up --accept-routes

To get it working in home assistant you need to go into the tailscale add on config and either edit the config yaml and add the line below or scroll to the bottom of the unused settings and toggle the userspace networking setting so that it stays off. Doing this will let your home assistant see the RTSP stream in Frigate for object analysis.

userspace_networking: false
2 Likes

A quick update for anyone looking at this -

Update 1- For reasons I don’t care to look into, this setup does not work out of the box on Ubuntu Server on the raspberry pi zero w. The RPZ does not detect the network when using the PoE hat. There are config changes to make it see it but it was all getting a little too jenky to make it all work. The exact same instructions do work on raspberry pi OS LITE version (x64). This OS sees the PoE hats network connection out of the box with no extra steps.

Update 2-
The script I am running on boot works fine on a raspberry pi 4 running ubuntu server but gives me the following warning, suggesting it could be done better.

Warning: UDP GRO forwarding is suboptimally configured on eth0, UDP forwarding throughput capability will increase with a configuration change.

To fix this I have adjusted the script as follows. Using this updated script will get everything up and running!

#!/bin/bash

# Operating system recommendations
echo "Recommendation: Use a recent version of your preferred operating system for optimal performance."
echo "For maximum performance, use Linux with kernel version 6.2 or later."

# Linux optimizations for subnet routers and exit nodes
echo "Optimizing Tailscale settings for improved UDP throughput..."
NETDEV=$(ip route show 0/0 | cut -f5 -d' ')
sudo ethtool -K $NETDEV rx-udp-gro-forwarding on rx-gro-list off

# Check for networkd-dispatcher and enable ethtool settings on each boot
if systemctl is-enabled networkd-dispatcher; then
    echo "networkd-dispatcher is enabled, proceeding with boot script creation..."
    printf '#!/bin/sh\n\n# Optimize network device settings for Tailscale\nethtool -K %s rx-udp-gro-forwarding on rx-gro-list off \n' "$NETDEV" | sudo tee /etc/networkd-dispatcher/routable.d/50-tailscale
    sudo chmod 755 /etc/networkd-dispatcher/routable.d/50-tailscale

    # Test the created script
    echo "Testing the new boot script..."
    sudo /etc/networkd-dispatcher/routable.d/50-tailscale
    if [ $? -eq 0 ]; then
        echo "Script executed successfully. Configuration is set for boot persistence."
    else
        echo "An error occurred. Check the script and configurations."
        echo "Visit https://tailscale.com/s/ethtool-config-udp-gro for more information on configuring UDP GRO."
    fi
else
    echo "networkd-dispatcher is not enabled. Manual configuration required on each boot."
    echo "Visit https://tailscale.com/s/ethtool-config-udp-gro for manual configuration instructions."
fi