Configuring SSH to protect against massive bruteforce. SSH brute force protection

In this article, we will look at a basic method of protecting SSH from mass bruteforce attacks. In this case, a mass bruteforce attack does not mean a targeted brute-force attack on your SSH password, but an extensive seizure of a range of servers, for subsequent identification from it that are unstable to brute-force login-password pairing.

The main features of the massive bruteforce SSH attack are extensive scanning of IP ranges on open port 22 and the use of frequently used username and password (for example, root: passwd123, admin: server123, etc.).

To view statistics from the log files of unsuccessful SSH authorization attempts on your server, enter the command:

Cat / var / log / secure * | grep "Failed password" | grep sshd | awk "(print $ 1, $ 2)" | sort -k 1,1M -k 2n | uniq -c

This screenshot provides statistics on the number of unsuccessful authorizations by day. If you steal similar data from you, then you should take measures to protect your SSH from massive bruteforce.

1. If you don't use frequently used usernames for authorization, such as root, admin, administrator, user, etc. and use a complex password for authorization, then you can immediately go to the second point. To change the password to a more complex one, enter the command:

Passwd # your_login #

where # your_login # - Your username.
When entering a new password, the password is not displayed, the cursor will be in one place.

Let's go to the server via SSH, create a new user and set a password for him, for this we enter the commands:

Adduser # newuser # passwd # newuser #

where # newuser # - Your new username, do not use frequently used usernames, not a bad option your_nickadmin (e.g. foxadmin, useralex, rootidler).

2. After that, go through SSH with a new username and password. And open the SSH daemon configuration (sshd_config) with the command:

Vi / etc / ssh / sshd_config

After that you should see something like this:

Lines starting with # are commented out.

To protect SSH from massive bruteforce, uncomment and change or add the following parameters file:
a) port - the port on which SSHD accepts and services connections. Uncomment (remove before the beginning of the line # ) and change the default 22 , to any other from 1024 to 65536, except for reserved ports - a list of reserved ports, for example:

Port 2022

To delete # and change the value port 22, press first on the keyboard i, after editing the required line, press the key ESC

b) LoginGraceTime - waiting time for user registration in the system. If the user did not have time to log in within the time allotted by this directive, the session is terminated. Let's decrease this value:

LoginGraceTime 1m

c) PermitRootLogin - allow user root login via SSH protocol. Change to no.

PermitRootLogin no

d) AllowUsers - usernames allowed for login via SSH protocol separated by a space. Here, instead of # your_login #, we specify the new created username.

AllowUsers # your_login #

e) MaxAuthTries - the number of attempts to log in to the system in one session. When the maximum allowed number of attempts is reached, the session is terminated.

MaxAuthTries 2

As a result, we get:

Port 2022 LoginGraceTime 1m PermitRootLogin no AllowUsers # your_login # MaxAuthTries 2

In this article, we will finish the setup SSH to protect against mass bruteforce... After editing , press on the keyboard : , a line appears below and then enter in it wq and press the key Enter... In this case, all changes made will be saved.

If you did something wrong (for example, you accidentally deleted something), to exit without saving use key combination instead wq, keys q!

After completing the SSH configuration, restart the daemon with the command:

Service sshd restart

Now when connecting via SSH protocol, use the new port 2022 (or the one that you specified in the settings) instead of standard port 22.

In the next article on setting up SSH, I would like to tell you, at the same time, we will prohibit password authorization and allow authorization only using the private SSH key, thereby protecting ourselves as much as possible from password guessing.

In contact with

SSH allows you to create a secure connection to the server, however, to work properly, the SSH service itself must have access to the Internet. This creates an attack vector for potential attackers, hence SSH needs additional protection.

In general, any service with network access is a potential target. In the logs of these services, you may notice repeated, systematic login attempts - these are brute force attacks by users and bots.

The fail2ban service can mitigate attacks with rules that automatically change the iptables firewall configuration based on a predefined number of failed login attempts. This will allow the server to respond in a timely manner to unauthorized access without administrator intervention.

This guide will help you install and configure fail2ban on an Ubuntu 14.04 server.

Install fail2ban

The Ubuntu repository provides the fail2ban package, so it can be installed using the standard package manager.

Update package index and install fail2ban using these commands:

sudo apt-get update
sudo apt-get install fail2ban

Now you can start configuring the utility.

Fail2ban configurations

The fail2ban configuration files are stored in the / etc / fail2ban directory. The standard parameters can be found in the jail.conf file.

Since this file can be changed during the package upgrade, you do not need to edit it. It is better to copy its contents to another file and adjust the parameters there. For these two files to work properly, it is best to leave in the new file only those settings that need to be overridden in the jail.local file. All parameters by default will be read from jail.conf file.

