
warning
This article is not a step-by-step guide to be blindly followed. First, read it, understand it, and determine what is relevant to you, and only then follow the recommendations! Simply copying some commands into the root console could result in losing access to your server. Support can certainly assist you, but the time lost cannot be recovered.
1. Change the Root User Password
Typically, after renting a server, you are provided with its IP address and user password. This password is clearly visible in the virtual server control panel. If the provider generated this password, they are aware of it and store it in their database, since it needs to be recorded somewhere to display it to you every time in the control panel.
Moreover, server passwords are usually randomly generated and difficult to crack. However, passwords displayed in the control panel do not always meet these standards. Therefore, the first step is to change the root password. Consider this not as paranoia, but as a simple precaution. Don’t forget to change your password every two to three months for security reasons. Log in via SSH as root and enter the command
passwd
Yes, when you enter your password, the characters won’t be displayed—no letters, numbers, or even asterisks will appear, and that’s normal. Enter your new password and press Enter. We are now secure and can proceed with the configuration.
There are several strategies for safeguarding a root account. The first involves creating a user account with a unique name known only to you and granting it sudo
capabilities (to edit configuration files and install software) followed by disabling SSH login for the root account. This results in password authentication using a user account with a name known only to you. The advantage is that the root account cannot be hacked since it is disabled. The downside lies in the word “password.”
Password authentication is inherently less secure than public key authentication. The latter strategy involves utilizing such an authentication method. The downside is the more complex setup, especially for end users: you’ll need to generate a key pair, which might initially seem daunting to someone who has never done it before. However, on a rented VDS, it’s uncommon to create multiple SSH login accounts—typically, one or two accounts are used, particularly if there are multiple admins. The advantage of public key authentication is that no one can guess the password to access your server. If you’re using key-based authentication, you can confidently skip steps 2 and 4, as there’s no need to create an additional account or add it to sudoers. However, be sure to read step 3, as a convenient editor will be beneficial.
2. Creating a Standard User Account
After purchasing a VDS, the user is provided with the root password, and they typically copy it into their SSH client profile. However, this approach is fundamentally flawed. First and foremost, the root account is a well-known name, and when an attacker attempts to brute-force your server, they will specifically target the root account. It’s simple: the attacker doesn’t know the names of the users you’ve created, but every system has a root account. Therefore, it’s essential to have a regular user account for your day-to-day operations. Create a user account (make sure to change the name to your own):
adduser user
passwd user
The first command adds an account with the name user
, and the second command changes the password for it. Just make sure not to create an admin
user, please!
To allow this user to work with root privileges, you’ll need to add them to the sudoers
file. However, there’s an intermediate step that must be completed first.
3. Install a User-Friendly Editor
The text editor Vi, which most providers use by default, can be inconvenient and requires special knowledge, which might be a bit overwhelming for beginners.
Before installing any software, the first step is to update the package lists. This is done using the command apt
. You should update the package list at least once before the initial installation. After that, updates can be performed as needed.
# apt update
So, install any text editor you prefer. For example, the user-friendly editor nano:
# apt install nano
You can launch the editor separately using the command nano
. Let’s see where this editor is located:
which nano
Typically, the directory is /
. Now, you need to set this editor as the default. In the latest versions of Ubuntu, you can do it this way:
update-alternatives --config editor
Next, you just need to select nano from the list of available options. If this method doesn’t work (meaning the update-alternatives
command is not available), you can take a straightforward approach by setting the EDITOR
environment variable:
export EDITOR=/bin/nano
To ensure the EDITOR
environment variable is set every time you log in to the system, edit the .
file located in your home directory. Add the command:
export EDITOR=/bin/nano
Note that this needs to be done for each user. The home directory for the root user is /
, and for the user denis
, it is /
.
After this, all commands that call the default editor will use the user-friendly nano editor. One such command is visudo
.
4. Elevate to Administrator
Earlier, we created a regular user named user
. Now we need to convert this user into an administrator by granting them the ability to use sudo
. Enter the following command in the terminal:
visudo
This command will open a text editor to modify the sudoers configuration file. Find and uncomment the line.
wheel ALL=(ALL) ALL
The specified line allows all users in the wheel
group to use the sudo
command. If it is already uncommented, no further action is necessary. Press F10 to exit the editor.
After that, add our user user
to the wheel
group:
usermod -aG wheel user
Next, disconnect from the SSH server and attempt to log in as the user user
with the password you previously set. Notice that when you were logged in as the root
user, the command prompt appeared as #
, but now it appears as $
. Once logged in, enter the command
sudo bash
If the command prompt changes to #
, you now have root
privileges. This trick allows you to execute commands as root
without using the sudo
command, which is certainly more convenient.
5. Disabling Root Login via SSH
The final step is to restrict the root user from logging into the system via SSH. To do this, while logged in as the new user, execute the following command:
sudo mcedit /etc/ssh/sshd_config
Add the following line to your SSH server configuration file (or uncomment it if it’s already there):
PermitRootLogin no
Save the configuration file, restart SSH (systemctl
), and try to connect as the root user — it won’t work.
warning
You should only restart SSH if you’re certain that you can log in as the user ‘user’ (this user can run the sudo command). Otherwise, there’s a risk of losing access to the server, which would require contacting support.
An alternative approach is to keep root login enabled but configure key-based authentication (as explained below). After ensuring you can log in as root using the key, add the following line to the SSH configuration.
PermitRootLogin without-password
Of course, after that, you’ll need to restart SSH again.
6. Access the Server with a Key
There is a method of authentication called public key authentication that doesn’t rely on passwords. We won’t delve into the pros and cons here, but there are clear advantages: no one can guess your password because it simply doesn’t exist. This is the most secure form of authentication.
The principle of key-based authentication is as follows: a pair of keys (public and private) is created. The private key is stored on the client side and ideally is not accessible to anyone else. The public key is uploaded to the server that you need to access.
In an ideal world, users should generate their own keys. You can generate them using the ssh-keygen
command, as well as by utilizing the functionality of SSH clients (for instance, Bitvise SSH Client and many other clients offer key pair generation). If you’re using Linux, there’s no need to install any additional software. Just enter the command
$ mkdir ~/.ssh; ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa
Here, we are generating RSA keys with a length of 2048 bits. Once the keys are generated, the public key will be available under the name ~/.
. Next, you need to transfer the public key to the server. The simplest and most effective way to do this is by using the ssh-copy-id
command:
ssh-copy-id username@remote_host
When you execute this command, you might see the following:
The
ECDSA
Are
Your local computer simply doesn’t recognize the remote server initially—this is normal during the first connection. Type yes
(specifically yes
, not y
) and press Enter. The ssh-copy-id
command will locate the key you created and send it to the server. The contents of the ~/.
key will be copied into the remote account’s ~/.
file. This method works as long as password authentication is still enabled. During the initial setup, it’s common for all users to generate key pairs and upload their public keys to the server, after which password access is disabled. However, if password login is already disabled and you need to upload a key for a new user, you’ll need to find a way to transfer the id_rsa.
file to the server. After that, you should navigate to the ~/.
directory of the account where the key is being set up and append the contents of id_rsa.
to the end of the authorized_keys
file.
cat id_rsa.pub >> authorized_keys
Let’s not make unnecessary assumptions or complicate matters. Assume that password access is still enabled, and it is sufficient to use the ssh-copy-id
command to upload keys to the server. Once the public keys of all users are uploaded, password authentication can be disabled. To do this, open the /
file in any text editor and set the PasswordAuthentication
directive to No
:
PasswordAuthentication no
Additionally, ensure that the following three directives are configured as follows:
PubkeyAuthentication yesAuthorizedKeysFile %h/.ssh/authorized_keysPermitRootLogin without-password
The first method involves authentication via public key, the second specifies the filename where the keys should be stored, and the third allows root login without using a password (via a key).
Now all that’s left is to restart SSH:
systemctl restart ssh
To log in to an SSH server with a key on the client side, you can do the following:
ssh -i ~/.ssh/id_rsa.pub user@example.com
Here, we specify the key file name, username, and server name. In Windows, you need to configure your SSH client. For example, in Bitvise SSH Client, click the “Client key manager” link on the Login tab, then click “Generate New” in the window that appears. In the “Generate New Keypair” window, simply click “Generate.” You can also add an extra layer of security by protecting the key pair with a password—just enter and confirm the password, then click “Generate.” It is recommended to use a passphrase—if someone tries to launch the SSH client and connect to the server using your public key while you’re away, they won’t succeed because they won’t know the password.
The password is required to access the key pair only on the local computer; it is not transmitted to the server in any form. Once the key pair is generated, click the Export button to export the public key in OpenSSH format. After saving the public key to a file, upload it to the server and add its contents to the ~/.
file.
There are many ways to do this. For example, you can use an account that already has authentication configured to download the file. You could also upload the key to a website and download it on the server with the command wget
. In short, use your imagination and you’ll succeed. Once the server “recognizes” your key, in the main window of the client, choose Initial method — publickey, and from the Client Key list, select the profile where you saved the key.


