hey
Greeting
/
·
6/5/2026, 1:27:04 PM
·
0 Files
+0
-0
Hey! What can I help you with?
there is an ssh tunnel on my vps rn which you are on i want to keep it open 24/7
Let me check what's currently running:
bash — ps aux | grep ssh completed 0s
Input
{
"command": "ps aux | grep ssh",
"description": "Check running SSH processes"
}
Output
root 17475 0.0 0.1 15452 3904 ? Ss May27 0:24 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups root 739778 0.1 0.1 16808 2284 ? Ss 13:00 0:02 sshd: root@pts/0 root 740688 0.0 0.4 19508 9988 ? Ss 13:23 0:00 sshd: root@pts/1 root 740788 0.0 0.1 4348 2872 ? Ss 13:28 0:00 /bin/bash -c ps aux | grep ssh root 740791 0.0 0.0 3456 1604 ? S 13:28 0:00 grep ssh
bash — systemctl list-units --type=service --state=running | grep -i ssh 2>/dev/null; crontab -l 2>/dev/null completed 0s
Input
{
"command": "systemctl list-units --type=service --state=running | grep -i ssh 2>/dev/null; crontab -l 2>/dev/null",
"description": "Check systemd services and crontab"
}
Output
ssh.service loaded active running OpenBSD Secure Shell server # Weather report for Turnhout at 7 AM Belgium time 5 * * * * python3 /root/sandbox/weather_bot.py --cron 6 * * * * python3 /root/sandbox/weather_bot.py --cron
I see the SSH server and active sessions, but no outgoing tunnel. What's the exact SSH command you're running for the tunnel? Or is it a reverse tunnel? Share the command and I'll help set it up as a systemd service so it stays alive 24/7 and auto-restarts.
ssh -L 5051:localhost:5051 [email protected] this is the command
bash — curl -s ifconfig.me completed 0s
Input
{
"command": "curl -s ifconfig.me",
"description": "Check this server's public IP"
}
Output
185.228.81.207
That's this VPS's own IP. ssh -L 5051:localhost:5051 [email protected] would connect back to itself, which isn't useful as a tunnel.
Do you mean:
- You run this from your local machine to the VPS (and want me to help with keepalive settings on the VPS side)?
- Or you want the VPS to initiate an outbound tunnel to somewhere else?
- Or you actually meant
-R(reverse tunnel)?
Let me clarify so I can set it up right.
yes rn its open in my terminal on a different pc
Got it. Two things to make it bulletproof:
1. Server-side (this VPS) – set keepalive so the connection doesn't drop:
read — /etc/ssh/sshd_config completed 0s
Input
{
"filePath": "/etc/ssh/sshd_config"
}
Output
<path>/etc/ssh/sshd_config</path> <type>file</type> <content> 1: 2: # This is the sshd server system-wide configuration file. See 3: # sshd_config(5) for more information. 4: 5: # This sshd was compiled with PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games 6: 7: # The strategy used for options in the default sshd_config shipped with 8: # OpenSSH is to specify options with their default value where 9: # possible, but leave them commented. Uncommented options override the 10: # default value. 11: 12: Include /etc/ssh/sshd_config.d/*.conf 13: 14: #Port 22 15: #AddressFamily any 16: #ListenAddress 0.0.0.0 17: #ListenAddress :: 18: 19: #HostKey /etc/ssh/ssh_host_rsa_key 20: #HostKey /etc/ssh/ssh_host_ecdsa_key 21: #HostKey /etc/ssh/ssh_host_ed25519_key 22: 23: # Ciphers and keying 24: #RekeyLimit default none 25: 26: # Logging 27: #SyslogFacility AUTH 28: #LogLevel INFO 29: 30: # Authentication: 31: 32: #LoginGraceTime 2m 33: PermitRootLogin yes 34: #StrictModes yes 35: #MaxAuthTries 6 36: #MaxSessions 10 37: 38: #PubkeyAuthentication yes 39: 40: # Expect .ssh/authorized_keys2 to be disregarded by default in future. 41: #AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2 42: 43: #AuthorizedPrincipalsFile none 44: 45: #AuthorizedKeysCommand none 46: #AuthorizedKeysCommandUser nobody 47: 48: # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts 49: #HostbasedAuthentication no 50: # Change to yes if you don't trust ~/.ssh/known_hosts for 51: # HostbasedAuthentication 52: #IgnoreUserKnownHosts no 53: # Don't read the user's ~/.rhosts and ~/.shosts files 54: #IgnoreRhosts yes 55: 56: # To disable tunneled clear text passwords, change to no here! 57: #PasswordAuthentication yes 58: #PermitEmptyPasswords no 59: 60: # Change to yes to enable challenge-response passwords (beware issues with 61: # some PAM modules and threads) 62: KbdInteractiveAuthentication no 63: 64: # Kerberos options 65: #KerberosAuthentication no 66: #KerberosOrLocalPasswd yes 67: #KerberosTicketCleanup yes 68: #KerberosGetAFSToken no 69: 70: # GSSAPI options 71: #GSSAPIAuthentication no 72: #GSSAPICleanupCredentials yes 73: #GSSAPIStrictAcceptorCheck yes 74: #GSSAPIKeyExchange no 75: 76: # Set this to 'yes' to enable PAM authentication, account processing, 77: # and session processing. If this is enabled, PAM authentication will 78: # be allowed through the KbdInteractiveAuthentication and 79: # PasswordAuthentication. Depending on your PAM configuration, 80: # PAM authentication via KbdInteractiveAuthentication may bypass 81: # the setting of "PermitRootLogin without-password". 82: # If you just want the PAM account and session checks to run without 83: # PAM authentication, then enable this but set PasswordAuthentication 84: # and KbdInteractiveAuthentication to 'no'. 85: UsePAM yes 86: 87: #AllowAgentForwarding yes 88: #AllowTcpForwarding yes 89: #GatewayPorts no 90: X11Forwarding yes 91: #X11DisplayO …truncated
That clears it up. Here's what I recommend:
On your local machine (most important) – use autossh which auto-reconnects on drop:
autossh -M 0 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -L 5051:localhost:5051 [email protected]
Even better, wrap it in a systemd service on your local machine for true 24/7 uptime:
[Unit]
Description=SSH tunnel
After=network.target
[Service]
Restart=always
RestartSec=10
ExecStart=/usr/bin/ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -L 5051:localhost:5051 [email protected]
[Install]
WantedBy=multi-user.target
On this VPS side – I can enable keepalive to prevent idle disconnects. Want me to add ClientAliveInterval 60 to sshd_config and reload?
uhm what does that mean
No worries. The short version:
Your terminal → VPS tunnel. If your terminal closes or network blips, the tunnel dies. You need something that keeps it alive and reconnects automatically.
Two simple things:
- On your local PC – replace
sshwithautossh(just install it, same command). It auto-reconnects when the tunnel drops. - On this VPS – I can tweak a setting so SSH doesn't kill idle connections.
Want me to just set up the VPS side? For the local PC, install autossh and run:
autossh -L 5051:localhost:5051 [email protected]but what if i close my pc
Then the tunnel can't stay up if your PC is off – that's just how it works.
But wait — ssh -L 5051:localhost:5051 means the service on this VPS only listens on localhost. You're using the tunnel to reach it from your PC. If that's the case, you don't need a tunnel at all — we can just make the service accessible directly.
What's running on port 5051 on this VPS?
you
Ah, I'm on port 5051! Let me check what service this is:
bash — ss -tlnp | grep 5051 completed 0s
Input
{
"command": "ss -tlnp | grep 5051",
"description": "Check what's listening on port 5051"
}
Output
LISTEN 0 128 127.0.0.1:5051 0.0.0.0:* users:(("opencode",pid=740662,fd=17))
I'm bound to 127.0.0.1:5051 — that's why you needed the tunnel.
Since your PC can't stay on 24/7, the easiest fix: bind me to 0.0.0.0 so you can reach me directly at http://185.228.81.207:5051.
But that means anyone could try hitting this port. Does opencode need auth, or is this just for you?
it definetely needs security
Let me check what auth options opencode has:
bash — cat /root/.config/opencode/opencode.json 2>/dev/null || cat /root/.opencode.json 2>/dev/null || echo "No config found at default locations" completed 0s
Input
{
"command": "cat /root/.config/opencode/opencode.json 2>/dev/null || cat /root/.opencode.json 2>/dev/null || echo \"No config found at default locations\"",
"description": "Check opencode config"
}
Output
No config found at default locations
bash — ps aux | grep opencode | grep -v grep completed 0s
Input
{
"command": "ps aux | grep opencode | grep -v grep",
"description": "Check how opencode was launched"
}
Output
root 729968 3.0 13.8 74456048 290320 ? Ssl Jun04 30:12 opencode serve --port 4096 root 739958 0.2 5.1 11843080 107340 ? Ssl 13:10 0:03 node /root/.npm/_npx/96ab324e177a8c2c/node_modules/@grinev/opencode-telegram-bot/dist/cli.js start root 740368 0.1 2.9 1335048 61524 ? Sl 13:14 0:01 npm exec @different-ai/opencode-browser agent-gateway root 740381 0.0 0.0 2876 96 ? S 13:14 0:00 sh -c opencode-browser agent-gateway root 740382 0.0 1.5 1045268 32588 ? Sl 13:14 0:00 node /root/.npm/_npx/8096bb92ae86a312/node_modules/.bin/opencode-browser agent-gateway root 740389 0.0 1.4 749604 30424 ? Sl 13:14 0:00 /usr/bin/node /root/.npm/_npx/8096bb92ae86a312/node_modules/@different-ai/opencode-browser/bin/agent-gateway.cjs root 740540 15.3 26.7 75318376 562008 pts/0 Sl+ 13:19 1:47 opencode -s ses_1681db4dfffeqedFZkdl3074Sd root 740662 10.0 16.6 74778084 349460 ? Rsl 13:22 0:52 /root/.opencode/bin/opencode serve --port 5051 --print-logs
bash — opencode serve --help 2>/dev/null || opencode help 2>/dev/null | head -40 completed 2s
Input
{
"command": "opencode serve --help 2>/dev/null || opencode help 2>/dev/null | head -40",
"description": "Check opencode auth options"
}
Output
(no output)
bash — opencode help 2>&1 completed 0s
Input
{
"command": "opencode help 2>&1",
"description": "Check opencode help"
}
Output
Commands:
opencode completion generate shell completion script
opencode acp start ACP (Agent Client Protocol) server
opencode mcp manage MCP (Model Context Protocol) servers
opencode [project] start opencode tui [default]
opencode attach <url> attach to a running opencode server
opencode run [message..] run opencode with a message
opencode debug debugging and troubleshooting tools
opencode providers manage AI providers and credentials [aliases: auth]
opencode agent manage agents
opencode upgrade [target] upgrade opencode to the latest or a specific version
opencode uninstall uninstall opencode and remove all related files
opencode serve starts a headless opencode server
opencode web start opencode server and open web interface
opencode models [provider] list all available models
opencode stats show token usage and cost statistics
opencode export [sessionID] export session data as JSON
opencode import <file> import session data from JSON file or URL
opencode github manage GitHub agent
opencode pr <number> fetch and checkout a GitHub PR branch, then run opencode
opencode session manage sessions
opencode plugin <module> install plugin and update config [aliases: plug]
opencode db database tools
Positionals:
project path to start opencode in [string]
Options:
-h, --help show help [boolean]
-v, --version show version number [boolean]
--print-logs print logs to stderr [boolean]
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
--pure run without external plugins [boolean]
--port port to listen on [number] [default: 0]
--hostname hostname to listen on [string] [default: "127.0.0.1"]
--mdns enable mDNS service discovery (defaults hostname to 0.0.0.0)
[boolean] [default: false]
--mdns-domain custom domain name for mDNS service (default: opencode.local)
[string] [default: "opencode.local"]
--cors additional domains to allow for CORS [array] [default: []]
-m, --model model to use in the format of provider/model [string]
-c, --continue continue the last ses
…truncated
opencode doesn't have built-in auth. Here are your best options to make it accessible 24/7 securely without keeping your PC on:
Option A: Tailscale (easiest) – creates a private network between your devices:
# on VPS
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
Then access me at http://<tailscale-ip>:5051 from any device. No open ports, encrypted, auth required.
Option B: Cloudflare Tunnel – also free, no open ports:
# on VPS
cloudflared tunnel --url http://localhost:5051
Gives you a URL to access from anywhere.
Both can be set up as systemd services to run 24/7. Which sounds better? Tailscale is probably the simplest.
lets go with cloudflare
bash — which cloudflared 2>/dev/null || echo "not installed" completed 0s
Input
{
"command": "which cloudflared 2>/dev/null || echo \"not installed\"",
"description": "Check if cloudflared is installed"
}
Output
not installed
bash — curl -fsSL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared && chmod +x /usr/local/bin/cloudflared completed 2s
Input
{
"description": "Install cloudflared",
"command": "curl -fsSL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflared && chmod +x /usr/local/bin/cloudflared",
"timeout": 30000
}
Output
(no output)
bash — cloudflared tunnel login 2>&1 completed 15s
Input
{
"command": "cloudflared tunnel login 2>&1",
"timeout": 15000,
"description": "Start cloudflare login process"
}
Output
Please open the following URL and log in with your Cloudflare account: https://dash.cloudflare.com/argotunnel?aud=&callback=https%3A%2F%2Flogin.cloudflareaccess.org%2FBIU9JH8yIxAP5oWh8IrIE6YjFxIz_tK6-F8cGVbXQSw%3D Leave cloudflared running to download the cert automatically. <shell_metadata> shell tool terminated command after exceeding timeout 15000 ms. If this command is expected to take longer and is not waiting for interactive input, retry with a larger timeout value in milliseconds. </shell_metadata>
Open this link in your browser to log in with your Cloudflare account:
https://dash.cloudflare.com/argotunnel?aud=&callback=https%3A%2F%2Flogin.cloudflareaccess.org%2FBIU9JH8yIxAP5oWh8IrIE6YjFxIz_tK6-F8cGVbXQSw%3D
After you authenticate, come back and I'll finish setting up the tunnel.
i have this problem
You need a domain on Cloudflare for this. Do you have one, or is that page empty?
If you don't have a domain, there's a simpler option: quick tunnel. It gives you a random trycloudflare.com URL — works instantly, no domain needed. The URL changes on restart though.
If you want a permanent URL, you'll need to add a domain to Cloudflare first. Do you have one?
i dont have a domain fix it
No domain needed then. I'll switch to Tailscale — free, no domain, static private IP, and dead simple:
bash — which tailscale 2>/dev/null && echo "already installed" || echo "not installed" completed 0s
Input
{
"command": "which tailscale 2>/dev/null && echo \"already installed\" || echo \"not installed\"",
"description": "Check if tailscale is installed"
}
Output
not installed
bash — curl -fsSL https://tailscale.com/install.sh | sh 2>&1 completed 0s
Input
{
"command": "curl -fsSL https://tailscale.com/install.sh | sh 2>&1",
"description": "Install Tailscale",
"timeout": 30000
}
Output
Installing Tailscale for ubuntu jammy, using method apt + mkdir -p --mode=0755 /usr/share/keyrings + tee /usr/share/keyrings/tailscale-archive-keyring.gpg + curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg + chmod 0644 /usr/share/keyrings/tailscale-archive-keyring.gpg + tee /etc/apt/sources.list.d/tailscale.list + curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.tailscale-keyring.list # Tailscale packages for ubuntu jammy deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/ubuntu jammy main + chmod 0644 /etc/apt/sources.list.d/tailscale.list + apt-get update Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease Get:2 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB] Get:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB] Hit:4 https://deb.nodesource.com/node_22.x nodistro InRelease Get:5 https://pkgs.tailscale.com/stable/ubuntu jammy InRelease Get:6 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages [3565 kB] Get:7 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [3291 kB] Get:8 https://pkgs.tailscale.com/stable/ubuntu jammy/main all Packages [354 B] Get:9 https://pkgs.tailscale.com/stable/ubuntu jammy/main amd64 Packages [15.0 kB] Fetched 7134 kB in 4s (1743 kB/s) Reading package lists... + [ -n ] + apt-get install -y tailscale tailscale-archive-keyring Reading package lists... Building dependency tree... Reading state information... The following packages were automatically installed and are no longer required: adwaita-icon-theme dns-root-data gtk-update-icon-cache hicolor-icon-theme humanity-icon-theme libevent-2.1-7 libgnutls-dane0 libidn12 liblockfile-bin liblockfile1 libunbound8 ubuntu-mono Use 'apt autoremove' to remove them. The following NEW packages will be installed: tailscale tailscale-archive-keyring 0 upgraded, 2 newly installed, 0 to remove and 19 not upgraded. Need to get 37.1 MB of archives. After this operation, 73.0 MB of additional disk space will be used. Get:1 https://pkgs.tailscale.com/stable/ubuntu jammy/main amd64 tailscale amd64 1.98.4 [37.1 MB] Get:2 https://pkgs.tailscale.com/stable/ubuntu jammy/main all tailscale-archive-keyring all 1.35.181 [3082 B] Fetched 37.1 MB in 1s (61.6 MB/s) Selecting previously unselected package tailscale. (Reading database ... (Reading database ... 5% (Reading database ... 10% (Reading database ... 15% (Reading database ... 20% (Reading database ... 25% (Reading database ... 30% (Reading database ... 35% (Reading database ... 40% (Reading database ... 45% (Reading database ... 50% (Reading database ... 55% (Reading database ... 60% (Reading database ... 65% (Reading database ... 70% (Reading database ... 75% (Reading database ... 80% (Reading database ... 85% (Reading database ... 90% (Reading database ... 95% (Reading database ... 100% (Reading database ... 56308 files and directories currently installed.) Preparing to unpack .../ …truncated
bash — tailscale up 2>&1 completed 0s
Input
{
"command": "tailscale up 2>&1",
"description": "Start Tailscale authentication",
"timeout": 10000
}
Output
failed to connect to local tailscaled (which appears to be running as tailscaled, pid 741527). Got error: Failed to connect to local Tailscale daemon for /localapi/v0/status; systemd tailscaled.service not running. Error: dial unix /var/run/tailscale/tailscaled.sock: connect: no such file or directory
bash — systemctl start tailscaled && sleep 2 completed 3s
Input
{
"description": "Start tailscaled service",
"command": "systemctl start tailscaled && sleep 2",
"timeout": 10000
}
Output
(no output)
bash — tailscale up 2>&1 completed 0s
Input
{
"description": "Authenticate Tailscale",
"command": "tailscale up 2>&1",
"timeout": 10000
}
Output
failed to connect to local tailscaled; it doesn't appear to be running (sudo systemctl start tailscaled ?)
bash — systemctl status tailscaled 2>&1; journalctl -u tailscaled --no-pager -n 20 2>&1 completed 0s
Input
{
"description": "Check tailscaled status",
"command": "systemctl status tailscaled 2>&1; journalctl -u tailscaled --no-pager -n 20 2>&1",
"timeout": 10000
}
Output
× tailscaled.service - Tailscale node agent
Loaded: loaded (/lib/systemd/system/tailscaled.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2026-06-05 13:37:00 UTC; 819ms ago
Docs: https://tailscale.com/docs/
Process: 741820 ExecStart=/usr/sbin/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=${PORT} $FLAGS (code=exited, status=1/FAILURE)
Process: 741850 ExecStopPost=/usr/sbin/tailscaled --cleanup (code=exited, status=0/SUCCESS)
Main PID: 741820 (code=exited, status=1/FAILURE)
Jun 05 13:37:00 vps.server.com systemd[1]: tailscaled.service: Scheduled restart job, restart counter is at 5.
Jun 05 13:37:00 vps.server.com systemd[1]: Stopped Tailscale node agent.
Jun 05 13:37:00 vps.server.com systemd[1]: tailscaled.service: Start request repeated too quickly.
Jun 05 13:37:00 vps.server.com systemd[1]: tailscaled.service: Failed with result 'exit-code'.
Jun 05 13:37:00 vps.server.com systemd[1]: Failed to start Tailscale node agent.
Jun 05 13:36:59 vps.server.com tailscaled[741820]: getLocalBackend error: createEngine: tstun.New("tailscale0"): CreateTUN("tailscale0") failed; /dev/net/tun does not exist
Jun 05 13:36:59 vps.server.com systemd[1]: tailscaled.service: Main process exited, code=exited, status=1/FAILURE
Jun 05 13:36:59 vps.server.com tailscaled[741850]: TPM: error opening: stat /dev/tpmrm0: no such file or directory
Jun 05 13:36:59 vps.server.com tailscaled[741850]: logtail started
Jun 05 13:36:59 vps.server.com tailscaled[741850]: Program starting: v1.98.4-t9e69045b2-ged3a62f14, Go 1.26.3: []string{"/usr/sbin/tailscaled", "--cleanup"}
Jun 05 13:36:59 vps.server.com tailscaled[741850]: LogID: 49a079199d0eeee78190d0c8caae47f461edc3e7d48e8e95d002d5e221fca0da
Jun 05 13:36:59 vps.server.com tailscaled[741850]: logpolicy: using $STATE_DIRECTORY, "/var/lib/tailscale"
Jun 05 13:36:59 vps.server.com tailscaled[741850]: dns: resolvedIsActuallyResolver error: resolv.conf doesn't point to systemd-resolved; points to [8.8.8.8 8.8.4.4]
Jun 05 13:36:59 vps.server.com tailscaled[741850]: dns: [rc=resolved resolved=not-in-use ret=direct]
Jun 05 13:36:59 vps.server.com tailscaled[741850]: dns: using "direct" mode
Jun 05 13:36:59 vps.server.com tailscaled[741850]: dns: using *dns.directManager
Jun 05 13:36:59 vps.server.com tailscaled[741850]: dns: inotify: NewDirWatcher: context canceled
Jun 05 13:36:59 vps.server.com tailscaled[741850]: flushing log.
Jun 05 13:36:59 vps.server.com tailscaled[741850]: logger closing down
Jun 05 13:37:00 vps.server.com systemd[1]: tailscaled.service: Failed with result 'exit-code'.
Jun 05 13:37:00 vps.server.com systemd[1]: tailscaled.service: Scheduled restart job, restart counter is at 5.
Jun 05 13:37:00 vps.server.com systemd[1]: Stopped Tailscale node agent.
Jun 05 13:37:00 vps.server.com systemd[1]: tailscaled.service: Start request repeated too quickly.
Jun 05 13:37:00 vps.server.com systemd[1]: tailsc
…truncated
This VPS doesn't have a TUN device (common in some VPS setups). Let me try Tailscale in userspace mode:
bash — systemctl stop tailscaled && sleep 1 && tailscale up --tun=userspace-networking 2>&1 completed 0s
Input
{
"command": "systemctl stop tailscaled && sleep 1 && tailscale up --tun=userspace-networking 2>&1",
"description": "Try Tailscale userspace mode",
"timeout": 15000
}
Output
flag provided but not defined: -tun
Connect to Tailscale, logging in if needed
USAGE
tailscale up [flags]
"tailscale up" connects this machine to your Tailscale network,
triggering authentication if necessary.
With no flags, "tailscale up" brings the network online without
changing any settings. (That is, it's the opposite of "tailscale
down").
If flags are specified, the flags must be the complete set of desired
settings. An error is returned if any setting would be changed as a
result of an unspecified flag's default value, unless the --reset flag
is also used. (The flags --auth-key, --force-reauth, and --qr are not
considered settings that need to be re-specified when modifying
settings.)
FLAGS
--accept-dns, --accept-dns=false
accept DNS configuration from the admin panel (default true)
--accept-risk value
accept risk and skip confirmation for risk types: lose-ssh,mac-app-connector,all
--accept-routes, --accept-routes=false
accept routes advertised by other Tailscale nodes (default false)
--advertise-connector, --advertise-connector=false
advertise this node as an app connector (default false)
--advertise-exit-node, --advertise-exit-node=false
offer to be an exit node for internet traffic for the tailnet (default false)
--advertise-routes value
routes to advertise to other nodes (comma-separated, e.g. "10.0.0.0/8,192.168.0.0/24") or empty string to not advertise routes
--advertise-tags value
comma-separated ACL tags to request (e.g. "tag:eng,tag:montreal,tag:ssh"); the "tag:" prefix is optional and added automatically when omitted (e.g. "eng,montreal,ssh")
--audience value
Audience used when requesting an ID token from an identity provider for auth keys via workload identity federation
--auth-key value
node authorization key; if it begins with "file:", then it's a path to a file containing the authkey
--client-id value
Client ID used to generate authkeys via workload identity federation
--client-secret value
Client Secret used to generate authkeys via OAuth; if it begins with "file:", then it's a path to a file containing the secret
--exit-node value
Tailscale exit node (IP, base name, or auto:any) for internet traffic, or empty string to not use an exit node
--exit-node-allow-lan-access, --exit-node-allow-lan-access=false
Allow direct access to the local network when routing traffic via an exit node (default false)
--force-reauth, --force-reauth=false
force reauthentication (WARNING: this may bring down the Tailscale connection and thus should not be done remotely over SSH or RDP) (default false)
--hostname value
hostname to use instead of the one provided by the OS
--id-token value
ID token from the identity provider to exchange with the control server for workload identity federation; if it begins with "file:", then it's a path to a file containing the token
--json, --json=false
output in JSON format (WARNING: format
…truncated
bash — /usr/sbin/tailscaled --help 2>&1 | head -20 completed 0s
Input
{
"command": "/usr/sbin/tailscaled --help 2>&1 | head -20",
"description": "Check tailscaled options",
"timeout": 5000
}
Output
Usage of /usr/sbin/tailscaled:
-bird-socket string
path of the bird unix socket
-cleanup
clean up system state and exit
-config string
path to config file, or 'vm:user-data' to use the VM's user-data (EC2)
-debug string
listen address ([ip]:port) of optional debug server
-encrypt-state
encrypt the state file on disk; when not set encryption will be enabled if supported on this platform; uses TPM on Linux and Windows, on all other platforms this flag is not supported
-hardware-attestation
use hardware-backed keys to bind node identity to this device when supported
by the OS and hardware. Uses TPM 2.0 on Linux and Windows; SecureEnclave on
macOS and iOS; and Keystore on Android. Only supported for Tailscale nodes that
store state on filesystem.
-no-logs-no-support
disable log uploads; this also disables any technical support
-outbound-http-proxy-listen string
optional [ip]:port to run an outbound HTTP proxy (e.g. "localhost:8080")
bash — mkdir -p /dev/net && mknod /dev/net/tun c 10 200 && chmod 666 /dev/net/tun && ls -la /dev/net/tun 2>&1 completed 0s
Input
{
"command": "mkdir -p /dev/net && mknod /dev/net/tun c 10 200 && chmod 666 /dev/net/tun && ls -la /dev/net/tun 2>&1",
"description": "Try creating TUN device manually",
"timeout": 5000
}
Output
crw-rw-rw- 1 root root 10, 200 Jun 5 13:37 /dev/net/tun
bash — systemctl start tailscaled && sleep 2 && systemctl status tailscaled 2>&1 completed 0s
Input
{
"command": "systemctl start tailscaled && sleep 2 && systemctl status tailscaled 2>&1",
"description": "Start tailscaled after creating TUN",
"timeout": 10000
}
Output
● tailscaled.service - Tailscale node agent
Loaded: loaded (/lib/systemd/system/tailscaled.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2026-06-05 13:37:19 UTC; 2s ago
Docs: https://tailscale.com/docs/
Main PID: 741900 (tailscaled)
Status: "Needs login: "
Tasks: 10 (limit: 308812)
Memory: 19.2M
CGroup: /system.slice/tailscaled.service
└─741900 /usr/sbin/tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --port=41641
Jun 05 13:37:19 vps.server.com tailscaled[741900]: Backend: logs: be:49a079199d0eeee78190d0c8caae47f461edc3e7d48e8e95d002d5e221fca0da fe:
Jun 05 13:37:19 vps.server.com tailscaled[741900]: Switching ipn state NoState -> NeedsLogin (WantRunning=false, nm=false)
Jun 05 13:37:19 vps.server.com tailscaled[741900]: blockEngineUpdates(true)
Jun 05 13:37:19 vps.server.com tailscaled[741900]: wgengine: Reconfig: configuring router
Jun 05 13:37:19 vps.server.com tailscaled[741900]: wgengine: Reconfig: user dialer
Jun 05 13:37:19 vps.server.com tailscaled[741900]: wgengine: Reconfig: configuring DNS
Jun 05 13:37:19 vps.server.com tailscaled[741900]: dns: Set: {DefaultResolvers:[] Routes:{} SearchDomains:[] Hosts:0}
Jun 05 13:37:19 vps.server.com tailscaled[741900]: dns: Resolvercfg: {Routes:{} Hosts:0 LocalDomains:[]}
Jun 05 13:37:19 vps.server.com tailscaled[741900]: dns: OScfg: {}
Jun 05 13:37:19 vps.server.com tailscaled[741900]: health(warnable=wantrunning-false): error: Tailscale is stopped.
Tailscale is running. Now authenticate:
bash — tailscale up 2>&1 completed 0s
Input
{
"command": "tailscale up 2>&1",
"description": "Start Tailscale auth",
"timeout": 10000
}
Output
To authenticate, visit: https://login.tailscale.com/a/13495df301709b context canceled <shell_metadata> shell tool terminated command after exceeding timeout 10000 ms. If this command is expected to take longer and is not waiting for interactive input, retry with a larger timeout value in milliseconds. </shell_metadata>
Open this in your browser to log in (Google/GitHub/Microsoft/any account works):
https://login.tailscale.com/a/13495df301709b
Come back after you authenticate and I'll finish the setup!
okay done
bash — tailscale status 2>&1 completed 0s
Input
{
"command": "tailscale status 2>&1",
"description": "Check Tailscale status and IP"
}
Output
100.67.221.82 vps willem.haesaert@ linux -
Tailscale is connected. VPS's Tailscale IP: 100.67.221.82
Now I'll rebind opencode to the Tailscale IP so it's only accessible through your private network:
bash — kill 740662 2>/dev/null; sleep 1; nohup opencode serve --port 5051 --hostname 100.67.221.82 --print-logs > /dev/null 2>&1 & sleep 2; ss -tlnp | grep 5051 running
Input
{
"command": "kill 740662 2>/dev/null; sleep 1; nohup opencode serve --port 5051 --hostname 100.67.221.82 --print-logs > /dev/null 2>&1 &\nsleep 2; ss -tlnp | grep 5051",
"description": "Restart opencode on Tailscale IP",
"timeout": 10000
}
Output
is it done?
Let me check:
bash — ss -tlnp | grep 5051 completed 0s
Input
{
"command": "ss -tlnp | grep 5051",
"description": "Check opencode on port 5051"
}
Output
LISTEN 0 128 127.0.0.1:5051 0.0.0.0:* users:(("opencode",pid=742463,fd=17))
bash — kill 742463 2>/dev/null; sleep 1; opencode serve --port 5051 --hostname 100.67.221.82 --print-logs > /dev/null 2>&1 & sleep 2; ss -tlnp | grep 5051 running
Input
{
"command": "kill 742463 2>/dev/null; sleep 1; opencode serve --port 5051 --hostname 100.67.221.82 --print-logs > /dev/null 2>&1 &\nsleep 2; ss -tlnp | grep 5051",
"description": "Restart opencode on Tailscale IP",
"timeout": 10000
}