Linux: Say Goodbye to Complexity! Unlocking the Magical Uses of the SSH `config` File

As an operations development engineer, <span>SSH</span> is a command we use almost every day. We use it to connect to remote servers for code deployment, log viewing, and various system management tasks. But are we still manually typing long <span>ssh</span> commands like <span>ssh -p 2222 -i ~/.ssh/my_key [email protected]</span>? If we manage dozens or even hundreds of servers, this repetitive work is not only inefficient but also prone to errors.

Today, I will guide you to unlock the powerful configuration file <span>~/.ssh/config</span>. With simple configurations, we can simplify complex connection commands to <span>ssh myserver</span>, and also achieve advanced features like bastion host proxying and connection multiplexing, greatly enhancing our work efficiency and satisfaction.

Linux: Say Goodbye to Complexity! Unlocking the Magical Uses of the SSH `config` File

Understanding the <span>.ssh/config</span> File

The SSH client reads configuration information in the following order when attempting to establish a connection:

  1. Command line options
  2. User configuration file <span>~/.ssh/config</span>
  3. System-wide configuration file <span>/etc/ssh/ssh_config</span>

This order means that configurations in the user-defined <span>~/.ssh/config</span> file will override the system-wide default configurations, while options specified on the command line take the highest priority.

The basic syntax of the configuration file is very simple, consisting of keywords and parameter values, which can be separated by spaces or <span>=</span>. The file content is organized into <span>Host</span> blocks, with each <span>Host</span> block defining a set of exclusive configurations for one or more hosts.

# This is a comment
Host <alias>
    HostName <actual hostname or IP>
    User <username>
    Port <port number>
# More configurations...

Basic Configuration: The Art of Simplification

Let’s start with the most common configurations and see how to make lengthy commands elegant.

Setting Aliases for Servers

Suppose we have a development server with the following connection information:

  • IP Address: <span>198.51.100.1</span>
  • User: <span>dev</span>
  • Port: <span>10022</span>
  • Private Key: <span>~/.ssh/dev_key</span>

Every time we connect, we need to enter:<span>ssh -p 10022 -i ~/.ssh/dev_key [email protected]</span>.

Now, we can add the following configuration in the <span>~/.ssh/config</span> file (create it manually if it doesn’t exist):

Host dev-server
    HostName 198.51.100.1
    User dev
    Port 10022
    IdentityFile ~/.ssh/dev_key

Once configured, connecting to the server only requires a simple command:

ssh dev-server

Isn’t it much cleaner now?

Common Basic Command Explanations

  • <span>Host</span>: Defines the start of a configuration block, followed by one or more patterns (aliases). Wildcards can be used, such as <span>*</span> to match all hosts, and <span>?</span> to match a single character.
  • <span>HostName</span>: Specifies the actual remote hostname or IP address.
  • <span>User</span>: Specifies the username for login.
  • <span>Port</span>: Specifies the port number for connection, defaulting to 22.
  • <span>IdentityFile</span>: Specifies the path to the private key file used for authentication. Multiple keys can be specified, and SSH will try them in order.
  • <span>IdentitiesOnly</span>: When set to <span>yes</span>, the SSH client will only use the keys specified in <span>IdentityFile</span> for authentication, even if there are other available keys in <span>ssh-agent</span>. This is very useful when too many keys cause authentication failures.

Advanced Techniques: Doubling Operational Efficiency

After mastering the basic configurations, let’s look at a few advanced techniques that can double our efficiency.

Technique 1: Seamless Connection via Bastion Host

In many production environments, for security reasons, we cannot directly access internal servers and must first log into a server acting as a “bastion host” or “jump server” before connecting to the target server. The <span>ProxyJump</span> directive (requires OpenSSH 7.3+ version) makes this process exceptionally simple.

Assuming the architecture is as follows:

  • Our local machine -> Bastion Host -> Internal Server
# Bastion Host Configuration
Host bastion
    HostName bastion.example.com
    User jumpuser
    IdentityFile ~/.ssh/bastion_key

# Internal Application Server Configuration
Host internal-app
    HostName 10.0.1.10
    User app_admin
    ProxyJump bastion
    IdentityFile ~/.ssh/internal_key

Once configured, we can execute <span>ssh internal-app</span> directly from our local machine, and the SSH client will automatically connect to <span>bastion</span> first, then establish a tunnel to <span>internal-app</span>. The entire process is completely transparent to the user, just like a direct connection.

For older versions of OpenSSH, you can use <span>ProxyCommand</span> to achieve similar functionality, but the configuration is slightly more complex:

Host internal-app
    HostName 10.0.1.10
    User app_admin
    ProxyCommand ssh bastion -W %h:%p

Below is a diagram illustrating the workflow of <span>ProxyJump</span>:

Linux: Say Goodbye to Complexity! Unlocking the Magical Uses of the SSH `config` File

Technique 2: Reusing Connections with <span>ControlMaster</span>

Have you ever encountered a situation where you are already connected to a server and need to open another terminal to execute <span>scp</span> or <span>rsync</span> commands, only to go through the entire authentication and connection process again, which is especially time-consuming on a poor network?

<span>ControlMaster</span> functionality allows subsequent SSH connections to share the same established network connection, thus skipping the handshake and authentication steps, enabling instant new sessions.

Add the following configuration in <span>~/.ssh/config</span> to enable connection reuse for all hosts:

Host *
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h:%p
    ControlPersist 10m
  • <span>ControlMaster auto</span> automatically opens or uses an existing master connection.
  • <span>ControlPath</span> specifies the path for the Unix socket file used for communication. <span>%r</span> represents the remote username, <span>%h</span> represents the hostname, and <span>%p</span> represents the port, ensuring each connection has a unique socket file.
  • <span>ControlPersist 10m</span> keeps the master connection alive in the background for 10 minutes even after the initial SSH session closes, facilitating subsequent connection reuse.

Now, when we first <span>ssh</span> to a server, we can immediately open a new terminal and use <span>ssh</span> or <span>scp</span> again, and we will find the connection established instantly, greatly enhancing the interactive experience.

Technique 3: Keep Connections Alive, Say Goodbye to “Disconnects”

When connecting to some inactive servers, you may be disconnected due to timeout policies of intermediate network devices (like firewalls or NAT). By setting up heartbeat packets, you can effectively avoid this situation.

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
  • <span>ServerAliveInterval 60</span> sends a “heartbeat” message from the client to the server every 60 seconds, requesting a response.
  • <span>ServerAliveCountMax 3</span> if the client does not receive a response from the server for 3 consecutive times, it considers the connection to be broken.

Practical Tips and Best Practices

  1. Organize in Blocks and Use Wildcards Group configurations for specific projects or environments together. Use <span>Host *</span> to place common configurations (like <span>ControlMaster</span>, <span>ServerAliveInterval</span>) at the end of the file so they can be overridden by the specific configurations above.
  2. Security First Never store passwords in plain text in configuration files. Always prioritize key-based authentication.
  3. Version Compatibility<span>ProxyJump</span> is a convenient feature of modern OpenSSH, but when interacting with older systems, <span>ProxyCommand</span> remains a reliable alternative.
  4. Keep It Clean Regularly clean up unused configurations to keep our <span>config</span> file clear and readable.

Conclusion

<span>~/.ssh/config</span> is far more than just a simple alias tool; it is a powerful efficiency amplifier. By mastering its configuration techniques, whether simplifying daily connections or handling complex network environments, we can navigate with ease. Spend some time organizing our <span>config</span> file, and it will save us a lot of time and effort in our future work.

Now, let’s open our terminal and start building our own efficient SSH workflow!

Leave a Comment