banner
niracler

niracler

长门大明神会梦到外星羊么?
github
email
steam_profiles
douban
nintendo switch
tg_channel
twitter_id

Encrypt your SSH private key on your personal computer in three minutes - v1.0

Background - Why Use SSH Keys and Encrypt Them?#

Let's start with three reasons. If you don't want to read them, you can skip to the operation steps (which take less than 2 minutes).

First - Use SSH Keys Instead of Passwords#

In our daily work, we frequently deal with tools like git, rsync, and ssh. The traditional password authentication method can be cumbersome and vulnerable to attacks. Here are some potential issues:

  • Risk of eavesdropping: Traditional password input methods can be observed by onlookers, compromising security. Using SSH keys eliminates the need for password input, greatly reducing the risk of eavesdropping.
  • Complexity of password management: Using different passwords on multiple remote servers can lead to confusion and forgetfulness. With SSH keys, you only need to manage a few key pairs, simplifying password management.
  • Security of remote servers: Logging into remote servers with passwords exposes them to the risk of easy attacks by malicious actors. Using SSH keys makes it more difficult for attackers to forge identities and access remote servers, enhancing security.

Second - Encrypt SSH Private Keys in All Cases#

Even when using SSH keys, it is important to protect the private key. Don't take the convenience route and leave your SSH private key unencrypted. Many people do this, right?

  • Private key is the core of authentication: It is equivalent to the master key for your system and data. If the private key is exposed, malicious actors may access your system, steal sensitive information, or perform unauthorized operations by impersonating you.
  • Private key may exist in insecure environments: Whether on a local computer, mobile device, or transmitted over a network, these environments are insecure. By encrypting the private key, even if it is accessed without authorization, your data and system will not be immediately exposed.
  • In case of theft, loss, or unauthorized access to the device: Encrypted private keys provide an additional layer of security. Even if an attacker gains access to the private key file, its encrypted state will hinder direct use.
  • Malware and viruses: They may scan your system for unencrypted private key files. For example, many people have pirated software on their computers, right? If the private key is encrypted, they cannot easily obtain sensitive information, reducing the risk of attacks.

Sometimes people even conveniently transmit plaintext private keys through QQ or other means, which is actually very dangerous. It's a plaintext private key, after all.

Third - Reduce Password Input with SSH-Agent#

Using an encrypted private key alone does not completely solve the problem of password input. It simply replaces all your passwords with a single password. We don't want to enter the private key password every time we git pull, right? So, to solve the inconvenience of frequent password input and the risk of password leakage, we introduce SSH-Agent here.

It can temporarily store decrypted private keys, allowing users to enter the password only once at the beginning of a session. Subsequent connections will automatically use the decrypted private key. This greatly reduces the number of password inputs and avoids the possibility of passwords being observed or intercepted. For users who need to interact frequently with multiple remote servers, SSH-Agent can significantly improve work efficiency.

BOSS quote: The agent essentially loads the key into memory. There is a possibility of memory leakage of the key, but it requires complex methods, vulnerabilities, and certain permissions. Moreover, modern operating systems have address space layout randomization to resist this.

Operation Steps#

Encrypt the Local Private Key#

Assuming you already have an existing SSH key pair locally (those who use GitHub should have one, if not, you can generate one using ssh-keygen or refer to the SSH-related articles at the end of this document).

The following command is used to encrypt the local private key (<id_rsa_path> is the path to your local SSH private key, usually ~/.ssh/id_rsa):

ssh-keygen -p -f <id_rsa_path>

Alright, encryption is complete. The next step is to start the ssh-agent.

Use SSH-Agent to Manage Decrypted Private Keys#

Here is a simple shell code to start ssh-agent and load your default key pair on your computer into the agent:

if [ -z "$SSH_AUTH_SOCK" ] ; then
    eval `ssh-agent`
    ssh-add # <id_rsa_path>, add if you want to use a specific path
fi

However, this method has some issues. If you open a new shell session, the agent needs to be restarted, and if you don't close the agent when your previous session ends, it will continue running as a process on your computer.

Persist SSH-Agent Settings for Convenience and Security#

⚠️⚠️⚠️ Note: This solution is only suitable for personal computers. ⚠️⚠️⚠️

To address the above issues, we recommend adding the SSH-Agent startup settings to your shell configuration file so that SSH-Agent is automatically started and your private key is loaded every time you open a terminal session. This provides greater convenience and security.

