Properly setting up your server lays the foundation for everything that follows, including software installations and configurations

A well-prepared server not only ensures smooth operation but also optimizes performance and security. This critical first step helps ensure your server runs smoothly and performs at its best.

In this guide, I will walk you through the process of preparing your Ubuntu server for its first use, so you can start off on the right track.

Documentation

Before we get into the technical steps, I want to highlight the importance of documenting everything you do on the server.

Writing down key details like changes you make, installed software, and any issues you encounter can save you a lot of time later.

This habit is essential for troubleshooting, ensuring consistency, and maintaining a secure, well-functioning server over the long term.

Personally, I always make sure to note the date and time, the commands I run, and a brief description of what I intended to achieve. I document every detail, no matter how small.

This includes changes to critical configuration files like sshd_config, software installations, and firewall modifications – literally everything.

To get started, you can use a simple plain text file. Later, you can explore different tools to find what works best for you.

I sometimes use Notion for this purpose.

Logging in as Root

To access your Ubuntu server, you'll need the root password and the server's IP address.

Many providers allow you to set this password during server creation on their dashboard or send it to you via email with the server details, as Hetzner does.

Keep in mind that the root password provided by providers like Hetzner is often temporary. Once you access your server, you'll need to change it.

👉
New to Hetzner? Use my link to get free credits!

With the server IP and root password in hand, accessing your server is very simple.

Just open the local terminal and type this:

ssh root@<server_ip_address>

Enter the password, and that's it – you're in!

💡
Use the passwd command to change the root password or update the password for any user on your server.

Running Updates

After accessing your server, you may encounter a message indicating that there are packages, including security patches, available for updating.

Using outdated software may exposes your server to security vulnerabilities.

Therefore, a very important step in securing and maintaining your server's health is to update your server's packages and download any available security patches.

Begin by updating the package list on your server with the following command:

apt update

This command prompts the server to scan the server's packages and identify those requiring updates, including security patches.

Once this is done, run the following command to update your server's packages that need updating:

apt upgrade

The server may ask for confirmation by displaying a prompt that requires a yes or no response. Make sure to type yes.

The updating process may take a while, depending on the number of updates needed.

🙆‍♂️
Some immediately reboot after updating, but I prefer waiting until the server setup is complete to ensure all changes apply.

Updates provide critical security patches, performance improvements, and software bug fixes.

Adding a Non-Root User

The root user possesses unrestricted control over the entire server, allowing you to execute any command.

Using root increases the risk of making mistakes, as you can accidentally break your server.

It’s safer to use a non-root user, requiring the sudo prefix for administrative commands and a password prompt.

This slight difference in permission levels makes sure you proceed carefully, as trying to execute commands without the sudo prefix will result in error messages.

To add a new user, simply use this command:

adduser <username>

The server will ask for a password and some optional details – Simply press ENTER to skip through these optional details.

💡
Avoid weak passwords and use a password manager for generating and securely storing complex passwords.

Now, we need to grant this user root privileges by making them part of the sudo group:

usermod -aG sudo <username>

To check that the new user is good to go, log out with the logout command and access your server again with the new user:

ssh <new_user>@<server_ip_address>

Try running the apt update command. It should not work directly, as you need to run the command like this: sudo apt update and then enter your password.

👍
Now you can use the non-root user instead of root.

SSH Keys & Hardening

When it comes to accessing your server, you use your password, but SSH key authentication offers a more secure alternative. This method uses a key pair (public and private keys) to replace password authentication.

The public key is stored on the server, and the private key is kept by you, the server administrator.

Authentication occurs when the server sends a message encrypted with the public key, and if the user can decrypt it using the private key, access is granted.

This ensures that only those with the private key can access the server, significantly improving security over password-only authentication.

Now, let’s generate your key pair and transfer the public key to your server.

First, check if you already have a key pair on your computer by running:

ls -l ~/.ssh

If the directory is empty or only contains known_hosts files, you're good to proceed. Otherwise, back up existing keys.

If the directory doesn’t exist, it will be created automatically when generating a key pair.

To create a new key pair, run:

ssh-keygen -b 4096

This command generates a 4096-bit key pair, providing a stronger key than the default size. You can accept the default path to save the key, or specify a custom name to avoid overwriting an existing key. You’ll also be prompted to set a passphrase for extra security, which you'll need whenever you connect to the server.

