SSH

intermediate ssh encryption keys port-forwarding remote

SSH (Secure Shell) is the encrypted remote login we use every day to manage servers. It runs on port 22 and replaces older insecure tools like Telnet, rlogin, and rsh.

In simple language: SSH gives us a secure terminal into a remote machine — and a Swiss army knife for tunneling traffic.

What SSH Gives Us

  • Encrypted remote shell.
  • Strong authentication (passwords or, much better, key pairs).
  • Secure file transfer (scp, sftp).
  • Port forwarding to tunnel arbitrary TCP traffic.

Key-Based Authentication

Instead of typing a password every time, we generate a key pair:

  • Private key — stays on our laptop (~/.ssh/id_ed25519). Never share it.
  • Public key — copied to the server’s ~/.ssh/authorized_keys.

When we connect, the server challenges us to prove we hold the private key. Math happens. We’re in.

# Generate a modern key pair
ssh-keygen -t ed25519 -C "manish@laptop"

# Copy our public key to the server
ssh-copy-id manish@server.example.com

# Now connect — no password prompt
ssh manish@server.example.com

Why this is better than passwords:

  • Brute-forcing a key is mathematically infeasible.
  • We can revoke a key by removing one line from authorized_keys.
  • Works great with ssh-agent so we type the passphrase once per session.

known_hosts — Trust on First Use

The first time we connect to a new server, SSH shows the server’s host key fingerprint and asks if we trust it. If we say yes, it’s saved to ~/.ssh/known_hosts.

Next time we connect, SSH compares the offered key with what’s on file. If it doesn’t match, we get a scary warning:

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

This protects us from man-in-the-middle attacks. If we genuinely changed servers, we remove the old entry:

ssh-keygen -R server.example.com

Port Forwarding (Tunneling)

This is SSH’s superpower. We can tunnel arbitrary TCP traffic through the SSH connection.

Local forwarding (-L)

Forwards a port on our machine to something reachable from the server.

# Access a database on the server that's only listening on localhost
ssh -L 5432:localhost:5432 manish@server.example.com
# Now we connect to localhost:5432 on our laptop and hit Postgres on the server

Remote forwarding (-R)

Exposes a port on the server that points back to our machine.

# Make our laptop's web app on :3000 accessible on the server's :8080
ssh -R 8080:localhost:3000 manish@server.example.com

Dynamic forwarding (-D)

Turns SSH into a SOCKS proxy.

# Browse the web through the server
ssh -D 1080 manish@server.example.com
# Then point our browser at SOCKS5 proxy localhost:1080

Common Commands

# Basic login
ssh manish@server.example.com

# Use a non-default port
ssh -p 2222 manish@server.example.com

# Specify a key
ssh -i ~/.ssh/work_key manish@server.example.com

# Run a single command and exit
ssh manish@server.example.com "df -h"

# Copy a file to the server
scp local.txt manish@server.example.com:/tmp/

# Copy a directory recursively
scp -r ./build manish@server.example.com:/var/www/

# Use the ~/.ssh/config file for shortcuts
cat ~/.ssh/config
# Host prod
#   HostName server.example.com
#   User manish
#   Port 2222
#   IdentityFile ~/.ssh/prod_key

# Now we just type:
ssh prod

Interview Tip

If asked “how does SSH stay secure,” explain three layers:

  1. Transport — encrypted channel via Diffie-Hellman key exchange.
  2. Authentication — host key (server proves itself), then user key/password (we prove ourselves).
  3. Channels — multiple sessions multiplexed over the same encrypted connection (shell + sftp + forwarding all together).