Your VPS is a remote machine. SSH is the encrypted way to log into it, run commands, move files and reach things only it can see — replacing insecure telnet.
← / → to navigate · EN/VI switch below · the architect's view — mental model first, a few small examples
You can't plug a keyboard into it. Everything you do to it happens over the network — so how you log in decides how safe it is.
telnet is the old way in. It sends your username AND password in plaintext — readable by anyone on the wire between you and the VPS.
Your traffic crosses routers, ISPs and cables you don't control. On any hop, a sniffer sees your login — including the password — in cleartext.
To ship, you'll log in, run commands, edit files and reach services that only the VPS can see. That remote hand must be safe, not just convenient.
SSH = Secure Shell. It does the same job as telnet — remote login plus a shell — but encrypts the whole conversation so the wire only ever carries gibberish.
The same login — one readable by anyone, one unreadable by anyone.
Telnet hands your credentials to the wire. SSH wraps the entire session in a tunnel — from the password to the very last command you type, nobody on the wire can read it.
From the moment you connect, your username, password and every command are unreadable to anyone on the wire. The tunnel is the whole point.
ssh user@host drops you into a real shell on the VPS. Type a command, it runs there, you see the output — as if you were sitting at that machine.
scp and sftp copy files to and from the VPS over the same encrypted channel — the same security, for moving files instead of typing commands.
Port forwarding lets you reach things that only the VPS can see — a database on its private network — through the encrypted pipe.
Telnet is a conversation shouted across an open field. SSH is the same conversation in a sealed, encrypted tube — the field can't read it.
The first command, the custom port, and the fingerprint prompt you'll see exactly once per server.
Default port is 22; -p overrides it. The first connect asks you to confirm a fingerprint — a one-time 'trust this server' decision.
Every SSH server has a host key. On first connect it shows a fingerprint (a short hash of that key) so you can verify you're talking to the right server — not an impostor.
You check the fingerprint against the value the provider gave you (console, email). Match? Type yes. That's the whole trust step.
Once accepted, the fingerprint is remembered on your machine. Future connects are silent — and if the server's key ever CHANGES, SSH warns you loudly (possible MITM).
Passwords are guessable and phishable. A key pair is unforgeable math. Here's how to set it up — and how to lock the door behind it.
You type a secret both sides know. It can be guessed, leaked, phished or reused. Every login sends it across the wire — encrypted, but still a moving secret.
You generate a private key (your secret) and a public key (your name). The server stores only the public key. Login proves you hold the private key — no secret ever travels.
ssh-keygen creates a private key (keep it — never share) and a matching public key. Accept the defaults or add a passphrase.
ssh-copy-id sends your PUBLIC key to the server and appends it to ~/.ssh/authorized_keys. Only the public half ever travels.
Now ssh asks for no password — it proves you with your private key. Same security, zero typing, and nothing to phish.
Two commands on your laptop do the whole job. The private key stays here; only the public key reaches the VPS.
Once keys work, remove the password route so only keys get in. One line, and the password becomes irrelevant.
In /etc/ssh/sshd_config, set PasswordAuthentication no. Restart the SSH service. From then on, only key-based logins are accepted.
Make sure your key login works BEFORE you disable passwords — and keep a provider console open as a failsafe. Lock yourself out and you're stuck.
No password = nothing to brute-force, phish or stuff. An attacker who finds your server still can't get in without the private key.
The same encrypted channel, now for files. One to copy, one to browse, one to sync.
cp for the network. scp file user@host:/path copies a file to (or from) the VPS over the encrypted channel. One command, done.
An interactive file shell. sftp user@host drops you in a little prompt where you ls, cd, get, put — a safer cousin of ftp.
The workhorse for bigger jobs. rsync diffs the two sides and transfers only what changed — resumable, fast, and it can run over ssh.
# scp: copy a file TO the VPS
scp deploy.py deploy@203.0.113.10:/home/deploy/
# scp: copy a file FROM the VPS
scp deploy@203.0.113.10:/var/log/app.log ./app.log
# sftp: interactive file shell
sftp deploy@203.0.113.10
sftp> ls
sftp> get app.log
sftp> bye
# rsync: sync a folder over ssh
rsync -avz --progress ./site/ deploy@203.0.113.10:/var/www/site/
scp is one-shot (to/from), sftp is the interactive browse-and-get/put shell, and rsync is the resumable diff-based sync — all over the same encrypted channel.
The mental model: a tunnel runs THROUGH your encrypted SSH connection to reach things only the VPS can see.
Local forward (-L): your laptop → encrypted SSH → VPS → private network → the database.
You point your DB client at 127.0.0.1:5432 (localhost). SSH carries that traffic, encrypted, through to the private database on the VPS's internal network — which the internet can't reach at all. No public port, no exposure.
ssh -L 5432:10.0.0.5:5432 user@vps opens port 5432 on YOUR laptop; anything sent to it is tunnelled, encrypted, to 10.0.0.5:5432 as seen from the VPS. Reach a private DB without ever exposing it.
The mirror image — opens a port on the VPS that tunnels back to something on your machine. Useful when the other side can't reach you directly.
Opens a local SOCKS proxy; any app pointed at it routes all its traffic through the VPS. The general-purpose version of the same idea.
The quality-of-life win: name your servers once, then ssh myvps and go. No typing hostnames, ports or key paths every single time.
# ~/.ssh/config — one block per server
Host myvps
HostName 203.0.113.10
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519
# now this just works:
ssh myvps
Define a Host alias once with HostName, User, Port and IdentityFile — after that, ssh myvps, scp file myvps:/path and ssh -L ... myvps all use it automatically.
ssh myvps instead of ssh -i ~/.ssh/id_ed25519 deploy@203.0.113.10. Short, memorable, hard to typo. Every tool that takes a host (ssh, scp, sftp) honors the alias.
Change a port or key path once in the file and every command updates. New server? Add one Host block. It scales from one VPS to ten without muscle memory failing.
The alias carries User, Port and IdentityFile — so tunnels (ssh -L ... myvps), copies (scp x myvps:/path) and everything else inherit the config for free.
Zoom out. SSH is not a pile of flags — it's one secure relationship with your VPS.
Login, run commands, move files, reach private things — all encrypted, all from your laptop. It's the single channel you manage the VPS with.
Key-based login (so there's nothing to phish or guess) and tunnels (so private things stay private). Master those two and the rest of SSH is convenience on top.
SSH is the handshake between you and your VPS — encrypted from the first byte to the last. Get keys and tunnels right and the rest writes itself.
ssh user@host, keys over passwords, one tunnel to the private stuff — and a ~/.ssh/config alias so you never type it all again.