When running autossh with the -f
flag for background operation, many users encounter a perplexing issue where SSH suddenly can't find the specified identity file. Here's what's happening under the hood:
# Working foreground command
autossh -M 33201 -N -i /path/to/myIdFile -R 33101:localhost:22 user@host.com
# Failing background command
autossh -f -M 33201 -N -i /path/to/myIdFile -R 33101:localhost:22 user@host.com
The problem stems from how autossh
handles daemonization and environment variables. When using -f
, the process:
- Drops privileges and changes working directory
- Loses access to relative path identity files
- May have different environment variables than your shell
Solution 1: Absolute Paths Everywhere
autossh -f -M 33201 -N \
-i /absolute/path/to/myIdFile \
-R 33101:localhost:22 \
user@host.com
Solution 2: Systemd Service File
[Unit]
Description=AutoSSH tunnel service
After=network.target
[Service]
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh -M 0 -N \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-i /etc/ssh/tunnel_key \
-R 33101:localhost:22 \
user@host.com
Restart=always
[Install]
WantedBy=multi-user.target
When standard debugging fails, try these approaches:
# Method 1: Log to file
autossh -f -M 33201 -N -E /var/log/autossh.log -v \
-i /path/to/key ...
# Method 2: Test without fork first
autossh -M 33201 -N -v -i /path/to/key ... > debug.log 2>&1
For reliable background operation, combine these best practices:
autossh -f -M 0 \
-o "ExitOnForwardFailure=yes" \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-i ~/.ssh/tunnel_key \
-N -R 33101:localhost:22 \
-L 33102:remote:3306 \
user@host.com
When running autossh in foreground mode, everything works perfectly:
autossh -M 33201 -N -i ~/.ssh/myIdFile -R 33101:localhost:22 autossh@myhost.com
But when adding the -f
flag to run in background, authentication suddenly fails:
autossh -f -M 33201 -N -i ~/.ssh/myIdFile -R 33101:localhost:22 autossh@myhost.com
Adding the -y
option to log ssh debug output reveals the issue:
debug1: Trying private key: /home/myuser/.ssh/id_rsa
debug1: Trying private key: /home/myuser/.ssh/id_dsa
debug1: Trying private key: /home/myuser/.ssh/id_ecdsa
debug1: No more authentication methods to try.
Notice how it's not even attempting to use the specified key file (myIdFile
). This suggests a permissions or path resolution issue when running in background mode.
Option 1: Use Absolute Paths
The most reliable fix is to use absolute paths for both the key file and the known_hosts file:
autossh -f -M 33201 -N \
-i /home/myuser/.ssh/myIdFile \
-o UserKnownHostsFile=/home/myuser/.ssh/known_hosts \
-R 33101:localhost:22 autossh@myhost.com
Option 2: Environment Variables
Alternatively, you can set the SSH_AUTOSSH_DEBUG and SSH_AUTOSSH_LOGFILE environment variables:
export AUTOSSH_LOGFILE=/tmp/autossh.log
export AUTOSSH_DEBUG=1
autossh -f -M 33201 -N -i ~/.ssh/myIdFile -R 33101:localhost:22 autossh@myhost.com
When autossh runs in background mode (-f
), it spawns a child process that may lose access to:
- Relative paths
- Environment variables
- SSH agent connections
For persistent cases, try:
# Check process environment
cat /proc/$(pgrep autossh)/environ | tr '\\0' '\\n'
# Verify key permissions
stat -c "%a %n" ~/.ssh/myIdFile
# Test SSH connection directly
ssh -v -i ~/.ssh/myIdFile autossh@myhost.com
Remember that key files typically need 600 permissions and the .ssh directory 700.