SSH #
Secure Shell: an encrypted connection to a remote machine. Authenticate with a key pair instead of a password, then layer file transfer and tunnels on top of the same connection.
Connecting #
ssh user@host # connect (default port 22)
ssh -p 2222 user@host # non-default port
ssh user@host 'uname -a; uptime' # run a command and exit
ssh -v user@host # verbose, for debugging auth
ssh -J jump@bastion user@host # hop through a bastion (ProxyJump)
Keys #
ssh-keygen -t ed25519 -C "you@email" # generate a modern key pair
ssh-keygen -t rsa -b 4096 -C "you@email" # RSA if ed25519 is unsupported
ssh-copy-id user@host # install your public key on a host
ssh-keygen -p -f ~/.ssh/id_ed25519 # change a key's passphrase
ssh-keygen -lf ~/.ssh/id_ed25519.pub # show the key fingerprint
# Keys live in ~/.ssh : id_ed25519 (private, keep secret) and .pub (public)
The config file #
# ~/.ssh/config -- aliases and per-host options
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host *.internal
ProxyJump bastion
ForwardAgent yes
ssh prod # uses everything defined above
The agent #
eval "$(ssh-agent -s)" # start the agent in this shell
ssh-add ~/.ssh/id_ed25519 # load a key (caches the passphrase)
ssh-add -l # list loaded keys
ssh-add -D # remove all keys from the agent
Copying files #
scp file.txt user@host:/tmp/ # local -> remote
scp user@host:/var/log/app.log . # remote -> local
scp -r dir/ user@host:/srv/ # recurse a directory
rsync -avz --progress dir/ user@host:/srv/ # faster, resumable, deltas
rsync -avz --delete src/ user@host:/dst/ # mirror (removes extras)
Tunnels & forwarding #
ssh -L 8080:localhost:80 user@host # local: your :8080 -> remote :80
ssh -R 9000:localhost:3000 user@host # remote: their :9000 -> your :3000
ssh -D 1080 user@host # dynamic SOCKS proxy on :1080
ssh -fN -L 5432:db.internal:5432 user@host # background tunnel, no shell
Hardening (server side) #
# /etc/ssh/sshd_config -- then: sudo systemctl reload sshd
PasswordAuthentication no # keys only
PermitRootLogin no # no direct root login
Port 2222 # move off the default
AllowUsers deploy # allow-list accounts
Troubleshooting #
chmod 700 ~/.ssh; chmod 600 ~/.ssh/id_ed25519 # fix "permissions too open"
ssh -o StrictHostKeyChecking=accept-new user@host
ssh-keygen -R host # drop a changed host key (after a rebuild)
ssh -T git@github.com # test auth without opening a shell