Once generated, you'll find two files in your .ssh directory: id_ed25519 (your private key) and id_ed25519.pub (your public key).

Before copying the public key to the server, note the following:

If the public key is placed in the .ssh directory of the root user, only the root user will use key authentication. If placed in another user's .ssh directory, only that user will have key access, while root will not. It's important to copy the key to the specific user's .ssh directory for whom you want to enable key-based access.

Since we've created a non-root user, we'll copy the public key for that user, as root access isn't needed.

To enable key authentication, copy the public key to the server using the following command on your computer:

ssh-copy-id -i ~/.ssh/id_ed25519.pub <user>@<server_ip_address>

Replace <user> with the username and <server_ip_address> with your server’s IP address. After entering the password for that user once, you’ll be able to access the server using SSH keys instead of a password.

💡
Users without a public key can still have access with a password, unless password authentication has been disabled in the sshd_config file.

Now that we have a non-root user with root privileges and have successfully set up SSH key authentication, the next step is to secure the server further by restricting root access via SSH and disabling password authentication.

This ensures that only our non-root user with the SSH key can connect, while root and password-based access attempts are blocked, protecting the server from brute-force attacks.

To achieve this, we need to edit the /etc/ssh/sshd_config file.

Open the file with your preferred text editor and find the #PasswordAuthentication and #PermitRootLogin variables.

Uncomment them and set both to no like this:

PasswordAuthentication no
PermitRootLogin no
Some server providers add their own SSH settings in the /etc/ssh/sshd_config.d directory. Be sure to check this before reloading the SSH service.

Save and close the file, then reload the SSH service:

sudo systemctl reload ssh

At this point, root access is blocked, and users without an SSH key will be denied access. If you attempt to connect as the root user, you'll see the error:

root@serverip: Permission denied (publickey).

Similarly, users without a public key will also be denied, ensuring that only your non-root user with SSH key authentication can have access.

Changing Server Hostname

Setting a meaningful hostname for your servers is like giving them a name tag – it makes them easily recognizable and more user-friendly.

This comes in handy when you want to double-check that you're working on the right server, reducing the chances of accidentally messing with the wrong one.

But, there are other reasons why setting a hostname is important:

  • Some programs need the hostname to work correctly. Properly configuring a server's hostname is essential for certain network services to function as they should.
  • If a server's hostname can't be resolved to an IP address, it can cause communication and networking issues. This may result in timeouts, connection errors, and other unexpected behavior.

To change the hostname, use the following command:

sudo hostnamectl set-hostname <yourservername.yourdomain.com>

Typically, a hostname has two parts: the server name and the domain name.

For instance, if you're naming your server myserver and your domain is example.com, your hostname would be myserver.example.com.

Make sure to add an A record for your hostname.

Changing Timezone

Setting the timezone for your server is important because it ensures that the server's clock matches the correct time in your specific location.

If the server's timezone is not set right, it can cause problems like wrong timestamps on log files, scheduling issues with tasks (cron jobs), and other issues that depend on accurate time information.

Use the following command to list the available timezones:

timedatectl list-timezones

This will show you a long list of timezones to choose from.

Once you've picked the right one, type the following command to set it:

sudo timedatectl set-timezone <yourtimezone>

Your server is now in sync with the correct timezone.

Changing Default Editor

You can change the default editor used by your server, such as when running the crontab or visudo commands.

It's usually Nano, but you can switch it to Vim or any other preferred editor using the following command:

sudo update-alternatives --config editor

Enter the number corresponding to the chosen editor and press the ENTER key.

🙆‍♂️
I personally use Vim.

Installing Essential Software

Depending on your specific needs and the purpose of your server, there may be additional essential packages you would want to install.

I always install these packages on my servers:

sudo apt install git htop curl wget zip unzip net-tools ncdu rsync

These packages cover a range of common tasks that you may encounter while managing and using your server.

Setting Up a Firewall

Configuring a basic firewall that allows only SSH traffic is an essential step in preparing your server for use.

This initial setup ensures that your server is secure, allowing you to plan additional firewall rules later with confidence that only SSH traffic is permitted.

Ubuntu uses the UFW (Uncomplicated Firewall) utility to make setting up and managing firewall rules simple and straightforward.

On Debian-based distributions, like Ubuntu, it often comes pre-packaged. You can check and install it using:

