Skip to content
0

ssh

SSH (Secure Shell) and GPG (GNU Privacy Guard) are the backbone of secure engineering, DevOps, and even personal data protection. While they both use cryptography, they solve different problems.

Where is SSH

bash
╭╴  alowree on Mac OS at ~
╰─❯ which ssh
/usr/bin/ssh

View your IP address

On macOS, run ipconfig getifadd en1 inside the terminal to view your IP address.

bash
╭╴  alowree on Mac OS at ~
╰─❯ ipconfig getifaddr en1
192.168.0.117

At home

On Arch Linux, run ip addr show inside the terminal to view your IP address and the port.

bash
╭╴  alowree on Arch Linux at ~
╰─❯ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 9c:2f:9d:b3:38:23 brd ff:ff:ff:ff:ff:ff
    altname wlx9c2f9db33823
    inet 192.168.0.118/24 brd 192.168.0.255 scope global dynamic noprefixroute wlp1s0
       valid_lft 4966sec preferred_lft 4966sec
    inet6 fd00:9c47:824d:9e08:86cb:daad:4d70:475b/64 scope global dynamic noprefixroute
       valid_lft 86347sec preferred_lft 14347sec
    inet6 fd00:9c47:824d:9e08::1003/128 scope global dynamic noprefixroute
       valid_lft 84169sec preferred_lft 84169sec
    inet6 fe80::ad40:289d:2836:be15/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

At office cubicle with Wifi synchronwl

bash
╭╴  alowree on Arch Linux at ~/OneDrive/scripts_python/ingest_ads_reports took 2s via 3.14.5 (ingest-ads-reports)
╰─❯ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: wlp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 9c:2f:9d:b3:38:23 brd ff:ff:ff:ff:ff:ff
    altname wlx9c2f9db33823
    inet 128.50.100.7/23 brd 128.50.101.255 scope global dynamic noprefixroute wlp1s0
       valid_lft 51796sec preferred_lft 51796sec
    inet6 fe80::8d77:7955:f7ee:6736/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

Note that neither IP address uses the default port 22 for the SSH connection. Therefore, you will need to specify the port when trying to connect through SSH.

SSH commands

For the very basic uses, run tldr command to get a hint:

bash
╭╴  alowree on Mac OS at ~
╰─❯ tldr ssh

  ssh

  Secure Shell is a protocol used to securely log onto remote systems.
  It can be used for logging or executing commands on a remote server.
  More information: https://man.openbsd.org/ssh.

  Connect to a remote server:

    ssh username@remote_host

  Connect to a remote server with a specific [i]dentity (private key):

    ssh -i path/to/key_file username@remote_host

  Connect to a remote server with IP 10.0.0.1 and using a specific [p]ort
  (Note: 10.0.0.1 can be shortened to 10.1):

    ssh username@10.0.0.1 -p 2222

  Run a command on a remote server with a [t]ty allocation allowing
  interaction with the remote command:

    ssh username@remote_host -t command command_arguments

  SSH tunneling: [D]ynamic port forwarding (SOCKS proxy on localhost:1080):

    ssh -D 1080 username@remote_host

  SSH tunneling: Forward a specific port (localhost:9999 to example.org:80)
  along with disabling pseudo-[T]ty allocation and executio[N] of remote
  commands:

    ssh -L 9999:example.org:80 -N -T username@remote_host

  SSH [J]umping: Connect through a jumphost to a remote server (Multiple jump
  hops may be specified separated by comma characters):

    ssh -J username@jump_host username@remote_host

  Close a hanged session:

    <Enter><~><.>

I'm learning two popular utilities ssh and gpg, along with ssh-agent and gpg-agent...Create a tutorial for beginners to introduce each concept, explain why it is useful, and some popular use cases in the real world. Compare these two popular utilities and list out the common vs. different areas among them. Finally, provide some best practices in managing the gpg keys and ssh keys, what you should do and what you should definitely avoid for security considerations.

