Tightening security for SSH Server…

Hi all.

When I was setting up my server while back I have noticed 100’s of entries in my:

/var/log/auth.log

about failed log in attempts from various IP’s with various logins. I wondered what it was until I saw this:

https://www.youtube.com/watch?v=7CP-JB4QARo

Conclusions? There is at least one (wishful thinking…) bot out there which will scan the entire range of IP’s for opened port 22 and will use some brute-force tool trying to crack it. Now that’s not a very positive conclusion for all the SSH users…

What can be done about this? There are several thing You can do.

A) Forbid the root’s log in.
B) Install and configure fail2ban.
C) Change the SSH port from 22 to something above the 10100
D) Limit users so that they can log only from a selected IP (or IP range).
E) Use stronger encryption.
F) Disable password authentication and use authentication keys instead.

I use all of them.

A) Forbidding the root’s log in is a must. Root is the only 100% sure login on every Linux based system. Attacker don’t have to guess it. It’s there for sure. Now all he has to do is to guess the password. Blocking root’s login will make him to guess Your user login and password. This is more difficult for them and that’s the whole point.

To do this You need to do two things. Add the word root to the /etc/ssh/denyusers file:

su -c "echo 'root' > /etc/ssh/denyusers"

un# and change the value of PermitRootLogin from yes to no in the /etc/ssh/sshd_config file:

su -c "sed -i 's/#PermitRootLogin yes/PermitRootLogin no/i' /etc/ssh/sshd_config"

and then restart the sshd daemon.

systemctl restart sshd

Those settings will block all the attempts of root log in to Your SSH server and yet will allow You to use su command for Your convenience. Why? Even if attacker knows root password he will not be able to log in. However user who is logged into the system via SSH can raise his / her privileges using su command. This is far more secure and comfortable in the same time. Sometimes root’s privileges are necessary so its important to be able to gain root and yet You have to log in as user and know the root’s password to gain full control over the machine.

B) Another method – Fail2ban – (You will find it in the repositories) will add a firewall rules to block all the attempts of connecting to the SSH port for a machine that unsuccessfully tried to log in X amount of times in Y time period. Example – xxx.yyy.zzz.uuu machine tried to log in with logins jack, ann, mark 3 times in 20 minutes period so it got banned for an hour.

In this Arch Linux wiki article You will find out how to configure fail2ban with shorewall firewall.

Fail2ban configuration file can be found here:

/etc/fail2ban/jail.conf

and if You have local e-mail server configured it can be set so that fail2ban will send You a message with notifications about new events.

Fail2ban will protect not only SSH but also FTP, SFTP, and other protocols that are using authentication. Very very cool tool indeed.

Here are my .conf files for shorewall and fail2ban edited to work well together, protect sshd and keep you informed via e-mail.

C) Another thing that You can do is to change the port of the SSH server to something above 10100 – I will use 20202 as an example. Here is how its done.

su -c "sed -i 's/#Port 22/Port 20202/i' /etc/ssh/sshd_config"

Don’t forget the modify the firewall rule to open tcp port 20202 instead of default port 22.

You need to restart sshd for this change to take place:

systemctl restart sshd

From now on You will need to add -p 20202 to Your ssh command. Example:

ssh -p 20202 -l mylogin remotemachine.net

Why changing the port and why above 10100? Default port for SSH is 22. All the script kiddies aka skiddies will use that port in their bots. Even if script kiddie is smart and will scan Your IP with port scanner like nmap – by default he will scan first 10000 ports only. Setting up SSH above that will cause the port scanner to find ZIP, ZERO, NADA, BIG BOBKAS. Even if skiddy is smarter then that and he will scan all the 65k ports the open port will be shown as unknown service. He would have to add few more switches to the nmap to find out that its a SSH server. Skiddies are mostly lazy and they are going after the easy prey. Making it just that little bit more difficult can be a blessing for Your security.

