SONiC with Fail2Ban Container
Fail2Ban offer a security enforcement to protect against malicious attack based on port/services identification and brute force authentication.
Disclaimer
The Fail2ban is a free software, developed and maintained by the open-source community. It falls under the terms of the GNU General Public License as published by the Free Software Foundation. DELL do not provide any support related to the Fail2ban software.
The Goal
To reduce the risk of brute force attack over SSH (Secure Shell) or a REST API, Fail2Ban can be used to protect against multiples fail authentication based on bad login/password. Fail2ban uses iptables and a specific table to manage a dynamic filtering.
About Fail2Ban and SONiC
Enterprise SONiC provides an audit file (located in /var/log/audit.log) that logs all the changes and all the events with an associated flag (Warning, Failed, Success)
Fail2ban parses log files and bans IPs that show signs of the malicious behavior — too many password failures, seeking for exploits, etc. Generally, Fail2Ban is used to update iptables rules to reject the malicious IP addresses for a specified amount of time, although any other arbitrary action (like sending an email) could also be configured. Out of the box Fail2Ban comes with filters for various services (Apache, courier, ssh, etc).
Fail2Ban can reduce the rate of incorrect authentications attempts, however it cannot eliminate the risk associated with weak authentication.
About this whitepaper
This document describes an example of a typical and basic configuration of the fail2ban container from the Docker Hub but a lot of variation in term of rule and usage are possible. We will see how to add local rules to parse the audit log to identifying SSH login failures and ban the IP source from where the failures come. Fail2ban allows to define some variables as max failures, time to ban, delay before unban, identify recursive request and some other capabilities. If you need further configuration information, the fail2ban wiki is accessible on GitHub at https://github.com/fail2ban/fail2ban/wiki.
The process installation was successfully test with:
Dell Enterprise SONiC |
3.5.0 4.0.5 4.1 4.4.x |
Iptables, Nftables and Enterprise SONiC
Entreprise SONiC 4.0.5 and later is compiled with nf_table support whereas SONiC 3.5 doesn’t not have this option enabled so some differences exist between those two versions in term of filtering behavior.
Nftables is a recent implementation of Linux Kernel packet classification providing more flexibility and native NAT (Network Address Translation) support as well as a Netlink API for third-party applications. For further detail on nftables check the Wikipage of the project (What is nftables? – nftables wiki)
By default, Fail2Ban uses the legacy mode of iptables but does support nftables so depending on the SONiC Release Fail2ban rules visibility would be different :
- With SONiC 3.5, Fail2Ban can keep using legacy mode. Rules generated by FAil2Ban would be visible from the SONiC Linux shell by using the iptables command
- With SONiC 4.0.5 and later,
- if Fail2Ban is left with default settings (legacy mode), rules generated won’t be visible by the iptables command but by the iptables-legacy command. This would add extra complexity as all rules cannot be seen in one shell command.
- If Fail2Ban is configured with nf-table support, all rules (including the ones generated by Fail2Ban) would be visible by using nft command from the SONiC Linux shell
So as a best practice, with SONiC 4.0.5 and later, nftable support should be enabled within the Fail2Ban container (please refer to section 3.1 for detail process)
Note:By default, SONiC CLI is unidirectional in term of synchronization with iptables/nftable. For instance, if you create a ACL from the SONiC CLI, it would be visible from the Linux shell iptable nevertheless iptables/nftable rules created from the Linux shell won’t be visible from the SONiC CLI. So the rule generated by Fail2Ban won’t be visible from the SONiC CLI. Therefore, best practice would be to use Linux shell iptables/nftable to check and diagnose rules insertion. .
Scenario and goal
To reduce the risk of brute force attack over SSH or a REST API, Fail2Ban can be used to protect against multiples fail authentication based on bad login/password. Fail2ban use different specific sub-tables (from the iptables/nftable tool) to manage dynamic filtering. The container manipulates the same kernel packet’s filtering tables than the SONiC host.
Deploying the Container
We assume that SONiC 4.1 is already configured with an internet access over the management interface (IP + default route) and a public nameserver (DNS)
From the sonic-cli, we use the SONiC image installation manager, called “TPCM”, it allows to install and manage third-party container images into the Enterprise SONiC. Please note that TPCM is available starting with SONiC 4.1 on onward. We will cover Fail2Ban installation without TPCM (for SONiC release below 4.1) in the annexe 1.
In this document, we use the official Fail2ban container available on docker hub portal (https://hub.docker.com/r/linuxserver/fail2ban)
Connection to the Enterprise SONiC switch
After login at the prompt type sonic-cli to launch the CLI (Command Line)
Installing the Fail2ban container by using TPCM commands
Use the tpcm command to launch installation of the container. To get more information see the cli guide Enterprise SONiC Distribution by Dell Technologies Management Framework CLI Reference Guide Release 4.1.0 | Dell US
TPCM args options are the same as the docker one: they must be between quotation marks
tpcm install name fail2ban pull linuxserver/fail2ban args “-v /var/log:/var/log:ro \ |
Type “exit” after the container installation
Let’s check the container and the host iptables status. Note that no ACL (Access Control List) has been configured on the SONiC host
Docker Fail2ban Status
From the linux shell, run the following command :
sudo tpcm list |
SONiC packet filter rules
sudo iptables -S |
Result for the Enterprise SONiC 4.1
Because Enterprise SONiC 4.1 use Nftables, we can show nftables rules with the command
sudo nft list ruleset |
Configure Fail2ban
let’s connect to the container in interactive mode to add additional filter and jail rules.
sudo tpcm exec name fail2ban |
Packet filtering
Let’s first compare the kernel packet filtering tables content from the container and from the host
Result with Enterprise SONiC 4.1, of iptables -S command from the container:
Iptables -S |
Result with Enterprise SONiC 4.1, of iptables -S command from the host:
The container does not “see” the kernel’s packet filtering table.
Let’s clarify this behavior:
Since the Enterprise SONiC 4.0.5, iptables is compiled with the nftables support but, by default, Fail2ban container is built without nftables support. Thus, to view all the kernel packet filtering rules, nft command (from the container) must be used instead of the iptables one.
Result with Enterprise SONiC 4.1, of nft list ruleset command from the container:
nft list ruleset |
Result with Enterprise SONiC 4.1, of nft list ruleset command from the host:
The rules displayed with the nft tool (using the command nft list ruleset) are the same from both, the container and the host
Please, note the kernel’s packet filter is shared between the host and the container.
Add support for nft in the Fail2Ban container (for Enterprise SONiC 4.0.5 and above)
To make Fail2Ban uses nftable, we need to add the command “banaction = nftables-multiport” in jail.local config file located in the /etc/fail2ban directory.
vi /etc/fail2ban/jail.local |
[DEFAULT] banaction = nftables-multiport chain = input |
This change allows Fail2ban to add subset of rules in the kernel packet filter table by using the nftables tools, and allow the visibility of the rules from the host by using the nft command
Add Fail2ban filters rule
In the Fail2ban container, the filter rule are located in the /etc/fail2ban/filter.d/ directory and must be named as <myfiltername>.local. In this example, we use the name audit-auth.local
In this white paper, we define a “failregex” allowing to identify source IP with multiples failed SSH attends.
vi /etc/fail2ban/filter.d/audit-auth.local |
[INCLUDES] before = common.conf [Definition] failregex = ^.*Failed password for (.*)from <HOST> ignoreregex = |
This regex defines the match expression that should be looked for in the /var/log/audit.log file
Add Fail2ban jails rule
After creating the filter, we define the jail ²in the /etc/fail2ban/jail.d/ directory. The jail must be named <myjailname>.local. In this example we use the name audit-auth.local
vi /etc/fail2ban/jail.d/audit-auth.local |
[audit-auth] enabled = true logpath = /var/log/audit.log maxretry = 3 |
The jail config file allows to parse the /var/log/audit.log and block the IP after 3 connection failures
Reload the Fail2ban:
From the container, we reload the jail and the filter. After the reload, fail2ban creates filter tables dynamically
fail2ban-client reload |
From the /config/log/fail2ban.log, we see the creation of the new jail
It is also possible to restart the fail2ban server by using the command
fail2ban-server restart |
Test and validation
From the container, we display the logs located in /config/log/fail2ban/fail2ban.log and in /var/log/audit.log
tail -f /var/log/audit/log /config/log/fail2ban/fail2ban.log |
From a remote host, we initiate several connections with a wrong login/password.
Connection test with wrong login or password
The IP of the host, with failed authentication is identified and blacklisted. A rule is added dynamically by the container. Fail2Ban create dynamically a table named “f2b-audit-auth”, with the list of the IP banned. Fail2Ban also adds a rule in the default INPUT table to block all connection of any IP from the “f2b-audit-auth” table.
Log from Fail2ban and audit.log
Fail2ban matches the 3 failed connections with the wrong password and retrieve the source IP to ban those IP.
Show the added rules from the container
Iptables -S |
Or, by using the nftables tools
nft list table inet f2b-table |
If we try to connect again from the server, the connection is now rejected.
Show packet filter table from the host
If we check the iptables from the SONiC Enterprise, the result is different between versions
Iptables result with the Enterprise SONiC 4.1 (from the host)
When the Fail2Ban rules are added since the Enterprise SONiC 4.1 we use the iptables-legacy command to see all tables and rules.
Or by using the nftables command
Conclusion
Fail2Ban can identify login, password, certificate failure attempts. The user can adapt the fail regex rules strategy to capture and support others authentication issues.
Using Fail2ban as container in SONiC is a powerful and flexible tool that would improve the security of any inbound connection to the SONiC device like ssh, https, snmp, gRPC or any other TCP/UDP based connection assuming a log file exists.
Annexes
Dell Enterprise SONiC 3.5.0 and 4.0.5 install notes
Docker status
To show the docker status with Enterprise SONiC 3.0.5 or Enterprise SONiC 4.0.5
docker ps -f name=fail2ban |
Connecting to the Fail2Ban container in interactive mode
Connection to the container with Enterprise SONiC 3.0.5 or Enterprise SONiC 4.0.5
sudo docker exec -it fail2ban /bin/bash |
Iptables status with Enterprise SONiC 3.5.0
Iptables status before Fail2Ban installation
Iptables status in the container before IP Ban
Iptables status in the container after Fail2Ban ban an IP
Iptables status from the host.
With the Enterprise SONiC 3.5, iptables result is the same from the host or the container
Upgrade fail2ban
Use the tpcm command to launch installation of the container. To get more information see the cli guide Enterprise SONiC Distribution by Dell Technologies Management Framework CLI Reference Guide Release 4.1.0 | Dell US
sudo tpcm upgrade name fail2ban pull linuxserver/fail2ban -y |
Install Fail2ban by using RestAPI
Here the request body to deploy the TPCM via REST API Command
Install Fail2ban by using remote_tpcm
For a prof of concept i develop a small python tool allowing to deploy the container remotely by using rest-api. This tools is available on SONiC_TPCM (github.com)