Securing your server
See Linode’s Securing Your Server guide for reference.
Next, we’ll need to create a system user to use for daily administration. It’s recommended that you not use the root user, as it’s too easy to issue damaging commands. Rather, we’ll use this system user and simply elevate to root privileges when necessary via the “sudo” command. I’ll add user “newuser” in this example:
[root@localhost ~]# adduser newuser
Then set the new user’s password:
[root@localhost ~]# passwd newuser
Enter the new user’s password, then enter again when prompted.
Now edit the sudoers file. This will allow our newly created user to obtain elevated privileges with the sudo command.
[root@localhost ~]# visudo
locate the entry for the root user, and add an entry below it. Press “i” to enter insert mode, and add
newuser All=(ALL) ALL
Then press escape to leave edit mode, then “:wq” to exit visudo and save the changes.
Logout of the current SSH session by typing:
[root@localhost ~]# logout
Create a new SSH connection logging in with the credentials of your newly created user.
Now we’ll disable SSH root login. This will prevent the root user from being able to obtain SSH access. This does NOT mean we won’t be able to obtain root privileges once we’ve obtained SSH access via our system user.
Edit the /etc/ssh/sshd-config file, and search for “PermitRootLogin”. Set this value to “no” and remove any line comments (“#”).
[newuser@mail ~]$ sudo nano /etc/ssh/sshd-config
Enter root password when prompted.
While we’re editing the SSH service configuration file, we may as well change the port that SSH runs on. If you intend to have remote users obtaining access to your server via SSH, you may want to skip this step. Otherwise, each user should be informed of the alternate port on which SSH will run. Search for the “Port” directive, uncomment the line by removing the “#”, and change the default SSH port value of 22 to some other, non-frequently used port. I chose 2202. Make the necessary change and save file. Restart the SSH service:
[newuser@mail ~]$ sudo systemctl restart sshd
The next step is to implement the system firewall. This will limit the amount of inbound traffic we’ll allow, significantly reducing the server’s vulnerability.
[newuser@mail ~]$ sudo systemctl start firewalld
At this point, the only services allowed through the firewall are a DHCP client and the SSH service. To see a list of services allowed through the firewall, type:
[newuser@mail ~]$ sudo firewall-cmd --list-services dhcpv6-client ssh
We changed the port number on which the SSH service will run. Therefore, we’ll need to remove ssh as an authorized service, then open the custom SSH port by typing:
[newuser@mail ~]$ sudo firewall-cmd --remove-service sshd [newuser@mail ~]$ sudo firewall-cmd --permanent --remove-service sshd [newuser@mail ~]$ sudo firewall-cmd --add-port=2202/tcp [newuser@mail ~]$ sudo firewall-cmd --permanent --add-port=2202/tcp
If you didn’t change the default port, then don’t remove the sshd service or add the custom port as specified above.
We’ll be installing Virtualmin, which runs it’s own webserver on port 10000. We’ll issue the following commands to open ports in the firewall. The first command will modify the current firewall configuration while the second command will modify what the firewall rules will be on a reload. This separation of current rules vs. permanent rules allows us to easily add temporary rules to the firewall. We’ll use this functionality later when configuring fail2ban.
[newuser@mail ~]$ sudo firewall-cmd --add-port=10000/tcp [newuser@mail ~]$ sudo firewall-cmd --permanent --add-port=10000/tcp
You can see how easy it is to configure the firewall. We’ll be adding more rules to the firewall as we proceed through this article. But we DO want to ensure that the firewall will start upon a reboot. Currently, the firewall-start-on-reboot status should be disabled, which can be confirmed by issuing:
[newuser@mail ~]$ sudo systemctl status firewalld firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled) Active: active (running) since Wed, 2014-10-08 22:32:13 EDT; 1 hour ago
And searching for the line that begins “Loaded” – it should end in “disabled”. To enable the start-on-boot, type:
[newuser@mail ~]$ sudo systemctl enable firewalld
The last step for securing our server is the implementation of fail2ban, which allows us to block IP addresses from certain services based on that IP failing to obtain authentication for a given service a set number of times within a set time frame. For example, we’ll be configuring a fail2ban jail for the SSH service. Any IP that fails login authentication for SSH five times within a 10 minute period will be banned from the service for one year. This may seem extreme, but you’ll thank me later once you see the number of hacking attempts.
We’ll configure fail2ban to e-mail a user when an IP has been banned. I will be using an e-mail address that will be hosted on this server, so I’m going to continue with the installation and configuration of web and mail services via Virtualmin, then return to the configuration of fail2ban.
On with installing Virtualmin!
2 thoughts on “Configuring a cloud-based secure multi-domain web and e-mail server”
I use Exim as mail server and I installed opendkim using the instructions at
Awesome! To be perfectly honest, i went with postfix because it’s been the default I’ve seen installed with Virtualmin. Why did you choose to go with exim?