D) Limiting users to be able to log in from a certain IP or IP range will improve the security of Your SSH server too. Let’s say one of Your users has a static IP and will always only use this machine to log into Your server – if someone finds out what his password is and will try to log in from a different IP the attempt will fail…

To achieve this You need to add AllowUsers directive as a last line in Your /etc/ssh/sshd_config file.

Here is an example:

AllowUsers johnnyb brandon anthony@73.12.134.14 robin@192.168.0.100 luke@64.*.*.*

In this case users johnnyb and brandon can log in from ANY IP, anthony can only log in from the IP 73.12.134.14, robin can only use local network IP 192.168.0.100 and luke is allowed to log in from the IP range starting with 64.

As always – restart sshd service for this to take effect.

systemctl restart sshd

E) To make the SSH server even more secure I would recommend enforcing strong crypto. By doing this You are forcing the clients to only use the very strong and secure cipher.

Add this line somewhere in the /etc/ssh/sshd_config:

Ciphers aes256-ctr

and restart the SSH server.

systemctl restart sshd

F) As I have wrote here in the post about passwordless SSH authentication using password as a authentication method is not all that secure. You can disable the possibility of authenticating with a password in the /etc/ssh/sshd_config file.

First what You need to do is create the set of keys and make sure that You have a working authentication with the public and private key.

Next You need to un# the PasswordAuthentication directive and change its value from yes to no:

su -c "sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/i' /etc/ssh/sshd_config"

and of course restart the SSH server:

systemctl restart sshd

Thanks for reading. This is all for now. Possibly I will edit this post to add more stuff.

Cheers.

Andrzej

Passwordless SSH authentication. Using authentication keys.

Hi all.

It would drive me bananas if I would have to remember password for each and every of my shell accounts… Using password as an authentication method is also not the greatest thing as the password could be brute-forced… Leaving the account with no password is unacceptable however from the security point of view. Solution? Use authentication keys – public and private.

How to get them? Its very easy.

Open terminal on Your local machine.

Use command:

ssh-keygen -t rsa -b 8192

When asked for:

Enter file in which to save the key (/home/mylogin/.ssh/id_rsa):

Press [ENTER].

Enter passphrase (empty for no passphrase)

Press [ENTER].

Enter same passphrase again:

Press [ENTER].

Passwordless_SSH_authentication_Using_authentication_keys_001-1024x546.png