Copy jail.conf and use it as a base for jail.local file. To do this, enter:

awk "(printf" # "; print;)" /etc/fail2ban/jail.conf | sudo tee /etc/fail2ban/jail.local

After that, look at jail.conf:

sudo nano /etc/fail2ban/jail.conf

Some parameters can be updated in this file. The section parameters will apply to all services that fail2ban supports (unless these values \u200b\u200bare overridden in the configuration files of these services).


. . .
ignoreip \u003d 127.0.0.1/8
. . .

The ignoreip parameter configures the source addresses that fail2ban will ignore. By default, it allows any traffic coming from the local machine to pass through. You can add other addresses to ignore by placing them at the end of the ignoreip directive, separated by a space.


. . .
bantime \u003d 600
. . .

The bantime parameter sets the time during which the client will be blocked if it failed to authenticate. Its value is measured in seconds. The default is 600 seconds (10 minutes).


. . .
findtime \u003d 600
maxretry \u003d 3
. . .

The next two parameters to watch out for are findtime and maxretry. Together they define the conditions under which illegal users will be blocked.

The maxretry variable specifies the number of login attempts, and findtime the time interval during which the user must authenticate. If the client has exceeded any of these indicators, he will be blocked. By default, fail2ban service blocks clients who failed to provide credentials 3 times within 10 minutes.


. . .
destemail \u003d [email protected]
sendername \u003d Fail2Ban
mta \u003d sendmail
. . .

The destemail, sendername, and mta parameters allow you to set up email alerts. The destemail parameter specifies the email address to receive messages about blocked users. The sendername parameter specifies the sender of the message. The mta parameter determines which mail service will be used to send mail. Add these parameters to jail.local in the section and set the appropriate values.


. . .
action \u003d $ (action_) s
. . .

This parameter configures the fail2ban action in case of blocking. The action_ value is defined in the file a little before this parameter. The default action will block attacker traffic until the ban time expires by reconfiguring the firewall.

If you want to customize email alerts, add or uncomment the action element in the jail.local file and change its value from action_ to action_mw. If you want the email to include the corresponding lines from the logs, you can specify the value of action_mwl. If you choose to use email alerts, make sure your mail settings support them.

Individual parameters

Support for individual services is included in special sections of the same name. For example, ssh service parameters can be specified in the section.

Each of these sections can be enabled by uncommenting the section header in jail.local and changing the enabled line to "true":


. . .
enabled \u003d true
. . .

By default, only SSH service is supported, and all other services are disabled.

These sections use the values \u200b\u200bset in the section as a basis and adjust them as necessary. To override any values, add a section for the corresponding service to jail.local and change its values.

Also some other parameters are set here. The filter parameter helps determine if a line in the log indicates a failed authentication attempt; the logpath parameter tells fail2ban where the logs for that particular service are located.

The value of the filter parameter is a link to a file with the .conf extension located in the /etc/fail2ban/filter.d directory. These files contain regular expressions that determine if a line in the log is a message about a failed authentication attempt. These files are beyond the scope of this tutorial because they are quite complex, and the default options are fine in most cases.

You can view filters in this catalog:

ls /etc/fail2ban/filter.d

Find the file associated with the required service and open it with a text editor. Most of the files are well commented out, and you can familiarize yourself with the service protection scenario. Most of these filters have corresponding sections in the jail.conf file (they are disabled by default). These can be included in the jail.local file if needed.

Let's say you have a site that is served with Nginx. The web server logs are constantly updated with failed login attempts. The fail2ban utility can use the nginx-http-auth.conf file to constantly check /var/log/nginx/error.log.

Almost all the necessary parameters for this are already in the section in the /etc/fail2ban/jail.conf file. You just need to uncomment this section in the jail.local file and set the enabled parameter to true.

. . .
enabled \u003d true
. . .

After that, you need to restart fail2ban.

Configuring fail2ban

Now you know the basics of fail2ban. Try configuring auto blocking policy for SSH and Nginx service. You also want the fail2ban tool to send email messages in case of IP blocking.

First, install the required software.

You will need nginx, as fail2ban will track its logs, and sendmail to send notifications. We also need the iptables-persistent package so that the server will save and automatically load the firewall rules when the server boots. All of these packages can be downloaded from the standard Ubuntu repositories:

sudo apt-get update
sudo apt-get install nginx sendmail iptables-persistent

Stop the fail2ban service to set up a basic firewall.

Configuring the firewall

The underlying firewall must support established connections as well as traffic generated by the server itself and traffic destined for SSH and web server ports. All other traffic will be blocked. The rules look like this:

sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED, RELATED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
sudo iptables -A INPUT -j DROP

