How to Configure SSH to Use Environment Variables for Custom Config File Location


11 views

When managing multiple Linux clients and remote servers, maintaining consistent SSH configurations across machines becomes crucial. The traditional approach of using -F flag with every SSH command creates friction when working with SSH-dependent tools like rsync, scp, or git.

While SSH doesn't directly support environment variables for config file paths, we have several effective workarounds:

Solution 1: SSH_CONFIG Environment Variable

Create a wrapper script for ssh that checks an environment variable:

#!/bin/bash
# ~/workspace/bin/ssh_wrapper
if [ -n "$SSH_CONFIG_FILE" ]; then
    /usr/bin/ssh -F "$SSH_CONFIG_FILE" "$@"
else
    /usr/bin/ssh "$@"
fi

Solution 2: PATH Modification with Wrapper

Prepend your custom directory to PATH in your bashrc:

# In workspace/bashrc
export PATH=~/workspace/bin:$PATH
export SSH_CONFIG_FILE=~/workspace/etc/ssh_config

For rsync and similar tools, create corresponding wrappers:

#!/bin/bash
# ~/workspace/bin/rsync_wrapper
if [ -n "$SSH_CONFIG_FILE" ]; then
    /usr/bin/rsync -e "ssh -F $SSH_CONFIG_FILE" "$@"
else
    /usr/bin/rsync "$@"
fi

For more permanent solutions, consider these approaches:

# Option 1: Symlink default config location
ln -s ~/workspace/etc/ssh_config ~/.ssh/config

# Option 2: Include directive in main config
echo "Include ~/workspace/etc/ssh_config" >> ~/.ssh/config

Your shared ssh_config might contain:

Host server1
    HostName server1.example.com
    User admin
    Port 2222
    IdentityFile ~/workspace/keys/server1_key
    ServerAliveInterval 60

Enhance your rsync script to maintain permissions:

#!/bin/bash
rsync -avz --delete --perms --chmod=600 \
    ~/workspace/etc/ssh_config \
    other-client:~/workspace/etc/

Consider storing your workspace in git for better change tracking:

cd ~/workspace
git init
echo "etc/ssh_config" >> .gitignore  # if containing sensitive data
git add bin/ bashrc
git commit -m "Initial workspace setup"

As a Linux sysadmin juggling multiple client machines (all running Debian in my case), maintaining consistent SSH configurations across devices becomes crucial. My current setup involves:

~/workspace/
├── bashrc
└── etc/
    └── ssh_config

The challenge emerges when non-interactive SSH commands (rsync, scp, etc.) need to reference my custom configuration. While interactive SSH works perfectly with aliases like:

alias s1='ssh -F ~/workspace/etc/ssh_config server1.example.com'

Other tools force verbose command-line specifications:

rsync -Pavz --delete -e "ssh -F $HOME/workspace/etc/ssh_config" ...

OpenSSH actually provides multiple ways to handle this without environment variables:

  1. System-wide configuration: Place your config in /etc/ssh/ssh_config.d/
  2. XDG Base Directory Specification: Use ~/.config/ssh/config
  3. SSH_CONFIG environment variable: Sadly doesn't exist (contrary to popular belief)

Here are three battle-tested approaches I've implemented:

1. Symbolic Link Strategy

ln -s ~/workspace/etc/ssh_config ~/.ssh/config

Pros:

  • Zero configuration changes needed in commands
  • Works with all SSH-based utilities

2. SSH Wrapper Function

Add to your bashrc:

ssh() {
    command ssh -F ~/workspace/etc/ssh_config "$@"
}

3. RSYNC_RSH Environment Variable

For rsync specifically:

export RSYNC_RSH="ssh -F $HOME/workspace/etc/ssh_config"

For teams managing multiple environments:

#!/bin/bash
# sync-ssh-config.sh
CONFIG_REPO="git@github.com:ourteam/ssh-configs.git"

pull_latest() {
    git -C ~/workspace/etc/ pull origin main
}

deploy_all() {
    ln -sf ~/workspace/etc/ssh_config ~/.ssh/config
    ln -sf ~/workspace/etc/ssh_config /etc/ssh/ssh_config.d/99_our_config
}

Remember to:

  • Set strict permissions: chmod 600 ~/workspace/etc/ssh_config
  • Use Include directives for machine-specific overrides
  • Consider SSH certificate authentication for large deployments

Example config snippet:

Host *.example.com
    IdentityFile ~/workspace/keys/production_key
    CertificateFile ~/workspace/keys/production_key-cert.pub
    Include ~/workspace/etc/ssh_config.d/region-specific