# fail2ban for Home Assistant

> Protect Home Assistant with fail2ban: log failed logins, a tested filter, jails for Docker, the built-in IP ban, and what works on Home Assistant OS.
>
> Source: https://fail2ban.dev/guides/home-assistant/ · Updated 2026-10-25 · Checked against fail2ban 1.1.1
> fail2ban.dev is an independent guide, not the official fail2ban project.

To protect Home Assistant with fail2ban, make sure the `homeassistant.components.http.ban` logger writes warnings to `home-assistant.log` in your config directory, create a filter matching `Login attempt or request with invalid authentication from … (<ADDR>)`, and enable a jail on port 8123 with `backend = auto` and `logpath` pointing to that file. This works for Home Assistant Container and Core. On Home Assistant OS, use Home Assistant's built-in IP ban instead.

```ini
[Definition]
failregex = ^\s*WARNING \([^)]*\) \[homeassistant\.components\.http\.ban\] Login attempt or request with invalid authentication from \S+ \(<ADDR>\)\.
```
[home-assistant]
enabled  = true
backend  = auto
filter   = home-assistant
logpath  = /opt/homeassistant/config/home-assistant.log
port     = 8123
maxretry = 5
findtime = 1h
bantime  = 1d
```

Before adding fail2ban, know what Home Assistant does by itself. Its HTTP server has two settings:

- **IP banning** (`ip_ban_enabled`) — on by default.
- **Login attempts threshold** (`login_attempts_threshold`) — **off by default** (`-1`). Until you set a number, nobody is ever banned.

In current releases you set both under **Settings → System → Network**, in the HTTP server section ("Enable IP banning" and the number of failed login attempts, 1–1000). Older releases used YAML:

```yaml
http:
  ip_ban_enabled: true
  login_attempts_threshold: 5
```

## Make Home Assistant log failed logins

Each failed login or request with a bad token produces a warning from the `homeassistant.components.http.ban` logger:

```log
2026-10-25 18:36:11.002 WARNING (MainThread) [homeassistant.components.http.ban] Login attempt or request with invalid authentication from host-198-51-100-7.example.net (198.51.100.7). Requested URL: '/api/states'. (curl/8.5.0)
```

The filter is anchored at the start of the message on purpose. The user agent at the end is client-controlled and could contain a fake "Login attempt … from x (192.0.2.1)." text; with the anchor it can't trigger a ban on someone else.

If you lowered the default log level, keep this logger at `warning`:

```yaml
logger:
  default: warning
  logs:
    homeassistant.components.http.ban: warning
```

## Home Assistant in Docker

Most Home Assistant Container setups run with `network_mode: host`:

```yaml
services:
  homeassistant:
    image: ghcr.io/home-assistant/home-assistant:stable
    container_name: homeassistant
    restart: unless-stopped
    network_mode: host
    volumes:
      - /opt/homeassistant/config:/config
      - /etc/localtime:/etc/localtime:ro
```

```ini
[home-assistant]
enabled   = true
backend   = auto
filter    = home-assistant
logpath   = /opt/homeassistant/config/home-assistant.log
banaction = iptables-allports
chain     = DOCKER-USER
maxretry  = 5
```

## Behind a reverse proxy

Behind nginx, Nginx Proxy Manager, Caddy or Traefik, Home Assistant sees the proxy's address and logs it — fail2ban would ban the proxy. Enable **Trust X-Forwarded-For** and add the proxy's address or network to **Trusted proxies** (Settings → System → Network; in older YAML configs `use_x_forwarded_for: true` and `trusted_proxies:` under `http:`). New log lines must then show public addresses.

When the proxy terminates TLS on 443, the ban must cover the proxy's ports: use `port = http,https,8123` or an all-ports action. If the proxy runs in Docker with published ports, ban in `DOCKER-USER` as in the [Nginx Proxy Manager guide](/guides/nginx-proxy-manager/). Behind Cloudflare, use [edge bans](/guides/cloudflare/).

## Home Assistant OS and the add-on question

On Home Assistant OS (and Supervised installs) Home Assistant doesn't write `home-assistant.log` by default — logs go to the system journal — and you can't install packages on the host or change its firewall. There's no official fail2ban add-on, and an add-on container can't reliably manage the host firewall. Your options:

1. **Use the built-in IP ban** with a `login_attempts_threshold` (above). This is the practical choice for most HA OS users.
2. **Ban one hop earlier**: if a reverse proxy on another machine (a VPS, a Raspberry Pi running nginx, your router) fronts Home Assistant, run fail2ban there on the proxy's logs.
3. **Ban at Cloudflare's edge** if Home Assistant is exposed through Cloudflare or a Cloudflare Tunnel.

## The Home Assistant "fail2ban" sensor integration

Home Assistant also has a legacy `fail2ban` sensor integration. It doesn't ban anything: it reads `/var/log/fail2ban.log` (or `file_path`) and shows the current and total bans of the jails you list as sensors:

```yaml
sensor:
  - platform: fail2ban
    jails:
      - sshd
      - home-assistant
```

## Test it

```bash
sudo fail2ban-client status home-assistant
```

## FAQ

### Can fail2ban protect Home Assistant?

Yes, on Home Assistant Container and Core. Home Assistant logs `Login attempt or request with invalid authentication from <host> (<IP>)` to `home-assistant.log`; a fail2ban filter matching that line plus a jail on port 8123 bans attackers at the firewall. On Home Assistant OS use the built-in IP ban instead.

### Is there a fail2ban add-on for Home Assistant OS?

There's no official one. Home Assistant OS doesn't let you install fail2ban on the host or manage its firewall, and it doesn't write `home-assistant.log` by default. Use the built-in IP ban (`login_attempts_threshold`), or run fail2ban on a reverse proxy or router in front of Home Assistant.

### How do I enable Home Assistant's built-in IP ban?

Set a failed-login threshold: in current releases under Settings → System → Network (HTTP server), in older releases with `login_attempts_threshold: 5` under `http:` in `configuration.yaml`. IP banning itself is on by default, but the threshold defaults to off. Bans are stored in `ip_bans.yaml` and don't expire.

### Do I need DOCKER-USER for Home Assistant in Docker?

Only if the container publishes port 8123 from a bridge network. The common `network_mode: host` setup has no Docker NAT, so traffic passes the normal `INPUT` chain and the default fail2ban action blocks it.

### Why does fail2ban see my proxy's IP in the Home Assistant log?

Home Assistant only trusts `X-Forwarded-For` from proxies you list. Enable "Trust X-Forwarded-For" and add the proxy to "Trusted proxies" (or `use_x_forwarded_for` and `trusted_proxies` in older YAML). Then the log, and fail2ban, see the client's real address.