These commands implement the above policy. To view the current firewall rules, type:

sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT




-A INPUT -j DROP

Save your firewall rules so they are not lost after a reboot.

sudo dpkg-reconfigure iptables-persistent

Restart fail2ban:

sudo service fail2ban start

Request firewall rules:

sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-ssh

-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED, ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -j DROP
-A fail2ban-ssh -j RETURN

Each chain now has its own default policy. There are also five basic rules in the firewall. The fail2ban structure is highlighted in red: this tool already enforces SSH blocking rules. Sometimes this structure is not shown at first, as fail2ban may not add the structure until the first block.

Configuring fail2ban

Now you need to add the fail2ban settings to the jail.local file:

sudo nano /etc/fail2ban/jail.local

Here you can set a stricter blocking time interval. Find and uncomment the title. In this section, change the bantime parameter so that the service blocks the client for half an hour:


. . .
bantime \u003d 1800
. . .

You also need to set up notifications. First, find the destemail parameter, which should also be in the section. Enter the email address you want to use to collect these messages:


. . .
destemail \u003d [email protected]
. . .

In sendername, specify any convenient value. We recommend that you use a descriptive value here that the postal service can easily filter out.

Then you need to correct the value of action. You can set the action_mw value, which blocks the client and then sends the "whois" report. The action_mwl value does the same, but it also sends the appropriate log lines in the message.


. . .
action \u003d% (action_mwl) s
. . .

In the SSH section in the maxretry directive, you can change the number of failed authentication attempts. If you are using a non-standard port (not 22), specify it in the port parameter. As stated earlier, this server is already on.

Then find the nginx-http-auth section. Uncomment the header and change the enabled parameter to "true".

. . .

enabled \u003d true
. . .

That's all you need to do in this section if your web server uses standard ports and its logs are stored in a standard directory.

Restart fail2ban

Save and close the file.

Then restart the fail2ban service. Sometimes it is even better to stop it and then start it again.

sudo service fail2ban stop
sudo service fail2ban start

It can take a few minutes for all firewall rules to load. Sometimes rules are not added until the first client is blocked. After a while, you will be able to check the new rules:

sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-nginx-http-auth

-N fail2ban-ssh

-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-http-auth


-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh

-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED, ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -j DROP
-A fail2ban-nginx-http-auth -j RETURN

-A fail2ban-ssh -j RETURN

Lines created by fail2ban policy are highlighted in red. Now they simply route traffic to new, almost empty chains, and then pass the traffic flow back to the INPUT chain.

Blocking rules will be added to these chains.

Testing the blocking policy

Now you can test the rules by connecting from another server that does not have credentials on the fail2ban server.

Try to create an SSH connection to the server using non-existent credentials:

ssh [email protected]_server_IP

Enter a random set of characters for the password. Repeat a few times. At some point fail2ban will deny access and display the message "Permission denied".

Go back to the first server and view the new iptables rules:

sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N fail2ban-nginx-http-auth
-N fail2ban-ssh
-A INPUT -p tcp -m multiport --dports 80,443 -j fail2ban-nginx-http-auth
-A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED, ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -j DROP
-A fail2ban-nginx-http-auth -j RETURN
-A fail2ban-ssh -s 203.0.113.14/32 -j REJECT --reject-with icmp-port-unreachable
-A fail2ban-ssh -j RETURN

The new rule is highlighted in red. It blocks traffic from the second server's IP address to the SSH port. You will receive a notification about the client being blocked shortly.

Conclusion

You are now familiar with the basics of fail2ban and can create a basic configuration for this tool.

As soon as a service "lights up" on a public network, it instantly becomes an object for attack. One of the problems is an attempt to gain access by brute-force passwords. And SSH is no exception in this case.

Analysis of the authentication log file /var/log/auth.log or its analogues shows that attempts to guess a password are usually made from several IPs at once and are stretched in time.

SSH brute force protection

You can protect yourself from this in different ways:

  • Using SSH Daemon Configuration Capabilities
  • Packet filter
  • Special applications
  • Port knocking

The easiest and most effective way is to change the default port 22, for example, to 2002, if this does not interfere with other tasks. We make an entry in / etc / ssh / sshd_config:

After that, attempts to guess passwords practically stop. There are times when you cannot change the port. Alternatively, you can restrict SSH access to specific users (in particular, root) or a group. In sshd_config, a number of parameters are responsible for this: AllowUsers, AllowGroups, DenyUsers and DenyGroups. Conveniently, you can specify IP or subnet with the login. For example, let's allow access to the user admin and user, the latter from only one IP:

