Basic Security on a Linux Server

Basic Security on a Linux Server

Here in this guide we will show how to make some basic security configurations on the Server, so it is a bit more secure against hackers.

In this example we will use a fresh installed “Ubuntu 16.04 – Plesk Onyx” vServer M8 to showcase and test it.

1. Make sure that the Server is up to date
(this is something you should do regularly on the Server so the latest security patches etc. are installed)

Code:
apt-get update && apt-get dist-upgrade

2. Configure login over SSH Key and disable Password login

3. Create a new non-root-user (you can add this user to the sudo list “usermod -aG sudo <username>” as a root user, or just “su root” when needed)

Code:
# adduser community
Adding user `community' ...
Adding new group `community' (1010) ...
Adding new user `community' (1000) with group `community' ...
Creating home directory `/home/community' ...
Copying files from `/etc/skel' ...
Enter new password:
Retype new password:
passwd: password updated successfully
Changing the user information for community
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n] Y

Also add an SSH Key there for the login

Code:
su <username>
mkdir /home/<username>/.ssh/
chmod 700 /home/<username>/.ssh/
nano /home/<username>/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Test if you can login into the new user

4. Configure the sshd_config (Change SSH Port/Disable root login)
Change the SSH Port there (If you already have a firewall configured DO NOT forget to allow the connection on the new port) and disable root login

Code:
nano /etc/ssh/sshd_config

Change “Port 22″there to the port number that you want, in this example I will use 1923

My SSHD_CONFIG now looks like this:

Code:
# cat /etc/ssh/sshd_config
# Package generated configuration file
# See the sshd_config(5) manpage for details

# What ports, IPs and protocols we listen for
Port 1923
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 1024

# Logging
SyslogFacility AUTH
LogLevel INFO

# Authentication:
LoginGraceTime 120
PermitRootLogin no
StrictModes yes

RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile     %h/.ssh/authorized_keys

# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no

#MaxStartups 10:30:60
#Banner /etc/issue.net

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes

5a. Basic configuration of the firewall via UFW(uncomplicated firewall)

Keep in mind that on the vServers there is a limit on the rules that you can set. You can check how many you are using and how many you can set with:
cat /proc/user_beancounters | grep numiptent

Example:

# cat /proc/user_beancounters | grep -iE “numiptent|uid”
uid resource held maxheld barrier limit failcnt
numiptent 173 177 256 256 0

As you can see I am using 173 and I am allowed a max of 256

Install UFW

Code:
apt install ufw

As we do not have IPv6 we can disable it

Code:
nano /etc/default/ufw

and change the “IPV6=yes” to “IPV6=no”

Add the rules:

Code:
ufw allow 1923

Change this one to the port number that you using for SSH

ufw allow 22 -> for the fake SSH
Add all ports that you use

If you are sure that the SSH port is allowed runs then
(with “ufw show added” you can check all the rules that will be added”

Example:
# ufw show added
Added user rules (see ‘ufw status’ for running firewall):
ufw allow 1923
ufw allow 22
ufw allow 21
ufw allow 8443
ufw allow 80
ufw allow 443
ufw allow Postfix)

to start the Firewall and update the rules use:

Code:
ufw enable

5b. Basic configuration of the firewall via IPTables

Please do not forget that the firewall configuration depends on your needs and your configuration so the rules and ports need to be changed according to your server! Running this blindly may cause losing the connection to the server. We take no responsibility for that.

You can also setup the configuration over IPTables.
Here in this example we will block all incoming traffic and only allow the one we want.
Do not forget to set your SSH port to allow incoming first before setting the drop policy!

To check all your rules you can use the command “iptables -L”

Here you can see that at the moment there are no rules and the policy is to accept all:

Code:
# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Also as external check I did a port scan before the setup:

Code:
$ nmap <Your IP or Hostname> -PN -p1-10000