Here is an example code snippet to add to your ~/.bashrc or ~/.bash_profile file (for zsh, it's ~/.zshrc or ~/.zprofile; personally, I recommend putting it in the rc file since the mechanism to trigger a login shell is often not met):

For fish shell, see here

Add the following code to the file ~/.config/fish/config.fish:

set SSH_ENV_FILE "$HOME/.ssh/agent-environment"
set SSH_TIMEOUT 86400 # 24 hours in seconds

function ssh_start_agent
    ssh-agent -c -t "$SSH_TIMEOUT" > "$SSH_ENV_FILE"
    chmod 600 "$SSH_ENV_FILE"
    source "$SSH_ENV_FILE"
    ssh-add # [<id_rsa_path>] Change to your path
end

if test -f "$SSH_ENV_FILE"
    source "$SSH_ENV_FILE"
    if not ps -p "$SSH_AGENT_PID" > /dev/null
        ssh_start_agent
    end
else
    ssh_start_agent
end
SSH_ENV_FILE="$HOME/.ssh/agent-environment"
SSH_TIMEOUT=86400 # 24 hours in seconds

ssh_start_agent(){
    ssh-agent -t $SSH_TIMEOUT | sed 's/^echo/#echo/' > "${SSH_ENV_FILE}"
    echo "Initialising new SSH agent succeeded"
    chmod 600 "${SSH_ENV_FILE}"
    . "${SSH_ENV_FILE}"
    ssh-add # [<id_rsa_path>] Change to your path
}

if [ -f "${SSH_ENV_FILE}" ]; then
    . "${SSH_ENV_FILE}"
    if ! ps -p "$SSH_AGENT_PID" > /dev/null; then
        start_ssh_agent
    fi
else
    ssh_start_agent
fi

(This is a highly-rated example from Stack Overflow, with a slight modification to the expiration time. If your computer is always on, you only need to enter the password once a day. Although there may be issues with SSH forwarding, it is more than sufficient for personal computers.)

This code will check if SSH-Agent is running every time you start a shell session. If it is not running, it will automatically start and load your private key. This way, you will always enjoy the convenience and security provided by SSH-Agent. (If you don't understand it, you can try using ChatGPT. The key is to store the SSH-Agent's SSH_AUTH_SOCK and other information in a file so that other shell sessions can read it.)

Alright, that's all for the operations.

Considerations When Using ssh-agent#

Of course, using ssh-agent doesn't mean you are completely secure and have no concerns. There are still some issues to consider when using ssh-agent:

  1. Do not run ssh-agent on a computer where others have root privileges: If you run ssh-agent on a computer with lower trust level, malicious users may access your private data through ssh-agent, compromising your security. (Also, remember to lock your screen when not using the computer, and avoid running it on shared computers.)
  2. Use caution with agent connection forwarding: ssh-agent allows agent connection forwarding, which is convenient in certain situations. However, you should only forward agent connections to trusted computers to prevent your private data from being accessed by untrusted hosts.
  3. Unload keys and agent when logging out: When you log out of your computer or exit a shell session, make sure to unload the keys and ssh-agent to prevent unauthorized access. You can use the command ssh-agent -k to achieve this.

When using ssh-agent, please follow the above considerations to ensure the security of your private data and system.

Afterword#

In fact, managing SSH keys is not limited to ssh-agent. You can also try using the 1Password CLI, although I haven't used it much.

This article is just a record of my personal security practices and may be redundant for some. It will likely become a series in the future, the CyberSecurity series, to apply my knowledge of network security in daily life.

Note: The content described in this article represents personal opinions and experiences, and is not an absolute security recommendation. For more detailed and professional security advice, consult security experts or relevant literature.

References#

  1. SSH Tutorial - WangDoc: For basic knowledge about SSH, you can refer to this tutorial by Ruanyifeng.
  2. Using ssh-agent and How to Safely Enter Your Password Once: This article mentions the scenario of ssh-agent forwarding in a bastion host, which I didn't cover in this article.
  3. Pitfalls of ssh-agents and How to Use Them Safely: Written by the same author as the previous article, it discusses some considerations when using ssh-agent.

Updates#

  • 2023-08-17 19:11 v0.7 Added fish version of the code.
  • 2023-08-22 22:17 v0.8 Received feedback from a colleague that there were too many bold parts, making the article look too fancy and affecting the reading experience. Revised accordingly.
  • 2023-08-22 23:05 v1.0 Made minor adjustments and removed some unnecessary content. It should be passable now.
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.