LFCA 52 ๐ง SSH Keys โ Generating and Using
The previous chapter covered connecting with SSH โ the commands, the file transfers, and the configuration. This chapter goes deeper into the authentication itself: the key pairs that replace the password with the cryptographic proof. A key pair is two mathematically linked files โ the private key that stays on the client and the public key that is copied to the server. The server grants the access only to the connections that can prove they hold the private key, and the proof never sends the private key across the network. This is the modern’s authentication, and it is more secure than the password for the three reasons: the private key is not guessable, the server never sees the secret, and the key can be protected by the passphrase. This chapter covers the key’s generation, the algorithm’s choice, the ssh-copy-id‘s, the manual’s authorized_keys, the permissions’s, the ssh-agent‘s, the passphrase’s, the key’s rotation, the known_hosts, the authorized_keys‘s options, and the patterns that make the key’s management safe.
Key point: The ssh-keygen -t ed25519 -C "comment" is the generation’s, and the Ed25519 is the modern’s algorithm. The ~/.ssh/id_ed25519 is the private’s, and the ~/.ssh/id_ed25519.pub is the public’s. The ssh-copy-id user@host is the copy’s, and the copy’s is the server’s ~/.ssh/authorized_keys‘s. The private’s permission is the 600‘s, the ~/.ssh‘s is the 700‘s, and the authorized_keys‘s is the 600‘s. The ssh-agent‘s is the passphrase’s cache’s, and the ssh-add‘s is the key’s addition’s. The authorized_keys‘s options are the from=, the command=, the no-pty, the no-port-forwarding, the restrict‘s. The known_hosts‘s is the server’s identity’s, and the ssh-keygen -R host is the entry’s removal’s.
Why the SSH keys matter
The SSH keys are the modern’s authentication’s, and the modern’s is the secure’s.
The password’s weaknesses. The password is the guessable’s, the reuse’s, the brute-forceable’s. The ssh‘s password is the network’s, and the network’s is the MITM’s. The password’s is the server’s, and the server’s is the exposure’s.
The key’s strengths. The key’s is the cryptographic’s, and the cryptographic’s is the unguessable’s. The key’s is the two’s, and the two’s is the private’s and the public’s. The key’s is the server’s never’s, and the never’s is the safety’s.
Why the keys are the standard. The keys are the standard, and the standard is the modern’s. The GitHub, the GitLab, the cloud’s, the server’s are the keys’s, and the keys’s is the universal’s. The two are the pair, and the pair is the design’s.
Why the keys matter for the automation. The keys matter for the automation, and the automation’s is the script’s. The scp, the rsync, the git, the ansible are the keys’s, and the keys’s is the passwordless’s. The two are the pair, and the pair is the efficiency’s.
Why the keys matter for the security. The keys matter for the security, and the security’s is the password’s disabling’s. The PasswordAuthentication no is the keys’s, and the keys’s is the only’s. The two are the pair, and the pair is the design’s.
Why the keys matter for the compliance. The keys matter for the compliance, and the compliance’s is the audit’s. The PCI-DSS, the HIPAA, the SOC 2 are the keys’s, and the keys’s is the requirement’s. The two are the pair, and the pair is the design’s.
Why the keys matter for the scale. The keys matter for the scale, and the scale’s is the fleet’s. The thousands’s servers are the keys’s, and the keys’s is the automation’s. The two are the pair, and the pair is the efficiency’s.
Why the keys matter for the rotation. The keys matter for the rotation, and the rotation’s is the lifecycle’s. The keys’s is the periodic’s, and the periodic’s is the rotation’s. The two are the pair, and the pair is the design’s.
Why the keys are the better’s. The keys are the better’s, and the better’s is the password’s. The keys’s is the cryptographic’s, and the cryptographic’s is the stronger’s. The two are the pair, and the pair is the design’s.
The key’s generation
The ssh-keygen -t ed25519 -C "comment" is the generation’s, and the generation’s is the pair’s.
ssh-keygen -t ed25519 -C "user@host"
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (/home/user/.ssh/id_ed25519):
# Enter passphrase (empty for no passphrase):
# Enter same passphrase again:
# Your identification has been saved in /home/user/.ssh/id_ed25519
# Your public key has been saved in /home/user/.ssh/id_ed25519.pub
# The key fingerprint is:
# SHA256:abcdef... user@host
# The key's randomart image is:
# +--[ED25519 256]--+
# | .o. |
# | . . . |
# | o . |
# | . + . |
# | S + . |
# | . . . |
# | . |
# +----[SHA256]-----+
The ssh-keygen -t ed25519 -C "user@host" is the generation’s, and the generation’s is the pair’s. The -t ed25519 is the algorithm’s, and the -C "user@host" is the comment’s. The two are the pair, and the pair is the modern’s.
Why the ssh-keygen matters. The ssh-keygen is the generation’s, and the generation’s is the pair’s. The ssh-keygen is the prompt’s, and the prompt’s is the file’s, the passphrase’s, the confirmation’s. The two are the pair, and the pair is the design’s.
The algorithm’s choice. The -t ed25519 is the modern’s, the -t rsa is the legacy’s, the -t ecdsa is the alternative’s.
ssh-keygen -t ed25519 # the modern's
ssh-keygen -t rsa -b 4096 # the legacy's
ssh-keygen -t ecdsa -b 521 # the alternative's
The -t ed25519 is the modern’s, the -t rsa -b 4096 is the legacy’s, the -t ecdsa -b 521 is the alternative’s. The three are the algorithms’s, and the algorithms’s is the choice’s. The two are the pair, and the pair is the design’s.
Why the algorithm’s choice matters. The algorithm’s choice is the security’s, and the security’s is the key’s length’s. The Ed25519’s is the 256-bit’s, the RSA’s is the 2048-bit’s or the 4096-bit’s. The two are the pair, and the pair is the modern’s.
Why the Ed25519’s is the recommended. The Ed25519’s is the modern’s, and the modern’s is the recommended’s. The Ed25519’s is the fast’s, the small’s, the secure’s. The two are the pair, and the pair is the design’s.
Why the RSA’s is the legacy. The RSA’s is the legacy’s, and the legacy’s is the compatibility’s. The RSA’s is the older’s, and the older’s is the system’s. The two are the pair, and the pair is the design’s.
Why the RSA’s key size matters. The RSA’s key size is the 2048’s or the 4096’s, and the 4096’s is the larger’s. The 2048’s is the minimum’s, and the minimum’s is the acceptable’s. The two are the pair, and the pair is the design’s.
Why the ECDSA’s matters. The ECDSA’s is the alternative’s, and the alternative’s is the NIST’s. The ECDSA’s is the specific’s, and the specific’s is the concern’s. The two are the pair, and the pair is the design’s.
The key’s files
The ~/.ssh/id_ed25519 is the private’s, and the ~/.ssh/id_ed25519.pub is the public’s.
ls -la ~/.ssh/
# -rw------- 1 user user 411 id_ed25519 โ the private's
# -rw-r--r-- 1 user user 100 id_ed25519.pub โ the public's
The id_ed25519 is the private’s, and the private’s is the 600’s. The id_ed25519.pub is the public’s, and the public’s is the 644’s. The two are the pair, and the pair is the permission’s.
Why the private’s permission matters. The private’s permission is the 600’s, and the 600’s is the owner’s only. The sshd refuses the loose’s permission, and the refuse’s is the safety’s. The two are the pair, and the pair is the design’s.
Why the public’s permission matters. The public’s permission is the 644’s, and the 644’s is the world’s readable’s. The public’s is the shareable’s, and the shareable’s is the public’s. The two are the pair, and the pair is the design’s.
The private’s content. The -----BEGIN OPENSSH PRIVATE KEY----- is the private’s, and the private’s is the base64’s.
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
...
-----END OPENSSH PRIVATE KEY-----
The -----BEGIN OPENSSH PRIVATE KEY----- is the private’s, and the private’s is the base64’s. The private’s is the secret’s, and the secret’s is the never’s. The two are the pair, and the pair is the design’s.
Why the private’s content matters. The private’s content is the secret’s, and the secret’s is the never’s. The private’s is the never’s shared’s, and the shared’s is the compromise’s. The two are the pair, and the pair is the security’s.
The public’s content. The ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host is the public’s, and the public’s is the one-line’s.
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host
The ssh-ed25519 is the type’s, the AAAAC3... is the key’s, the user@host is the comment’s. The three are the public’s, and the public’s is the one-line’s. The two are the pair, and the pair is the design’s.
Why the public’s content matters. The public’s content is the one-line’s, and the one-line’s is the authorized_keys‘s. The public’s is the copyable’s, and the copyable’s is the easy’s. The two are the pair, and the pair is the design’s.
Why the public’s fingerprint matters. The public’s fingerprint is the SHA256:...‘s, and the SHA256:...‘s is the identity’s.
ssh-keygen -lf ~/.ssh/id_ed25519.pub
# 256 SHA256:abcdef... user@host (ED25519)
The ssh-keygen -lf ~/.ssh/id_ed25519.pub is the fingerprint’s, and the fingerprint’s is the identity’s. The 256 SHA256:... is the fingerprint’s, and the fingerprint’s is the verification’s. The two are the pair, and the pair is the design’s.
Why the public’s fingerprint matters. The public’s fingerprint is the identity’s, and the identity’s is the verification’s. The fingerprint’s is the short’s, and the short’s is the human’s. The two are the pair, and the pair is the design’s.
The ssh-copy-id
The ssh-copy-id user@host is the copy’s, and the copy’s is the authorized_keys‘s.
ssh-copy-id user@example.com
# /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_ed25519.pub"
# /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
# /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
# user@example.com's password:
# Number of key(s) added: 1
# Now try logging into the machine, with: "ssh 'user@example.com'"
# and check to make sure that only the key(s) you wanted were added.
The ssh-copy-id user@example.com is the copy’s, and the copy’s is the authorized_keys‘s. The Number of key(s) added: 1 is the confirmation’s, and the confirmation’s is the success’s. The two are the pair, and the pair is the design’s.
Why the ssh-copy-id matters. The ssh-copy-id is the copy’s, and the copy’s is the authorized_keys‘s. The ssh-copy-id is the one-command’s, and the one-command’s is the convenient’s. The two are the pair, and the pair is the design’s.
The ssh-copy-id‘s options. The -i is the key’s, and the -p is the port’s, and the -o is the ssh’s option’s.
ssh-copy-id -i ~/.ssh/my_key.pub user@example.com
ssh-copy-id -p 2222 user@example.com
The -i ~/.ssh/my_key.pub is the key’s, and the -p 2222 is the port’s. The two are the pair, and the pair is the option’s.
Why the ssh-copy-id‘s options matter. The ssh-copy-id‘s options are the -i, the -p, the -o. The three are the specific’s, and the specific’s is the design’s. The two are the pair, and the pair is the design’s.
The ssh-copy-id‘s mechanism. The ssh-copy-id is the ssh’s, and the ssh’s is the cat >> ~/.ssh/authorized_keys‘s. The ssh-copy-id is the password’s, and the password’s is the last’s. The two are the pair, and the pair is the design’s.
Why the ssh-copy-id‘s mechanism matters. The ssh-copy-id‘s mechanism is the password’s, and the password’s is the last’s. The ssh-copy-id‘s is the authorized_keys‘s, and the authorized_keys‘s is the append’s. The two are the pair, and the pair is the design’s.
The manual’s method. The manual’s method is the cat‘s and the >>‘s.
# On the client:
cat ~/.ssh/id_ed25519.pub
# On the server:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "paste_the_public_key_here" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
The cat ~/.ssh/id_ed25519.pub is the client’s, and the client’s is the read’s. The mkdir -p ~/.ssh, the chmod 700, the echo >> ~/.ssh/authorized_keys, the chmod 600 are the server’s, and the server’s is the manual’s. The two are the pair, and the pair is the design’s.
Why the manual’s method matters. The manual’s method is the fallback’s, and the fallback’s is the ssh-copy-id‘s missing’s. The manual’s is the portable’s, and the portable’s is the universal’s. The two are the pair, and the pair is the design’s.
The authorized_keys
The ~/.ssh/authorized_keys is the server’s, and the server’s is the public’s keys’s.
cat ~/.ssh/authorized_keys
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... another@host
The ssh-ed25519 AAAAC3... is the one-key’s, and the one-key’s is the one-line’s. The two-lines are the two-keys’s, and the two-keys’s is the multiple’s. The two are the pair, and the pair is the design’s.
Why the authorized_keys matters. The authorized_keys is the server’s, and the server’s is the public’s. The authorized_keys is the one-per-line’s, and the one-per-line’s is the format’s. The two are the pair, and the pair is the design’s.
The authorized_keys‘s permission. The 600‘s is the permission’s, and the permission’s is the requirement’s.
chmod 600 ~/.ssh/authorized_keys
The chmod 600 ~/.ssh/authorized_keys is the permission’s, and the permission’s is the requirement’s. The two are the pair, and the pair is the design’s.
Why the authorized_keys‘s permission matters. The authorized_keys‘s permission is the requirement’s, and the requirement’s is the sshd‘s. The sshd refuses the loose’s, and the loose’s is the security’s. The two are the pair, and the pair is the design’s.
The authorized_keys‘s options. The from=, the command=, the no-pty, the no-port-forwarding, the restrict‘s are the common’s.
from="192.168.1.0/24" ssh-ed25519 AAAA... user@host
command="/usr/bin/backup" ssh-ed25519 AAAA... backup@host
no-pty,no-port-forwarding ssh-ed25519 AAAA... restricted@host
The from="192.168.1.0/24" is the source’s, the command="/usr/bin/backup" is the command’s, the no-pty,no-port-forwarding is the restriction’s. The three are the options’s, and the options’s is the restriction’s. The two are the pair, and the pair is the security’s.
Why the authorized_keys‘s options matter. The authorized_keys‘s options are the security’s, and the security’s is the least’s privilege’s. The from= is the source’s, and the command= is the command’s. The two are the pair, and the pair is the design’s.
The restrict‘s option. The restrict is the modern’s, and the modern’s is the all’s disabling’s.
restrict ssh-ed25519 AAAA... user@host
The restrict ssh-ed25519 AAAA... is the modern’s, and the modern’s is the all’s. The restrict is the shorthand’s, and the shorthand’s is the no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-user-rc‘s. The two are the pair, and the pair is the design’s.
Why the restrict matters. The restrict is the modern’s, and the modern’s is the recommended’s. The restrict is the explicit’s, and the explicit’s is the secure’s. The two are the pair, and the pair is the design’s.
The authorized_keys‘s command‘s. The command="/usr/bin/backup" is the specific’s, and the specific’s is the restriction’s.
command="/usr/bin/backup",no-pty ssh-ed25519 AAAA... backup@host
The command="/usr/bin/backup",no-pty is the specific’s, and the specific’s is the restriction’s. The two are the pair, and the pair is the design’s.
Why the command matters. The command is the specific’s, and the specific’s is the automation’s. The command is the backup’s, and the backup’s is the safe’s. The two are the pair, and the pair is the design’s.
The ssh-agent
The ssh-agent is the passphrase’s cache’s, and the cache’s is the session’s.
eval "$(ssh-agent -s)"
# Agent pid 12345
ssh-add ~/.ssh/id_ed25519
# Enter passphrase for /home/user/.ssh/id_ed25519:
# Identity added: /home/user/.ssh/id_ed25519 (user@host)
The eval "$(ssh-agent -s)" is the agent’s start’s, and the start’s is the pid’s. The ssh-add ~/.ssh/id_ed25519 is the addition’s, and the addition’s is the passphrase’s. The two are the pair, and the pair is the design’s.
Why the ssh-agent matters. The ssh-agent is the passphrase’s cache’s, and the cache’s is the convenience’s. The ssh-agent is the once’s, and the once’s is the many’s. The two are the pair, and the pair is the design’s.
The ssh-add‘s options. The -l is the list’s, the -d is the delete’s, the -D is the clear’s, the -t is the timeout’s.
ssh-add -l # the list's
ssh-add -d ~/.ssh/id_ed25519 # the delete's
ssh-add -D # the clear's
ssh-add -t 1h ~/.ssh/id_ed25519 # the 1-hour's
The ssh-add -l is the list’s, the ssh-add -d is the delete’s, the ssh-add -D is the clear’s, the ssh-add -t 1h is the timeout’s. The four are the options’s, and the options’s is the control’s. The two are the pair, and the pair is the design’s.
Why the ssh-add‘s options matter. The ssh-add‘s options are the control’s, and the control’s is the management’s. The -l is the audit’s, and the -D is the cleanup’s. The two are the pair, and the pair is the design’s.
The agent’s forwarding. The ForwardAgent yes is the forwarding’s, and the forwarding’s is the risk’s.
Host example
ForwardAgent yes
The ForwardAgent yes is the forwarding’s, and the forwarding’s is the risk’s. The two are the pair, and the pair is the security’s.
Why the agent’s forwarding matters. The agent’s forwarding is the risk’s, and the risk’s is the remote’s root’s. The remote’s root can use the agent’s, and the agent’s is the keys’s. The two are the pair, and the pair is the security’s.
Why the agent’s forwarding should be the sparing. The agent’s forwarding should be the sparing, and the sparing’s is the trusted’s. The ForwardAgent yes should be the trusted’s, and the trusted’s is the specific’s. The two are the pair, and the pair is the design’s.
The agent’s the desktop’s. The agent’s the desktop’s is the auto-start’s, and the auto-start’s is the graphical’s.
# The desktop's auto-start:
# The ssh-agent is started with the graphical session.
# The ssh-add is called on the first use.
The ssh-agent‘s is the desktop’s, and the desktop’s is the auto-start’s. The two are the pair, and the pair is the convenience’s.
Why the agent’s the desktop’s matters. The agent’s the desktop’s is the auto-start’s, and the auto-start’s is the graphical’s. The macOS’s is the Keychain’s, and the Keychain’s is the automatic’s. The two are the pair, and the pair is the design’s.
The known_hosts
The ~/.ssh/known_hosts is the server’s identity’s, and the identity’s is the trust’s.
cat ~/.ssh/known_hosts
# example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
# |1|abcdef...= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
The example.com ssh-ed25519 AAAA... is the entry’s, and the entry’s is the host’s key’s. The |1|abcdef...= is the hashed’s, and the hashed’s is the HashKnownHosts‘s. The two are the pair, and the pair is the design’s.
Why the known_hosts matters. The known_hosts is the server’s identity’s, and the identity’s is the MITM’s prevention’s. The known_hosts is the client’s record’s, and the record’s is the verification’s. The two are the pair, and the pair is the security’s.
The known_hosts‘s warning. The WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! is the warning’s, and the warning’s is the MITM’s.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
The WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! is the warning’s, and the warning’s is the MITM’s. The two are the pair, and the pair is the security’s.
Why the known_hosts‘s warning matters. The known_hosts‘s warning is the MITM’s, and the MITM’s is the security’s. The warning’s is the legitimate’s or the attack’s, and the attack’s is the serious’s. The two are the pair, and the pair is the design’s.
The known_hosts‘s removal. The ssh-keygen -R host is the removal’s, and the removal’s is the entry’s.
ssh-keygen -R example.com
# # Host example.com found: line 1
# /home/user/.ssh/known_hosts updated.
# Original contents retained as /home/user/.ssh/known_hosts.old
The ssh-keygen -R example.com is the removal’s, and the removal’s is the entry’s. The Original contents retained as ...old is the backup’s, and the backup’s is the safety’s. The two are the pair, and the pair is the design’s.
Why the known_hosts‘s removal matters. The known_hosts‘s removal is the legitimate’s, and the legitimate’s is the server’s reinstall’s. The removal’s is the old’s, and the old’s is the stale’s. The two are the pair, and the pair is the design’s.
The StrictHostKeyChecking‘s. The StrictHostKeyChecking=yes is the strict’s, and the strict’s is the refuse’s.
ssh -o StrictHostKeyChecking=yes user@example.com
The ssh -o StrictHostKeyChecking=yes is the strict’s, and the strict’s is the refuse’s. The two are the pair, and the pair is the security’s.
Why the StrictHostKeyChecking‘s matters. The StrictHostKeyChecking‘s is the strict’s, and the strict’s is the security’s. The accept-new is the modern’s, and the modern’s is the balance’s. The two are the pair, and the pair is the design’s.
The HashKnownHosts‘s. The HashKnownHosts yes is the hash’s, and the hash’s is the privacy’s.
HashKnownHosts yes
The HashKnownHosts yes is the hash’s, and the hash’s is the privacy’s. The two are the pair, and the pair is the design’s.
Why the HashKnownHosts‘s matters. The HashKnownHosts‘s is the hash’s, and the hash’s is the host’s names’s. The hash’s is the local’s, and the local’s is the privacy’s. The two are the pair, and the pair is the design’s.
The key’s rotation
The key’s rotation is the lifecycle’s, and the lifecycle’s is the periodic’s.
The rotation’s reasons. The rotation’s reasons are the compromise’s, the employee’s departure’s, the policy’s. The three are the common’s, and the common’s is the reason’s.
The rotation’s process. The rotation’s process is the generate’s, the copy’s, the test’s, the remove’s. The four are the steps’s, and the steps’s is the process’s.
# 1. Generate the new key
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new -C "user@host"
# 2. Copy the new key
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@example.com
# 3. Test the new key
ssh -i ~/.ssh/id_ed25519_new user@example.com
# 4. Remove the old key
# On the server, edit ~/.ssh/authorized_keys
The ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new, the ssh-copy-id -i ~/.ssh/id_ed25519_new.pub, the ssh -i ~/.ssh/id_ed25519_new, the remove the old key are the four, and the four are the rotation’s. The two are the pair, and the pair is the process’s.
Why the rotation’s process matters. The rotation’s process is the four’s, and the four’s is the safe’s. The generate’s is the first’s, and the first’s is the new’s. The two are the pair, and the pair is the design’s.
The rotation’s no-downtime’s. The rotation’s no-downtime’s is the both’s, and the both’s is the temporary’s.
# The both keys are the authorized_keys's
# The old's is removed after the new's is tested.
The both keys’s is the authorized_keys’s, and the authorized_keys’s is the both’s. The two are the pair, and the pair is the design’s.
Why the rotation’s no-downtime’s matters. The rotation’s no-downtime’s is the both’s, and the both’s is the safe’s. The old’s is the removed’s, and the removed’s is the after’s. The two are the pair, and the pair is the design’s.
The rotation’s automation’s. The rotation’s automation’s is the ansible’s, and the ansible’s is the fleet’s.
# Ansible's:
- name: Rotate SSH keys
ansible.posix.authorized_key:
user: "{{ item.user }}"
state: present
key: "{{ lookup('file', item.key) }}"
The ansible.posix.authorized_key is the ansible’s, and the ansible’s is the fleet’s. The two are the pair, and the pair is the scale’s.
Why the rotation’s automation’s matters. The rotation’s automation’s is the scale’s, and the scale’s is the fleet’s. The rotation’s is the periodic’s, and the periodic’s is the policy’s. The two are the pair, and the pair is the design’s.
The rotation’s the audit’s. The rotation’s the audit’s is the who’s, and the who’s is the when’s.
# The audit's:
# The authorized_keys's is the who's.
# The file's mtime's is the when's.
The who's is the authorized_keys’s, and the when's is the mtime’s. The two are the pair, and the pair is the audit’s.
Why the rotation’s the audit’s matters. The rotation’s the audit’s is the compliance’s, and the compliance’s is the review’s. The audit’s is the periodic’s, and the periodic’s is the policy’s. The two are the pair, and the pair is the design’s.
Complete Example Session
# ============================================
# PART 1: THE KEY'S GENERATION
# ============================================
ssh-keygen -t ed25519 -C "user@host"
# Generating public/private ed25519 key pair.
# Enter file in which to save the key (/home/user/.ssh/id_ed25519):
# Enter passphrase (empty for no passphrase):
# Your identification has been saved in /home/user/.ssh/id_ed25519
# Your public key has been saved in /home/user/.ssh/id_ed25519.pub
# ============================================
# PART 2: THE KEY'S FILES
# ============================================
ls -la ~/.ssh/
# -rw------- 1 user user 411 id_ed25519
# -rw-r--r-- 1 user user 100 id_ed25519.pub
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host
# ============================================
# PART 3: THE SSH-COPY-ID
# ============================================
ssh-copy-id user@example.com
# Number of key(s) added: 1
# ============================================
# PART 4: THE MANUAL'S METHOD
# ============================================
# On the client:
cat ~/.ssh/id_ed25519.pub
# On the server:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "paste_the_public_key_here" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# ============================================
# PART 5: THE TEST
# ============================================
ssh user@example.com
# The passwordless's login.
# ============================================
# PART 6: THE SSH-AGENT
# ============================================
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# Enter passphrase for /home/user/.ssh/id_ed25519:
# Identity added: /home/user/.ssh/id_ed25519 (user@host)
ssh-add -l
# 256 SHA256:abcdef... user@host (ED25519)
# ============================================
# PART 7: THE AUTHORIZED_KEYS'S OPTIONS
# ============================================
# ~/.ssh/authorized_keys
# from="192.168.1.0/24" ssh-ed25519 AAAA... user@host
# command="/usr/bin/backup",no-pty ssh-ed25519 AAAA... backup@host
# restrict ssh-ed25519 AAAA... restricted@host
# ============================================
# PART 8: THE KNOWN_HOSTS
# ============================================
cat ~/.ssh/known_hosts
# example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
ssh-keygen -R example.com
# /home/user/.ssh/known_hosts updated.
# ============================================
# PART 9: THE ROTATION
# ============================================
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new -C "user@host"
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub user@example.com
ssh -i ~/.ssh/id_ed25519_new user@example.com
# The old's is removed after the new's is tested.
# ============================================
# PART 10: WHAT NOT TO DO
# ============================================
# Don't share the private's key
# The private's is the secret's. // โ ๏ธ
# Don't use the loose's permission
chmod 644 ~/.ssh/id_ed25519 # โ // โ ๏ธ
# Don't use the RSA's 1024-bit's
ssh-keygen -t rsa -b 1024 # โ the weak's // โ ๏ธ
# Don't forget the authorized_keys's permission
chmod 644 ~/.ssh/authorized_keys # โ // โ ๏ธ
# Don't use the agent's forwarding on the untrusted's
ForwardAgent yes # โ the risk's // โ ๏ธ
# Don't ignore the known_hosts's warning
# The MITM's. // โ ๏ธ
The ten parts cover the key’s generation, the key’s files, the ssh-copy-id, the manual’s method, the test, the ssh-agent, the authorized_keys‘s options, the known_hosts, the rotation, and the anti-patterns.
Quick Reference
The Key’s Generation
| Command | Purpose |
|---|---|
ssh-keygen -t ed25519 | The modern’s |
ssh-keygen -t rsa -b 4096 | The legacy’s |
ssh-keygen -t ecdsa -b 521 | The alternative’s |
ssh-keygen -f FILE | The custom’s file |
ssh-keygen -C "comment" | The comment’s |
ssh-keygen -lf FILE | The fingerprint’s |
The Key’s Files
| File | Purpose |
|---|---|
~/.ssh/id_ed25519 | The private’s |
~/.ssh/id_ed25519.pub | The public’s |
~/.ssh/authorized_keys | The server’s keys |
~/.ssh/known_hosts | The client’s record |
~/.ssh/config | The client’s config |
The Key’s Permissions
| File | Permission |
|---|---|
~/.ssh | 700 |
~/.ssh/id_ed25519 | 600 |
~/.ssh/id_ed25519.pub | 644 |
~/.ssh/authorized_keys | 600 |
The ssh-copy-id‘s Options
| Option | Purpose |
|---|---|
-i FILE | The specific’s key |
-p PORT | The port’s |
-o OPTION | The ssh’s option |
-f | The force’s |
The ssh-agent‘s Commands
| Command | Purpose |
|---|---|
eval "$(ssh-agent -s)" | The start’s |
ssh-add ~/.ssh/id_ed25519 | The addition’s |
ssh-add -l | The list’s |
ssh-add -d KEY | The delete’s |
ssh-add -D | The clear’s |
ssh-add -t 1h KEY | The timeout’s |
The authorized_keys‘s Options
| Option | Purpose |
|---|---|
from="..." | The source’s |
command="..." | The command’s |
no-pty | The no-tty’s |
no-port-forwarding | The no-forward’s |
no-agent-forwarding | The no-agent’s |
restrict | The all’s disabling’s |
The Algorithms
| Algorithm | Status |
|---|---|
| Ed25519 | The modern’s |
| RSA 4096 | The acceptable’s |
| RSA 2048 | The minimum’s |
| ECDSA | The alternative’s |
Best Practices
โ Do This:
# Use the ed25519's key
ssh-keygen -t ed25519 -C "user@host" # โ
# Copy the public's key
ssh-copy-id user@example.com # โ
# Set the permission
chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_ed25519 # โ
# Use the ssh-agent
eval "$(ssh-agent -s)" && ssh-add ~/.ssh/id_ed25519 # โ
# Use the restrict's option
restrict ssh-ed25519 AAAA... user@host # โ
# Use the fingerprint's verification
ssh-keygen -lf ~/.ssh/id_ed25519.pub # โ
# Rotate the keys periodically
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new # โ
# Use the known_hosts's removal for the legitimate's
ssh-keygen -R example.com # โ
โ Don’t Do This:
# Don't share the private's key
cat ~/.ssh/id_ed25519 # โ the secret's // โ ๏ธ
# Don't use the loose's permission
chmod 644 ~/.ssh/id_ed25519 # โ // โ ๏ธ
# Don't use the RSA's 1024-bit's
ssh-keygen -t rsa -b 1024 # โ the weak's // โ ๏ธ
# Don't forget the authorized_keys's permission
chmod 644 ~/.ssh/authorized_keys # โ // โ ๏ธ
# Don't use the agent's forwarding on the untrusted's
ForwardAgent yes # โ the risk's // โ ๏ธ
# Don't ignore the known_hosts's warning
# The MITM's. // โ ๏ธ
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| The shared private | The compromise | The never’s |
| The loose’s permission | The sshd‘s refusal | The chmod 600 |
| The RSA’s 1024-bit’s | The weak | The Ed25519’s |
The authorized_keys‘s loose’s | The refusal | The chmod 600 |
| The agent’s forwarding | The risk | The no or the trusted’s |
| The known_hosts’s warning | The MITM’s | The investigate’s |
The missing ssh-copy-id | The manual’s | The cat‘s and the >>‘s |
| The no passphrase’s | The compromise’s | The agent’s |
Real-World Examples
1. The generation
ssh-keygen -t ed25519 -C "user@host"
2. The copy
ssh-copy-id user@example.com
3. The manual
cat ~/.ssh/id_ed25519.pub
echo "..." >> ~/.ssh/authorized_keys
4. The permission
chmod 600 ~/.ssh/id_ed25519
5. The agent
ssh-add ~/.ssh/id_ed25519
6. The authorized_keys‘s options
from="192.168.1.0/24" ssh-ed25519 AAAA... user@host
7. The known_hosts
ssh-keygen -R example.com
8. The rotation
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new
9. The fingerprint
ssh-keygen -lf ~/.ssh/id_ed25519.pub
10. The test
ssh user@example.com
Visual: The Key’s Pair
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE CLIENT โ
โ ~/.ssh/id_ed25519 โ the private's โ
โ ~/.ssh/id_ed25519.pub โ the public's โ
โ โ
โ โ The ssh-copy-id โ
โ โผ โ
โ THE SERVER โ
โ ~/.ssh/authorized_keys โ the public's โ
โ โ
โ The private's never leaves the client's. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: The Authentication’s Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. The client's โ the server's โ
โ 2. The server's โ the challenge's โ
โ 3. The client's signs the challenge's with โ
โ the private's key's โ
โ 4. The server's verifies with the public's โ
โ 5. The access's is granted's โ
โ โ
โ The private's key's never crosses the โ
โ network's. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: The Key’s Files
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ~/.ssh/ โ
โ โโโ id_ed25519 600 the private's โ
โ โโโ id_ed25519.pub 644 the public's โ
โ โโโ authorized_keys 600 the server's โ
โ โโโ known_hosts 644 the record's โ
โ โโโ config 600 the config's โ
โ โ
โ The private's and the server's are the โ
โ 600's, and the public's is the 644's. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: The authorized_keys‘s Options
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ from="192.168.1.0/24" โ
โ The source's restriction's โ
โ โ
โ command="/usr/bin/backup" โ
โ The command's restriction's โ
โ โ
โ no-pty โ
โ The no-terminal's โ
โ โ
โ restrict โ
โ The all's disabling's โ
โ โ
โ The options's is the least's privilege's. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Visual: The Rotation’s Process
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. The new's key's generation's โ
โ ssh-keygen -f ~/.ssh/id_ed25519_new โ
โ โ
โ 2. The new's public's copy's โ
โ ssh-copy-id -i ..._new.pub โ
โ โ
โ 3. The new's key's test's โ
โ ssh -i ~/.ssh/id_ed25519_new โ
โ โ
โ 4. The old's key's removal's โ
โ The authorized_keys's edit's โ
โ โ
โ The both's is the no-downtime's. โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| The algorithm | The Ed25519’s |
| The private’s | The ~/.ssh/id_ed25519 |
| The public’s | The ~/.ssh/id_ed25519.pub |
| The server’s | The ~/.ssh/authorized_keys |
| The copy’s | The ssh-copy-id |
| The private’s permission | The 600‘s |
The authorized_keys‘s permission | The 600‘s |
| The agent’s | The ssh-agent‘s |
| The agent’s add’s | The ssh-add‘s |
| The record’s | The ~/.ssh/known_hosts |
| The removal’s | The ssh-keygen -R‘s |
| The rotation’s | The periodic’s |
Key takeaways:
- The SSH keys are the modern’s authentication’s โ the private’s stays on the client, the public’s goes to the server, and the proof never sends the private’s
- The
ssh-keygen -t ed25519 -C "comment"is the generation’s โ the Ed25519 is the modern’s, and the RSA is the legacy’s - The
ssh-copy-id user@hostis the copy’s โ it is the one-command’s, and the manual’s is thecat‘s and the>>‘s - The private’s permission is the
600‘s, the~/.ssh‘s is the700‘s, and theauthorized_keys‘s is the600‘s โ thesshdrefuses the loose’s - The
ssh-agentis the passphrase’s cache’s โ thessh-add‘s is the addition’s, and the-l, the-d, the-D, the-tare the management’s - The
authorized_keys‘s options are thefrom=, thecommand=, theno-pty, theno-port-forwarding, therestrict‘s โ the options’s is the least’s privilege’s - The
known_hostsis the server’s identity’s โ thessh-keygen -R hostis the removal’s, and theHashKnownHostsis the privacy’s - The key’s rotation is the periodic’s โ the new’s generation’s, the copy’s, the test’s, the old’s removal’s
- The passphrase’s is the extra’s โ the
ssh-agent‘s is the convenience’s, and the no-passphrase’s is the risk’s - The agent’s forwarding is the risk’s โ the
ForwardAgent yesshould be the trusted’s only
Remember: The SSH keys are the pair’s, and the pair’s is the private’s and the public’s. The ssh-keygen‘s is the generation’s, and the ssh-copy-id‘s is the copy’s. The ssh-agent‘s is the passphrase’s cache’s, and the authorized_keys‘s options are the restriction’s. The private’s permission is the 600’s, and the server’s is the requirement’s. The keys’s is the modern’s, and the modern’s is the secure’s.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!