Goal: connect to Euler and configure a dedicated SSH key without replacing existing keys or rewriting an existing SSH configuration.
Prerequisites: a valid personal ETH account. Outside the ETH network, connect to the ETH VPN first.
Execution context: commands alternate between your local Windows PowerShell/macOS/Linux terminal and an Euler login-node Bash prompt. Every step labels its context. If the label does not match the prompt in front of you, stop; never paste a PowerShell block into Euler Bash.
The private key remains on your local computer. Never create or copy your local private key on Euler.
1. Confirm Password Login First#
Enter the short ETH username when prompted, not an email address.
Windows laptop - PowerShell#
$User = Read-Host "ETH username"
if ($User -notmatch '^[A-Za-z0-9._-]+$') { throw "Invalid ETH username" }
ssh "$User@euler.ethz.ch"
macOS or Linux laptop - zsh/Bash#
read -r -p "ETH username: " eth_user
case "$eth_user" in
''|*[!A-Za-z0-9._-]*) printf 'STOP: invalid ETH username\n' >&2 ;;
*) ssh "$eth_user@euler.ethz.ch" ;;
esac
On first access, Euler may require acceptance of its usage rules and an access code sent to the registered ETH email address. An ETH password prompt is normal at this stage.
Expected result: the prompt changes to an Euler login node such as
eu-login-36:~$.
Run this on the Euler login node - Bash, then disconnect:
hostname
exit
If login fails, stop and use Euler troubleshooting. Do not generate a new key to solve an account, VPN, or password problem.
2. Generate A Dedicated Key Without Overwriting Anything#
The canonical filename is id_ed25519_euler. The following commands preserve
an existing file with that name.
Windows laptop - PowerShell#
$SshDir = Join-Path $env:USERPROFILE ".ssh"
$KeyPath = Join-Path $SshDir "id_ed25519_euler"
New-Item -ItemType Directory -Force $SshDir | Out-Null
if ((Test-Path $KeyPath) -or (Test-Path "$KeyPath.pub")) {
Write-Host "STOP: $KeyPath or its public key already exists. Nothing was overwritten."
} else {
ssh-keygen -t ed25519 -f $KeyPath -C "$env:USERNAME@euler"
}
Set a passphrase when prompted. If the command printed STOP, inspect the
existing pair or ask for help; do not choose overwrite.
Restrict the private key to the current Windows user:
$KeyPath = Join-Path $env:USERPROFILE ".ssh\id_ed25519_euler"
icacls $KeyPath /inheritance:r
icacls $KeyPath /grant:r "$($env:USERNAME):(R)"
Expected result: both id_ed25519_euler and
id_ed25519_euler.pub exist. The file ending in .pub is the public key.
macOS or Linux laptop - zsh/Bash#
(
set -eu
key="$HOME/.ssh/id_ed25519_euler"
mkdir -p "$HOME/.ssh"
chmod 700 "$HOME/.ssh"
if [ -e "$key" ] || [ -e "$key.pub" ]; then
printf 'STOP: %s or its public key already exists. Nothing was overwritten.\n' "$key"
else
ssh-keygen -t ed25519 -f "$key" -C "$USER@euler"
fi
)
Set a passphrase. If the command printed STOP, inspect the existing pair or
ask for help.
3. Install Only The Public Key On Euler#
Windows laptop - PowerShell#
Run this in a new local PowerShell session if necessary; it defines its own variables.
$User = Read-Host "ETH username"
$PublicKey = Join-Path $env:USERPROFILE ".ssh\id_ed25519_euler.pub"
if (-not (Test-Path $PublicKey)) { throw "Missing public key: $PublicKey" }
Get-Content $PublicKey | ssh "$User@euler.ethz.ch" 'umask 077; mkdir -p ~/.ssh; chmod 700 ~/.ssh; touch ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys; key="$(cat)"; if ! grep -Fqx "$key" ~/.ssh/authorized_keys; then if [ -s ~/.ssh/authorized_keys ] && [ "$(tail -c 1 ~/.ssh/authorized_keys | wc -l | tr -d " ")" -eq 0 ]; then printf "\n" >> ~/.ssh/authorized_keys; fi; printf "%s\n" "$key" >> ~/.ssh/authorized_keys; fi'
Enter the ETH password when prompted. Only the .pub file is sent.
macOS or Linux laptop - zsh/Bash#
(
set -eu
printf 'ETH username: '
read -r eth_user
public_key="$HOME/.ssh/id_ed25519_euler.pub"
test -f "$public_key"
cat "$public_key" | ssh "$eth_user@euler.ethz.ch" \
'umask 077; mkdir -p ~/.ssh; chmod 700 ~/.ssh; touch ~/.ssh/authorized_keys; chmod 600 ~/.ssh/authorized_keys; key="$(cat)"; if ! grep -Fqx "$key" ~/.ssh/authorized_keys; then if [ -s ~/.ssh/authorized_keys ] && [ "$(tail -c 1 ~/.ssh/authorized_keys | wc -l | tr -d " ")" -eq 0 ]; then printf "\n" >> ~/.ssh/authorized_keys; fi; printf "%s\n" "$key" >> ~/.ssh/authorized_keys; fi'
)
Repeated installation does not add a duplicate exact public-key line. Ask for
help before manually editing authorized_keys.
4. Prove Public-Key Authentication Works#
This test disables password and keyboard-interactive fallback. A key passphrase prompt is expected; an ETH password prompt is not.
Windows laptop - PowerShell#
$User = Read-Host "ETH username"
$KeyPath = Join-Path $env:USERPROFILE ".ssh\id_ed25519_euler"
ssh -i $KeyPath -o IdentitiesOnly=yes -o PreferredAuthentications=publickey -o PasswordAuthentication=no -o KbdInteractiveAuthentication=no "$User@euler.ethz.ch" "echo key-ok"
macOS or Linux laptop - zsh/Bash#
read -r -p "ETH username: " eth_user
ssh -i "$HOME/.ssh/id_ed25519_euler" \
-o IdentitiesOnly=yes \
-o PreferredAuthentications=publickey \
-o PasswordAuthentication=no \
-o KbdInteractiveAuthentication=no \
"$eth_user@euler.ethz.ch" "echo key-ok"
Expected output: key-ok.
Do not continue to euler-tunnel until this test passes.
5. Add A Safe euler Alias#
The procedure validates and backs up an existing config, writes the Euler host to a separate include file, and does not replace unrelated host blocks.
Windows laptop - PowerShell#
& {
$User = Read-Host "ETH username"
$SshDir = Join-Path $env:USERPROFILE ".ssh"
$Config = Join-Path $SshDir "config"
$IncludeDir = Join-Path $SshDir "config.d"
$EulerConfig = Join-Path $IncludeDir "euler.conf"
New-Item -ItemType Directory -Force $IncludeDir | Out-Null
if (Test-Path $Config) {
ssh -G euler.ethz.ch | Out-Null
if ($LASTEXITCODE -ne 0) { throw "Existing SSH config is invalid. Stop and repair it before continuing." }
Copy-Item $Config "$Config.backup.$(Get-Date -Format yyyyMMdd-HHmmss)"
}
if (Test-Path $EulerConfig) {
Copy-Item $EulerConfig "$EulerConfig.backup.$(Get-Date -Format yyyyMMdd-HHmmss)"
}
@"
Host euler
HostName euler.ethz.ch
User $User
IdentityFile ~/.ssh/id_ed25519_euler
IdentitiesOnly yes
ForwardAgent no
"@ | Set-Content $EulerConfig -Encoding ascii
$Include = "Include ~/.ssh/config.d/*"
if (-not (Test-Path $Config)) {
Set-Content $Config $Include -Encoding ascii
} elseif (-not (Select-String -Path $Config -SimpleMatch $Include -Quiet)) {
$OldConfig = Get-Content $Config -Raw
Set-Content $Config "$Include`r`n$OldConfig" -Encoding ascii
}
ssh -G euler | Select-String '^(hostname|user|identityfile|identitiesonly) '
}
macOS or Linux laptop - zsh/Bash#
(
set -eu
printf 'ETH username: '
read -r eth_user
ssh_dir="$HOME/.ssh"
config="$ssh_dir/config"
include_dir="$ssh_dir/config.d"
mkdir -p "$include_dir"
chmod 700 "$ssh_dir" "$include_dir"
if [ -f "$config" ]; then
ssh -G euler.ethz.ch >/dev/null
cp -p "$config" "$config.backup.$(date +%Y%m%d-%H%M%S)"
fi
if [ -f "$include_dir/euler.conf" ]; then
cp -p "$include_dir/euler.conf" \
"$include_dir/euler.conf.backup.$(date +%Y%m%d-%H%M%S)"
fi
cat > "$include_dir/euler.conf" <<EOF
Host euler
HostName euler.ethz.ch
User $eth_user
IdentityFile ~/.ssh/id_ed25519_euler
IdentitiesOnly yes
ForwardAgent no
EOF
chmod 600 "$include_dir/euler.conf"
include='Include ~/.ssh/config.d/*'
if [ ! -f "$config" ]; then
printf '%s\n' "$include" > "$config"
elif ! grep -Fqx "$include" "$config"; then
temporary="$config.passport-new"
{ printf '%s\n' "$include"; cat "$config"; } > "$temporary"
mv "$temporary" "$config"
fi
chmod 600 "$config"
ssh -G euler | grep -E '^(hostname|user|identityfile|identitiesonly) '
)
Final Verification#
Run on your local computer:
ssh euler "echo config-ok"
Expected output: config-ok, after at most the SSH key passphrase prompt.
Common Failures And Safe Recovery#
Bad configuration optionorextra arguments at end of line: stop. Use the backup created above and inspect the line named in the error. Do not append another host block to the broken line.- Warning names a file ending in
.pubas a private key:IdentityFileis wrong. It must point toid_ed25519_euler, never.pub. - Public-key-only test says
Permission denied: the public key is not installed correctly, the username is wrong, or permissions are wrong. Do not regenerate another key yet. - Timeout: connect to ETH VPN and retry.
Ask For Help When#
The password login works but the public-key-only test does not, the existing SSH
config fails validation, or the private key permissions cannot be restricted.
Share only sanitized output from ssh -v; never share the private key.
Primary Sources#
Verified: 2026-08-04. Review by: 2026-11-04. Owner: IDEAL Lab IT.