--advertise-exit-node, AdGuard DNS filteringberyllium.oryx-ide.ts.netHeadscale does not support Tailscale Funnel (the feature that exposes services to the public internet via *.ts.net). Options:
1. Set up a standard reverse proxy (Caddy/nginx) for Ava instead
2. Keep one device on Tailscale just for Funnel (hybrid approach)
3. Use Cloudflare Tunnel as a Funnel replacement
---
# On any device currently connected to Tailscale
tailscale status
Document all devices and their roles:
Add a DNS record for Headscale. Options:
hs.bensima.com → beryllium's public IPManual step: Add A record in your DNS provider.
For Ava's web interface (beryllium.oryx-ide.ts.net), choose one:
Option A: Caddy reverse proxy (recommended)
ava.bensima.com or similarOption B: Cloudflare Tunnel
---
Omni/Dev/Vpn.nix# Omni/Dev/Vpn.nix
{config, ...}: let
ports = import ../Cloud/Ports.nix;
in {
services.headscale = {
enable = true; # ← CHANGE: enable headscale
address = "0.0.0.0";
port = ports.headscale;
settings = {
server_url = "https://hs.bensima.com"; # ← ADD: your headscale URL
dns.base_domain = "hs.bensima.com";
dns.magic_dns = true;
dns.nameservers.global = [
"100.64.0.1" # AdGuard on the tailnet (see below)
];
# Use Tailscale's public DERP servers (free, works fine)
derp.server.enabled = false;
derp.urls = ["https://controlplane.tailscale.com/derpmap/default"];
};
};
# Headscale needs HTTPS - add nginx reverse proxy
services.nginx = {
enable = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts."hs.bensima.com" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString ports.headscale}";
proxyWebsockets = true;
};
};
};
security.acme = {
acceptTerms = true;
defaults.email = "ben@bensima.com"; # ← your email
};
networking.firewall.allowedTCPPorts = [80 443];
# ... rest of existing config (tailscale, adguard) stays the same for now
};
Omni/Dev/Beryllium/Ava.nix (Funnel Replacement)If using Caddy for Ava instead of Tailscale Funnel:
# Add to Beryllium.nix or create Omni/Dev/Beryllium/Caddy.nix
services.caddy = {
enable = true;
virtualHosts."ava.bensima.com".extraConfig = ''
reverse_proxy localhost:8079
'';
};
# Remove the Tailscale Funnel comment from Ava.nix since it won't apply
After deploying, you need to create a user (Headscale calls them "users", formerly "namespaces"):
# SSH to beryllium after deploy
headscale users create ben
headscale users create family
---
# Build and deploy beryllium
bild Omni/Dev/Beryllium.nix
# Then rebuild NixOS on beryllium (however you normally do it)
# On beryllium
headscale preauthkeys create --user ben --reusable --expiration 24h
# Save this key for the next steps
headscale preauthkeys create --user family --reusable --expiration 24h
# Give this key to family members
For NixOS machines (beryllium, lithium):
Update Omni/Dev/Vpn.nix Tailscale config:
services.tailscale = {
enable = true;
extraUpFlags = [
"--login-server=https://hs.bensima.com" # ← ADD this
"--accept-dns=true"
"--advertise-exit-node" # only on beryllium
];
authKeyFile = "/run/secrets/tailscale-authkey"; # ← ADD: or use --auth-key manually
};
For phones/other devices:
1. Open Tailscale app
2. Log out of current account
3. Use "Custom control server" option (may need to enable in settings)
4. Enter: https://hs.bensima.com
5. Use the preauth key or OIDC if you set that up
Manual registration (any device):
tailscale up --login-server=https://hs.bensima.com --authkey=YOUR_KEY
# On beryllium, list routes
headscale routes list
# Enable the exit node route (find the route ID from above)
headscale routes enable -r <route-id>
If you want all Headscale clients to use AdGuard for DNS:
1. AdGuard should listen on the Tailscale IP (e.g., 100.64.0.1)
2. Update Headscale config:
services.headscale.settings.dns.nameservers.global = ["100.64.0.1"];
---
headscale users create family
headscale preauthkeys create --user family --reusable --expiration 720h
Send family members:
1. Install Tailscale app (same app, works with Headscale)
2. Go to Settings → Custom control server → https://hs.bensima.com
3. Use auth key: [their key]
4. To use your home internet: Enable "Exit Node" → select beryllium
Create Omni/Dev/headscale-acl.json to control who can access what:
{
"acls": [
{"action": "accept", "src": ["ben"], "dst": ["*:*"]},
{"action": "accept", "src": ["family"], "dst": ["beryllium:*"]}
]
}
headscale policy set -f /path/to/headscale-acl.json
---
tailscale status)hs.bensima.comOmni/Dev/Vpn.nix - enable Headscale, add nginxOmni/Dev/Beryllium/Ava.nix - remove Funnel, add Caddycurl https://hs.bensima.com/healthheadscale users create benfamily user---
If something goes wrong, you can always:
1. Set services.headscale.enable = false in Vpn.nix
2. Re-run tailscale up without --login-server flag (uses Tailscale.com)
3. All devices can reconnect to Tailscale.com instantly
---
| File | Changes |
|------|---------|
| Omni/Dev/Vpn.nix | Enable Headscale, add nginx reverse proxy |
| Omni/Dev/Beryllium/Ava.nix | Remove Funnel comment, document new URL |
| Omni/Dev/Beryllium.nix | Possibly add Caddy module |
| Omni/Cloud/Ports.nix | Already has headscale = 8844 ✓ |
| File | Purpose |
|------|---------|
| Omni/Dev/headscale-acl.json | Access control policies |
| Omni/Dev/Beryllium/Caddy.nix | Ava web interface reverse proxy |
No activity yet.