Initial Ubuntu 18.04 Server Setup: SSH, Users, UFW, Fail2ban

If you’ve ever spun up a fresh Ubuntu 18.04 server and then locked yourself out over SSH, you know the feeling.
One wrong path, one missing firewall rule, and suddenly you’re staring at “Permission denied” instead of your shiny new shell.

After a clean setup, life is better: you log in with your own user, SSH keys work, root login is disabled, and basic protections like UFW and Fail2ban are already in place.
This guide walks through that path, step by step, using only what’s in the original tutorial and comments, plus a few safety notes.

I’m assuming you already have a working Ubuntu 18.04 server and SSH access as root.
We’ll walk from root login to a safer, more usable server with minimal drama.

1. Why You Shouldn’t Live in Root

Most new servers drop you straight into the root account.
It feels powerful, but it’s also dangerous: one bad command and you can destroy the system.

Also, many tools and guides expect you to have a regular user with sudo, not full-time root.
So first goal: create a normal user, give it sudo, and log in with SSH keys.

While you’re doing initial setup, keep a second connection or console open if possible.
If something goes wrong, you still have a way back in.

2. Create a Non-Root User and Copy SSH Keys (Without Breaking Them)

You want a regular user (let’s call them sammy, same as in the source comments) that can log in over SSH using the same key you’re already using for root.
The basic idea: create user, set permissions, then copy the .ssh directory from root.

Step 2.1 – Create the user

From your current root SSH session:

adduser sammy

Follow the prompts to set a password and basic info.
The password is mostly for sudo and console login; we’ll use SSH keys for remote access.

If you need sudo powers for this user:

usermod -aG sudo sammy

Now sammy is a regular user with admin ability via sudo.

Step 2.2 – Copy your root SSH keys correctly with rsync

The original tutorial used rsync to copy the .ssh directory from root’s home to the new user.
The comment in the source pointed out a very common trap: a trailing slash on the source path changes what rsync copies.

They used:

rsync --archive --chown=sammy:sammy ~/.ssh /home/sammy

Important detail: no trailing slash on ~/.ssh.

Why this matters:

  • ~/.ssh (no slash) → rsync copies the directory itself into /home/sammy.
  • Result: /home/sammy/.ssh/authorized_keys (correct for SSH).
  • ~/.ssh/ (with slash) → rsync copies the contents of .ssh directly into /home/sammy.
  • Result: /home/sammy/authorized_keys just sitting in the home folder, and SSH won’t see it.

If you accidentally hit <Tab> and get a trailing slash, rsync will happily copy things, but SSH will ignore your keys and you’ll get a login failure.

So, from root, run exactly:

rsync --archive --chown=sammy:sammy ~/.ssh /home/sammy

The --chown flag fixes ownership in one go so sammy owns their .ssh folder.
That’s important because SSH is strict about permissions.

Step 2.3 – Quick permission sanity check

Still as root, check the new home and .ssh permissions:

ls -ld /home/sammy
ls -ld /home/sammy/.ssh
ls -l /home/sammy/.ssh

You want to see something like:

  • /home/sammy owned by sammy:sammy
  • /home/sammy/.ssh owned by sammy:sammy
  • authorized_keys inside .ssh

If authorized_keys is loose in /home/sammy instead of inside .ssh, you probably used the trailing slash.
Move it into place:

mkdir -p /home/sammy/.ssh
mv /home/sammy/authorized_keys /home/sammy/.ssh/
chown -R sammy:sammy /home/sammy/.ssh

Now your new user should be ready to try SSH.

3. Make Sure the Firewall Isn’t Blocking You (UFW + OpenSSH)

Another very common problem: you set up the new user perfectly… then UFW blocks you from logging in.
The source comments specifically mention this: you might not be able to access with the new user until you allow OpenSSH in UFW.

Step 3.1 – Allow SSH through UFW

From root or via the console (if you’re already locked out over SSH), run:

ufw allow OpenSSH

In the comment, they also allowed port 22 explicitly:

ufw allow 22

Both rules punch a hole for SSH.
In many setups, ufw allow OpenSSH is enough, but if you’re following that comment literally, you can add both.

Step 3.2 – Enable UFW (if it’s not already)

If UFW is installed but not enabled:

ufw enable

Always make sure you’ve allowed SSH before enabling UFW, or you risk locking yourself out.
Once enabled, check status:

ufw status verbose

You should see rules for OpenSSH and/or port 22.

4. Test SSH Login as the New User Safely

Time to see if it all works, but don’t close your root session yet.
Keep it open until you confirm sammy can log in and use sudo.

Step 4.1 – New SSH test login

From your local machine, open a new terminal window and connect with:

ssh sammy@your_server_ip

If your key is set up right and permissions are correct, you should drop into a shell without a password prompt (for SSH).
If you get Permission denied (publickey), re-check where authorized_keys actually lives and its permissions.

