Skip to content

Instantly share code, notes, and snippets.

@zudsniper
Last active March 28, 2026 11:00
Show Gist options
  • Select an option

  • Save zudsniper/98eebbc5e8f51c75192978e7c104291c to your computer and use it in GitHub Desktop.

Select an option

Save zudsniper/98eebbc5e8f51c75192978e7c104291c to your computer and use it in GitHub Desktop.
The Case of the Silent Tunnel: Troubleshooting Cursor Remote-SSH Connection Failures

The Case of the Silent Tunnel: A Remote-SSH Mystery

It was a quiet Saturday morning. I was trying to connect to my Raspberry Pi 5 (srv01) using Cursor's Remote SSH. But instead of a warm terminal welcome, I was met with a cold, hard failure.

The Victim

The Cursor Remote-SSH connection. It wouldn't start. No heartbeat. Just a "404" error in the logs that seemed to point to a missing server artifact.

The First Suspect: The 404 Red Herring

The internet pointed a finger at a common culprit: Architecture Mismatch. The forum threads were buzzing with tales of 32-bit userlands on 64-bit kernels causing a 404 Not Found when Cursor tried to fetch the server artifact (cli-linux-armhf.tar.gz).

I performed an autopsy on the remote system:

# Checking the architecture and bitness
uname -m && getconf LONG_BIT
# Output: aarch64, 64

The victim was 64-bit through and through. The 404 was a ghost, a red herring. The server was already there, lying in wait at ~/.cursor-server/bin/linux-arm64/.

The Forensic Breakthrough: The Logs Don't Lie

I dug deeper into the extension logs (~/.config/Cursor/logs/...). That's where I found the true blood splatter:

2026-03-28 05:52:57.046 [info] (ssh_tunnel) stderr: channel 3: open failed: administratively prohibited: open failed
2026-03-28 05:52:57.047 [error] [forwarding][code] error while creating socks forwarding Socket closed

"Administratively prohibited." This wasn't a missing file; it was a lockout. The system itself was slamming the door shut.

The Reveal: The Culprit in the Closet

I started searching the server's configuration files. I looked in /etc/ssh/sshd_config, but it looked clean. Then I saw it—a small, unassuming file in /etc/ssh/sshd_config.d/ named hardening.conf.

Inside, the killer was hiding in plain sight:

# Disable unnecessary features
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no  <-- THE MURDERER

AllowTcpForwarding no had strangled the SSH tunnel before it could even take its first breath. Cursor (and VS Code) requires TCP forwarding to create the SOCKS tunnel it uses for communication.

The Resolution (Part 1)

The fix was surgical. I flipped the bit and restarted the service:

# The intervention
sudo sed -i 's/AllowTcpForwarding no/AllowTcpForwarding yes/' /etc/ssh/sshd_config.d/hardening.conf
sudo systemctl restart ssh

The tunnel cleared. The connection was established. Justice—and productivity—was served.


The Plot Thickens: The Sandbox Strangler

Just when I thought the case was closed, a new ghost appeared. The terminal wouldn't start. A persistent error haunted the UI:

"Terminal sandbox could not start. This may be caused by an AppArmor configuration on your Linux system (kernel 6.2+)."

Even in the SSH environment, the error persisted. It was as if the lockdown had followed me across the network.

The Forensic Evidence: Kernel 6.2+ and the LSM

I checked the local machine (Ubuntu 24.10, kernel 6.11). The evidence was in the dmesg:

audit: apparmor="DENIED" operation="capable" profile="unprivileged_userns" comm="bwrap" capability=8 capname="setpcap"

The culprit was a new security feature in modern kernels (6.2+) that restricts unprivileged user namespaces. Even if AppArmor profiles are present, they are often not applied correctly to Cursor's AppImage or binary helpers, leading to a fallback to a restricted unprivileged_userns profile.

The Final Blow: Tearing Down the Walls

The fix required a local override of the kernel's AppArmor restrictions. The user had the settings ready in /etc/sysctl.d/50-cursor.conf, but they were commented out—likely by a cautious admin or a botched update.

I applied the antidote:

# Enabling unprivileged user namespaces in AppArmor
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

# Making it permanent
sudo sed -i 's/#kernel.apparmor_restrict_unprivileged_userns=0/kernel.apparmor_restrict_unprivileged_userns=0/' /etc/sysctl.d/50-cursor.conf
sudo sysctl -p /etc/sysctl.d/50-cursor.conf

Case Closed (Again)

The sandbox opened. The terminal breathed. The SSH environment was finally free of the shadows of the local AppArmor policies.

Final Lessons

  1. Local Issues Shadow Remote ones: Even when using SSH, Cursor's UI and its terminal-bridge processes run locally and are subject to local kernel security policies.
  2. AppArmor 6.2+ is Strict: Newer kernels have very aggressive defaults for user namespaces. If an application isn't explicitly profiled, it's effectively jailed.
  3. Check your /etc/sysctl.d/: Always look for fragments that were meant to solve the problem but were left commented out.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment