How to Auto-Start the SSH Agent
Headless1 servers usually do not have an SSH agent service pre-installed. To keep SSH keys in memory for convenience while working on the server, an SSH agent must be started by the user manually. However, the lifespan of the SSH agent is not tied to the current session, so the process remains active even after the user session ends. The connection parameters, on the other hand, are lost after the session if only stored in environment variables. Additionally, using multiple instances of agent may be undesirable as each instance may have different keys loaded into memory, requiring multiple password inputs.
In this article, I explain how the SSH agent can be used on a headless server without needing to start a new instance manually with each new session.
In my previous article “Tips and Tricks: SSH”, I give more details on configuring SSH with cryptographic keys.
Usage Modes of ssh-agent
The command ssh-agent
starts the ssh agent service. This command usually offers two usage modes:
ssh-agent
starts a permanently running background service, prints the connection parameter on the console and terminates.ssh-agent command [arg ...]
starts an SSH agent in the background and runs the commandcommand
with the given arguments. This started child process receives the connection parameters from its parent. The SSH agent terminates as soon as the child process terminates.
Usage of ssh-agent
as Background Service
The following session protocol shows that ssh-agent
starts a background process with the same name, prints the connection parameters and returns the control flow back to the user.
|
|
According to the manual, this mode is for login sessions. The output of ssh-agent
is valid shell code and can be evaluated with the builtin eval
, whereby the connection parameter are made available to the current session as environment variables.
Usage of ssh-agent
as Parent Process
This mode is usually used as parent process for an X session. When ssh-agent
receives positional arguments, it will start an SSH agent in the background, setups the environment with the connection parameters and executes the command with the given arguments as a child process. This child process will inherit the environment of its parent process, so it also receives the environment variables with the connection parameters.
The following session protocol visualizes this behaviour. Since the command ssh-agent
is started with the argument bash
, a new interactive shell opens. Therefore, the process IDs differ before and after the execution of ssh-agent bash
. Within this interactive shell, the necessary connection parameters are available and the SSH agent process is running in the background. After the user exits the session, the user returns to the original session, the environment variables with the connection parameters are empty and the SSH agent terminated as well.
|
|
System Configuration
This chapter contains a few possible system configurations that
- start the SSH agent in the background without user intervention, and
- only start at most one SSH agent per user/session.
Script to start an instance of ssh-agent
The basic idea is to store the connection parameter of ssh-agent
in a file and load this file every time a new session is opened. Since the connection parameters could be out-of-date or invalid, a few checks are required. The following code block contains a possible implementation.
|
|
This code reads the connection parameters of the SSH agent from the file ~/.local/state/ssh/ssh_agent_env
. If this file does not exist or the given process ID is invalid, a new agent process is started and the file content is overwritten by the new connection parameters. Finally, the configured keys are loaded automatically in memory if the value of the AddKeysToAgent
setting is not yes
.
To automatically start an SSH agent in the background, this script can be loaded in ~/.bashrc
, so the current configuration parameters are available in every new command line session.
The configuration AddKeysToAgent yes
in the user or system configuration (cf. “SSH-Client Configuration”) results in automatically loading the key in the agent when it is used. In this case, ssh-add
does not has to be executed in advance.
SSH Agent as System Service
Instead starting ssh-agent
with the above-mentioned script, it can also be started and maintained with systemd. systemd is a system program that is, among others, responsible for the administration of background services in the majority of current Linux distributions.
Services in systemd are registered with a configuration file. These configuration files are usually stored by the system administrator in the directory /etc/systemd/system
. Regular users who usually do (should) not have write permissions in /etc
can also define their own services by storing configuration files in ~/.config/systemd/user
. If this directory does not yet exist, it must be created first.
The following shell code sets up an SSH agent service with systemd:
|
|
Here, the service ssh-agent
is provided with an uniquely determined path for the socket. %t
stands for the directory where runtime data for the current user is stored. This corresponds to the value of the environment variable $XDG_RUNTIME_DIR
. When the user logs in, the service is started automatically and the runtime of the background service can be manually controlled with the usual systemd commands.
Next, the user has to manually configure the value of the environment variable $SSH_AUTH_SOCK
, so the SSH clients in the new sessions can connect to the SSH agent background process. One possibility to configure this is:
|
|
The files in the directory environment.d contain definitions of environment variables and will be loaded by systemd during startup. After reloading the systemd services, the new service can be enabled:
|
|
This solution was proposed in StackExchange Unix&Linux.
IT Security Considerations
To minimize the possibility of misuse, it is recommended to configure a timeout for the keys. The applications ssh-agent
and ssh-add
offer the option -t
with which the user can set a time in seconds that the unlocked keys should remain in memory.
Servers without graphical user interfaces ↩︎