๐ŸŽฏ Goal

Master SSH for secure remote access, authentication hardening, port forwarding, and tunneling. Learn to configure SSH servers securely, use key-based authentication, and leverage SSH tunnels for accessing internal networks.


1. SSH Fundamentals & Key-Based Authentication

Why SSH Keys Over Passwords?

Passwords are weak:

  • Vulnerable to brute force attacks
  • Can be keylogged or phished
  • Easily forgotten or reused

SSH keys are strong:

  • 4096-bit RSA or ed25519 provide cryptographic security
  • Private key never leaves your machine
  • Cannot be brute forced in reasonable time

Generate an SSH Key Pair

Recommended: Ed25519 (modern, fast, secure)

ssh-keygen -t ed25519 -C "cypherpunk@$(hostname)"

Alternative: RSA 4096-bit (universal compatibility)

ssh-keygen -t rsa -b 4096 -C "cypherpunk@$(hostname)"

Important: Always set a strong passphrase for your private key!

Files created:

  • Private key: ~/.ssh/id_ed25519 (NEVER share this!)
  • Public key: ~/.ssh/id_ed25519.pub (safe to distribute)

Deploy Your Public Key to Servers

Method 1: ssh-copy-id (easiest)

ssh-copy-id username@server_ip

Method 2: Manual (Windows/restricted)

# From your local machine
cat ~/.ssh/id_ed25519.pub

# On the server
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "your-public-key-here" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Method 3: SCP from Windows

scp $env:USERPROFILE/.ssh/id_ed25519.pub username@server_ip:~/.ssh/authorized_keys

Test Key-Based Authentication

ssh username@server_ip

If configured correctly, you’ll be prompted for your key passphrase (not server password).


2. SSH Server Hardening

โš ๏ธ Warning: Test these changes from a second terminal session before disconnecting! Lock yourself out = bad day.

Edit SSH Daemon Configuration

sudo nano /etc/ssh/sshd_config

Essential Hardening Steps

1. Disable Password Authentication

PasswordAuthentication no

Forces key-based auth only

2. Disable Root Login

PermitRootLogin no

Prevents direct root SSH access (must sudo after login)

3. Change Default Port (Security Through Obscurity)

Port 7777  # Or any port 1024-65535

Reduces automated bot attacks on port 22

4. Restrict to IPv4 Only (if not using IPv6)

AddressFamily inet

5. Limit Login Grace Time

LoginGraceTime 30

Disconnects if authentication not completed in 30 seconds

6. Max Authentication Attempts

MaxAuthTries 3

Disconnects after 3 failed attempts

7. Allow Specific Users Only (Optional)

AllowUsers username1 username2

Restart SSH Daemon

sudo systemctl restart sshd

Test Connection on New Port

ssh username@server_ip -p 7777

3. Firewall Configuration (UFW)

Check Current Network Connections

sudo ss -tupln

See what ports are listening

Install UFW (Uncomplicated Firewall)

sudo apt install ufw -y

Open SSH Port Before Enabling!

# Allow your custom SSH port
sudo ufw allow 7777/tcp

# Or allow port 22 if you didn't change it
sudo ufw allow 22/tcp

โœ… Enable Firewall

sudo ufw enable

Check Firewall Status

sudo ufw status verbose

Allow Additional Services

Web server:

sudo ufw allow 80/tcp   # HTTP
sudo ufw allow 443/tcp  # HTTPS

Custom application:

sudo ufw allow 8080/tcp

๐Ÿšซ Block ICMP Ping (Stay Hidden)

Edit UFW rules:

sudo nano /etc/ufw/before.rules

Add at the top of the # ok icmp codes for INPUT section:

-A ufw-before-input -p icmp --icmp-type echo-request -j DROP

Reload firewall:

sudo ufw reload

Test: Try pinging your server - it should not respond!


4. SSH Port Forwarding & Tunneling

Use case: Access services on internal networks through an SSH jumpbox.

Local Port Forwarding

Forwards a local port to a remote destination through SSH tunnel.

Syntax:

ssh -L [local_port]:[destination_ip]:[destination_port] user@jumpbox

Example 1: Access internal web server

ssh -L 8080:10.10.15.10:80 [email protected]

Access http://127.0.0.1:8080 in your browser to reach internal server

Example 2: Access internal database

ssh -L 3306:192.168.1.50:3306 [email protected]

Connect to MySQL at localhost:3306

Example 3: Bind to specific interface

ssh -L 0.0.0.0:8080:internal.host:80 user@jumpbox

Makes forwarded port accessible to other machines on your network

Dynamic Port Forwarding (SOCKS Proxy)

Creates a SOCKS proxy for routing all traffic through SSH tunnel.

ssh -D 9050 user@server_ip

Configure browser to use SOCKS5 proxy:

  • Host: 127.0.0.1
  • Port: 9050

All browser traffic now tunneled through SSH!

Remote Port Forwarding

Makes a local service accessible from the remote server.

ssh -R [remote_port]:localhost:[local_port] user@server_ip

Example: Share local web server

ssh -R 8080:localhost:3000 [email protected]

Your local port 3000 is now accessible at public-server.com:8080

ProxyJump (Multi-Hop SSH)

Access a target machine through one or more jumpboxes in a single command.

Syntax:

ssh -J user@jumpbox1,user@jumpbox2 user@target

Example:

SSH Config shortcut:

nano ~/.ssh/config

Add:

Host internal-server
    Hostname 10.10.15.8
    User kevin
    ProxyJump [email protected]

Now just:

ssh internal-server

5. SSH Configuration File (~/.ssh/config)

Store connection details for quick access

nano ~/.ssh/config

Example configuration:

Host myserver
    Hostname 192.168.1.100
    User cypherpunk
    Port 7777
    IdentityFile ~/.ssh/id_ed25519

Host jumpbox
    Hostname jumpbox.example.com
    User admin
    Port 22
    IdentityFile ~/.ssh/work_key

Host internal
    Hostname 10.0.0.50
    User dev
    ProxyJump jumpbox
    LocalForward 8080 localhost:80

Usage:

ssh myserver   # Connects with all saved settings
ssh internal   # Auto-jumps through jumpbox

6. Secure Copy (SCP) for File Transfers

Local File โ†’ Remote Server

scp /path/to/local/file username@server:/path/to/remote/destination

Remote File โ†’ Local

scp username@server:/path/to/remote/file /path/to/local/destination

Transfer Directory (Recursive)

scp -r /path/to/local/directory username@server:/path/to/remote/

Use Specific SSH Key

scp -i ~/.ssh/custom_key file.txt username@server:~/

Specify Custom Port

scp -P 7777 file.txt username@server:~/

Note: SCP uses -P (uppercase) for port, unlike SSH’s -p (lowercase)!

Quiet Mode (Suppress Progress)

scp -q file.txt username@server:~/

7. Managing Multiple SSH Keys

SSH Agent for Key Management

Start ssh-agent:

eval "$(ssh-agent -s)"

Add keys:

ssh-agent add ~/.ssh/id_ed25519
ssh-agent add ~/.ssh/work_key_rsa

List loaded keys:

ssh-add -l

Specify Key Per Host

In ~/.ssh/config:

Host personal-server
    IdentityFile ~/.ssh/personal_key

Host work-server
    IdentityFile ~/.ssh/work_key

8. Additional Hardening & Best Practices

Disable Empty Passwords

# In /etc/ssh/sshd_config
PermitEmptyPasswords no

Strong Ciphers Only

# In /etc/ssh/sshd_config
Ciphers [email protected],[email protected]
MACs [email protected],[email protected]
KexAlgorithms curve25519-sha256,[email protected]

Automatic Session Timeout

# In /etc/ssh/sshd_config
ClientAliveInterval 300
ClientAliveCountMax 2

Disconnects idle sessions after 10 minutes

Monitor SSH Attempts

Check failed login attempts:

sudo grep "Failed password" /var/log/auth.log | tail -20

Install fail2ban for automatic blocking:

sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

9. Journal & Git Commit

Reflect on Week 5

cat >> ~/cypherpunk-journal/week05.md << 'EOF'
# Week 5: SSH Deep Dive

## Key Takeaways
- Generated ed25519 SSH keys with passphrase protection
- Hardened SSH server: disabled passwords, changed default port
- Configured UFW firewall to allow only necessary ports
- Practiced local port forwarding to access internal web server
- Set up ~/.ssh/config for convenient connection management
- Used ProxyJump for multi-hop SSH access

## Commands Practiced
- ssh-keygen -t ed25519
- ssh-copy-id user@host
- ssh -L 8080:target:80 user@jumpbox
- ssh -J jumpbox target
- ufw allow 7777/tcp && ufw enable

## Security Insights
- Key-based auth eliminates password brute force risk
- Changing SSH port reduces automated bot attacks
- Port forwarding enables secure access to internal services
- fail2ban automates blocking of repeat attackers

EOF

Git Commit (If tracking notes)

cd ~/cypherpunk-journal
git add week05.md
git commit -m "Week 5: SSH hardening, tunneling, and port forwarding"

โœ… Week 5 Checklist

  • Generated ed25519 SSH key pair with strong passphrase
  • Deployed public key to at least one server
  • Hardened SSH server configuration (disabled passwords, root login)
  • Changed SSH default port and updated firewall
  • Configured UFW firewall with SSH port exception
  • Blocked ICMP ping responses
  • Practiced local port forwarding (-L)
  • Used ProxyJump to access internal server
  • Created ~/.ssh/config for connection management
  • Transferred files using SCP
  • Set up fail2ban for brute force protection
  • Updated journal with SSH learnings

Up Next: Week 6 Preview

Week 6: Encrypted Email & Metadata Hygiene

  • GPG-encrypted email setup
  • Metadata dangers in email and messaging
  • Private messaging with Signal, SimpleX, Session
  • Email aliasing for identity compartmentalization

Notes & Best Practices

Key Management:

  • Rotate SSH keys annually
  • Use different keys for personal vs work
  • NEVER commit private keys to Git

SSH Server Security:

  • Only open ports you actively use
  • Monitor /var/log/auth.log regularly
  • Use fail2ban or similar intrusion prevention

Tunneling Use Cases:

  • Access internal web dashboards without VPN
  • Secure database connections over internet
  • Bypass restrictive firewalls (use responsibly!)

Troubleshooting:

  • Check firewall: sudo ufw status
  • Verify SSH daemon: sudo systemctl status sshd
  • Test config without restart: sudo sshd -t
  • Debug connection: ssh -vv user@host

Additional Resources


Next: Week 6 - Encrypted Email & Metadata Hygiene