Find Which Images Docker Compose Services Are Using
If you need to find out which image a Docker Compose service is using, you need the docker compose images command. In this short tutorial, I’ll show you how it works.
One of the most common attack vectors against servers is bruteforce login attempts. This is where attackers attempt to access your server, by trying endless combinations of usernames and passwords. So how do you defend yourself against this kind of attack?
If you’re a web application developer, the most common response might be to refactor some aspect of your application. There’s nothing wrong with this approach, but it’s likely not the right solution. This is because there are specifically-designed, open source applications for defending against this very type of attack.
In today’s post, I’m going to introduce you to one, and show you how to use it; it’s called Fail2Ban. In the setup we’re going to walk through, you’ll see how to defend against brute force SSH logins.
Originally developed by Cyril Jaquier back in 2004, Fail2Ban is:
An intrusion prevention software framework that protects computer servers from brute-force attacks.
More specifically, quoting from the Fail2Ban website:
Fail2ban scans log files (e.g.,
/var/log/apache/error_log
) and bans IPs that show malicious activity, such as too many password failures, and seeking for exploits, etc. Generally, Fail2Ban is then used to update firewall rules to reject the IP addresses for a specified amount of time, although any other arbitrary action (e.g., sending an email) could also be configured.
Now you might be asking, if your website’s the target of malicious activity, why wouldn’t you just ban the host permanently? Good question. And on the surface of it, that might sound like the logical thing to do.
But what if the seemingly malicious activity wasn’t malicious. What if it was a genuine user — perhaps even you — who fat-fingered the keyboard, whether because of a lack of sleep, stress, or some other valid cause? What if the user just plain forgot their password?
Would you want them to be permanently locked out of their own server, with no way of logging back in? I’d suggest the answer would be a resounding no! That’s why the ban isn’t permanent, at least not by default.
What’s more, assuming that the activity is genuinely malicious, ban’s don’t need to be permanent. Often, all you need to do is to discourage attackers from attacking you, not block them altogether. Discouraging them normally makes you a target not worth attacking, because it requires too much effort, or too much time.
To be fair, this isn’t always the case, as you may be a particularly inviting target. But if you can make it a royal PITA to attack you, the majority of attackers are likely to just go elsewhere and find lower-hanging fruit. That’s why Fail2Ban is an excellent tool for helping to protect your application from brute force login attempts.
For the purposes of this post, I’ll assume that you’re using a Ubuntu-based Linux server to host your website. The server that I used as the foundation for the information in this post was Ubuntu 14.04.5 LTS.
Yes, it’s a little old now, but fundamentally you configure Fail2Ban the same way and use the same command-line tools in later releases.
If you’re using a different distribution, adjust the commands and package names to suit. To install Fail2Ban, first update your Apt cache, and then install Fail2Ban as shown in the following example.
sudo apt-get update && sudo apt-get install -y fail2ban
When installed, you’ll find Fail2Ban’s configuration files in /etc/fail2ban
.
If you run ls -l
on that directory, you should see output similar to the following:
drwxr-xr-x 2 root root 4096 Jan 24 16:09 action.d
-rw-r--r-- 1 root root 2328 Aug 1 2015 fail2ban.conf
drwxr-xr-x 2 root root 4096 Aug 2 2015 fail2ban.d
drwxr-xr-x 3 root root 4096 Jan 24 16:09 filter.d
-rw-r--r-- 1 root root 18562 Aug 1 2015 jail.conf
drwxr-xr-x 2 root root 4096 Jan 24 16:09 jail.d
Fail2Ban’s configuration is split, primarily, across two key files; these are fail2ban.conf
and jail.conf
.
fail2ban.conf
is Fail2Ban’s broader configuration file, where you can configure such settings as:
jail.conf
is where you configure such options as:
When setting up Fail2Ban, you should never alter jail.conf, as it’s part of the core distribution and may be overwritten when you upgrade the package. Instead, copy it to a new file called jail.local, and make changes there instead.
Before we dive into configuring Fail2Ban, we need to cover one key concept, and that’s a jail. You’ll hear the term as you dig through the Fail2Ban documentation and configuration files.
The term is pretty apt as, in a figurative sense, we want to jail offenders that try to maliciously access our servers.
A jail is a configuration grouping or bucket.
These can be configured both globally, in jail.conf, and in individual jail configuration files, stored in /etc/fail2ban/jail.d/
.
Local configuration directives take precedence over global configuration directives.
Regardless of where you store the configuration, in them you store all the details for a specific service that you want Fail2Ban to defend. They’re composed of two parts, the core configuration and a filter.
Here’s an example of the core configuration for ssh.
What this does is check for malicious attempts to access the server on the default SSH port (22).
It does this by parsing /var/log/auth.log
looking for the pattern defined in the sshd
filter config file.
This filter file is stored in the filter.d directory, named: sshd.conf
.
Finally, if the pattern occurs six times, then it’s considered to be malicious activity.
[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
There’s more to a filter file than I’m going to cover here.
What I want to show you is the key configuration item: failregex
.
As Fail2Ban parses log files, it uses regular expressions to do so as efficiently as possible.
failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error) for .* from <HOST>( via \S+)?\s*$
^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$
^%(__prefix_line)sFailed \S+ for .*? from <HOST>(?: port \d*)?(?: ssh\d*)?(: (ruser .*|(\S+ ID \S+ \(serial \d+\) CA )?\S+ %(__md5hex)s(, client user ".*", client host ".*")?))?\s*$
^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$
^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$
^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$
^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$
I know that regular expressions aren’t for everyone, and that this example may not mean a whole lot. So if you want to learn more about them, check out these two excellent sites:
Assuming that you’ve copied jail.conf to jail.local, open the new file in your editor of choice; I can’t help but use VIM. There are a number of key settings that you can configure to suit your particular needs; these are:
Setting | Description |
---|---|
bantime |
This is the number of seconds that you want a malicious host to be banned for. By default, it’s set to 600 . If you want them banned longer, feel free to increase it. However, be careful. If you’re attempting to login and get banned, you’ll ban yourself for that long as well. |
findtime |
(default: 600 ) The number of seconds to look for the failure pattern |
maxretry |
(default: 3 ) The maximum number of times to look for the failure pattern |
destemail |
The email address to send failure reports to. You could leave it set at its default value of root@localhost , but then you’d either have to SSH into the box, or run a remote SSH command to view the information. Having the information sent to an external email address is likely far more convenient. |
sender |
The name of the account that sends the reports. Change it from its default value of root@localhost to something more meaningful. |
After you’ve configured these settings, the next thing to do is to ensure action
is set appropriately.
This is the default action to take when an attack is detected.
By default it’s set to action_
, which bans the IP address.
However, that doesn’t help us a whole lot if we want to know what’s going on.
So I suggest you change it to %(action_mwl)s
.
This will ban the IP and send an e-mail, along with a whois report, to the email address defined by destemail
.
Here are all the available options that you can use.
Setting | Description |
---|---|
action_ |
The simplest action to take: ban only |
action_mw |
Ban & send an e-mail with whois report to the destemail. |
action_mwl |
Ban & send an e-mail with whois report and relevant log lines to the destemail. |
action_xarf |
Ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines to the destemail. |
action_cf_mwl |
Ban IP on CloudFlare & send an e-mail with whois report and relevant log lines to the destemail. |
action_blocklist_de |
Report block via blocklist.de fail2ban reporting service API |
action_badips |
Report ban via badips.com, and use as blacklist |
With the configuration set, we now need to check that the ssh jail is enabled, and configured, as in the example below.
[ssh]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
With that change made, you lastly need to reload Fail2Ban, by running service fail2ban reload
, so that all the changes are enabled.
When you do that, you should see the output below.
sudo service fail2ban reload
* Reloading authentication failure monitor fail2ban
With that done, let’s do a quick check, to see that Fail2Ban is running and that the ssh jail’s active. To do that, we’ll use fail2ban-client, as follows:
sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: ssh
You can see that one jail is listed, and that it’s SSH. So we’re ready to test that our configuration will protect against malicious SSH logins.
To do this, attempt to login to your test server using ssh. Login with any username that comes to mind and supply any password. As the username and passwords are wrong, you’ll be prompted to try again, twice. Do this, and then attempt to login again with another bogus username and password.
On the sixth attempt, the login attempt should hang, because it’s waiting for a timeout to occur.
At this point, it’s now time to use fail2ban-client
, to check if our IP address has been banned.
To do that, we’ll use the status argument again, but this time specifying the ssh jail, as follows.
sudo fail2ban-client status ssh
Status for the jail: ssh
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 0
| `- Total failed: 6
`- action
|- Currently banned: 1
| `- IP list: 172.28.128.3
`- Total banned: 1
You can see that there is one banned IP, which is our IP: 172.28.128.3. You should have received an email as well. So have a look at your email inbox.
Now that we’ve successfully banned an IP, what if we want to unban it? To do that, we can again use fail2ban-client, and tell it to unban a specific IP, as in the following example.
sudo fail2ban-client set ssh unbanip 172.28.128.3
172.28.128.3
After we do that, we need to check that it’s been removed from the ban list, so we’ll check the ssh jail’s status again, as we did before. You can see in the following example that it’s no longer banned.
sudo fail2ban-client status ssh
Status for the jail: ssh
|- filter
| |- File list: /var/log/auth.log
| |- Currently failed: 0
| `- Total failed: 6
`- action
|- Currently banned: 0
| `- IP list:
`- Total banned: 1
And that’s how to use Fail2Ban to protect your servers against malicious, brute force login attempts. That said, it’s only just scratched the surface of what Fail2Ban can do.
However, please be aware that Fail2Ban — especially with this minimalist configuration — doesn’t provide 100% protection against attacks on your websites and servers. Yet, it’s an excellent way to start!
If nothing else, now you have far greater protection than you did before, and you’re far more aware of just how many attacks are being made against your servers on an hour-by-hour basis.
If you like what you’ve learned so far, I strongly encourage you to keep learning. There’s so much to uncover by reading them.
If you’re experienced with Fail2Ban, I’d love to hear about your configurations and experience with it in the comments.
If you need to find out which image a Docker Compose service is using, you need the docker compose images command. In this short tutorial, I’ll show you how it works.
The tech sector, if you know what you’re doing, is easier than most fields to get started in. However, you do have to know what you’re doing. In this post, I’m going to step through a series of ways to get started, in case you’re not sure.
Recently, I’ve moved into security at ownCloud. As part of the new role, I’ve had to invest lots of time learning about web application security attack vectors and about applications and tools for testing security.
Earlier today, I upgraded my installation of Google Chrome from version 68 to version 69. While not a major upgrade, there’s a key security update that I want to draw your attention to. Here’s a quick look at it.
Please consider buying me a coffee. It really helps me to keep producing new tutorials.
Join the discussion
comments powered by Disqus