7. Assigning a Non-Standard Port for SSH
By default, SSH uses port 22. However, you can reconfigure it to use a different port for security reasons—this way, connecting via SSH will require knowing the port number as well. Open the /
file and locate the Port
directive. Replace 22
with another port number:
Port 2206
After that, restart SSH and log in again. When connecting, specify the new port number in your client settings.
8. Configuring the Firewall
Once you’ve ensured user security, the next step is to configure the firewall. Traditionally, Ubuntu uses iptables as its firewall (packet filter). However, since Ubuntu is aimed at being a user-friendly distribution, an appropriate interface for iptables was created—UFW (Uncomplicated Firewall). UFW is a simple firewall. First, make sure the ufw
package is installed, and install it if it isn’t:
sudo apt install ufw
Basic Setup
Now let’s check the status of the firewall:
sudo ufw status verbose
By default, the packet filter is turned off, so the command will display Status:
. There’s no need to rush into enabling the firewall: it needs to be configured first. If port 22 is unavailable by default, you might lose access to your VDS. Sure, support can assist, but it would be a waste of time.
With default settings, the firewall blocks all incoming connections and allows all outgoing ones. This policy is ideal from a security standpoint—if anyone (including you) tries to connect to it, they’ll be unsuccessful. Meanwhile, applications on the server can still establish outgoing connections.
Let’s consider two teams:
ufw default deny incoming
ufw default allow outgoing
These two rules define the default policy: all incoming connections are blocked, while all outgoing connections are allowed.
All incoming connections are blocked. To access the server through a specific port, that port must be opened. The advantage of UFW (Uncomplicated Firewall) is that the administrator doesn’t even need to remember the port number—it’s sufficient to know the service name. For example, here is how you can allow SSH connections:
ufw allow ssh
UFW will automatically create a rule for port 22, which is used for SSH. The firewall recognizes the ports and names of all common services such as HTTP, SSH, FTP, SFTP, and others.
However, if you have reconfigured SSH to use a non-standard port, you need to specify the port number explicitly:
ufw allow 2206
After ensuring SSH access (this is crucial so that the firewall doesn’t disrupt our connection), you can enable UFW with the following command:
ufw enable
Confirmation of launch is required:
Command may disrupt existing ssh connections. Proceed with operation (y|n)?