Starting Nmap 7.01 ( https://nmap.org ) at 2018-03-23 08:05 CET
Nmap scan report for euve183269.serverprofi24.de (62.75.138.43)
Host is up (0.0073s latency).
Not shown: 9984 closed ports
PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
25/tcp   open  smtp
53/tcp   open  domain
80/tcp   open  http
106/tcp  open  pop3pw
110/tcp  open  pop3
143/tcp  open  imap
443/tcp  open  https
465/tcp  open  smtps
993/tcp  open  imaps
995/tcp  open  pop3s
1923/tcp open  unknown
4190/tcp open  sieve
8443/tcp open  https-alt
8880/tcp open  cddbp-alt

Nmap done: 1 IP address (1 host up) scanned in 0.74 seconds

So as advised above first I will set my SSH port to accept connections:

Code:
iptables -A INPUT -p tcp --dport 1923 -j ACCEPT

change the 1923 to the port where your SSH is active

Code:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

This will allow connections to port 22 where I will setup the fake SSH in step 6

Code:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 8443 -j ACCEPT

Here I did now allow access to the Webserver and Plesk

Code:
iptables -A INPUT -i lo -j ACCEPT

Here we do allow the loopback connections so that we do not get issues with some services etc.

Now that we do have our SSH allowed we can change the policy to drop with:

Code:
sudo iptables -P INPUT DROP

This will now cause all incoming connections where there is no allow rule specified to be rejected.

Now we check again with iptables -L

Code:
# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:1923
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:8443
ACCEPT     all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

As you can see “Chain INPUT (policy DROP)” so the default is set to reject all input/incoming
And then we have the other rules to accept the connection. We can check that with a new port scan:

Code:
$ nmap 62.75.138.43 -PN -p1-10000

Starting Nmap 7.01 ( https://nmap.org ) at 2018-03-23 08:16 CET
Nmap scan report for euve183269.serverprofi24.de (62.75.138.43)
Host is up (0.0075s latency).
Not shown: 9995 filtered ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
443/tcp  open  https
1923/tcp open  unknown
8443/tcp open  https-alt

Nmap done: 1 IP address (1 host up) scanned in 24.99 seconds

And a 2nd scan checking all ports that where open in the first scan:

Code:
$ nmap 62.75.138.43 -PN -p21,22,25,53,80,106,110,143,443,465,993,995,1923,4190,8443,8880

Starting Nmap 7.01 ( https://nmap.org ) at 2018-03-23 08:18 CET
Nmap scan report for euve183269.serverprofi24.de (62.75.138.43)
Host is up (0.0075s latency).
PORT     STATE    SERVICE
21/tcp   filtered ftp
22/tcp   open     ssh
25/tcp   filtered smtp
53/tcp   filtered domain
80/tcp   open     http
106/tcp  filtered pop3pw
110/tcp  filtered pop3
143/tcp  filtered imap
443/tcp  open     https
465/tcp  filtered smtps
993/tcp  filtered imaps
995/tcp  filtered pop3s
1923/tcp open     unknown
4190/tcp filtered sieve
8443/tcp open     https-alt
8880/tcp filtered cddbp-alt

Nmap done: 1 IP address (1 host up) scanned in 1.26 seconds

As you can see all ports we did not specify in the IPTables are filtered (not accepting the connection)
Please be careful when setting this rules as it is way to easy to get locked out of the server if wrongly done or in wrong order!

We recommend you to use a bash script to runs this changes.
Here a small example:

For this we will suppose that we do have a Server with a Plesk setup so we need Webserver, Mailserver, Plesk, SSH reachable.

Code:
nano /opt/rules.sh

here we will input all the rules we want to set:

Code:
#!/bin/sh

# Flush all rules
sudo iptables -t filter -F
sudo iptables -t filter -X

# Block everything by Policy
sudo iptables -t filter -P INPUT DROP
sudo iptables -t filter -P FORWARD DROP
sudo iptables -t filter -P OUTPUT DROP

# Allow already established connections
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -t filter -A INPUT -i lo -j ACCEPT
sudo iptables -t filter -A OUTPUT -o lo -j ACCEPT

# Allow SSH connections (CHANGE IN THIS BLOCK THE PORT TO YOUR SSH CONNECTION)
sudo iptables -t filter -A INPUT -p tcp --dport 1923 -j ACCEPT
sudo iptables -t filter -A OUTPUT -p tcp --dport 1923 -j ACCEPT

# Allow Fake SSH connections
sudo iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -t filter -A OUTPUT -p tcp --dport 22 -j ACCEPT

# Allow DNS requests
sudo iptables -t filter -A OUTPUT -p tcp --dport 53 -j ACCEPT
sudo iptables -t filter -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -t filter -A INPUT -p tcp --dport 53 -j ACCEPT
sudo iptables -t filter -A INPUT -p udp --dport 53 -j ACCEPT

# Allow HTTP&HTTPS connections
sudo iptables -t filter -A OUTPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -t filter -A OUTPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT

# Allow FTP connections
sudo iptables -t filter -A OUTPUT -p tcp --dport 20:21 -j ACCEPT
sudo iptables -t filter -A INPUT -p tcp --dport 20:21 -j ACCEPT

# Allow Mail SMTP connections
iptables -t filter -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 25 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 465 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 465 -j ACCEPT

# Allow Mail POP3 connections
iptables -t filter -A INPUT -p tcp --dport 110 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 110 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 995 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 995 -j ACCEPT

# Allow Mail IMAP connections
iptables -t filter -A INPUT -p tcp --dport 143 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 143 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 993 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 993 -j ACCEPT

# Allow Plesk HTTPS and HTTP connections
iptables -t filter -A INPUT -p tcp --dport 8443 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 8880 -j ACCEPT

# Allow NTP (server time)
sudo iptables -t filter -A OUTPUT -p udp --dport 123 -j ACCEPT

# Allow Ping Requests
sudo iptables -t filter -A INPUT -p icmp -j ACCEPT
sudo iptables -t filter -A OUTPUT -p icmp -j ACCEPT

Now then lets use the file:

Code:
cd /opt/
chmod +x rules.sh
./rules.sh

This will make the rules look like:

Code:
# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:1923
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere             tcp dpts:ftp-data:ftp
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:smtp
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:urd
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:pop3
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:pop3s
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imap2
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imaps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:8443
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:8880
ACCEPT     icmp --  anywhere             anywhere

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:1923
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
ACCEPT     tcp  --  anywhere             anywhere             tcp dpts:ftp-data:ftp
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:smtp
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:urd
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:pop3
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:pop3s
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imap2
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imaps
ACCEPT     udp  --  anywhere             anywhere             udp dpt:ntp
ACCEPT     icmp --  anywhere             anywhere

6. Install a fake SSH (optional, this may help against bots and less skilled hackers who may not even try to find the real ssh port).

Check: https://github.com/tylermenezes/FakeSSH there are other options

Code:
apt-get install git
cd /opt/
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
pip install paramiko

git clone https://github.com/tylermenezes/FakeSSH.git
ssh-keygen

Save it to /opt/FakeSSH/data/rsa

Code:
cp /opt/FakeSSH/data/config.sample.json /opt/FakeSSH/data/config.json

You can edit /opt/FakeSSH/data/config.json as required

Code:
chmod +x /opt/FakeSSH/server.py
chmod +x /opt/FakeSSH/stats.py
Code:
nano /etc/init/fakessh.conf

Add there:

Code:
# fakessh
description "A fake SSH server"
author "Tyler Menezes <tylermenezes@gmail.com>"
start on runlevel [2345]
stop on runlevel [016]
respawn
exec python /opt/fakessh/server.py

now run the server.py
example:

Code:
cd /opt/FakeSSH/
screen -S "fakeSSH" -d -m ./server.py

Now to check it:

Code:
$ nmap <Your IP or Hostname> -p-

Starting Nmap 7.01 ( https://nmap.org ) at 2018-03-21 10:21 CET
Nmap scan report for <Your IP or Hostname>.serverprofi24.de (<Your IP or Hostname>)
Host is up (0.0074s latency).
Not shown: 65519 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh <--- Fake port
25/tcp open smtp
53/tcp open domain
80/tcp open http
106/tcp open pop3pw
110/tcp open pop3
143/tcp open imap
443/tcp open https
465/tcp open smtps
993/tcp open imaps
995/tcp open pop3s
1923/tcp open unknown <--- Real port
4190/tcp open sieve
8443/tcp open https-alt
8880/tcp open cddbp-alt

Nmap done: 1 IP address (1 host up) scanned in 2.77 seconds

 

Code:
ssh root@<Your IP or Hostname> -p22
hello, welcome to my internet home!
please don't guess my password!
root@<Your IP or Hostname>'s password:
Access denied

As you can see the server does reply and always says that it is a wrong password. So a bot, etc. will think that it’s a real port.

With these steps all done, your Server should be mostly secure.

If you using Plesk it is probably also recommended to check:
https://support.plesk.com/hc/en-us/a…best-practices
Also make sure that your CMS systems etc. are always up to date!

(THIS IS NO GUARANTEE THAT YOUR SERVER WILL BE HACK PROOF BUT IT SHOULD HELP IN MOST CASES)