[andrzejl@wishmasus ~]$ ssh-keygen -t rsa -b 8192
Generating public/private rsa key pair.
Enter file in which to save the key (/home/andrzejl/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/andrzejl/.ssh/id_rsa.
Your public key has been saved in /home/andrzejl/.ssh/id_rsa.pub.
The key fingerprint is:
c4:f6:76:41:cb:00:ac:88:4b:d8:fd:67:2e:75:91:30 andrzejl@wishmasus.loc
The key's randomart image is:
...
Randomart
...
[andrzejl@wishmasus ~]

SO what You did so far? You have generated a pair of authenticating keys. Private – which is for Your eyes only and public which can be shown to anyone.

Keys are placed in those two files:

PRIVATE KEY:

~/.ssh/id_rsa

PUBLIC KEY:

~/.ssh/id_rsa.pub

Run this command:

cat ~/.ssh/id_rsa.pub

Lets say it spits out this:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQDITvIRB6YbQlkp0GuXSnxtYANQqQ6mw4zhvDsEjW4xfpg63PvUsJepeD7QtCZr06iuWM2lmTKWtKgALIgRvJtL1v483EAyHSap84Q2+j5AC+wuLTuwYB41QkRZzUAW0+vvTUOAoRZdpSGU6F0FQJ73rQPBkwrJp+qD/0Pa5+eVH1fXOM/A5/F0LLOV1Bp92X9Pjd9RmL4BFAeRcEiOyUUklpDI1rDFcpOWxRBsWK/vnp2KEM6nPemIPYrie4wDqkOJtch32xcx70qXoJZVBZvo26T/PpHjUbOlV1XjBP9IlL/oEXkCRowP7tu2ZnRPnv8CQ2780IVee0QATXTS+Fw5yuUJfO/HMyOH2tmO2whgqr+MoLOOigmcXESeKb+LAysrudmc94cdnqxeAKPmUjIkILeQUDpHJQtwOFpE+1Ls/KGsZ4ThY6UkopuHVp3nYBNL7TOwyqAR9yv/afsLFwmseQ8sbo1doPDAf3XZItY70jLos5xIMs/ZdDkyV+XN+EIynG0pqd8+2Rz31ZxeIbNTt1zEEd52TImOKa/ibPHvObtvPEN5fYsptWNjSHDSWF6qFrCdEr1+yJAkMQt1VkZGkbN3Cru8zjaVWJx9oXkNRZ0TlSC3McuP9BThK6WoEAifrQA7NpDEdFOxWPnknI0gI7wUYPEYKQLG5b9ABP4GfKc8C9DzCCNzaQnPcJ9P9BmlHELEEBuIOLIDDzsxoJ7WB/NmUmwKVpCqwaqsHOiZuwFaFKtyJAY39i1qC6MDsQRuPUuAnui4QM0yKyhOyRr9GUJzfSlZ5jzRTD8v8Ri9V+aaAqJgJ7nEk2wRrhoAwIO8G3j1+5EALy1l1AnurZMbwVyDZDoDbgkbHwIBnoL6xGHZbLQA7vCpRk+1PmdGe7Hql+4mz06TUyavkWQPgl+OLtJT99/i5Lm8glgyNvrMsZsK9hptXnc3iWrpn43CpqUfjdQmaP+x2aKNDnz/rkCfPUZTr3hZz/LnRFzxNKp3FriNbsUUEEnmf/3UVh939krsMCa/INScILeCrdV0Zgy9XN2SfidMNep2dIyAjIRGuiBqsauHbJ31ZB9XRRqkRoj3RrNXaWIQe471oBsw+5oA2Y+v40ksdbR0VU600teLDbU9yMaf839zVHzoZKBswu9nO6DhO41ffHEHJ+oprLbcC9C/W8N5v/WmqNE10fOLFasF1j/N/sup6wIhXzQ8xiiJ+0PrR88k64pGl2Bb9zySUR0lfSibv4nMt904xV8ebdgH++B9h9KGUJMD4iPPkC7an7EyGA+apf70aMEOzjKe+G4bSdCBkkAnUXzP3G5lo0D6nL+Zo/AIBUjSF5bcsC4NP04E2zD7S/uTNAC93BSZ andrzejl@wishmasus.loc

Now copy this ^^^ ENTIRE line.

Now that You have generated authentication keys and copied the public one – You have to place the public key in a file on the remote machine. Not just any file. Its a specific file in a specific folder both with a specific permissions.

Passwordless_SSH_authentication_Using_authentication_keys_002-1024x543.png

Open new terminal. Ssh Yourself to the remotemachine.net

ssh -p 22 -l mylogin remotemachine.net

Create directory in .ssh in Your home folder

mkdir ~/.ssh

Give it correct permissions:

chmod 700 ~/.ssh

Create file authorized_keys in the newly created directory

touch ~/.ssh/authorized_keys

Give it correct permissions:

chmod 600 ~/.ssh/authorized_keys

Paste the content previously copied from the cat /home/mylogin/.ssh/id_rsa.pub command combined with

echo "PASTE" > ~/.ssh/authorized_keys

Example:

echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAEAQDITvIRB6YbQlkp0GuXSnxtYANQqQ6mw4zhvDsEjW4xfpg63PvUsJepeD7QtCZr06iuWM2lmTKWtKgALIgRvJtL1v483EAyHSap84Q2+j5AC+wuLTuwYB41QkRZzUAW0+vvTUOAoRZdpSGU6F0FQJ73rQPBkwrJp+qD/0Pa5+eVH1fXOM/A5/F0LLOV1Bp92X9Pjd9RmL4BFAeRcEiOyUUklpDI1rDFcpOWxRBsWK/vnp2KEM6nPemIPYrie4wDqkOJtch32xcx70qXoJZVBZvo26T/PpHjUbOlV1XjBP9IlL/oEXkCRowP7tu2ZnRPnv8CQ2780IVee0QATXTS+Fw5yuUJfO/HMyOH2tmO2whgqr+MoLOOigmcXESeKb+LAysrudmc94cdnqxeAKPmUjIkILeQUDpHJQtwOFpE+1Ls/KGsZ4ThY6UkopuHVp3nYBNL7TOwyqAR9yv/afsLFwmseQ8sbo1doPDAf3XZItY70jLos5xIMs/ZdDkyV+XN+EIynG0pqd8+2Rz31ZxeIbNTt1zEEd52TImOKa/ibPHvObtvPEN5fYsptWNjSHDSWF6qFrCdEr1+yJAkMQt1VkZGkbN3Cru8zjaVWJx9oXkNRZ0TlSC3McuP9BThK6WoEAifrQA7NpDEdFOxWPnknI0gI7wUYPEYKQLG5b9ABP4GfKc8C9DzCCNzaQnPcJ9P9BmlHELEEBuIOLIDDzsxoJ7WB/NmUmwKVpCqwaqsHOiZuwFaFKtyJAY39i1qC6MDsQRuPUuAnui4QM0yKyhOyRr9GUJzfSlZ5jzRTD8v8Ri9V+aaAqJgJ7nEk2wRrhoAwIO8G3j1+5EALy1l1AnurZMbwVyDZDoDbgkbHwIBnoL6xGHZbLQA7vCpRk+1PmdGe7Hql+4mz06TUyavkWQPgl+OLtJT99/i5Lm8glgyNvrMsZsK9hptXnc3iWrpn43CpqUfjdQmaP+x2aKNDnz/rkCfPUZTr3hZz/LnRFzxNKp3FriNbsUUEEnmf/3UVh939krsMCa/INScILeCrdV0Zgy9XN2SfidMNep2dIyAjIRGuiBqsauHbJ31ZB9XRRqkRoj3RrNXaWIQe471oBsw+5oA2Y+v40ksdbR0VU600teLDbU9yMaf839zVHzoZKBswu9nO6DhO41ffHEHJ+oprLbcC9C/W8N5v/WmqNE10fOLFasF1j/N/sup6wIhXzQ8xiiJ+0PrR88k64pGl2Bb9zySUR0lfSibv4nMt904xV8ebdgH++B9h9KGUJMD4iPPkC7an7EyGA+apf70aMEOzjKe+G4bSdCBkkAnUXzP3G5lo0D6nL+Zo/AIBUjSF5bcsC4NP04E2zD7S/uTNAC93BSZ andrzejl@wishmasus.loc" > ~/.ssh/authorized_keys

Logout from the remote machine:

exit

Log back in.

ssh -p 22 -l mylogin remotemachine.net

Remote ssh server shouldn’t ask for a password. If it does – You messed up…

You can use 1 private key to connect to multiple servers. Just copy the public key to all of them like I explained above. Permissions are crucial. 700 for the .ssh folder and 600 for the authorized_keys file. 99% of errors are connected to the wrong permissions of the folder / file or due to the wrong file name.

Cheers.

Andrzej

SSH installation and first steps…

SSH as in Secure SHell in the words of wikipedia:

Secure Shell (SSH) is a cryptographic network protocol for secure data communication, remote command-line login, remote command execution, and other secure network services between two networked computers. It connects, via a secure channel over an insecure network, a server and a client running SSH server and SSH client programs, respectively.

Its great. Its awesome. Its fantastic. Its the best thing since the sliced bread…

Install it:

pacman -S openssh

Enable it:

systemctl enable sshd

Start it:

systemctl start sshd

By default sshd uses port 22. Make sure that its open in Your firewall.

Now go to Your other machine and type in:

ssh -p 22 -l loginTOtheREMOTEmachine ipORhostname

Port, login and ip / hostname can vary but in general the command should look something like this:

ssh -p 22 -l andrzejl 192.168.0.100

If You did everything properly – You should see a password prompt from the remote machine. Type in the password. There… You are now in control of the remote computer.

Cheers.

Andrzej

Secure access to the website’s resources with .htaccess and .htpasswd files.

This is a very loose translation of this article by SloniuPL. Its actually an improvement as You don’t have to rely on a 3rd party website to generate password hashes plus there is no password length limit and the encryption used is not md5 but far more secure bcrypt.

Secure access to the website’s resources with .htaccess and .htpasswd files.

So… You have this subdomain on Your httpd (apache) server that You want to restrict access to? Awesome…

Use the .htaccess and .htpasswd files to demand authorization. How? Ok.

Lets say that the root of Your website is located in /var/www/html/ and in there You have this SuperSecret folder that You want to password protect.

Go into this folder:

cd /var/www/html/SuperSecret/

Create the .htaccess file:

mcedit .htaccess

Paste this as a content:

AuthName "Speak friend and enter:"
AuthType Basic
AuthUserFile /var/www/html/SuperSecret/.htpasswd
Require valid-user

F2 to save the file, F10 to close mcedit.

Now we will use the htpasswd utility to generate access credentials.

htpasswd comes with apache:

[root@icsserver andrzejl]# which htpasswd
/sbin/htpasswd
[root@icsserver andrzejl]# pacman -Q –owns /sbin/htpasswd
/sbin/htpasswd is owned by apache 2.4.9-1

If You want to know more about it read man page or --help. I will just show You how to create login credentials just how I do it.

Lets say that You want to give access to this folder to:

User Name: Gandalf
Password: mellon

I would run this command because it will create the most secure password hash:

htpasswd -nb -B -C 31 Gandalf mellon

but.. FAIR WARNING: It will take forever and a day to generate that password hash – IF Your machine is not up to the task it may even freeze / crash (not just during the password hash generation but also during the browsing of the password protected resources!) – use lower value (think 3 times before going with something higher then 10!) for the -C switch. 5 is default, accepted values are between 4 and 31. The higher the value – the more time and cpu power is used to generate the password’s hash – the more secure it is. Let’s go with:

htpasswd -nb -B -C 10 Gandalf mellon

The result will look somewhat like this:

[root@icsserver SuperSecret]# htpasswd -nb -B -C 10 Gandalf mellon
Gandalf:$2y$15$q6v13VuSpKmmwJmjXRZiruxYZY5HJZr4u3zEupS5OI2uGrhkJSZ0q
[root@icsserver SuperSecret]#

Copy the line that the command spat out and run:

mcedit .htpasswd

Paste the Gandalf:$2y$15$q6v13VuSpKmmwJmjXRZiruxYZY5HJZr4u3zEupS5OI2uGrhkJSZ0q bit, F2 to save the file, F10 to close mcedit.

If You want more users to have access to this folder generate the password hashes for all of them using the same command we have used before and paste them in the .htpasswd file (every user in a separate line).

Secure_access_to_the-websites_resources_with_.htaccess_and_.htpasswd_files_001-1024x546.png

From now on if someone tries to join Your https://domain.loc/SuperSecret (or any subdirectory in the SuperSecret) they will see a password prompt.

Secure_access_to_the-websites_resources_with_.htaccess_and_.htpasswd_files_002.png

AND if they will fail…

Secure_access_to_the-websites_resources_with_.htaccess_and_.htpasswd_files_003.png

That’s all that they will see ;)…

