{"id":49272765,"url":"https://github.com/alaub81/fail2ban-dockerized","last_synced_at":"2026-04-25T14:31:55.020Z","repository":{"id":318121470,"uuid":"1070037454","full_name":"alaub81/fail2ban-dockerized","owner":"alaub81","description":"Fail2ban is Docker Container","archived":false,"fork":false,"pushed_at":"2026-03-16T09:33:59.000Z","size":75,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-16T22:22:15.456Z","etag":null,"topics":["docker","docker-compose","dockerized","fail2ban","iptables","nftables","security","security-tools","ssh"],"latest_commit_sha":null,"homepage":"https://lhlab.wiki/wiki/Fail2ban-Dockerized:_SSH_und_andere_Dienste_absichern_per_Docker_Compose","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alaub81.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/funding.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"buy_me_a_coffee":"alaub81"}},"created_at":"2025-10-05T06:05:07.000Z","updated_at":"2026-03-16T09:33:57.000Z","dependencies_parsed_at":"2025-10-05T09:13:02.426Z","dependency_job_id":"0f975278-bbfc-41a2-915c-6060626265c2","html_url":"https://github.com/alaub81/fail2ban-dockerized","commit_stats":null,"previous_names":["alaub81/fail2ban-dockerized"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/alaub81/fail2ban-dockerized","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaub81%2Ffail2ban-dockerized","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaub81%2Ffail2ban-dockerized/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaub81%2Ffail2ban-dockerized/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaub81%2Ffail2ban-dockerized/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alaub81","download_url":"https://codeload.github.com/alaub81/fail2ban-dockerized/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alaub81%2Ffail2ban-dockerized/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32265974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T09:15:33.318Z","status":"ssl_error","status_checked_at":"2026-04-25T09:15:31.997Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","dockerized","fail2ban","iptables","nftables","security","security-tools","ssh"],"created_at":"2026-04-25T14:31:54.094Z","updated_at":"2026-04-25T14:31:55.012Z","avatar_url":"https://github.com/alaub81.png","language":"Shell","funding_links":["https://buymeacoffee.com/alaub81"],"categories":[],"sub_categories":[],"readme":"# fail2ban-dockerized (Debian 13 / journald)\n\nDockerized **Fail2ban** tuned for systemd **journald** on the host and **iptables (nf_tables)** banning. Also included email notifications via **msmtp**.\n\n- **Debian slim** as base\n- Journald backend support (bind mounts), no host file logs required\n- iptables/nftables banning for host SSH (INPUT chain)\n- ENV-driven msmtp config (password via file/secret), logs to STDOUT\n- Works on amd64 and arm64\n\n## Requirements\n\n- Host runs systemd **journald** and exposes it to the container (see volumes).\n- Docker with `--cap-add=NET_ADMIN` and `--network host` allowed (see compose).\n- SMTP relay (optional) if you want email notifications.\n\n## Quick start\n\n1. **Docker Compose File**\n\n   - use one one of the docker-compose.yml files\n   - here is an example if you just like to pull the published images:\n\n   ```yml\n   services:\n     fail2ban:\n       image: ghcr.io/alaub81/fail2ban-dockerized:latest\n       network_mode: host\n       cap_add:\n         - NET_ADMIN\n         - NET_RAW\n       restart: always\n       env_file:\n         - fail2ban.env\n       volumes:\n         # Fail2ban-Config + State\n         - ./data/fail2ban/fail2ban.d/:/etc/fail2ban/fail2ban.d:ro\n         - ./data/fail2ban/jail.d/:/etc/fail2ban/jail.d:ro\n         - data_fail2ban:/var/lib/fail2ban\n         # Host-Journal (volatile + persistent) and machine-id\n         - /run/log/journal:/run/log/journal:ro\n         - /var/log/journal:/var/log/journal:ro\n         - /etc/machine-id:/etc/machine-id:ro\n       logging:\n         # Fail2ban-Logs into Host-Journal\n         driver: journald\n         options:\n           tag: \"fail2ban-DC\"\n\n   volumes:\n     data_fail2ban:\n\n   ```\n\n2. **Configure environment**\n   Create a local env file and adjust values:\n\n   ```bash\n   cp fail2ban.env.example fail2ban.env\n   # edit fail2ban.env (SMTP host/user, recipient, etc.)\n   ```\n\n3. **Enable SSH protection**\n   Create your SSH jail from the example:\n\n   ```bash\n   mkdir -p data/fail2ban/jail.d\n   cp data/fail2ban/jail.d/10-sshd.local.example data/fail2ban/jail.d/10-sshd.local\n   ```\n\n   Recommended configuration:\n\n   ```ini\n   [sshd]\n   enabled   = true\n   mode      = aggressive\n   port      = ssh\n   maxretry  = 3\n   ```\n\n   Adjust ports if you use non‑standard SSH ports (e.g., `2222`).\n\n4. **Start with Docker Compose**\n\n   ```bash\n   # pull a published image:\n   docker compose -f docker-compose.yml up -d\n   # or build locally:\n   docker compose -f docker-compose.dev.yml up -d\n   ```\n\n5. **Verify**\n\n   ```bash\n   docker logs -f \u003ccontainer\u003e\n   docker exec -it \u003ccontainer\u003e fail2ban-client status\n   docker exec -it \u003ccontainer\u003e fail2ban-client status sshd\n   ```\n\n## Configuration layout\n\n- **Global fail2ban overrides**: put `.local` files into\n  `data/fail2ban/fail2ban.d/` → mounted read-only to `/etc/fail2ban/fail2ban.d`\n- **Jails**: put `.local` files into\n  `data/fail2ban/jail.d/` → mounted read-only to `/etc/fail2ban/jail.d`\n\nTypical files:\n\n- `data/fail2ban/jail.d/10-sshd.local` – enable/adjust SSH jail (`enabled = true`, `port`, `backend = systemd`, etc.)\n- `data/fail2ban/jail.d/99-custom.local` – your custom jails/filters\n- `data/fail2ban/fail2ban.d/00-logging.local` – override global loglevel/target if needed\n\n### Journald vs file backend\n\n- Using host **journald** is the standard backend of the image\n\n  ```ini\n  backend = systemd\n  ```\n\n- Using file logs instead: provide `logpath` and mount the log file into the container.\n\n## Configuration\n\nSet in `fail2ban.env` (see `fail2ban.env.example`):\n\n```dotenv\nF2B_WAIT_BEFORE_START=15\nF2B_DESTEMAIL=alerts@yourdomain.tld\nMSMTP_HOST=mx.yourdomain.tld\nMSMTP_PORT=587\nMSMTP_MAILDOMAIN=yourdomain.tld\nMSMTP_FROM=fail2ban@yourdomain.tld\nMSMTP_USER=fail2ban@yourdomain.tld\nMSMTP_PASSWORD=CHANGE_ME\nMSMTP_TLS=on\nMSMTP_STARTTLS=on\n\n```\n\nAt container start, the entrypoint renders:\n\n- `/etc/msmtprc` with your SMTP settings (logging to STDOUT by default),\n- `/etc/msmtp-aliases` mapping both `root` and `default` to `F2B_DESTEMAIL`.\n\nFail2ban’s default mail action is `%(action_mwl)s` (mail with log excerpt).\nYou can change the action in a `.local` file under `data/fail2ban/jail.d/`.\n\n## Compose files\n\n- `docker-compose.yml` — pulls **ghcr.io/alaub81/fail2ban-dockerized:latest**\n- `docker-compose.dev.yml` — builds locally from `Dockerfile-fail2ban`\n\nBoth use:\n\n```yaml\nnetwork_mode: host\ncap_add:\n  - NET_ADMIN\n  - NET_RAW\nvolumes:\n  - ./data/fail2ban/fail2ban.d/:/etc/fail2ban/fail2ban.d:ro\n  - ./data/fail2ban/jail.d/:/etc/fail2ban/jail.d:ro\n  - data_fail2ban:/var/lib/fail2ban\n  - /run/log/journal:/run/log/journal:ro\n  - /var/log/journal:/var/log/journal:ro\n  - /etc/machine-id:/etc/machine-id:ro\nlogging:\n  driver: journald\n  options: { tag: \"fail2ban-DC\" }\n```\n\n## Local test tips\n\n- Force a ban manually:\n\n  ```bash\n  docker exec -it \u003ccontainer\u003e fail2ban-client set sshd banip 203.0.113.77\n  docker exec -it \u003ccontainer\u003e iptables -L f2b-sshd -n --line-numbers\n  ```\n\n- Unban:\n\n  ```bash\n  docker exec -it \u003ccontainer\u003e fail2ban-client set sshd unbanip 203.0.113.77\n  ```\n\n## CI/CD\n\n- **CI**: lint (actionlint, yamllint, hadolint, shellcheck), build, **Trivy FS + Image**, and an **E2E ban test** that injects a fake sshd log entry and asserts an iptables rule.\n- **Release**: Tag with `vX.Y.Z` to build multi‑arch and push to GHCR with SemVer tags and `latest`.\n\n## Security notes\n\n- Never commit real secrets. Prefer `MSMTP_PASSWORD_FILE` (Docker secret or mounted file).\n- Consider `allowipv6 = auto` so IPv6 bans are enforced (via `ip6tables`) when IPv6 is enabled on the host.\n\n## License \u0026 Security\n\n- License: MIT (see `LICENSE`)\n- Security Policy: see `SECURITY.md` (how to report vulnerabilities)\n\n---\n\n## Changelog\n\nSee Git commit history and release notes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falaub81%2Ffail2ban-dockerized","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falaub81%2Ffail2ban-dockerized","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falaub81%2Ffail2ban-dockerized/lists"}