# Do you access a server with username and password? It's a combination padlock facing the street

> Source: <https://dev.to/murilo_negrao_59aada6e774/do-you-access-a-server-with-username-and-password-its-a-combination-padlock-facing-the-street-cn3>
> Published: 2026-07-17 12:50:07+00:00

✍️ This post was written with two hands.The story — the first part — is Murilo's, lived and told by the person who was there. Thetechnical manual, at the end, was written with AI. The split is intentional and marked in the text. Nothing hidden about the seam: part is human, part is machine, and the reader sees both.

If you've ever managed or logged into a web server and never set up SSH keys, it's because you don't yet know the real risks of a break-in — and that's okay. Until you find out what can happen.

Logging into a server over SSH with a username and password is like locking the front door of a house that faces the street, with nobody keeping watch. Anyone can try as many combinations as they want, freely.

And setting this up takes almost as much time as typing a username and password — and it makes getting into the server much faster and easier afterwards.

Ignorant of best practices, I managed my servers for a long time by typing:

```
ssh user@server-ip
password
```

That nearly cost me dearly, the day I found out my server had been broken into.

After that incident, I realized just how vulnerable a username and password are on SSH.

Today I can't say I sleep soundly — no system is completely break-in proof — but I sleep a lot better (and honestly, I always slept well, until I started managing servers).

Waking up on a fine Sunday morning to do some maintenance on the server, and finding out it was broken into through the front door because you left a combination padlock facing the street — that is not the kind of surprise I'd wish on anyone.

I have a degree in Law. I worked for 15 years in the legal field at a public institution, until I decided to venture into the world of programming.

And where did I end up? Managing systems at the institution I work for, after spending some time building automations in Python.

Managing systems wasn't exactly what I had in mind when I wanted to learn to code and understand the world of programming.

But that opportunity ended up teaching me far more about systems in general, about how the internet works — much more than I imagined back when the urge to work in development first hit me.

Today I can't picture myself doing anything other than this: automating deploys and backups, improving application performance on the server side, monitoring, alerting.

When it comes to SSH, there are bots scanning the internet all day long, trying usernames and passwords on the default port of servers all over the world. A weak, obvious, or reused password falls fast — it's just a matter of the right bot knocking on your door.

A truly strong password holds up much longer: since every attempt has to travel back and forth across the network, brute-forcing it takes far too long to be worth it. But it's still a secret — and any secret can leak, be reused on a service that got compromised, or end up in the wrong place. That kind of slip doesn't usually happen to a good systems administrator. Which, at the time, I was not.

So one way to minimize the risk is to disable password login and allow access only through SSH keys.

Even if you use a tool to fend off repeated attempts, like fail2ban, it's still less effective and less secure than SSH keys, because an attacker can switch IPs or use other tricks to get around it.

With an SSH key pair, the attacker only gets in if they get hold of the key. And for that, your slip-up has to be a bigger one — leaving it exposed somehow, or sharing it with the wrong people.

When you set up the key pair, you put the padlock on the door and keep the key on your computer — so access happens only with the private key. And you can put that padlock on as many servers as you want.

In other words: you create a pair of keys, one private and one public.

The private one is the key; the public one is the padlock.

So you hold on to the key and place as many padlocks as you like on the servers you manage.

First benefit: security.

On top of that, you can set up an alias. Instead of typing `ssh name@server-ip`

and then the password every single time you want to reach the server, you just type `ssh alias`

. It will ask for the passphrase you configured — only on the first access.

For the next ones that use that key — even on other servers — it's just `ssh alias`

.

With that, you get both more security and more speed when accessing your servers.

A padlock with a key is harder for an intruder to open than a combination padlock — wouldn't you agree?

Luckily, when my server was broken into, it was a test machine I had just wiped to install a few applications for testing — I hadn't configured anything yet, nor deployed a single app. Damage contained, but the scare was real.

Want to know how to set up SSH keys in practice? Below is a tutorial put together with the help of AI, and at the end a checklist and a command map — for both your PC and the server — to configure SSH keys, with a full, step-by-step explanation.

If you have any questions, I'm happy to chat. I love talking about technology, infrastructure, DevOps, SRE, and related topics.

🤖 From here on: technical manual, written with AI.I told my story. Now comes the practical step-by-step — the part AI writes well. If you manage any server (a $5 VPS, an EC2 instance, the company machine), you can do this today, in about 20 minutes.

This is the hands-on part. I won't just list commands — I'll explain the *why* behind each one, because understanding the reason is what lets you touch a production server without breaking into a cold sweat.

You already saw the idea in the story above: the public key is the padlock, the private key is the key. It's just worth understanding what happens at the moment of login.

When you connect, the server sends a challenge that **only the holder of the private key can solve**. Your machine solves that challenge locally and sends back only the answer — the private key itself never travels across the network, not even during login.

That's where the difference from a password lives. A password is a secret that leaves your machine every time and *can be guessed*. The private key never leaves, and can't be guessed: an Ed25519 pair is such an astronomically large number that brute-forcing it stops being an option. You're not using a stronger password — you're switching to a mechanism where guessing simply doesn't exist.

On **your computer** (not on the server):

```
ssh-keygen -t ed25519 -C "your-user@laptop-2026"
```

`-t ed25519`

— the algorithm. Ed25519 is modern, fast, and secure. Forget the old RSA.`-C`

— a comment that stays attached to the public key. Use something that identifies the `your-user@laptop-2026`

). Later on, this tells you which key is which.`~/.ssh/id_ed25519`

).This creates two files:

