๐ฏ 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.logregularly - 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