Let’s break down what happened. First, we enabled SSH and received the response Rules
, which means the rules have been updated. Then we activated the firewall and received a message indicating that it is now active and will start on system boot. With this, the basic configuration is complete—SSH is working successfully, and we can proceed with further packet filter configuration.
Configuring Service Rules
Now it’s time to allow other applications to function. Typically, you need to enable the HTTP service (web server), FTP (if you require this service), and make sure not to overlook HTTPS (which has become increasingly important recently):
ufw allow http
ufw allow https
ufw allow ftp
The same could also be done using port numbers:
ufw allow 80
ufw allow 443
ufw allow 21
If necessary, you can allow an entire range of ports by specifying the transport protocol (UDP or TCP):
sudo ufw allow 2000:2200/tcp
sudo ufw allow 4000:4400/udp
Configuring IP Address Permissions
Ufw allows you to grant a specific IP address access to all server ports, for example:
ufw allow from 111.222.33.44
If you need to allow a specific IP address access to only a certain port, here’s how you do it:
ufw allow from 111.222.33.44 to any port 22
Here, we allow SSH connections only from the IP address 111.
, not all connections.
warning
You should only do this if you have a static IP address, which you can obtain from your provider for an additional fee. Normally, users have dynamic IP addresses—if you check your external IP and use it in the command above, you’ll lose access to the server as soon as your IP changes. So be careful!
You can allow access for an entire range of IP addresses (for example, when an admin has a dynamic IP) as follows:
ufw allow from 123.45.67.89/24 to any port 22
Blocking IP Addresses and Services
To block access from a specific IP address, use the following command:
ufw deny from 123.45.67.89
If desired, you can block all connections to a specific service:
ufw deny ftp
Removing and Resetting Rules
The following command will reset all the rules:
ufw reset
Before entering this command, make sure you’ve disabled the firewall (use the command ufw
), otherwise you might lose SSH access.
You can delete a specific rule by its number. Start by entering the following command to find the rule number:
ufw status numbered
Next, enter a command of the following format:
ufw delete <rule number>
9. Setting Up Backup Systems
Typically, the admin panel used for managing servers and other provider services offers the option to set up backups for each server. Depending on the terms of the plan, backup storage might be free (allowing you to use a certain amount of space for backups) or it might require payment. In practice, providers often charge for storing backups, so while the backup feature is available, it is often disabled to prevent any additional costs to the client.
As a VDS admin, you have two options. The first is to use the provider’s backup services, and the second is to configure backups on your own server. Backups on the provider’s side are more reliable since the copies are stored off-server. The second option is less reliable, as any issues with the server’s file system could result in total data loss. So, what should you do? The best approach is a hybrid solution—set up backups on the provider’s side with moderate frequency, say once a week. This way, the cost won’t be exorbitant, and if something happens to the file system, you can restore your data, even if it’s not the most recent. That’s still better than starting from scratch.
Now let’s talk about manually backing up on the server side. There are comprehensive backup solutions available. Whether you need them or not is up to you. I suggest taking the simplest approach. First, you need to decide which data should be backed up. If you have a website on the server (for instance, an online store), you only need to copy the files from the web server’s root directory (DocumentRoot, typically /
, but this can vary depending on server settings) and the database.
Web server files can be backed up once a week, as they don’t change very often. If you’re using your provider’s backup services, say every Friday, you can schedule the backup of server files for mid-week, like Wednesday. This way, you’ll have two backups each week just in case. You can back up more frequently, as long as you have enough disk space. If you have 1 TB of space and your site takes up 250 GB, you won’t need to create backups too often.
You can create an archive with a backup of your website files using the command
zip -r /backups/latest.zip /var/ww/html
You need to add this command to the crontab schedule. Enter the command crontab
and add the following line:
0 2 * * 3 /usr/bin/zip –r /backups/latest.zip /var/ww/html
It’s best to perform backups at night to reduce server load. In this case, backups will be created on Wednesdays at 2 AM. You can extract the archive using the unzip
command.
Now, about the database. The database is constantly being updated: managers add product information, an import script modifies prices and stock levels, and visitors place orders. Therefore, a backup of the database should be created once a day. We use mysql-dump
for the backup:
mysqldump -u cp_user -p --opt cp_main_v2 --max_allowed_packet=100M > db-latest.sql
In this context, cp_user
is the database username, cp_main_v2
is the database name, and the max_allowed_packet
option sets the maximum packet size—which is useful if your database is several gigabytes in size, as this option can prevent issues. The backup is saved to the file db-latest.
. To restore, you can proceed as follows:
mysql --host=127.0.0.1 --port=3310 --max_allowed_packet=100M -u cp_user -p cp_main_v2 < /db-latest.sql
The purpose of the parameters should be clear. You can omit the host
and port
parameters if MySQL is running on localhost and using the default port. Since the dump creation command needs to be executed daily, add the following line to crontab.
0 1 * * * /usr/bin/mysqldump -u cp_user -p --opt cp_main_v2 --max_allowed_packet=100M > /root/db-latest.sql
A backup will be taken every day at 1 AM (and at 2 AM, we start the creation of the file backup).
Besides backups, don’t forget about snapshots! Before making any significant changes on the server (such as installing extensions, rebuilding the CMS, or updating software like upgrading to a new PHP version), create a snapshot. While you can always restore from a backup, backups may not be the most recent, and restoration takes longer than recovering from a snapshot. Snapshots also come with a cost, but it’s negligible compared to the downtime of a production server.
Lastly – Setting Up the Admin Panel
Personally, I find it easier and more familiar to manage a server via SSH. However, if you need a graphical interface for daily routine tasks, you can install a control panel. The choice of a specific panel depends on two factors: the required functionality and the cost of the control panel. If you are looking for free solutions, consider Webmin and VestaCP; other options are less popular.
That’s all there is to it—the basic setup of the VDS is complete. You can now proceed with installing and configuring the necessary software, such as Nginx, MySQL, PHP, and more.

