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)
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)
# 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
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
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:
# 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
apt install ufw
As we do not have IPv6 we can disable it
nano /etc/default/ufw
and change the “IPV6=yes” to “IPV6=no”
Add the rules:
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:
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:
# 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:
$ 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:
iptables -A INPUT -p tcp --dport 1923 -j ACCEPT
change the 1923 to the port where your SSH is active
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
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
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:
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
# 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:
$ 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:
$ 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.
nano /opt/rules.sh
here we will input all the rules we want to set:
#!/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:
cd /opt/ chmod +x rules.sh ./rules.sh
This will make the rules look like:
# 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
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
cp /opt/FakeSSH/data/config.sample.json /opt/FakeSSH/data/config.json
You can edit /opt/FakeSSH/data/config.json as required
chmod +x /opt/FakeSSH/server.py chmod +x /opt/FakeSSH/stats.py
nano /etc/init/fakessh.conf
Add there:
# 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:
cd /opt/FakeSSH/ screen -S "fakeSSH" -d -m ./server.py
Now to check it:
$ 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
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)