Linux over Tailscale
Your Mac and iPhone can reach Looper on the Linux host. The host cannot start connections to other tailnet devices. Internet access still works.
1. Set the policy
Download the policy template.
Replace the example addresses: .10 is your Mac, .11 your iPhone, .20 the
Linux host, and .21 another host. All use the 100.64.0 prefix.
Merge the template into your existing policy, preserving unrelated settings.
It allows only TCP 8765, TCP 8766, and UDP 8766 from your two controllers
to tag:looper-bot. Port 8765 also permits pairing; use trusted devices.
- Remove broad allow rules that match the bot. Grants are additive.
- Tag each isolated Linux host only
tag:looper-bot. Keep personal devices untagged. - Run the template's six policy tests before saving.
- After tagged access works, remove any old direct-IP grant to the host.
This policy grants no SSH access. Use the local or hosting-provider console for setup. On a shared LAN, use a separate VM/VLAN or an egress firewall too: Tailscale policy controls tailnet traffic.
2. Set up Linux
Use an ordinary user with Tailscale authenticated and nftables installed. Download these files into one directory:
Firewall · Firewall service · Looper service override · Environment
Replace the Mac and iPhone addresses in the firewall. It allows loopback and
those two devices through tailscale0, then drops other Looper ingress.
Keep Looper's wildcard listeners: its local CLI and hooks need loopback.
Linux setup commands
Clear routing roles and disable Tailscale SSH:
sudo tailscale set --accept-routes=false --advertise-routes= \
--advertise-exit-node=false --advertise-connector=false \
--exit-node= --ssh=false --webclient=false
Validate and install the firewall. The service expects nft at /usr/sbin/nft.
sudo nft -c -f looper-ingress.nft
sudo install -d -m 755 /etc/nftables.d
sudo install -m 644 looper-ingress.nft /etc/nftables.d/looper-ingress.nft
sudo install -m 644 looper-ingress.service /etc/systemd/system/looper-ingress.service
sudo systemctl daemon-reload
sudo systemctl enable --now looper-ingress.service
Download the Linux archive and checksum, then install without starting the server:
LOOPER_ARCHIVE='replace-with-downloaded-linux-archive.tar.gz'
sha256sum -c "$LOOPER_ARCHIVE.sha256"
tar -xzf "$LOOPER_ARCHIVE"
bash looper-linux/looper-linux.sh install --no-start
export PATH="$HOME/.local/bin:$PATH"
install -d -m 700 "$HOME/.config/looper"
install -d -m 700 "$HOME/.config/systemd/user/looper.service.d"
install -m 644 tailscale.conf "$HOME/.config/systemd/user/looper.service.d/tailscale.conf"
For a new installation, copy server.env.example to
~/.config/looper/server.env with mode 600. For an existing installation,
merge its three listener settings; retain the store path and other settings.
--no-start leaves an existing process running.
systemctl --user daemon-reload
systemctl --user enable looper.service
systemctl --user restart looper.service
curl --fail --max-time 3 http://127.0.0.1:8765/health
The override runs serve --tailscale. Its user needs access to the local
Tailscale daemon. For startup after logout, an administrator can run
sudo loginctl enable-linger "$USER".
If your firewall manager flushes nftables on reload, integrate this file with
that manager. Check sudo nft list table inet looper_ingress after reload and
reboot; an active service alone does not prove the rules exist.
3. Run Grok and pair
Install and authenticate Grok Build as the same user. Back up existing hooks, then run:
looper hooks register grok
# From your project directory:
looper grok
On iPhone, connect Tailscale. In Looper, choose Add Computer, enable
Tailscale, and enter the host's IP or full .ts.net name. Choose Open Server
Pairing Page and enter the generated four-letter code. For an already paired
host, select its Tailscale route.
Check access from your approved Mac, using the host's real address:
curl --fail --max-time 3 http://100.64.0.20:8765/health
Then verify:
- The phone connects and sends a harmless prompt to the same Grok session.
- HTTP/3 uses UDP 8766 in app diagnostics.
- Bot-to-device and bot-to-bot connections fail against known listening ports.
- Looper and the firewall survive reboot.