Cheers.

Andrzej

P.S. Passwords like mellon are to short / simple – they should never be used – it was just an example / Lord of The Rings reference ;).

So I have a mail server configured and I want cron to send me a summary each time it runs the task…

So I have a mail server configured and I want cron to send me a summary each time it runs the task…

Am I asking for to much?

No.

Run:

crontab -e

and add this as a first line:

MAILTO="email@my.domain"

This will tell cron that You want it to send You e-mail to the email@my.domain with a summary after each job was ran.

You have to do this for each user – setting up MAILTO parameter for lets say user john will only send You messages for tasks ran by john’s crontab.

Cheers.

Andrzej

Cron installation and first steps.

Cron installation and first steps.

Cron? What is it…?

Well… Cron is a task scheduler. Its an application that runs as a daemon in the background and can run other applications / scripts / commands at the times scheduled by you. It can run chosen command every 5 minutes or exactly at 12:11 each day, or on every Thursday at 5:05 or right after a reboot and so on and so forth. It can automate some tedious and boring tasks for You.

So how do I get it?

Gain root and then run:

pacman -S cronie

Now You need to enable and start it:

systemctl enable cronie

systemctl start cronie

Now You can start adding tasks.

Adding tasks is easy but You need to know few things.

First of all: your user needs to have the permission to run the task. Cron uses the permissions of the user that the job was added by to run the tasks. What does it means? If You want to run something that needs root access You have to add this task to root’s cron task list. If You want your user john to run something – You add it to the john’s cron jobs list.

