Goal: connect VS Code or SSH to a Slurm compute allocation instead of doing computation on an Euler login node.
Prerequisites: the public-key-only key-ok test in
Euler access passes. Do not continue if Euler still needs
the ETH password for that test.
Execution context: euler-tunnel config/start/status/stop run on an Euler
login-node Bash prompt. SSH files and the tunnel hostname test run on the local
computer in the explicitly labelled PowerShell or zsh/Bash block.
What euler-tunnel Does#
euler-tunnel start submits a Slurm job containing an SSH server. Your local
Host euler-tunnel entry reaches that allocated compute node through the Euler
login service. Installing .vscode-server in your Euler home directory on the
first VS Code connection is expected.
Use a tunnel for interactive editing, notebooks, setup, and short debugging.
Use sbatch for unattended training, sweeps, and long computation.
1. Generate Personal Configuration#
Run on an Euler login node - Bash:
euler-tunnel config
Expected output:
- one
euler-tunnel ssh-ed25519 ...known-hosts line; - one
Host euler-tunnelconfiguration block containing your username and aProxyCommand.
The generated host key is personal. Copy the output from your own account; do not copy another student's known-hosts line.
2. Add The Known-Hosts Line Locally#
Fetch your own generated output through the verified Host euler alias. The
commands below extract only the host-key line, back up an existing file, and do
not append a duplicate.
Windows laptop - PowerShell#
& {
$SshDir = Join-Path $env:USERPROFILE ".ssh"
$KnownHosts = Join-Path $SshDir "known_hosts"
New-Item -ItemType Directory -Force $SshDir | Out-Null
$TunnelOutput = ssh euler "euler-tunnel config"
if ($LASTEXITCODE -ne 0) { throw "Could not obtain euler-tunnel configuration" }
$HostKeyLines = @($TunnelOutput | Where-Object { $_ -match '^euler-tunnel\s+ssh-' })
if ($HostKeyLines.Count -ne 1) { throw "Expected exactly one euler-tunnel host-key line" }
if (Test-Path $KnownHosts) {
Copy-Item $KnownHosts "$KnownHosts.backup.$(Get-Date -Format yyyyMMdd-HHmmss)"
}
if (-not (Test-Path $KnownHosts) -or
-not (Select-String -Path $KnownHosts -SimpleMatch $HostKeyLines[0] -Quiet)) {
if (Test-Path $KnownHosts) {
$Existing = [System.IO.File]::ReadAllText($KnownHosts)
if ($Existing.Length -gt 0 -and -not $Existing.EndsWith("`n")) {
[System.IO.File]::AppendAllText($KnownHosts, [Environment]::NewLine)
}
}
Add-Content $KnownHosts $HostKeyLines[0] -Encoding ascii
}
ssh-keygen -F euler-tunnel -f $KnownHosts
}
macOS or Linux laptop - zsh/Bash#
(
set -eu
ssh_dir="$HOME/.ssh"
known_hosts="$ssh_dir/known_hosts"
mkdir -p "$ssh_dir"
chmod 700 "$ssh_dir"
tunnel_output="$(ssh euler 'euler-tunnel config')"
host_key_lines="$(printf '%s\n' "$tunnel_output" | \
grep -E '^euler-tunnel[[:space:]]+ssh-')"
if [ "$(printf '%s\n' "$host_key_lines" | sed '/^$/d' | wc -l | tr -d ' ')" -ne 1 ]; then
printf 'STOP: expected exactly one euler-tunnel host-key line.\n' >&2
exit 1
fi
if [ -f "$known_hosts" ]; then
cp -p "$known_hosts" "$known_hosts.backup.$(date +%Y%m%d-%H%M%S)"
fi
touch "$known_hosts"
if ! grep -Fqx "$host_key_lines" "$known_hosts"; then
if [ -s "$known_hosts" ] &&
[ "$(tail -c 1 "$known_hosts" | wc -l | tr -d ' ')" -eq 0 ]; then
printf '\n' >> "$known_hosts"
fi
printf '%s\n' "$host_key_lines" >> "$known_hosts"
fi
chmod 600 "$known_hosts"
ssh-keygen -F euler-tunnel -f "$known_hosts"
)
Expected result: ssh-keygen prints one euler-tunnel host-key entry.
3. Add The Tunnel Host In The Existing Include Directory#
The Euler access procedure created ~/.ssh/config.d/. Use a separate file so
the Host euler block cannot be joined accidentally to the tunnel block.
Windows laptop - PowerShell#
& {
$User = Read-Host "ETH username"
if ($User -notmatch '^[A-Za-z0-9._-]+$') { throw "Invalid ETH username" }
$SshDir = Join-Path $env:USERPROFILE ".ssh"
$IncludeDir = Join-Path $SshDir "config.d"
$KeyPath = Join-Path $SshDir "id_ed25519_euler"
$TunnelConfig = Join-Path $IncludeDir "euler-tunnel.conf"
if (-not (Test-Path $KeyPath)) { throw "Missing private key: $KeyPath" }
New-Item -ItemType Directory -Force $IncludeDir | Out-Null
if (Test-Path $TunnelConfig) {
Copy-Item $TunnelConfig "$TunnelConfig.backup.$(Get-Date -Format yyyyMMdd-HHmmss)"
}
@"
Host euler-tunnel
User $User
IdentityFile ~/.ssh/id_ed25519_euler
IdentitiesOnly yes
ServerAliveInterval 10
ServerAliveCountMax 10
ProxyCommand ssh euler euler-tunnel connect
"@ | Set-Content $TunnelConfig -Encoding ascii
ssh -G euler-tunnel | Select-String '^(user|identityfile|proxycommand) '
}
Do not add the generated ControlMaster, ControlPath, or ControlPersist
lines on Windows; they use Unix sockets.
macOS or Linux laptop - zsh/Bash#
(
set -eu
printf 'ETH username: '
read -r eth_user
case "$eth_user" in
''|*[!A-Za-z0-9._-]*) printf 'STOP: invalid ETH username\n' >&2; exit 1 ;;
esac
include_dir="$HOME/.ssh/config.d"
tunnel_config="$include_dir/euler-tunnel.conf"
test -f "$HOME/.ssh/id_ed25519_euler"
mkdir -p "$include_dir"
if [ -f "$tunnel_config" ]; then
cp -p "$tunnel_config" "$tunnel_config.backup.$(date +%Y%m%d-%H%M%S)"
fi
cat > "$tunnel_config" <<EOF
Host euler-tunnel
User $eth_user
IdentityFile ~/.ssh/id_ed25519_euler
IdentitiesOnly yes
ServerAliveInterval 10
ServerAliveCountMax 10
ProxyCommand ssh euler euler-tunnel connect
ControlMaster auto
ControlPath ~/.ssh/cs-%r@%h:%p
ControlPersist 15
EOF
chmod 600 "$tunnel_config"
ssh -G euler-tunnel | grep -E '^(user|identityfile|proxycommand) '
)
4. Start The Smallest Suitable Allocation#
Run these only on an Euler login node - Bash.
CPU-only interactive work on es_fuge#
euler-tunnel start --account=es_fuge --cpus-per-task=2 --mem-per-cpu=4G --time=02:00:00
CPU-only public-share work#
euler-tunnel start --account=public --cpus-per-task=2 --mem-per-cpu=4G --time=02:00:00
Short RTX 4090 debugging#
euler-tunnel start --account=es_fuge --gpus=rtx_4090:1 --cpus-per-task=4 --mem-per-cpu=4G --time=00:30:00
Short RTX 3090 debugging#
euler-tunnel start --account=es_fuge --gpus=rtx_3090:1 --cpus-per-task=4 --mem-per-cpu=4G --time=00:30:00
The smaller interactive CPU/memory profile is intentional. Use the batch starter profile in Slurm GPU jobs for representative training, then right-size from measurements.
RTX 4090 is the standard GPU tunnel choice. The lab also has access to two RTX
PRO 6000 GPUs, but they require explicit pro_6000 selection and compatible
CUDA 13 software. Use their
special-purpose batch profile
rather than treating them as an interactive fallback.
Check on the Euler login node - Bash:
euler-tunnel status
5. Prove The Tunnel Before Opening VS Code#
Run on your local computer:
ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no euler-tunnel "hostname"
Expected output: a compute-node hostname such as eu-g5-047-2. A key
passphrase prompt is normal. An ETH password prompt means the upstream Host euler key setup is not working; stop and fix it.
6. Connect VS Code#
- Install the Microsoft Remote - SSH extension locally.
- Open the Command Palette.
- Select Remote-SSH: Connect to Host....
- Select
euler-tunnel. - Wait for VS Code Server to install or start in your Euler home directory.
- Open your project clone, not the whole
/cluster/work/fugetree.
Only If Terminal SSH Works But VS Code Fails#
Do not change SSH files when the local tunnel test in step 5 still fails. If that test succeeds but VS Code does not connect:
- In VS Code, open View > Output and select Remote - SSH.
- Check which local SSH configuration file the log says it is using.
- If it is not the existing user file that contains
Include config.d/*, open local User Settings, search for Remote.SSH: Config File, and enter the full path to that same existing file (normally~/.ssh/config). - Retry Remote-SSH: Connect to Host... > euler-tunnel.
This setting only tells VS Code which existing file to read; it does not replace or regenerate the file. Do not weaken password settings or add unrelated Remote-SSH compatibility toggles to make the prompt disappear. A key passphrase is expected; an ETH password prompt is not.
The terminal prompt should be a compute node. Verify in the VS Code terminal:
hostname
echo "$SLURM_JOB_ID"
Stop The Allocation#
Run on an Euler login node - Bash when interactive work ends:
euler-tunnel stop
Common Failures And Safe Recovery#
- Tunnel asks for ETH password: repeat the public-key-only
key-oktest. Host euler-tunnelis malformed: runssh -G euler-tunnel; each SSH keyword must be on its own line.- Private-key warning names
.pub: remove.pubfromIdentityFile. - VS Code prints download/install logs: wait for
listeningOnand successful startup. This is normal on first connection. - Terminal tunnel works but VS Code fails: follow the config-file check in step 6; do not regenerate a working SSH key.
- No tunnel job exists: start it on the Euler login node before connecting.
Ask For Help When#
key-ok succeeds and euler-tunnel status shows a running job, but the local
SSH tunnel test still fails. Share sanitized ssh -v euler-tunnel hostname
output, never key contents.
Primary Source#
Verified: 2026-08-04. Review by: 2026-11-04. Owner: IDEAL Lab IT.