sudo apt install ufw

Some providers, like Vultr, enable UFW by default with only SSH traffic allowed. You can check UFW’s status with:

sudo ufw status

If it’s inactive, we’ll configure and activate it. If it’s active, disable and reset it with:

sudo ufw disable
sudo ufw reset

By default, UFW blocks all incoming traffic while allowing outgoing connections.

To allow SSH access on port 22, use:

sudo ufw allow 22/tcp

Then, enable UFW:

sudo ufw enable

Now, UFW allows only SSH traffic.

💡
If you add services like a web server, open ports 80 (HTTP) and 443 (HTTPS) as needed.

Configuring Swap Space

One way to protect your server from running out of memory is by adding swap space, especially if you are low on RAM.

Swap space is essentially a portion of the hard drive that can be used like RAM when your server no longer has enough free memory.

The caveat is that it is slower than RAM since data is written to the disk. However, it provides valuable safety against out-of-memory situations.

I typically configure swap space on servers with SSD or NVMe storage. On older hardware, I prefer to add more RAM instead.

First, check if your server already has existing swap space by running:

sudo swapon --show

If you receive no output, it means that swap space has not been added. You can confirm this by using the free -h command.

A good rule of thumb is to allocate swap space equal to the amount of RAM you have or double it if you have sufficient storage.

We will create a swap file of the desired size, which we will name swapfile, in the root directory:

sudo fallocate -l 1G /swapfile

In this example, we're allocating a 1 GB swap space.

Now that we have created the file, we need to secure it by adjusting the file permissions to ensure that only users with root privileges can read it. This is crucial for maintaining security.

Make the file accessible only to the root user by typing:

sudo chmod 600 /swapfile

Next, we will mark the file as swap space:

sudo mkswap /swapfile

After marking the file, enable the swap file so that the system can start using it:

sudo swapon /swapfile

Use the free -h command again to check that the swap space is now active.

While the swap file is enabled for the current session, it will not persist after a reboot. To ensure that the swap space remains available, you need to add it to the /etc/fstab file.

Add the following line to the end of the file:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Now, the swap space will remain active even after a reboot.

Configuring SMTP Relay

It is very important to install Postfix and configure it to use an external SMTP server for sending emails.

By doing this, your server will be able to send email notifications and alerts from packages like Unattended Upgrades, for example, in case an updating process fails.

Email notifications and alerts play a crucial role in maintaining the health of your server.

How to Configure Postfix for External SMTP Relay
Step-by-step tutorial to setting up Postfix for external SMTP relay with SMTP2GO for secure and efficient email delivery.

Applying Changes

Now, let's give the server a little reboot to make sure everything takes effect.

Use the following command to reboot:

sudo reboot

Now, all changes should be applied.

Using the Config File

The config file is basically a list that holds information about the servers we manage and access using SSH.

It simplifies the process of connecting to our servers and organizes server information into a single file for easy access.

Open your local terminal (without accessing the server) and create the file using the following command:

touch ~/.ssh/config

Open the file with your preferred editor and add the following:

Host server1
        HostName 81.41.156.93
        User ivan
        Port 22
        IdentityFile ~/.ssh/id_rsa

This is an example of a server I named server1 with the IP address 81.41.156.93.

I want to use the user ivan to access my server using port 22 and the private key id_rsa.

Now, if I want to access my server, instead of using this command:

ssh -p 22 -i ~/.ssh/id_rsa ivan@81.41.156.93

I simply use this:

ssh server1

Do you see how easy it is to access a server now?

I added the -p 22 option just to show you how the command will look without the config file. SSH will use port 22 by default, so there is no need to add this option when accessing the server normally.

Now, replace the information above with the details of your server and attempt to access the server as I did. Leave the SSH port as it is if you didn't change it, as SSH uses port 22 by default.

When you have multiple servers, add a new Host block for each server.

Conclusion and Final Thoughts

Congratulations on reaching the end!

You’ve successfully prepared your Ubuntu server for its first use and have taken important steps toward managing it safely.

Now, it’s time to take the security of your server up a notch.

I’ve created a comprehensive guide on server security and hardening, where I share the exact security measures I implement on my own servers.

If you found value in this guide or have any questions or feedback, please don't hesitate to share your thoughts in the discussion section.

Your input is greatly appreciated, and you can also contact me directly if you prefer.