- New page: Dovecot IMAP vsz_limit OOM from a bloated/corrupt index.log (152M index on an empty folder killed IMAP children with error 83). - fail2ban IMAP self-ban: add permanent ignoreip-whitelist fix + dynamic-IP caveat. - firewalld mail ports: add 'submission/587 never added' variant + correct Fedora service name; note Ansible now manages the full mail-service set. - Index + SUMMARY updated with the new page.
96 lines
4.4 KiB
Markdown
96 lines
4.4 KiB
Markdown
---
|
|
title: "firewalld: Mail Ports Wiped After Reload (IMAP + Webmail Outage)"
|
|
domain: troubleshooting
|
|
category: networking
|
|
tags: [firewalld, mail, imap, fedora, ports]
|
|
status: published
|
|
created: 2026-04-02
|
|
updated: 2026-06-05
|
|
---
|
|
# firewalld: Mail Ports Wiped After Reload (IMAP + Webmail Outage)
|
|
|
|
If IMAP, SMTP, and webmail all stop working simultaneously on a Fedora/RHEL mail server, firewalld may have reloaded and lost its mail port configuration.
|
|
|
|
## Symptoms
|
|
|
|
- `openssl s_client -connect mail.example.com:993` returns `Connection refused`
|
|
- Webmail returns connection refused or times out
|
|
- SSH still works (port 22 is typically in the persisted config)
|
|
- `firewall-cmd --list-services --zone=public` shows only `ssh dhcpv6-client mdns` or similar — no mail services
|
|
- Mail was working before a service restart or system event
|
|
|
|
## Why It Happens
|
|
|
|
firewalld uses two layers of configuration:
|
|
- **Runtime** — active rules in memory (lost on reload or restart)
|
|
- **Permanent** — written to `/etc/firewalld/zones/public.xml` (survives reloads)
|
|
|
|
If mail ports were added with `firewall-cmd --add-service=imaps` (without `--permanent`), they exist only in the runtime config. Any event that triggers a `firewall-cmd --reload` — including Fail2ban restarting, a system update, or manual reload — wipes the runtime config back to the permanent state, dropping all non-permanent rules.
|
|
|
|
## Diagnosis
|
|
|
|
```bash
|
|
# Check what's currently allowed
|
|
firewall-cmd --list-services --zone=public
|
|
|
|
# Check nftables for catch-all reject rules
|
|
nft list ruleset | grep -E '(reject|accept|993|143)'
|
|
|
|
# Test port 993 from an external machine
|
|
openssl s_client -connect mail.example.com:993 -brief
|
|
```
|
|
|
|
If the only services listed are `ssh` and the port test shows `Connection refused`, the rules are gone.
|
|
|
|
## Fix
|
|
|
|
Add all mail services permanently and reload:
|
|
|
|
```bash
|
|
firewall-cmd --permanent \
|
|
--add-service=smtp \
|
|
--add-service=smtps \
|
|
--add-service=smtp-submission \
|
|
--add-service=imap \
|
|
--add-service=imaps \
|
|
--add-service=http \
|
|
--add-service=https
|
|
firewall-cmd --reload
|
|
|
|
# Verify
|
|
firewall-cmd --list-services --zone=public
|
|
```
|
|
|
|
Expected output:
|
|
```
|
|
dhcpv6-client http https imap imaps mdns smtp smtp-submission smtps ssh
|
|
```
|
|
|
|
## Variant: One port (587) fails while the rest work — service never added
|
|
|
|
A subtler version of this: IMAP (993) and implicit-TLS submission (465) work fine, but **only STARTTLS submission on 587 fails** — clients on 587 get "no route to host." This is **not** a reload wipe; the `submission` service was simply never added during initial setup (the box's mail ports were opened by hand and one was missed).
|
|
|
|
```bash
|
|
# Each mail service, individually — submission will be the odd one out
|
|
for s in smtp smtps submission imap imaps; do printf "%-12s " "$s"; firewall-cmd --query-service=$s; done
|
|
|
|
# Fix (Fedora 44 / firewalld names the 587 service `submission`, NOT `smtp-submission`)
|
|
firewall-cmd --permanent --zone=public --add-service=submission
|
|
firewall-cmd --reload
|
|
```
|
|
|
|
> On majormail the full mail-service set is now managed declaratively in `roles/majormail/tasks/postfix.yml` (smtp/smtps/**submission**/imap/imaps), so a hand-edit can't leave 587 behind again (MajorAnsible commit `b75f14a`). Seen 2026-06-05.
|
|
|
|
## Key Notes
|
|
|
|
- **Service name differs by distro/version:** the 587 service is `submission` on current Fedora firewalld; older/other docs may say `smtp-submission`. Verify with `firewall-cmd --get-services | tr ' ' '\n' | grep submission`.
|
|
- **Always use `--permanent`** when adding services to firewalld on a server. Without it, the rule exists only until the next reload.
|
|
- **Fail2ban + firewalld**: Fail2ban uses firewalld as its ban backend (`firewallcmd-rich-rules`). When Fail2ban restarts or crashes, it may trigger a `firewall-cmd --reload`, resetting any runtime-only rules.
|
|
- **Verify after any firewall event**: After Fail2ban restarts, system reboots, or `firewall-cmd --reload`, always confirm mail services are still present with `firewall-cmd --list-services --zone=public`.
|
|
- **Check the permanent config directly**: `cat /etc/firewalld/zones/public.xml` — if mail services aren't in this file, they'll be lost on next reload.
|
|
|
|
## Related
|
|
|
|
- [Linux Server Hardening Checklist](../../02-selfhosting/security/linux-server-hardening-checklist.md)
|
|
- [Mail Client Stops Receiving: Fail2ban IMAP Self-Ban](fail2ban-imap-self-ban-mail-client.md)
|
|
- [Dovecot IMAP Clients Fail to Sync: vsz_limit OOM from a Bloated Index Log](dovecot-imap-oom-vsz-limit-bloated-index.md)
|