Docker hosted openssh-server with fail2ban
This is how I setup and secured an openssh server which allows me access via ssh to my network while securing it against the usual attacks. I also log these attempts into InfluxDB for information. The firewall blocking done with fail2ban is done on my internet router instead of at the server.
You should be able to modify these instructions to work with your router or use the server's firewall.
Setup
My setup consists of this.
- EdgeRouter 4 as router and firewall.
- Configured with vlan 192.168.5.0/24 for servers.
- Configured with a user, that can connect via ssh, using key-pairs that have no password.
- Raspberry Pi 4, with 8gb ram, 120gb USB-3 M2 SSD. Raspbian 64bit o/s.
- Docker installed and docker-compose
- Connected to the vlan
- User configured with docker access. See Serving Wordpress with Caddy 2 and Docker on how to set this up.
Directory Structure
This is the directory structure that we will use from the users home directory.
docker
conf
fail2ban
action.d
db
filter.d
jail.d
influxdb2
data
influxdb2
docker-image-sources
fail2ban-ssh-client
openssh-server
scripts
logs
Make these paths with.
mkdir ~/docker #or some other base
cd ~/docker
mkdir -p conf/fail2ban/action.d
mkdir -p conf/fail2ban/db
mkdir -p conf/fail2ban/filter.d
mkdir -p conf/fail2ban/jail.d
mkdir -p conf/influxdb2
mkdir -p docker-image-sources/fail2ban-ssh-client
mkdir -p docker-image-sources/openssh-server
mkdir -p data/openssh-server/.ssh
mkdir -p data/influxdb2
mkdir -p scripts
mkdir -p logs
Docker images
Fail2ban and openssh both require custom docker images which add extra packages.
openssh-server
The following docker file is required for openssh server.
docker-image-sources/openssh-server/Dockerfile
FROM linuxserver/openssh-server
RUN apk add --no-cache --upgrade openssh-client rsyslog rsync
fail2ban
The following docker file is required for fail2ban.
docker-image-sources/fail2ban-ssh-client/Dockerfile
FROM crazymax/fail2ban:latest
RUN apk add --no-cache --upgrade openssh-client
RUN wget https://bootstrap.pypa.io/get-pip.py
RUN python3 get-pip.py
RUN pip --no-cache-dir -q install influxdb-client requests
Docker containers
The 3 docker containers will be configured via docker-compose
.
This is the docker-compose.yaml
you will need I suggest you make
changes per your individual needs.
docker-compose.yaml
version: '3.8'
services:
influxdb:
image: influxdb:2.0
hostname: influxdb
container_name: influxdb
restart: unless-stopped
user:
1001:1001 # change to your User's UID.
env_file:
- "./conf/influxdb.env"
networks:
backend:
ports:
- "8086:8086"
volumes:
- "./conf/influxdb2:/etc/influxdb2"
- "./data/influxdb2:/var/lib/influxdb2"
openssh-server:
build:
context: ./docker-image-sources/openssh-server
dockerfile: Dockerfile
container_name: openssh-server
hostname: openssh-server
networks:
backend:
env_file:
- "./conf/openssh-server.env"
volumes:
- ./data/openssh-server:/config
- ./logs:/config/logs
ports:
- 2222:2222
restart: unless-stopped
fail2ban:
build:
context: ./docker-image-sources/fail2ban-ssh-client
dockerfile: Dockerfile
container_name: fail2ban
networks:
backend:
depends_on:
- openssh-server
volumes:
- "./conf/fail2ban:/data"
- "./logs:/var/log"
- "./data/fail2ban/ssh:/root/.ssh"
- "./scripts:/scripts"
env_file:
- "./conf/fail2ban.env"
restart: unless-stopped
networks:
backend:
InfluxDB Files
conf/influxdb.env
InfluxDB requires some environment variables to initialise the database
and create a user. Set DOCKER_INFLUXDB_INIT_USERNAME
and DOCKER_INFLUXDB_INIT_PASSWORD
to
suitable values. Set DOCKER_INFLUXDB_INIT_ORG
to an org name, for example example.org
.
TZ=Pacific/Auckland
# set these values for initial setup.
DOCKER_INFLUXDB_INIT_MODE=setup
DOCKER_INFLUXDB_INIT_USERNAME=<username>
DOCKER_INFLUXDB_INIT_PASSWORD=<password>
DOCKER_INFLUXDB_INIT_ORG=<your org>
DOCKER_INFLUXDB_INIT_BUCKET=default
No extra files are required for InfluxDB.
OpenSSH Server Files
conf/openssh-server.env
Change <your username>
to the username you want to use to login to the
ssh server. Change PUID
and UID
to the user who is running the docker containers.
PUID=1001
PGID=1001
TZ=Pacific/Auckland
SUDO_ACCESS=false
PASSWORD_ACCESS=false
USER_NAME=<your username>
LOGLEVEL=VERBOSE
data/openssh-server/.ssh/authorized_keys
This file should be populated with the pubic key(s) you will use to access the ssh server.
Fail2Ban Files
Configuration
conf/fail2ban.env
This file should be customised to suit your settings
# change to your timezone
TZ=Pacific/Auckland
F2B_LOG_TARGET=STDOUT
F2B_LOG_LEVEL=INFO
F2B_DB_PURGE_AGE=1d
# required if firewalling on host.
F2B_IPTABLES_CHAIN=DOCKER-USER
F2B_LOG_LEVEL=INFO
# smtp configuration for fail2ban
SSMTP_HOST=smtp.gmail.com
SSMTP_PORT=465
SSMTP_HOSTNAME=<smpthostname>
SSMTP_USER=<smtpusername>
SSMTP_PASSWORD=<smtppassword>
SSMTP_TLS=YES
GEO_IP_API_KEY=<geoipkey>
#influx2
INFLUX_BUCKET=fail2ban
# this value is what you set in DOCKER_INFLUXDB_INIT_ORG in the docker-compose.yaml
INFLUX_ORG=<influxorg>
# you will need to populate this after starting and setting up influxdb
INFLUX_TOKEN=<influxtoken>
INFLUX_URL=http://influxdb:8086
conf/fail2ban/jail.d/jail.local
This sets a list of ip address to ignore.
[DEFAULT]
ignoreip = 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 155.63.200.55 155.63.200.3
conf/fail2ban/jail.d/sshd.conf
sshd jail configuration.
[sshd]
enabled = true
port = 2222,22
filter = sshd[mode=aggressive]
logpath = /var/log/openssh/current
maxretry = 1
bantime = 86400
# custom ban action, leave blank for default
banaction = edgerouter
# banaction = nftables
conf/fail2ban/filter.d/common.conf
# Generic configuration items (to be used as interpolations) in other
# filters or actions configurations
#
[INCLUDES]
# Load customizations if any available
after = common.local
[DEFAULT]
# Type of log-file resp. log-format (file, short, journal, rfc542):
logtype = file
# Daemon definition is to be specialized (if needed) in .conf file
_daemon = \S*
#
# Shortcuts for easier comprehension of the failregex
#
# PID.
# EXAMPLES: [123]
__pid_re = (?:\[\d+\])
# Daemon name (with optional source_file:line or whatever)
# EXAMPLES: pam_rhosts_auth, [sshd], pop(pam_unix)
__daemon_re = [\[\(]?%(_daemon)s(?:\(\S+\))?[\]\)]?:?
# extra daemon info
# EXAMPLE: [ID 800047 auth.info]
__daemon_extra_re = \[ID \d+ \S+\]
# Combinations of daemon name and PID
# EXAMPLES: sshd[31607], pop(pam_unix)[4920]
__daemon_combs_re = (?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:?)
# Some messages have a kernel prefix with a timestamp
# EXAMPLES: kernel: [769570.846956]
__kernel_prefix = kernel:\s?\[ *\d+\.\d+\]:?
__hostname = \S+
# A MD5 hex
# EXAMPLES: 07:06:27:55:b0:e3:0c:3c:5a:28:2d:7c:7e:4c:77:5f
__md5hex = (?:[\da-f]{2}:){15}[\da-f]{2}
# bsdverbose is where syslogd is started with -v or -vv and results in <4.3> or
# <auth.info> appearing before the host as per testcases/files/logs/bsd/*.
__bsd_syslog_verbose = <[^.]+\.[^.]+>
__vserver = @vserver_\S+
__date_ambit = (?:\[\])
# Common line prefixes (beginnings) which could be used in filters
#
# [bsdverbose]? [hostname] [vserver tag] daemon_id spaces
#
# This can be optional (for instance if we match named native log files)
__prefix_line = <lt_<logtype>/__prefix_line>
# PAM authentication mechanism check for failures, e.g.: pam_unix, pam_sss,
# pam_ldap
__pam_auth = pam_unix
# standardly all formats using prefix have line-begin anchored date:
datepattern = <lt_<logtype>/datepattern>
[lt_file]
# Common line prefixes for logtype "file":
__prefix_line = %(__date_ambit)s?\s*(?:%(__bsd_syslog_verbose)s\s+)?(?:%(__hostname)s\s+)?(?:%(__kernel_prefix)s\s+)?(?:%(__vserver)s\s+)?(?:%(__daemon_combs_re)s\s+)?(?:%(__daemon_extra_re)s\s+)?
datepattern = {^LN-BEG}
[lt_short]
# Common (short) line prefix for logtype "journal" (corresponds output of formatJournalEntry):
__prefix_line = \s*(?:%(__hostname)s\s+)?(?:%(_daemon)s%(__pid_re)s?:?\s+)?(?:%(__kernel_prefix)s\s+)?
datepattern = %(lt_file/datepattern)s
[lt_journal]
__prefix_line = %(lt_short/__prefix_line)s
datepattern = %(lt_short/datepattern)s
[lt_rfc5424]
# RFC 5424 log-format, see gh-2309:
#__prefix_line = \s*<__hostname> <__daemon_re> \d+ \S+ \S+\s+
__prefix_line = \s*<__hostname> <__daemon_re> \d+ \S+ (?:[^\[\]\s]+|(?:\[(?:[^\]"]*|"[^"]*")*\])+)\s+
datepattern = ^<\d+>\d+\s+{DATE}
# Author: Yaroslav Halchenko, Sergey G. Brester (aka sebres)
conf/fail2ban/action.d/edgerouter.conf
This is the custom action, this setup is for logging to influxdb and also to set firewall rules on the edgerouter.
# Fail2Ban configuration file
[INCLUDES]
before = iptables-common.conf
[Definition]
actionstart = /scripts/fail2ban-totals.py
actionflush = <remote-command> ipset flush <ipmset>
/scripts/fail2ban-totals.py
actionstop = <actionflush>
actionban = <remote-command> ipset add <ipmset> <ip> -exist
/scripts/fail2ban-to-influx.py <ip>
/scripts/fail2ban-totals.py
actionunban = <remote-command> ipset del <ipmset> <ip> -exist
/scripts/fail2ban-totals.py
[Init]
# make sure to use the router ip address
remote-command = ssh -i /data/fail2ban_id_rsa [email protected] sudo
default-ipsettime = 0
ipsettime = 0
timeout-bantime = $([ "<bantime>" -le 2147483 ] && echo "<bantime>" || echo 0)
ipmset = f2b-<name>
familyopt =
[Init?family=inet6]
ipmset = f2b-<name>6
familyopt = family inet6
Note the remote-command, this will need to be set to your router's ip address and the user you will use to connect to it.
conf/fail2ban/fail2ban_id_rsa
Generate a key pair for fail2ban to use to ssh into the edgerouter. Do no add a passphrase.
> cd conf/fail2ban
> ssh-keygen -f fail2ban_id_rsa -t rsa -q
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
scripts
These scripts are used by fail2ban.
scripts/fail2ban-to-influx.py
This script sends information about each ban and location to influxdb.
#!/usr/bin/python3
import os
import sys
import requests
import influxdb_client
from influxdb_client.client.write_api import SYNCHRONOUS
from rx import for_in
INFLUX_BUCKET = None
INFLUX_ORG = None
INFLUX_TOKEN = None
INFLUX_URL = None
GEO_IP_API_KEY = None
def do(ipaddress):
data = getipdata(ipaddress)
print(data)
sendtoinfluxdb(data)
def sendtoinfluxdb(data):
iclient = influxdb_client.InfluxDBClient(
url=INFLUX_URL,
token=INFLUX_TOKEN,
org=INFLUX_ORG
)
write_api = iclient.write_api(write_options=SYNCHRONOUS)
point = influxdb_client.Point("fail2ban_ip_location") \
.tag("latitude", data['latitude']) \
.tag("longitude", data['longitude']) \
.tag("location", data['city'] + ' ' + data['district'] + ' ' + data['state_prov'] + ' ' + data['country_name'])
for i in data:
point = point.field(i, data[i])
print(point.to_line_protocol())
write_api.write(bucket=INFLUX_BUCKET, org=INFLUX_ORG, record=point)
def getipdata(ipaddress):
response = requests.get(
f"https://api.ipgeolocation.io/ipgeo?apiKey={GEO_IP_API_KEY}&fields=geo&ip={ipaddress}")
if response.status_code == requests.codes.OK:
json = response.json()
return json
return None
if __name__ == '__main__':
if os.environ.get('INFLUX_BUCKET'):
INFLUX_BUCKET = os.environ.get('INFLUX_BUCKET')
if os.environ.get('INFLUX_ORG'):
INFLUX_ORG = os.environ.get('INFLUX_ORG')
if os.environ.get('INFLUX_TOKEN'):
INFLUX_TOKEN = os.environ.get('INFLUX_TOKEN')
if os.environ.get('INFLUX_URL'):
INFLUX_URL = os.environ.get('INFLUX_URL')
if os.environ.get('GEO_IP_API_KEY'):
GEO_IP_API_KEY = os.environ.get('GEO_IP_API_KEY')
if not INFLUX_BUCKET or not INFLUX_ORG or not INFLUX_TOKEN or not INFLUX_URL or not GEO_IP_API_KEY:
print("Provide environment")
exit(1)
do(sys.argv[1])
scripts/fail2ban-totals.py
This script sends information about total bans to influxdb.
#!/usr/bin/python3
import os
import sys
import subprocess
import re
import requests
import influxdb_client
from influxdb_client.client.write_api import SYNCHRONOUS
INFLUX_BUCKET = None
INFLUX_ORG = None
INFLUX_TOKEN = None
INFLUX_URL = None
def do():
jails = getJails()
for jail in jails:
current_failed, current_banned, total_failed, total_banned = getTotal(jail)
sendToInfluxDB(jail, current_failed, current_banned, total_failed, total_banned)
def getJails():
out = runProcess(['fail2ban-client','status'])
m = re.search(r"^.*Jail list:\s(.*)$", out, re.MULTILINE)
jails = m.group(1).split(", ")
print(jails)
return jails;
def getTotal(jail):
out = runProcess(['fail2ban-client','status',jail])
m = re.search(r"^.*Currently failed:\s(.*)$", out, re.MULTILINE)
current_failed = int(m.group(1))
m = re.search(r"^.*Total failed:\s(.*)$", out, re.MULTILINE)
total_failed = int(m.group(1))
m = re.search(r"^.*Currently banned:\s(.*)$", out, re.MULTILINE)
current_banned = int(m.group(1))
m = re.search(r"^.*Total banned:\s(.*)$", out, re.MULTILINE)
total_banned = int(m.group(1))
return current_failed, current_banned, total_failed, total_banned
def runProcess(args):
completed = subprocess.run(args, capture_output=True)
return completed.stdout.decode('utf-8')
def sendToInfluxDB(jail, current_failed, current_banned, total_failed, total_banned):
iclient = influxdb_client.InfluxDBClient(
url=INFLUX_URL,
token=INFLUX_TOKEN,
org=INFLUX_ORG
)
write_api = iclient.write_api(write_options=SYNCHRONOUS)
point = influxdb_client.Point("fail2ban_stats") \
.tag("jail", jail) \
.field("current_failed",current_failed) \
.field("current_banned",current_banned) \
.field("total_failed",total_failed) \
.field("total_banned",total_banned)
print(point.to_line_protocol())
write_api.write(bucket=INFLUX_BUCKET, org=INFLUX_ORG, record=point)
if __name__ == '__main__':
if os.environ.get('INFLUX_BUCKET'):
INFLUX_BUCKET = os.environ.get('INFLUX_BUCKET')
if os.environ.get('INFLUX_ORG'):
INFLUX_ORG = os.environ.get('INFLUX_ORG')
if os.environ.get('INFLUX_TOKEN'):
INFLUX_TOKEN = os.environ.get('INFLUX_TOKEN')
if os.environ.get('INFLUX_URL'):
INFLUX_URL = os.environ.get('INFLUX_URL')
if not INFLUX_BUCKET or not INFLUX_ORG or not INFLUX_TOKEN or not INFLUX_URL:
print("Provide environment")
exit(1)
do()
Permissions
The python scripts should have execute permission.
chmod a+x scripts/*
Router Configuration - EdgeRouter 4
For the edgerouter, it will need some firewall rules and a user created for fail2ban to use. These steps will require use of the edgerouter CLI
ssh into your edgerouter using your normal user then follow these steps.
-
Enable configure mode.
bob@EdgeRouter-4:~$ configure
-
Create an address group called
f2b-sshd
.set firewall group address-group f2b-sshd
-
Modify
WAN_IN
to use the address group.set firewall name WAN_IN rule 60 action drop set firewall name WAN_IN rule 60 description 'Fail2Ban SSD' set firewall name WAN_IN rule 60 destination port 2222 set firewall name WAN_IN rule 60 log enable set firewall name WAN_IN rule 60 protocol tcp_udp set firewall name WAN_IN rule 60 source group address-group f2b-sshd
-
Create port forward rule for ssh.
For this rule, you will need to know the host address of the server that docker is running on. I recommend a fixed ip address. Put that address in
<hostaddress>
.set port-forward rule 5 description ssh2 set port-forward rule 5 forward-to address <hostaddress> set port-forward rule 5 forward-to port 2222 set port-forward rule 5 original-port 23 set port-forward rule 5 protocol tcp
-
Create a user for fail2ban to ssh into the router.
For this step you will need the contents of
conf/fail2ban/fail2ban_id_rsa.pub
. You will need to put the base64 encoded portion the key in place of<publickeyhere>
at the end of the following command. It also seems that the edge router wont allow the creation of a user without a password so you must supply one as well.set system login user fail2ban2 authentication plaintext-password <apassword> set system login user fail2ban authentication public-keys Fail2Ban type ssh-rsa set system login user fail2ban authentication public-keys key <publickeyhere> set system login user fail2ban level admin
-
Commit and Save changes
commit save exit
You will now be back in the normal shell.
-
Exit the ssh session to the edge router.
Test ssh connection
Now is a good time to make sure the user and ssh key are setup correctly on the edge router.
> ssh -i conf/fail2ban/fail2ban_id_rsa [email protected]
Linux EdgeRouter-4 4.9.79-UBNT #1 SMP Tue May 11 13:21:10 UTC 2021 mips64
fail2ban@EdgeRouter-4:~$
Startup and Configure InfluxDB
First start influxdb container.
> docker up influxdb
Watch the logs, if everything is good within a minute or so you will see a line something like:
influxdb | ts=2021-09-02T03:57:16.531008Z lvl=info msg=Listening log_id=0WLAIywW000 service=tcp-listener transport=http addr=:8086 port=8086
This means influx started and is listening on the http port 8086, so you should now be able to browse to the website and see the influxdb login screen.
Now we need to stop and restart influxdb in the background, so press Ctrl+C and edit /conf/influxdb.env
to remove
or comment out the following lines.
DOCKER_INFLUXDB_INIT_MODE=setup
DOCKER_INFLUXDB_INIT_USERNAME=username
DOCKER_INFLUXDB_INIT_PASSWORD=password
DOCKER_INFLUXDB_INIT_ORG=example.org
DOCKER_INFLUXDB_INIT_BUCKET=default
Then restart the influxdb container.
> docker up -d influxdb
After a minute re-connect to the influxdb site and Sign In with the username and password you
entered into the env variables DOCKER_INFLUXDB_INIT_USERNAME
and DOCKER_INFLUXDB_INIT_PASSWORD
.
Once on the Getting Started
screen follow these steps:
-
Click the
data
icon from the left side bar. -
Click
Buckets
from the tabs. - Click
+ Create Bucket
from the right side. -
Call the bucket
fail2ban
. -
Click
Create
- Select
Tokens
from the tabs. -
Click
+ Generate Token
from the right side. -
Then click
Read/Write Token
. -
Give the token the description
Fail2Ban
and selectfail2ban
bucket underRead
andWrite
. -
Click
Save
. -
You will now see the token listed. Click the token name
Fail2Ban
-
The generated token will be created, copy this to the clipboard.
-
Now go and edit
conf/fail2ban.env
and set theINFLUX_TOKEN=
to the token you copied to the clipboard.
InfluxDB is now configured ready to take data.
Startup and Test openssh-server
Starting the openssh-server
container the first time will build the container.
> docker-compose up -d openssh-server
When it is finished, you can then test the ssh server, and check the logs were created properly. We can do this by testing a good login and a bad login.
-
Bad user.
> ssh somestupiduser@localhost -p 2222 The authenticity of host '[localhost]:2222 ([::1]:2222)' can't be established. ECDSA key fingerprint is SHA256:eVjVn5Q2EW1tZWDqfK+5G5ypGLDwkOOf3mfowwUDuuA. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[localhost]:2222' (ECDSA) to the list of known hosts. somestupiduser@localhost: Permission denied (publickey,keyboard-interactive).
-
Good user. For this user you will need your
USER_NAME
fromconf/openssh-server.env
and you will need the private ssh key that matches the public one you put indata/openssh-server/.ssh/authorized_keys
.> ssh USER_NAME@localhost -p 2222 -i ~/.ssh/id_rsa The authenticity of host '[localhost]:2222 ([192.168.1.81]:2222)' can't be established. ECDSA key fingerprint is SHA256:eVjVn5Q2EW1tZWDqfK+5G5ypGLDwkOOf3mfowwUDuuA. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '[localhost]:2222,[192.168.1.81]:2222' (ECDSA) to the list of known hosts. Welcome to OpenSSH Server openssh-server:~$
-
Check the contents of
logs/openssh/current
you should see the following.logs/openssh/current
2021-09-02 16:48:48.831029185 Server listening on 0.0.0.0 port 2222. 2021-09-02 16:48:48.831199831 Server listening on :: port 2222. 2021-09-02 16:50:41.820462317 Invalid user somestupiduser from 172.20.0.1 port 35518 2021-09-02 16:50:41.837216587 Connection closed by invalid user somestupiduser 172.20.0.1 port 35518 [preauth] 2021-09-02 16:55:25.667971842 Connection closed by authenticating user USER_NAME 172.20.0.1 port 35526 [preauth] 2021-09-02 16:55:52.922482955 Connection closed by authenticating user USER_NAME 192.168.1.172 port 34908 [preauth] 2021-09-02 16:56:39.099231147 Accepted publickey for USER_NAME from 192.168.1.172 port 34924 ssh2: RSA SHA256:Bx3jLYpJ6OOavQREjCDygOULKCl5w5ggtsLE/Viebr4 2021-09-02 16:56:39.153657884 Attempt to write login records by non-root user (aborting)
This is what fail2ban will use to block anyone but the allowed user.
Startup and Test Fail2Ban
Starting the fail2ban
container the first time will build the container.
> docker-compose up -d fail2ban
When it is finished, you can then test fail2ban. Its best to also watch the fail2ban logs while testing, you can do this with docker.
> docker-compose logs -f fail2ban
Repeat the Good User test above, the fail2ban log should not show anything.
Repeat the Bad User test above, the fail2ban log should show something like.
INFO [sshd] Ignore 192.168.1.172 by ip
INFO [sshd] Ignore 192.168.1.172 by ip
This shows that fail2ban saw the incorrect login, but ignored it because it came
from an internal address listed in conf/fail2ban/jail.d/jail.local
.
Next repeat the above tests, but coming from outside the network. You should see something like when you enter an incorrect username.
INFO [sshd] Found 104.236.72.182 - 2021-08-31 09:27:23
NOTICE [sshd] Ban 104.236.72.182
Check the firewall, you should no-longer be able to attempt ssh connection your connection attempt will be blocked at the firewall.
Look at the blocked addresses in the EdgeRouter.
Login to the edge router via ssh, and issue the following command.
> sudo ipset list f2b-sshd
You should get the following output with the banned ip address listed.
Name: f2b-sshd
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 416
References: 4
Members:
104.236.72.182
Another view of the ip-addresses can be seen in the address group.
> show firewall group f2b-sshd
Name : f2b-sshd
Type : address
Family : IPv4
Description:
References : WAN_IN-20-source
Members :
104.236.72.182
Data in InfluxDB
Now we can check that InfluxDB has had the ban data recorded into it. Sign In to the influx web page and then:
- Click the
Explore
Icon on the left bar. - Select
Single Stat
from the top left dropdown of panel types. - Select
fail2ban
in theFROM
list of buckets. - Select
fail2ban_stats
,current_banned
andsshd
for filters. - Click
Submit
- See a number > 0.00 in the panel.
- Now Select
fail2ban_ip_location
in the first filter list. - Select
country_name
in the second filter list. - Unselect anything selected in the third filter list.
- Select
last
underAGGREGATE FUNCTION
. - Click
Submit
. - You should now see the country name where the most recent ban occurred.
- Try different fields to see the values recorded.
Conclusion
You will now see the count of bans adding up, i often see in excess of 500 in a 24 hour period.
Useful Fail2Ban commands
-
Show jail status.
bash > docker-compose exec fail2ban fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 0 | |- Total failed: 2 | `- File list: /var/log/openssh/current `- Actions |- Currently banned: 49 |- Total banned: 49 `- Banned IP list: 103.76.252.6 112.166.133.216 113.134.211.42 117.185.41.226 121.200.61.37 121.4.66.32 124.152.213.64 124.43.9.184 129.211.79.208 141.98.10.179 157.230.12.188 159.65.36.44 165.22.3.210 165.22.49.42 165.22.98.186 175.6.35.202 176.111.173.156 178.128.144.227 178.128.212.164 178.128.232.28 180.235.135.181 181.30.35.202 186.122.149.6 191.188.70.175 191.35.72.75 193.112.118.22 202.165.25.137 211.218.145.195 211.253.133.50 221.131.165.23 221.131.165.56 221.181.185.140 221.181.185.220 222.186.42.137 222.187.254.38 222.187.254.41 24.147.208.110 36.67.197.52 37.59.52.19 41.207.252.122 41.76.175.129 45.144.225.231 49.235.78.105 5.44.79.122 5.88.135.45 73.155.50.124 89.97.218.142 90.152.142.197 165.227.7.187
-
Unban an ip
> docker-compose exec fail2ban fail2ban-client unban 41.207.252.122
-
Ban an ip manually
> docker-compose exec fail2ban fail2ban-client set sshd banip 41.207.252.122
-
Unban all
> docker-compose exec fail2ban fail2ban-client unban --all
Useful docker-compose commands
-
Stop container
> docker-compose stop <containername>
-
Stop all containers
> docker-compose stop
-
Rebuild Container
> docker-compose build --pull <containername>
-
Update container
> docker-compose pull <containername>
-
Update all containers
> docker-compose pull
-
Restart container after update or build
> docker-compose up -d <containername>
-
Restart container
> docker-compose restart <containername>