This is an excellent topic. SSH (Secure Shell) and GPG (GNU Privacy Guard) are the backbone of secure engineering, DevOps, and even personal data protection. While they both use cryptography, they solve different problems.

Below is a beginner-friendly tutorial covering concepts, comparisons, and security best practices.

The Concepts & Real-World Use Cases

1. SSH (Secure Shell)

What it is: A network protocol that creates a secure, encrypted tunnel between two computers over an insecure network (like the internet).

Why it is useful: It replaces old, insecure protocols like telnet or rlogin which send passwords and data in plain text.

Core mechanic: Asymmetric cryptography.

  • Private Key (stays on your machine, never share).
  • Public Key (upload to servers you want to access).
  • Remote Server Administration: Logging into a cloud server (AWS, DigitalOcean) to run commands.
  • Git over SSH: Pushing code to GitHub/GitLab without typing a password each time.
  • Port Forwarding (Tunneling): Securely accessing a database inside a private network or bypassing firewalls.
  • File Transfer: scp (secure copy) or rsync over SSH.

2. GPG (GNU Privacy Guard)

What it is: An implementation of OpenPGP standard for encryption and signing of data and communications.

Why it is useful: Ensures confidentiality (only the intended recipient can read) and authenticity/non-repudiation (you can prove a message came from you and hasn't been altered).

Core mechanic: Also asymmetric keys (public/private), but used differently.

  • Email Encryption: Using Thunderbird + Enigmail or ProtonMail's GPG integration.
  • Software Signing: Linux distributions (Debian, Ubuntu) and package managers (like apt) verify that a package really came from the maintainer, not a hacker.
  • File Encryption: Encrypting a backup before uploading to Dropbox/Google Drive.
  • Git Commit Signing: Proving that a commit or tag in GitHub/GitLab was genuinely made by you (green "Verified" badge).
  • Password Management: Some tools (like pass) use GPG to encrypt password stores.

3. ssh-agent & gpg-agent

These are helper daemons (background processes) that hold your decrypted private keys in memory.

The problem: Your private key is encrypted with a passphrase. Without an agent, you'd type your long passphrase every time you SSH into a server or decrypt a file.

The solution:

  • ssh-agent: You add your key once (ssh-add ~/.ssh/id_ed25519). For the rest of your login session, ssh commands reuse that unlocked key.
  • gpg-agent: Does the same for GPG keys, plus manages pinentry dialogs (pop-ups asking for your passphrase). Modern gpg-agent can also act as an ssh-agent replacement.

SSH vs. GPG – Comparison

AreaSSHGPG
Primary GoalSecure network connection (encrypted session)Data encryption & digital signatures
Key TypeUsually simple key pair (RSA, Ed25519)More complex (master key + subkeys, expiration, trust levels)
InfrastructureRelies on ~/.ssh/authorized_keys and known_hostsUses a Web of Trust (or trust on first use)
Typical LifespanKeys often long-lived (years)Often rotated; subkeys changed regularly
Does it encrypt files?Not directly, but can tunnelYes (core feature)
Does it handle identity?Yes (who is allowed to log in)Yes (who signed this document)
Common overlapUsing gpg-agent as SSH agent; signing Git commits with SSH keys (GitHub now supports this)N/A

Common Areas

  • Both use public-key cryptography.
  • Both have agents to avoid re-entering passphrases.
  • Both can be used to authenticate you to remote services.
  • Private keys must be kept secret for both.

Different Areas

  • SSH is primarily about channels (secure communication between two endpoints).
  • GPG is primarily about objects (encrypting or signing files/messages that can be stored or emailed).
  • Key revocation: SSH has no built-in revocation mechanism; you just remove the public key from the server. GPG has a formal revocation certificate.
  • Key distribution: SSH keys are manually copied. GPG keys can be uploaded to public keyservers (though that practice is declining due to abuse).

Best Practices for Managing SSH & GPG Keys

✅ What You SHOULD Do

✅ For Both SSH & GPG

  1. Use strong passphrases – At least 12–16 characters, or a diceware phrase.
  2. Use modern algorithms:
    • SSH: ed25519 (preferred) or rsa 4096.
    • GPG: ed25519/cv25519 (curve25519) or rsa 4096.
  3. Back up your private keys – Encrypt them (e.g., with age or put in an encrypted vault like Bitwarden/1Password). Store a backup offline.
  4. Use agents with timeouts – Configure ssh-add -t 1h or gpg-agent max-cache-ttl to forget passphrases after idle time.
  5. Rotate keys – SSH: every 1-2 years. GPG: rotate subkeys more often (e.g., every year); master key can live longer offline.
  6. Use hardware tokens – YubiKey, Nitrokey, or similar. Store private keys on the token; they never leave the device.

✅ For SSH specifically

  • Disable password authentication on servers (key-only).
  • Use AllowUsers in sshd_config to restrict who can log in.
  • Lock down authorized_keys with command= or from= restrictions (e.g., allow only git push, no shell).
  • Run ssh-add -l occasionally to see what keys are loaded.

✅ For GPG specifically

  • Create an offline master key – Use --export-secret-subkeys to keep the main certifying key on an air-gapped machine. Only subkeys live on your daily laptop.
  • Generate a revocation certificate immediately after creating the key. Print it and store it in a safe.
  • Set expiry dates – Even 1 year out. You can always extend a non-expired key, but an expired key is a safety net if you lose it.
  • Upload your public key only to trusted keyservers (or use a static website / WKD). Be aware keyservers are not secure against spam/malicious certs.

❌ What You Should DEFINITELY Avoid

❌ For both

  • Never store private keys without a passphrase – If someone steals your laptop, they get all your servers/data.
  • Never share private keys – Not with colleagues, not across your own devices unless via a secure vault.
  • Never chmod 777 your .ssh or .gnupg directories – They must be 700 (drwx------).
  • Do not use keyservers for private keys – Obvious, but some beginners accidentally upload their private key.
  • Do not leave ssh-agent unlocked when away – An unlocked agent can be used by any process (or any user with access to the socket). Use ssh-add -x on some OSes, or lock screen.
  • Do not email your private keys – Even encrypted, it's a bad habit.

❌ For SSH specifically

  • Do not use ssh -A (agent forwarding) unless absolutely necessary – It gives the remote server access to your local agent. Use ProxyJump instead.
  • Do not disable host key checkingStrictHostKeyChecking=no is dangerous (MITM attacks).
  • Do not reuse the same SSH key across sensitive environments – Separate key for GitHub, separate for production servers.

❌ For GPG specifically

  • Do not lose your revocation certificate – Without it, a compromised key cannot be publicly revoked.
  • Do not set default-key to your master key – Use a subkey for daily signing/encryption.
  • Do not ignore trust warnings – GPG will warn you if a key is not fully trusted. Pay attention.
  • Do not trust Web of Trust blindly – It's weakened in recent years; manually verify fingerprints.

Final Hands-On Example for Beginners

Generate an SSH key (recommended):

bash
ssh-keygen -t ed25519 -C "your_email@example.com"
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

Generate a GPG key (modern):

bash
gpg --full-generate-key
# Choose (9) ECC and (1) Curve25519 for signing/encrypting
# Set expiry 1y
gpg --list-secret-keys --keyid-format LONG
gpg --export --armor <KEYID>  # public key
gpg --export-secret-keys --armor <KEYID>  # private key (store encrypted!)

Configure gpg-agent to act as SSH agent (best of both worlds): Add to ~/.gnupg/gpg-agent.conf:

enable-ssh-support
default-cache-ttl 3600

Then restart: gpg-connect-agent reloadagent /bye

Learn more: man ssh, man gpg, and YubiKey setup guides from NIST or EFF.

Would you like a separate cheat sheet for daily commands (signing a file, adding an SSH key permanently, etc.)?

最近更新