Tuesday, August 28, 2018

Fail2ban and Home Assistant

Following on from my earlier post I wanted to setup fail2ban on my Home Assistant server. This server is internet facing so I can do things like turn my air conditioner on and off remotely, it's configured for ssl and uses password authentication but I thought it would be prudent to add an extra layer of security.

First thing is Home Assistant needs to be configured to log invalid authentications, logging configuration needs to be modified in /home/homeassistant/.homeassistant/configuration.yaml:
$ nano /home/homeassistant/.homeassistant/configuration.yaml
Add the below lines or modify the existing logger configuration:
  default: critical
    homeassistant.components.http.ban: warning
Restart Home Assistant
$ sudo su -
# systemctl restart home-assistant
Now tail Home Assistants log file and attempt to login with an incorrect password, look for "Login attempt or request with invalid authentication from" entries in the log file:
# tail -f /opt/homeassistant/.homeassistant/home-assistant.log
2018-08-29 14:25:00 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on home/outside/humidity: b'59.9'
2018-08-29 14:26:52 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on home/outside/temperature: b'10.9'
2018-08-29 14:27:13 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on home/outside/tanklevel: b'43'
2018-08-29 14:28:15 WARNING (MainThread) [homeassistant.components.http.ban] Login attempt or request with invalid authentication from xxx.xxx.xxx.xxx
If that was successful then it's time to get fail2ban installed and configured, as with my previous post EPEL needs to be enabled to install fail2ban:
$ sudo su -
# dnf install epel-release
# dnf install -y fail2ban
Fail2ban doesn't have a predefined configuration for Home Assistant so a filter needs to be created:
# nano /etc/fail2ban/filter.d/ha.conf
before = common.conf

failregex = ^%(__prefix_line)s.*Login attempt or request with invalid authentication from .*$
ignoreregex =
Now a jail configuration needs to be created, be sure that logpath is the actual path to your home-assistant.log log file:
# nano /etc/fail2ban/jail.d/ha.conf
# 3600 seconds = 1 hour
bantime = 30
maxretry = 3

# Email config
sender = vmmgt01@hipowered.net
destemail = bircoe@gmail.com

# Action "%(action_mwl)s" will ban the IP and send an email notification including whois data and log entries.
action = %(action_mwl)s

enabled = true
filter = ha
logpath = /home/homeassistant/.homeassistant/home-assistant.log
Fail2ban can now be started:
# systemctl start fail2ban
Confirm that its running:
# systemctl status fail2ban
And lastly check that there are active jails:
# fail2ban-client status
|- Number of jail: 1
`- Jail list: ha
Now test that fail2ban detects Home Assistant login attempts, tail the fail2ban log file then log out of and back into the Home Assistant web interface with an invalid password, it should result in log entries showing the failed attempts:
# tail -f -n 20 /var/log/fail2ban.log
2018-08-29 13:25:37,907 fail2ban.server         [10208]: INFO    Starting Fail2ban v0.10.3.fix1
2018-08-29 13:25:37,916 fail2ban.database       [10208]: INFO    Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
2018-08-29 13:25:37,918 fail2ban.jail           [10208]: INFO    Creating new jail 'ha'
2018-08-29 13:25:37,922 fail2ban.jail           [10208]: INFO    Jail 'ha' uses poller {}
2018-08-29 13:25:37,922 fail2ban.jail           [10208]: INFO    Initiated 'polling' backend
2018-08-29 13:25:37,932 fail2ban.filter         [10208]: INFO    Added logfile: '/opt/homeassistant/.homeassistant/home-assistant.log' (pos = 5873, hash = 02ec3aefc005465a6cd8db91eff2d5e57c45757e)
2018-08-29 13:25:37,932 fail2ban.filter         [10208]: INFO      encoding: UTF-8
2018-08-29 13:25:37,933 fail2ban.filter         [10208]: INFO      maxRetry: 3
2018-08-29 13:25:37,934 fail2ban.filter         [10208]: INFO      findtime: 600
2018-08-29 13:25:37,934 fail2ban.actions        [10208]: INFO      banTime: 30
2018-08-29 13:25:37,938 fail2ban.jail           [10208]: INFO    Jail 'ha' started
2018-08-29 13:27:49,125 fail2ban.filter         [10208]: INFO    [ha] Found xxx.xxx.xxx.xxx - 2018-08-29 13:27:48
2018-08-29 13:27:51,330 fail2ban.filter         [10208]: INFO    [ha] Found xxx.xxx.xxx.xxx - 2018-08-29 13:27:51
2018-08-29 13:27:52,533 fail2ban.filter         [10208]: INFO    [ha] Found xxx.xxx.xxx.xxx - 2018-08-29 13:27:52
2018-08-29 13:27:52,678 fail2ban.actions        [10208]: NOTICE  [ha] Ban xxx.xxx.xxx.xxx
2018-08-29 13:28:23,941 fail2ban.actions        [10208]: NOTICE  [ha] Unban xxx.xxx.xxx.xxx
Now that fail2ban is working it can be enabled for startup at boot time, we can also raise the bantime, I'm using 8 hours which should deter people from trying again:
# sed -i 's/bantime = 30/bantime = 28800/g' /etc/fail2ban/jail.d/local.conf
# systemctl enable fail2ban
# systemctl restart fail2ban
A final note, if you need to unban an IP it can be done with fail2ban-client:
# fail2ban-client set JAILNAME unbanip IPADDRESS
# fail2ban-client set sshd unbanip 1.xxx.xxx.158

No comments:

Post a Comment

Raspberry Pi 4 heatsink testing

With all the talk of how hot the Raspberry Pi 4 runs I thought I’d do some testing to see how different heatsinks perform. I had a few heats...