2022.02.15 — EVE-NG: Building a cyberpolygon for hacking experiments
Virtualization tools are required in many situations: testing of security utilities, personnel training in attack scenarios or network infrastructure protection, etc. Some admins reinvent the wheel by…
Full article →
2022.01.01 — It's a trap! How to create honeypots for stupid bots
If you had ever administered a server, you definitely know that the password-based authentication must be disabled or restricted: either by a whitelist, or a VPN gateway, or in…
Full article →
2022.02.09 — First contact: An introduction to credit card security
I bet you have several cards issued by international payment systems (e.g. Visa or MasterCard) in your wallet. Do you know what algorithms are…
Full article →
2023.03.26 — Poisonous spuds. Privilege escalation in AD with RemotePotato0
This article discusses different variations of the NTLM Relay cross-protocol attack delivered using the RemotePotato0 exploit. In addition, you will learn how to hide the signature of an…
Full article →
2022.06.01 — Quarrel on the heap. Heap exploitation on a vulnerable SOAP server in Linux
This paper discusses a challenging CTF-like task. Your goal is to get remote code execution on a SOAP server. All exploitation primitives are involved with…
Full article →
2023.06.08 — Cold boot attack. Dumping RAM with a USB flash drive
Even if you take efforts to protect the safety of your data, don't attach sheets with passwords to the monitor, encrypt your hard drive, and always lock your…
Full article →
2023.02.13 — First Contact: Attacks on Google Pay, Samsung Pay, and Apple Pay
Electronic wallets, such as Google Pay, Samsung Pay, and Apple Pay, are considered the most advanced and secure payment tools. However, these systems are also…
Full article →
2022.06.01 — First contact. Attacks on chip-based cards
Virtually all modern bank cards are equipped with a special chip that stores data required to make payments. This article discusses fraud techniques used…
Full article →
2022.01.13 — Step by Step. Automating multistep attacks in Burp Suite
When you attack a web app, you sometimes have to perform a certain sequence of actions multiple times (e.g. brute-force a password or the second authentication factor, repeatedly…
Full article →
2022.02.09 — Dangerous developments: An overview of vulnerabilities in coding services
Development and workflow management tools represent an entire class of programs whose vulnerabilities and misconfigs can turn into a real trouble for a company using such software. For…
Full article →