Skip to content

Commit

Permalink
Merge pull request #8 from jhampson-dbre/jhampson-dbre/issue5
Browse files Browse the repository at this point in the history
Configure fail2ban to block brute force attacks
  • Loading branch information
jhampson-dbre authored Jan 7, 2021
2 parents bc60b72 + ff5fe09 commit 3c93404
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 0 deletions.
80 changes: 80 additions & 0 deletions roles/fail2ban/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
fail2ban
=========

Install and configure fail2ban to block IPs with excessive failed login attempts to Home Assistant Supervised. The fail2ban sensor integration is also added to Home Assistant

This role is based upon this documentation:

[Banning IPs from Home Assistant and SSH](https://kevinfronczak.com/blog/banning-ips-on-homeassistant-and-ssh)
[fail2ban Integration Documentation](https://www.home-assistant.io/integrations/fail2ban/)

**WARNING:** This role will make changes to Home Assisant's configuration.yaml and restart Home Assistant. As recommended before making any changes to Home Assisant, ensure you have a good snapshot of your current configuration.

Requirements
------------

- Home Assistant Supervised installation running on Debian 10
- NGINX Home Assistant SSL proxy add-on should be configured as reverse proxy for Home Assistant
- This role must be ran as root, or as an alternate user with `become: true` set
- Docker SDK for Python: `docker` Python package on the target server
- In Home Assistant's configuration.yaml, any pre-existing entries under `http` or `logger` headings will cause this role to fail. These settings are not defined in configuration.yaml by default, but if you have added any custom configuration under either of these headings, please remove it before running this role and then merge any custom configuration with the entries added by this role.

Role Variables
--------------
The following variables are set in `defaults/main.yml`, with default values shown:

```yaml
# The fail2ban jails that will be configured
# Currently only ssh and Home Assistant jails can be configured.
fail2ban_jails:
- ssh
- hass-iptables

# The number of failed log in attempts that will result in a ban
# This number is used for all jails
max_failed_login_attempts: 5
```
The following variables are set in `vars/main.yml`, with example values show. See `vars/main.yml` for the full values:

```yaml
# Properties to set, log path, ports, etc. for each fail2ban jail
fail2ban_properties:
- section: ssh
options:
- option: port
value: ssh
- option: filter
value: sshd
- option: logpath
value: /var/log/auth.log
```

Dependencies
------------

None.

Example Playbook
----------------

```yaml
# Configure fail2ban for Home Assistant Supervised
# with 3 failed login attempts resulting in ban
- hosts: pi
become: true
roles:
- role: jhampson_dbre.home_assistant.fail2ban
vars:
max_failed_login_attempts: 3
```

License
-------

MIT

Author Information
------------------

@jhampson-dbre
6 changes: 6 additions & 0 deletions roles/fail2ban/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fail2ban_jails:
- ssh
- hass-iptables

max_failed_login_attempts: 5
10 changes: 10 additions & 0 deletions roles/fail2ban/files/hass.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[INCLUDES]
before = common.conf

[Definition]
failregex = ^%(__prefix_line)s.*Login attempt or request with invalid authentication from <HOST>.*$

ignoreregex =

[Init]
datepattern = ^%%Y-%%m-%%d %%H:%%M:%%S
12 changes: 12 additions & 0 deletions roles/fail2ban/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
- name: restart fail2ban
service:
name: fail2ban
enabled: yes
state: restarted

- name: restart home assistant
shell: |
ha core restart
args:
warn: no
27 changes: 27 additions & 0 deletions roles/fail2ban/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
galaxy_info:
author: Jared Hampson
description: Install and configure fail2ban for Home Assistant Supervised

license: MIT

min_ansible_version: 2.9

# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
platforms:
- name: Debian
versions:
- buster

galaxy_tags:
- home
- assistant
- supervised
- raspberry
- pi
- hassio

dependencies: []
127 changes: 127 additions & 0 deletions roles/fail2ban/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
- name: Get nginx container ip
docker_container_info:
name: addon_core_nginx_proxy
register: nginx_container_info

# TODO: Allow for managing this more granularly, in case
# other properties in the http or logger sections are defined
- name: Enable failed login logging from Home Assistant
blockinfile:
path: /usr/share/hassio/homeassistant/configuration.yaml
marker: "# {mark} CONTENT ADDED BY home_assistant.fail2ban ANSIBLE ROLE"
backup: yes
block: |
http:
use_x_forwarded_for: true
trusted_proxies:
- {{ nginx_container_info.container.NetworkSettings.Networks.hassio.IPAddress }}
logger:
default: info
logs:
homeassistant.components.http.ban: warning
sensor fail2ban:
- platform: fail2ban
jails:
- hass-iptables
- ssh
file_path: /config/fail2ban.log
register: logging_config
notify:
- restart home assistant

- name: Ensure logging configuration is valid
block:
- name: Check Home Assistant configuration
shell: |
ha core check
rescue:
# NOTE: This does not work due to a bug that exists as of Ansible 2.9.16
# where blockinfile does not return backup location correctly.
# The backup file is created, but it would have to be restored manually.
# Ref: https://github.com/ansible/ansible/issues/27626
- name: Restore backup configuration
copy:
src: "{{ logging_config.backup_file }}"
dest: /usr/share/hassio/homeassistant/configuration.yaml

- name: Unable to continue
fail:
msg: |
Error configuring logger in configuration.yaml.
If you already custom logging configuration, please remove it and retry the role.
- name: Install fail2ban
apt:
name:
- fail2ban
state: present
notify:
- restart fail2ban

- name: Copy default fail2ban config for modification
copy:
src: /etc/fail2ban/fail2ban.conf
dest: /etc/fail2ban/fail2ban.local
remote_src: yes
mode: '0644'
notify:
- restart fail2ban

- name: Edit fail2ban log location so it can be read by Home Assistant
ini_file:
path: /etc/fail2ban/fail2ban.local
section: Definition
option: logtarget
value: /usr/share/hassio/homeassistant/fail2ban.log
notify:
- restart fail2ban

- name: Create the filter for Home Assistant jail
copy:
src: hass.local
dest: /etc/fail2ban/filter.d/hass.local
mode: '0644'
notify:
- restart fail2ban

- name: Copy default jail config for modification
copy:
src: /etc/fail2ban/jail.conf
dest: /etc/fail2ban/jail.local
remote_src: yes
mode: '0644'
notify:
- restart fail2ban

- name: Configure shared jail properties
ini_file:
path: /etc/fail2ban/jail.local
section: "{{ jail_common_config.0 }}"
option: "{{ jail_common_config.1.jail_option }}"
value: "{{ jail_common_config.1.jail_value }}"
loop: "{{ fail2ban_jails|product(jail_properties)|list }}"
loop_control:
loop_var: jail_common_config
vars:
jail_properties:
- jail_option: enabled
jail_value: "true"
- jail_option: maxretry
jail_value: "{{ max_failed_login_attempts }}"
notify:
- restart fail2ban

- name: Configure unique jail properties
ini_file:
path: /etc/fail2ban/jail.local
section: "{{ jail_unique_config.0.section }}"
option: "{{ jail_unique_config.1.option }}"
value: "{{ jail_unique_config.1.value }}"
loop: "{{ fail2ban_properties|subelements('options') }}"
loop_control:
loop_var: jail_unique_config
notify:
- restart fail2ban
1 change: 1 addition & 0 deletions roles/fail2ban/tests/inventory
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
localhost
5 changes: 5 additions & 0 deletions roles/fail2ban/tests/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- hosts: all
become: yes
roles:
- fail2ban
18 changes: 18 additions & 0 deletions roles/fail2ban/vars/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
fail2ban_properties:
- section: ssh
options:
- option: port
value: ssh
- option: filter
value: sshd
- option: logpath
value: /var/log/auth.log
- section: hass-iptables
options:
- option: action
value: iptables-allports[name=HASS]
- option: filter
value: hass
- option: logpath
value: /usr/share/hassio/homeassistant/home-assistant.log
4 changes: 4 additions & 0 deletions tests/sanity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@
- name: import preinstall_config
import_role:
name: roles/preinstall_config

- name: import fail2ban
import_role:
name: roles/fail2ban

0 comments on commit 3c93404

Please sign in to comment.