Files
computer-playbook/roles/web-app-stalwart/tasks/security.yml
kevinveenbirkenbachandClaude Opus 5.5 f92b7000af fix(web-app-stalwart): let address bans expire
Stalwart bans an address for good once it passes a failure rate: the four
*BanPeriod fields of its Security settings are null, and block_ip stores a
ban without a period with expires_at.unwrap_or(u64::MAX). Many clients reach
Stalwart through one address (the reverse proxy, published ports, Tor, the
swarm ingress), so one burst of failed logins locked that path out until
someone deleted the BlockedIp entry by hand.

The role now sets authBanPeriod, abuseBanPeriod, loiterBanPeriod and
scanBanPeriod to services.stalwart.ban_period_seconds, one hour by default,
and reloads the settings, as Stalwart's own security test does after it
changes a ban period. It reads the settings first and leaves them alone when
they already match, so a redeploy changes nothing.

Closes #916

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 12:01:36 +02:00

35 lines
1.3 KiB
YAML

---
- name: "📖 Read Stalwart's ban settings"
include_tasks: jmap_call.yml
vars:
stalwart_jmap_body: >-
{{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
'methodCalls': [['x:Security/get', {'ids': ['singleton']}, 'c0']]} | to_json }}
- name: "🔍 Resolve Stalwart's current ban periods"
ansible.builtin.set_fact:
stalwart_ban_periods_current: >-
{{ stalwart_jmap.methodResponses[0][1].list[0]
| dict2items | selectattr('key', 'in', STALWART_BAN_PERIODS) | items2dict }}
- name: "⏱️ Let Stalwart's address bans expire"
when: stalwart_ban_periods_current != STALWART_BAN_PERIODS
block:
- name: "🔧 Set Stalwart's ban periods"
include_tasks: jmap_call.yml
vars:
stalwart_jmap_body: >-
{{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
'methodCalls': [['x:Security/set',
{'update': {'singleton': STALWART_BAN_PERIODS}},
'c0']]} | to_json }}
- name: "🔄 Reload Stalwart's settings"
include_tasks: jmap_call.yml
vars:
stalwart_jmap_body: >-
{{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
'methodCalls': [['x:Action/set',
{'create': {'a': {'@type': 'ReloadSettings'}}},
'c0']]} | to_json }}