How?

Use su command.

For example:

su john

will log You in as john for this terminal session.

But how do I know if I am john?

Ask:

whoami

and the terminal will tell You.

So… IF I want to add a root’s job…

You need to do this:

su

crontab -e

This will open text editor and will allow You to add the task.

Just remember that running stuff as root has its risks and that You should avoid doing it.

I have no idea how to syntax the cron task properly…

Ok – visit this site. It will generate the syntax for You BUT… here is another thing You need to know.

What’s that?

Well – if You want a task to be ran exactly at 12…

Yes yes all I have to do is add:

* 12 * * * /path/to/executable

Yes AND no…

Huh?

This command will be ran at 12.

Awesome…

But it will also be run at 12:01 and 12:02 and 12:03… 12:59…

Awwww… But I only want it to run once…

Yes. You need to be more specific…

Oh… So I need to do it this way?

0 12 * * * /path/to/executable

That is correct. You need to tell cron to start it at exactly 12:00. By specifying hour only You’re telling cron to run this command on every minute of this hour.

Another thing that You may want to know is that there is more than one way to skin the cat…

Huh?

Let me give You and example. I want to run an executable exactly every 6 hours. I can do it this way:

0 0,6,12,18 * * * /path/to/executable

OR I can do it this way:

0 */6 * * * /path/to/executable

