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


4 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