| File | What it is | Safe to share? |
|---|---|---|
`~/.ssh/id_ed25519` |
Private key | Never. |
`~/.ssh/id_ed25519.pub` |
Public key | Yes, freely. |

The private key must be readable only by you. Check, and fix it if needed:

```
ls -la ~/.ssh/id_ed25519     # should show permission -rw------- (600)
chmod 600 ~/.ssh/id_ed25519
ssh-copy-id user@server-ip
```

This command asks for the **server password** — and that is, literally, the last time you'll type it. It copies your public key into the server's `~/.ssh/authorized_keys`

file, which is the list of padlocks that server accepts.

Test it:

```
ssh user@server-ip
```

An important detail to confirm it worked: if it asks for a **passphrase**, you're good — that's the passphrase *for your key*. If it asks for a **password**, you're still using the server's password. These are different things; pay attention to which word shows up.

Memorizing IPs is a waste of headspace. Create the `~/.ssh/config`

file on your computer:

```
Host app-prod
    HostName 203.0.113.10
    User deploy

Host app-staging
    HostName 203.0.113.20
    User deploy

# Applies to every host above
Host *
    IdentityFile ~/.ssh/id_ed25519
    AddKeysToAgent yes
    ServerAliveInterval 60
```

(The aliases and IPs above are fictional — replace them with your own.)

Fix the permission (`chmod 600 ~/.ssh/config`

) and that's it — now you connect like this:

```
ssh app-prod        # instead of ssh deploy@203.0.113.10
```

`ServerAliveInterval 60`

sends a little signal every 60s so your connection doesn't drop on its own when you go a while without typing.

Working with a key isn't enough — as long as the password is still accepted, brute-forcing is still possible. The final step is to **disable password authentication**.

⚠️ The golden rule: don't lock yourself out.Keep your current SSH session open throughout this whole step.You'll test the new configuration in asecondterminal window, without closing the first. If something goes wrong, the old session is still there for you to undo it. Only close it once the test passes.

Connected to the server, edit the SSH daemon configuration:

```
sudo nano /etc/ssh/sshd_config
```

Make sure these four lines look like this (uncomment any that have a `#`

in front):

```
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
```

`PermitRootLogin no`

— no one logs in directly as `root`

. You log in as a regular user and use `sudo`

when needed.`PasswordAuthentication no`

— the heart of the change: passwords are no longer accepted.Before applying it, **validate the syntax** — a typo here can take SSH down:

```
sudo sshd -t
```

If it prints nothing, you're clean. Then restart the service:

```
sudo systemctl restart ssh
```

📝 IfOn some distributions the service is called`ssh`

isn't the service name.`sshd`

. If the command above complains, use`sudo systemctl restart sshd`

.

Now the test — **without closing the current session**. Open a new terminal:

```
ssh app-prod
```

Got in with the key? Great. Now confirm the password is really dead:

```
ssh -o PubkeyAuthentication=no user@server-ip
```

This command tells SSH to ignore the key on purpose. The expected result is `Permission denied`

. If you got a "Permission denied", **congratulations — the password door is shut.** Now you can finally close the old session.

Your private key is your identity on those servers. Lose the file = lose access. Leak the file = hand access to someone else. Treat it accordingly.

**Do:** save the key's contents in a **secure note inside a password manager** (Bitwarden has a free plan and works well). Copy the contents with `cat ~/.ssh/id_ed25519`

and paste them into a Secure Note. Keep the passphrase in a *separate* place.

**Don't:** save the key on Google Drive, Dropbox, or OneDrive. Those services sync the file automatically across several devices and expose it through the browser. You lose control over where your identity lives.

Optional, but recommended on servers exposed to the internet:

`Port XXXX`

to `sshd_config`

and the matching `Port XXXX`

in the host block of your `~/.ssh/config`

.`fail2ban`

.`~/.ssh/config`

set up with aliases`PasswordAuthentication no`

and `PermitRootLogin no`

on all of them`Permission denied`

on the test)`fail2ban`

on public serversEvery command that appeared above, and what it does:

`ssh-keygen -t ed25519 -C "comment"`

— generates the key pair (private + public) using the Ed25519 algorithm.`ssh-keygen -p -f ~/.ssh/id_ed25519`

— adds or changes the passphrase of an existing key, without changing the key itself.`ls -la ~/.ssh/id_ed25519`

— shows the key file and its current permission.`chmod 600 ~/.ssh/id_ed25519`

— restricts read/write of the private key to your user only.`chmod 600 ~/.ssh/config`

— does the same for the aliases file.`ssh-copy-id user@server`

— copies your public key into the server's `authorized_keys`

.`ssh app-prod`

(or `ssh user@ip`

) — connects to the server.`sudo nano /etc/ssh/sshd_config`

— opens the server's SSH daemon configuration for editing.`sudo sshd -t`

— validates the `sshd_config`

syntax before applying it (prints nothing if it's OK).`sudo systemctl restart ssh`

— restarts the SSH service to apply the new configuration (`sshd`

on some distros).`ssh -o PubkeyAuthentication=no user@ip`

— forces password login on purpose; used to confirm the password is blocked (should give `Permission denied`

).`cat ~/.ssh/id_ed25519`

— prints the private key's contents, to copy into your password manager.*Murilo Negrão — backend/DevOps developer. I write about modernizing legacy stacks and the bridge between code and infrastructure.*