Step 4.2 – Test sudo works

Once logged in as sammy, confirm sudo is functional:

sudo ls /root

You should get a password prompt (use sammy’s password) and then see the contents of /root.
If sudo fails, make sure you added sammy to the sudo group from Step 2.1.

Only after this test succeeds should you think about disabling root SSH.

5. Disable Direct SSH Root Login (After You Confirm the New User)

One of the commenters suggested adding a “Step 6: Disable SSH root login”.
This is a good security habit: it forces attackers to guess a username as well as a key/password.

Step 5.1 – Edit the SSH config

Logged in as root or sammy with sudo, open the SSH daemon config file:

sudo nano /etc/ssh/sshd_config

Look for the line with PermitRootLogin.
If it’s commented out or set to something else, update it so it reads:

PermitRootLogin no

If the line doesn’t exist, you can add it near the other authentication settings.

Step 5.2 – Restart SSH daemon

Apply the changes by restarting the SSH service:

sudo systemctl restart sshd

Now try to SSH as root from your local machine:

ssh root@your_server_ip

It should refuse the login.
Your sammy user should still work fine.

Keep your sammy SSH session open while you test this, so you aren’t locked out if you mistype something in the config.

6. Add Basic Brute-Force Protection with Fail2ban

Another suggestion in the source comments was installing Fail2ban.
Fail2ban monitors logs (like SSH login attempts) and temporarily bans IPs that fail too many times.

The comment was very simple about it:

apt-get install fail2ban

That’s enough to get it installed.
Here’s how to do that safely and make sure it’s running.

Step 6.1 – Install Fail2ban

Logged in as root or your sudo user:

sudo apt-get update
sudo apt-get install fail2ban

This pulls in Fail2ban and its dependencies.
The default install already has basic SSH monitoring behaviour, which is usually fine for a quick hardening pass.

Step 6.2 – Check Fail2ban status

After installation, confirm it’s running:

sudo systemctl status fail2ban

You want to see active (running).
If it’s not active, you can start and enable it at boot with:

sudo systemctl start fail2ban
sudo systemctl enable fail2ban

From here, Fail2ban will start watching for repeated failed login attempts and block those IPs for a while.
It’s not a magic shield, but it helps a lot with noisy bots.

7. Alternative Key Transfer (If rsync or Paths Are Painful)

Someone in the comments mentioned https://transfer.sh/ as an alternative to rsync for moving files around.
They used curl like this:

curl -H "Max-Downloads: 1" -H "Max-Days: 5" --upload-file ./xxx.pub https://transfer.sh/xxx.pu...

That example shows the basic pattern:

  • Use curl to upload a file (./xxx.pub) to transfer.sh
  • Set a maximum number of downloads and days

The comment also said they weren’t sure about the security compliance on that service.
So this is more of a convenience tip than a strong recommendation.

If you’re just moving a public key (.pub file), this kind of service is generally less risky than handing around private keys.
But be careful: never upload your private key, and always think about whether you trust any external service with your data.

In many cases, copying keys locally and using rsync as in Section 2 is simpler and more under your control.

8. Common Gotchas and Quick Checks

Let’s wrap with the most common issues from this kind of setup, and what to check.

Gotcha #1 – SSH key doesn’t work for the new user

Symptoms:

  • Permission denied (publickey) when you ssh sammy@server.

Checks:

  • Confirm that authorized_keys is inside /home/sammy/.ssh/, not directly in /home/sammy/.
  • Make sure you didn’t add a trailing slash in the rsync command (~/.ssh/ vs ~/.ssh).
  • Confirm ownership:

bash
ls -ld /home/sammy /home/sammy/.ssh
ls -l /home/sammy/.ssh

You want sammy:sammy as the owner everywhere in that path.

Gotcha #2 – UFW locked you out

Symptoms:

  • SSH suddenly stops working; timeouts or connection refused.

Checks:

  • From console or recovery access, run:

bash
ufw status verbose

  • Ensure you see lines like:

text
OpenSSH ALLOW Anywhere
22 ALLOW Anywhere

  • If not, add them:

bash
ufw allow OpenSSH
ufw allow 22

Gotcha #3 – Root can still log in over SSH

Symptoms:

  • ssh root@server still works even though you thought you disabled it.

Checks:

  • Open /etc/ssh/sshd_config and confirm you have:

text
PermitRootLogin no

  • Make sure it’s not duplicated later in the file with a different value.
  • Restart the SSH service after any change:

bash
sudo systemctl restart sshd

That’s the basic, practical setup: non-root user with keys, firewall letting you in, root login blocked, and Fail2ban watching your back.
From here you can start layering on more tools and services knowing you’re not one typo away from a locked server.

Need more help? Check the latest CrushEdge posts.

No Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.