SSH connection setup, key management, tunnelling, and common network diagnostics. SSH (Secure Shell) is the standard protocol for securely accessing remote machines and authenticating with services like GitHub.
Connect to remote machines securely. The first connection to a
new host will ask you to verify its fingerprint โ type
yes to add it to ~/.ssh/known_hosts.
ssh user@host
ssh user@host -p 2222 # custom port
ssh -i ~/.ssh/id_ed25519 user@host # specific key
ssh -v user@host # verbose (debug connection issues)
Run a command without a shell:ssh user@host "ls -la /var/log"
(command runs and SSH exits immediately)
Connect with IPv6:ssh user@2804:14d:5c51:16b:a02d:4b2:d16b:b21
(use the scope global address from ip addr, not the link-local fe80:: one)
ssh-keygen -R hostname # remove stale entry (host key changed)
cat ~/.ssh/known_hosts # view all trusted hosts
WSL โ enable IPv6 mirrored networking:
Add to ~/.wslconfig:
[wsl2]
networkingMode=mirrored
~/.ssh/config lets you define aliases and per-host
settings so you can type ssh myserver instead of
the full command every time.
# ~/.ssh/config
Host myserver
HostName 192.168.1.100
User ubuntu
IdentityFile ~/.ssh/id_ed25519
Port 22
Host bastion
HostName bastion.example.com
User ec2-user
IdentityFile ~/.ssh/id_ed25519_aws
# Jump through bastion to reach internal host
Host internal
HostName 10.0.1.50
User ubuntu
ProxyJump bastion
Host *
ServerAliveInterval 60 # keep-alive ping every 60s
ServerAliveCountMax 3
(permissions must be 600: chmod 600 ~/.ssh/config)
AddKeysToAgent yes # auto-load key into ssh-agent
ForwardAgent yes # forward your local keys to the remote host
StrictHostKeyChecking no # skip fingerprint prompt (use carefully)
ControlMaster auto # multiplex connections (faster repeated ssh)
ControlPath /tmp/ssh-%r@%h:%p
ControlPersist 10m
SSH can forward TCP ports through an encrypted tunnel, useful for reaching services that aren't exposed to the internet or bypassing firewalls.
ssh -L 8080:localhost:80 user@server
# โ localhost:8080 on your machine reaches port 80 on server
ssh -L 5432:db-host:5432 user@bastion
# โ tunnel through bastion to a database on the internal network
(-N = don't execute a command, -f = background the process)
ssh -R 8080:localhost:3000 user@server
# โ server:8080 reaches your local port 3000 (useful for demos/webhooks)
ssh -D 1080 -N user@server
# โ configure browser/app to use SOCKS5 proxy at localhost:1080
ssh -J bastion user@internal-host
# โ SSH through bastion to reach an otherwise unreachable host
scp is simple for quick copies; rsync
is better for directories and incremental syncs (only transfers
changed files).
scp file.txt user@server:/remote/path/
scp user@server:/remote/file.txt ./local/
scp -r local_dir/ user@server:/remote/ # recursive
scp -P 2222 file.txt user@server:/path/ # custom port
rsync -avz ./local/ user@server:/remote/
rsync -avz --delete ./local/ user@server:/remote/ # mirror (remove extras)
rsync -avz --exclude='*.log' ./local/ user@server:/remote/
rsync -avz -e "ssh -p 2222" ./local/ user@server:/remote/ # custom port
rsync -avz user@server:/remote/ ./local/ # pull from server
(-a archive: preserves permissions/timestamps, -v verbose, -z compress, -n dry-run)
Generate a key pair once, add the public key to your service, and authenticate automatically without a password.
ssh-keygen -t ed25519 -C "your_email@example.com"
# or RSA if ed25519 isn't supported:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
(accept the default path; set a passphrase for extra security)
2. Copy your public key:cat ~/.ssh/id_ed25519.pub
(copy the entire output including the email comment at the end)
3. Add to your service:
Paste into account settings โ e.g. the GitHub SSH keys page.
4. Test:ssh -T git@github.com
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l # list loaded keys
Tools for checking connectivity, inspecting open ports, and debugging network issues.
ping -c 4 google.com # 4 packets, then stop
traceroute google.com # trace route (may need traceroute installed)
tracepath google.com # like traceroute, no root needed
mtr google.com # live combined ping + traceroute
ss -tulnp # listening TCP/UDP ports with process names
ss -tp # established TCP connections
netstat -tulnp # older alternative (may not be installed)
(-t TCP, -u UDP, -l listening, -n numeric, -p show process)
curl https://example.com
curl -I https://example.com # headers only
curl -o file.html https://example.com # save to file
curl -X POST https://api.example.com/data \
-H "Content-Type: application/json" \
-d '{"key": "value"}'
curl -u user:pass https://example.com # basic auth
curl -L https://example.com # follow redirects
dig example.com # full DNS query output
dig +short example.com # just the IP
dig MX example.com # mail exchange records
nslookup example.com # simpler alternative
host example.com
nmap hostname # scan common ports
nmap -p 80,443 hostname # specific ports
nmap -p 1-1000 hostname # port range
nmap -sV hostname # detect service versions
(only scan systems you own or have permission to scan)