{"course":{"slug":"cloud-and-shipping","title":"Shipping It","url":"https://addaly.com/learn/cloud-and-shipping","level":"intermediate","track":"build"},"lesson":{"slug":"the-box-and-the-shell","title":"The first ten minutes on a new machine","url":"https://addaly.com/learn/cloud-and-shipping/the-box-and-the-shell","position":2,"of":74,"minutes":9,"answer":"A fresh machine is scanned within minutes, so keys-only login, a non-root user, a closed firewall and automatic security updates are not hardening you do later: they are the machine's first ten minutes.","keyIdea":"A fresh machine is scanned within minutes, so keys-only login, a non-root user, a closed firewall and automatic security updates are not hardening you do later: they are the machine's first ten minutes."},"body":{"format":"markdown","text":"## A rented box is on the public internet within seconds\n\nThe moment a provider hands you an IP address, strangers start knocking. Put a fresh machine online with password login enabled and you will see failed SSH attempts within minutes: usually thousands a day, from botnets working through `root`, `admin`, `ubuntu`, `postgres` and every password in a leaked list. None of this is personal. It is a script.\n\nSo the first ten minutes on a new machine are the same ten minutes every time, and they are worth turning into a checklist you keep.\n\n## Keys, not passwords\n\nGenerate a key pair on your own machine, not on the server:\n\n```bash\nssh-keygen -t ed25519 -C \"laptop-2026\"\nssh-copy-id -i ~/.ssh/id_ed25519.pub user@203.0.113.10\n```\n\nEd25519 keys are short, fast, and the current default. RSA still works if you use 4096 bits, and you will meet it on older systems.\n\nThe private key never leaves your laptop. What you copy to the server is the `.pub` half, which lands in `~/.ssh/authorized_keys`. Anyone who can write to that file can add their own key and let themselves in, which is why the permissions matter: `700` on `~/.ssh`, `600` on the file. With the default StrictModes setting, sshd ignores `authorized_keys` if it, `~/.ssh` or your home directory is writable by anyone but you, and gives the reason only in the server's log.\n\nPut a passphrase on the private key. Without one, a stolen laptop is a stolen server. `ssh-agent` means you type it once per session rather than once per connection.\n\n## Turn off what you are no longer using\n\nIn `/etc/ssh/sshd_config`:\n\n```\nPasswordAuthentication no\nPermitRootLogin no\n```\n\nThen `sudo systemctl reload ssh`. Keep your current session open while you test the new one in a second terminal. Locking yourself out of a machine you have no console access to is a real way to lose a weekend, and it is entirely avoided by not closing the first window.\n\nChanging the SSH port from 22 is popular advice. It removes most of the log noise and stops none of the serious scanning, which enumerates ports anyway. Treat it as tidying, not security.\n\n## Do not work as root\n\nCreate a normal user, give it `sudo`, and use it. Root has no undo and no audit trail: every process it starts, every file it writes, every `rm -rf` with a typo in it runs with the whole machine's authority. The habit costs nothing and it is the difference between a mistake and an outage.\n\nYour application should run as its own user too, one with no login shell and no write access to its own code directory. If the process is ever made to run attacker-supplied code, that user's permissions are the blast radius.\n\n## Close the ports you are not using\n\nEverything a fresh install starts (a database on 5432, Redis on 6379, an admin panel on 8080) is reachable from the internet unless something stops it. Databases exposed this way are found and emptied within hours, and there are search engines dedicated to listing them.\n\n```bash\nsudo ufw default deny incoming\nsudo ufw allow 22,80,443/tcp\nsudo ufw enable\nss -tlnp    # what is actually listening, and on which address\n```\n\nRead the `ss` output carefully. `0.0.0.0:5432` means the whole internet; `127.0.0.1:5432` means only this machine. A cloud provider's security group does the same job one layer out, and it is fine to have both.\n\n## Patches, applied by something other than your memory\n\nOn Debian or Ubuntu:\n\n```bash\nsudo apt install unattended-upgrades\nsudo dpkg-reconfigure -plow unattended-upgrades\n```\n\nThis installs security updates on its own. It will occasionally need a reboot to take effect, which is what `/var/run/reboot-required` is telling you. Unattended upgrades are the highest-value five minutes on this list, because the alternative is a machine that stays on a kernel with a public exploit until you happen to think about it.\n\n## Two habits that save you later\n\n- **Write the machine down.** One file in your repository: what it is, who pays for it, what runs on it, which DNS names point at it. A server nobody can name is a server nobody dares turn off.\n- **Assume it is disposable.** If rebuilding this box from nothing would take you more than an hour of remembering, the recipe should be in a script, not in your head. That is the whole argument for configuration management, and a shell script committed to the repository already counts.\n\n## The free path\n\nAll of this is OpenSSH, `ufw` and `systemd`, which ship with every Linux distribution and cost nothing. `mosh` is worth installing if your connection drops on trains. Managed platforms hide this entire lesson from you, which is a genuine advantage, until the day you need to know what a machine is doing, and the machinery underneath is the same either way."},"check":{"question":"You copy your public key to a new server, then set `PasswordAuthentication no`. Your next SSH attempt is refused with \"Permission denied (publickey)\", although the same key works on another server. What is the most likely cause?","options":[{"text":"The key is Ed25519 and the server only accepts RSA, so it was never offered","correct":false,"tempting":"Assumes modern OpenSSH rejects Ed25519. It has been the recommended default for years; algorithm mismatch is a real failure, but it is rare and would show as a specific unsupported-type error."},{"text":"The firewall is blocking port 22, so the connection never reaches sshd","correct":false,"tempting":"Confuses a network failure with an authentication failure. A blocked port gives a timeout or connection-refused, not a \"Permission denied\" from the server."},{"text":"`PasswordAuthentication no` also disables public-key authentication until `PubkeyAuthentication yes` is added explicitly","correct":false,"tempting":"Treats the two settings as coupled. Public-key authentication is on by default; the password setting only removes the password path."},{"text":"Permissions on `~/.ssh` or `authorized_keys` are too open, so sshd is ignoring the file","correct":true}]},"prev":{"slug":"what-a-server-is","title":"What a server actually is","url":"https://addaly.com/learn/cloud-and-shipping/what-a-server-is"},"next":{"slug":"processes-that-restart-themselves","title":"What keeps your process running when you close the laptop","url":"https://addaly.com/learn/cloud-and-shipping/processes-that-restart-themselves"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'The first ten minutes on a new machine', in Shipping It. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/cloud-and-shipping/the-box-and-the-shell (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"The first ten minutes on a new machine","courseTitle":"Shipping It","module":{"index":1,"slug":"how-the-internet-reaches-you","title":"How the internet reaches your process"},"answer":null,"keyIdea":"A fresh machine is scanned within minutes, so keys-only login, a non-root user, a closed firewall and automatic security updates are not hardening you do later: they are the machine’s first ten minutes.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"a-rented-box-is-on-the-public-internet-within-seconds","runs":[{"text":"A rented box is on the public internet within seconds"}]},{"t":"p","runs":[{"text":"The moment a provider hands you an IP address, strangers start knocking. Put a fresh machine online with password login enabled and you will see failed SSH attempts within minutes: usually thousands a day, from botnets working through "},{"text":"root","code":true},{"text":", "},{"text":"admin","code":true},{"text":", "},{"text":"ubuntu","code":true},{"text":", "},{"text":"postgres","code":true},{"text":" and every password in a leaked list. None of this is personal. It is a script."}]},{"t":"p","runs":[{"text":"So the first ten minutes on a new machine are the same ten minutes every time, and they are worth turning into a checklist you keep."}]},{"t":"h2","id":"keys-not-passwords","runs":[{"text":"Keys, not passwords"}]},{"t":"p","runs":[{"text":"Generate a key pair on your own machine, not on the server:"}]},{"t":"code","lang":"bash","label":"Bash","text":"ssh-keygen -t ed25519 -C \"laptop-2026\"\nssh-copy-id -i ~/.ssh/id_ed25519.pub user@203.0.113.10"},{"t":"p","runs":[{"text":"Ed25519 keys are short, fast, and the current default. RSA still works if you use 4096 bits, and you will meet it on older systems."}]},{"t":"p","runs":[{"text":"The private key never leaves your laptop. What you copy to the server is the "},{"text":".pub","code":true},{"text":" half, which lands in "},{"text":"~/.ssh/authorized_keys","code":true},{"text":". Anyone who can write to that file can add their own key and let themselves in, which is why the permissions matter: "},{"text":"700","code":true},{"text":" on "},{"text":"~/.ssh","code":true},{"text":", "},{"text":"600","code":true},{"text":" on the file. With the default StrictModes setting, sshd ignores "},{"text":"authorized_keys","code":true},{"text":" if it, "},{"text":"~/.ssh","code":true},{"text":" or your home directory is writable by anyone but you, and gives the reason only in the server’s log."}]},{"t":"p","runs":[{"text":"Put a passphrase on the private key. Without one, a stolen laptop is a stolen server. "},{"text":"ssh-agent","code":true},{"text":" means you type it once per session rather than once per connection."}]},{"t":"h2","id":"turn-off-what-you-are-no-longer-using","runs":[{"text":"Turn off what you are no longer using"}]},{"t":"p","runs":[{"text":"In "},{"text":"/etc/ssh/sshd_config","code":true},{"text":":"}]},{"t":"code","lang":"","label":"Text","text":"PasswordAuthentication no\nPermitRootLogin no"},{"t":"p","runs":[{"text":"Then "},{"text":"sudo systemctl reload ssh","code":true},{"text":". Keep your current session open while you test the new one in a second terminal. Locking yourself out of a machine you have no console access to is a real way to lose a weekend, and it is entirely avoided by not closing the first window."}]},{"t":"p","runs":[{"text":"Changing the SSH port from 22 is popular advice. It removes most of the log noise and stops none of the serious scanning, which enumerates ports anyway. Treat it as tidying, not security."}]},{"t":"h2","id":"do-not-work-as-root","runs":[{"text":"Do not work as root"}]},{"t":"p","runs":[{"text":"Create a normal user, give it "},{"text":"sudo","code":true},{"text":", and use it. Root has no undo and no audit trail: every process it starts, every file it writes, every "},{"text":"rm -rf","code":true},{"text":" with a typo in it runs with the whole machine’s authority. The habit costs nothing and it is the difference between a mistake and an outage."}]},{"t":"p","runs":[{"text":"Your application should run as its own user too, one with no login shell and no write access to its own code directory. If the process is ever made to run attacker-supplied code, that user’s permissions are the blast radius."}]},{"t":"h2","id":"close-the-ports-you-are-not-using","runs":[{"text":"Close the ports you are not using"}]},{"t":"p","runs":[{"text":"Everything a fresh install starts (a database on 5432, Redis on 6379, an admin panel on 8080) is reachable from the internet unless something stops it. Databases exposed this way are found and emptied within hours, and there are search engines dedicated to listing them."}]},{"t":"code","lang":"bash","label":"Bash","text":"sudo ufw default deny incoming\nsudo ufw allow 22,80,443/tcp\nsudo ufw enable\nss -tlnp    # what is actually listening, and on which address"},{"t":"p","runs":[{"text":"Read the "},{"text":"ss","code":true},{"text":" output carefully. "},{"text":"0.0.0.0:5432","code":true},{"text":" means the whole internet; "},{"text":"127.0.0.1:5432","code":true},{"text":" means only this machine. A cloud provider’s security group does the same job one layer out, and it is fine to have both."}]},{"t":"h2","id":"patches-applied-by-something-other-than-your-memory","runs":[{"text":"Patches, applied by something other than your memory"}]},{"t":"p","runs":[{"text":"On Debian or Ubuntu:"}]},{"t":"code","lang":"bash","label":"Bash","text":"sudo apt install unattended-upgrades\nsudo dpkg-reconfigure -plow unattended-upgrades"},{"t":"p","runs":[{"text":"This installs security updates on its own. It will occasionally need a reboot to take effect, which is what "},{"text":"/var/run/reboot-required","code":true},{"text":" is telling you. Unattended upgrades are the highest-value five minutes on this list, because the alternative is a machine that stays on a kernel with a public exploit until you happen to think about it."}]},{"t":"h2","id":"two-habits-that-save-you-later","runs":[{"text":"Two habits that save you later"}]},{"t":"ul","items":[[{"text":"Write the machine down.","b":true},{"text":" One file in your repository: what it is, who pays for it, what runs on it, which DNS names point at it. A server nobody can name is a server nobody dares turn off."}],[{"text":"Assume it is disposable.","b":true},{"text":" If rebuilding this box from nothing would take you more than an hour of remembering, the recipe should be in a script, not in your head. That is the whole argument for configuration management, and a shell script committed to the repository already counts."}]]},{"t":"h2","id":"the-free-path","runs":[{"text":"The free path"}],"role":"free"},{"t":"p","runs":[{"text":"All of this is OpenSSH, "},{"text":"ufw","code":true},{"text":" and "},{"text":"systemd","code":true},{"text":", which ship with every Linux distribution and cost nothing. "},{"text":"mosh","code":true},{"text":" is worth installing if your connection drops on trains. Managed platforms hide this entire lesson from you, which is a genuine advantage, until the day you need to know what a machine is doing, and the machinery underneath is the same either way."}]}],"check":{"question":[{"text":"You copy your public key to a new server, then set "},{"text":"PasswordAuthentication no","code":true},{"text":". Your next SSH attempt is refused with “Permission denied (publickey)”, although the same key works on another server. What is the most likely cause?"}],"options":[{"text":[{"text":"The key is Ed25519 and the server only accepts RSA, so it was never offered"}],"correct":false,"tempting":[{"text":"Assumes modern OpenSSH rejects Ed25519. It has been the recommended default for years; algorithm mismatch is a real failure, but it is rare and would show as a specific unsupported-type error."}]},{"text":[{"text":"The firewall is blocking port 22, so the connection never reaches sshd"}],"correct":false,"tempting":[{"text":"Confuses a network failure with an authentication failure. A blocked port gives a timeout or connection-refused, not a “Permission denied” from the server."}]},{"text":[{"text":"PasswordAuthentication no","code":true},{"text":" also disables public-key authentication until "},{"text":"PubkeyAuthentication yes","code":true},{"text":" is added explicitly"}],"correct":false,"tempting":[{"text":"Treats the two settings as coupled. Public-key authentication is on by default; the password setting only removes the password path."}]},{"text":[{"text":"Permissions on "},{"text":"~/.ssh","code":true},{"text":" or "},{"text":"authorized_keys","code":true},{"text":" are too open, so sshd is ignoring the file"}],"correct":true,"tempting":null}],"order":[2,1,0,3],"why":null},"prev":{"slug":"what-a-server-is","title":"What a server actually is","minutes":7},"next":{"slug":"processes-that-restart-themselves","title":"What keeps your process running when you close the laptop","minutes":9}}}