That’s neat! But You said that I can also run stuff right after my machine boots up after a reboot. I don’t see how I can specify that value using the time / date.

That is correct. You would have to use @reboot option.

Oh… Cool! So if I want to run something right after cronie starts after reboot I have to add this:

@reboot /path/to/executable

Thats a a roger. You can also use things like:

3 0 * 1 1 /path/to/executable

So this will run the executable on every Monday of January exactly 3 minutes past midnight?

Yup.

So You can use:

crontab -e

to add new or edit current cron jobs and You can also use commands like:

crontab -l

to list all the jobs for the user You are currently logged in as and

crontab -r

to remove all the crontab entries for the user You are currently logged in as.

Oh I think I got it! This cron thing is awesome. It can make life so much easier! Thanks Andy.

You’re welcome Andy.

Cheers.

Andrzej

Changing the default command line text editor to Your favorite one.

Changing the default command line text editor to Your favorite one.

How?

Edit ~/.bashrc and add this:

export EDITOR=mcedit

after this line:

# User specific aliases and functions

So it looks like this:

# User specific aliases and functions
export EDITOR=mcedit

Close terminal and reopen it. Now applications like crontab or newsbeuter will use mcedit as their editor.

You can choose other editor (nano, pico) whatever works for You. Just edit the export line to suite your needs.

This change will only affect Your user. Other users on this system will use the default text file editor. If You have more then one account on this machine and You want all of them use Your favorite text editor – You will have to edit ~/.bashrc for them too.

Cheers.

Andrzej