.. _ssh: ================================== How SSH Works (the 7th-Grade Way) ================================== **SSH** stands for **S**\ ecure **SH**\ ell. It lets you type commands on a computer that's somewhere else, like a server across the country, as if you were sitting right in front of it. The tricky part: your commands travel over the internet, passing through lots of other people's wires and Wi-Fi. SSH builds a **secret tunnel** so nobody in the middle can read or change what you send. To pull that off, SSH needs to answer three questions: 1. How do you prove who you are? (**the two keys**) 2. How do two computers that have never met agree on a secret? (**the first connection**) 3. Why can't a snoop figure out the secret by watching? (**the wire**) ---- Part 1: The Two Keys ==================== When you run ``ssh-keygen``, your computer makes **two keys at the same time**. They're a matched pair, like two halves of a friendship bracelet. .. figure:: sshImages/keys.svg :width: 100% :alt: A private key that stays on your computer, and a public key you can copy and share with servers. One key you keep. One key you give away. **Private key** (file: ``~/.ssh/id_ed25519``) This is like your **secret stamp**. Only you have it, and it never leaves your computer. If someone steals it, they can pretend to be you. **Public key** (file: ``~/.ssh/id_ed25519.pub``) This is like a **picture of your stamp**. You can hand copies to anyone. A server keeps it in a list called ``~/.ssh/authorized_keys``. The magic: a picture of your stamp lets the server **check** that something was stamped by you, but it can't be used to **make** new stamps. So the public key really is safe to share. .. note:: The server has its **own** pair of keys too, called its *host key*. That's how *you* can check that you're talking to the real server and not a fake one. You'll see it in Part 2. ---- Part 2: What Happens When You First Connect =========================================== You type: .. code-block:: bash ssh student@school-server.example.com and within a second, all of this happens: .. figure:: sshImages/firstConnect.svg :width: 100% :alt: Sequence diagram: say hello, mix paint to share a secret, server shows its ID card, tunnel turns on, then you prove who you are. The five steps of an SSH connection. Step 1: Say hello Both computers agree on which "language" (which math and which scrambling method) to use. Step 2: Mix paint to make a shared secret The two computers make a secret that **only they** know, even though they've never met and everything they send can be seen. (How? See the paint trick in Part 3.) Step 3: The server shows its ID card The server proves it's the real server by stamping the conversation with **its** private key. Your laptop shows you a short summary of the server's public key, called a **fingerprint**. **The very first time**, your laptop has never seen this server before, so it asks you: .. code-block:: text The authenticity of host 'school-server.example.com' can't be established. ED25519 key fingerprint is SHA256:9f3aQx... Are you sure you want to continue connecting (yes/no)? When you type ``yes``, the fingerprint is saved in ``~/.ssh/known_hosts``. It's like memorizing a friend's face. Next time, your laptop checks automatically. If the face ever **changes**, SSH shows a big scary warning, because someone might be pretending to be the server. Step 4: The tunnel turns on From here on, **everything** is scrambled with the shared secret. Step 5: You prove who you are The server sends a random puzzle. Your laptop stamps it with your **private key** and sends it back. The server checks the stamp using your **public key** from ``authorized_keys``. If it matches, you're in! Your private key **never** gets sent. Only the stamped puzzle does. (If you use a password instead, it's sent **inside** the tunnel, so it's still scrambled.) ---- Part 3: Why Someone Watching the Wire Learns Nothing ==================================================== Imagine a snoop named **Eve** who can see every single message that goes between your laptop and the server. How can two computers agree on a secret while Eve is watching? The paint trick --------------- Mixing paint is **easy**, but **un-mixing** paint is basically impossible. SSH uses math that works the same way. .. figure:: sshImages/paint.svg :width: 100% :alt: Paint mixing: both sides start with public yellow, add their own secret color, swap the mixes, add their secret again, and both end up with the same brown. Eve only sees yellow, orange, and green. Both sides end up with the same brown. Eve can't make it. 1. Everyone (even Eve) knows the starting color: **yellow**. 2. You secretly pick **red**. The server secretly picks **blue**. These are **never** sent. 3. You send **orange** (yellow + red). The server sends **green** (yellow + blue). Eve sees both. 4. You add your red to the server's green. The server adds its blue to your orange. **Both of you get the same brown!** Eve has yellow, orange, and green. To make brown she needs red or blue, and she'd have to *un-mix* orange or green to get them. She can't. In real SSH the "colors" are huge numbers (hundreds of digits long), and the "mixing" is math that would take the fastest computers on Earth longer than the age of the universe to undo. What Eve actually sees ---------------------- Once both sides have the brown secret, they use it to scramble every message. .. figure:: sshImages/eavesdrop.svg :width: 100% :alt: You type "ls homework/" and the server reads "ls homework/", but Eve, watching the tunnel, only sees random-looking characters. Same message at both ends, gibberish in the middle. So Eve can't: * **Read** your commands or passwords, because they're scrambled. * **Steal your key**, because your private key is never sent. * **Pretend to be the server**, because she doesn't have the server's private key, so she can't make its stamp. (That's why Step 3 and ``known_hosts`` matter!) * **Change your messages**, because SSH adds a tamper check to each message, and a changed message fails the check and gets thrown away. ---- Try It Yourself =============== .. code-block:: bash # 1. Make your two keys (press Enter to accept the defaults) ssh-keygen -t ed25519 # 2. Look at your PUBLIC key (safe to show anyone) cat ~/.ssh/id_ed25519.pub # 3. Copy your public key to a server ssh-copy-id student@school-server.example.com # 4. Connect: no password needed now! ssh student@school-server.example.com ---- Quick Quiz ========== .. dropdown:: Which key do you give to the server? The **public** key. The private key never leaves your computer. .. dropdown:: What is ``known_hosts`` for? It remembers the fingerprint ("face") of every server you've said ``yes`` to, so your laptop can spot a fake server later. .. dropdown:: Eve saw yellow, orange, and green. Why can't she make brown? She'd need one of the secret colors (red or blue), and getting them would mean un-mixing paint. In real SSH, that's math too hard for any computer to undo. .. dropdown:: If Eve records the whole conversation, what does she get? Scrambled gibberish. Without the shared secret, it's useless.