Another effective option for brute force protection is to use certificates for authentication. Moreover, using the special parameter match, you can create a conditional block in which you can override the parameters of the global section. For example, we will disable SSH login by password for the root user, allowing everyone else:

# allow everyone access by password
PasswordAuthentication yes
# root will only use the certificate
match user root
PasswordAuthentication no
KbdInteractiveAuthentication no

Using TCP Wrapper, we can also restrict access to any service only from certain IPs, for this you just need to write the necessary rule in the /etc/hosts.allow or /etc/hosts.deny file. Allow in /etc/hosts.allow access only from the required subnet:

sshd: 192.168.1.0/24: allow

Or in /etc/hosts.deny:

sshd: ALL: deny
sshd: ALL EXCEPT 192.168.1.0/24: allow

The packet filter allows you to very precisely set the connection parameters by discarding unnecessary packets. With its help, it is easy to restrict access to the 22nd port only to certain addresses. Simple example:

iptables -A INPUT -s! 192.168.0.1 -p tcp -m tcp --dport 22 ↵
-j REJECT -reject-with icmp-port-unreachable

Filtering packets by ports and IP addresses is not very effective if the Administrator is not tied to the workplace. In this case, special utilities will help: Fail2ban, Sshguard. Fail2ban was originally designed to secure SSH. Although today it is already a framework that can be easily customized for any application. The principle of operation is very simple. The daemon periodically checks the logs for records of any suspicious activity. The suspicious IP address is then blocked by iptables or TCP Wrapper. After the time specified in the settings, the blocking is usually removed, so as not to accidentally block the legal site. When the rule is triggered, an event is logged in the /var/log/fail2ban.log log, and an email can be sent.

One process can control several services at once, and the package contains ready-made settings for popular Linux applications. In the default settings, only SSH is protected.

On Ubuntu and Debian, it is installed with the command:

$ sudo apt-get install fail2ban

All settings are made in several files located in the / etc / fail2ban directory. The fail2ban.conf contains parameters for starting the daemon itself, jail.conf describes the monitored services (inside the SSH section).

Enabled \u003d true
port \u003d 22
filter \u003d sshd
logpath \u003d /var/log/auth.log
maxretry \u003d 3

Filters and actions are written in files located in the filter.d and action.d subdirectories. By default, all files have the .conf extension, it is better not to touch them (including jail.conf). All changes should be entered into a file with the .local extension (for example, jail.local), the parameters of which replace the settings from the first one, and will not be lost during the update. You can use the fail2ban-regex utility to check if the filter is working.

Secure Shell can be found everywhere. Since its release in 1995, SSH has been widely adopted as a powerful remote access protocol for Linux.

However, as you know, great strength is great responsibility. An incorrectly configured SSH daemon can be more of a threat than a help. In this article, we'll walk through five steps to harden SSH security.

1. Disable root login.

The easiest step. Obviously, there are few reasons to allow root login over SSH. Disabling such access is quite simple and will improve security.

Find / etc / ssh / sshd_config (it may be in a different directory, it depends on the distribution). In it we define the place of PermitRootLogin and replace the value with "no":

PermitRootLogin no

Of course, this will not prevent anyone from breaking into the system under an ordinary user, but it will still serve as an extra obstacle on the way to the prevalence of the system.

After reading everything written above and implementing it in practice, we will receive the keys for authorization on the server as a result. After making sure everything works, you can disable interactive input:

PasswordAuthentication no
ChallengeResponseAuthentication no

Using this Python script, the administrator can automatically blacklist hosts upon unsuccessful login, banning them forever. Simplest way to install:

Europa ~ # emerge -pv denyhosts
These are the packages that would be merged, in order:
Calculating dependencies ... done!
app-admin / denyhosts-2.5 0 kB
Total size of downloads: 0 kB
europa ~ # emerge denyhosts

There is not a lot of documentation on the program (if there is anything, for example), however, all configuration options are normally described in the configuration file.

Europa $ nano -w /etc/denyhosts.conf

I don't think that configuring DenyHosts will cause any special problems - just read the config carefully.

After configuration, you can run the program with a daemon or through the scheduler. In Gentoo daemon:

Rc-update add denyhosts default

Via cron, let's say every 10 minutes:

Python / usr / bin / denyhosts -c /etc/denyhosts.conf

The joy of DenyHost is not only in blocking hosts trying to get to your SSH server, but also in the fact that you can synchronize your "blacklist" with DenyHost servers. This creates a collective host list containing all the attackers. It will prevent an attack at its root.

4. Change the port number.

Most of the hacking attempts come from automated scripts that scan the network for SSH daemons. In the overwhelming majority of cases, they try to break into port 22, which only plays into our hands. By changing the port, we will automatically cut off most unauthorized access attempts.

It is worth changing in the config.