# Limristem eMail Operations

## Backup configuration

Main files:
- `<BASE_DIR>/config/limristem-mail.env`
- `<BASE_DIR>/config/limristem-mail-backup.env`

Relevant backup options:

```bash
LIMRISTEM_MAIL_BACKUP_TYPE=auto
LIMRISTEM_MAIL_BACKUP_FULL_WEEKDAY=Sun
LIMRISTEM_MAIL_BACKUP_DB_MODE=logical
LIMRISTEM_MAIL_BACKUP_LOCAL_DIR=/var/backups/limristem-mail
LIMRISTEM_MAIL_BACKUP_RETENTION_DAYS=14
LIMRISTEM_MAIL_BACKUP_REMOTE_TARGETS="s3-mail:bucket/path sftp-mail:/srv/backup"
LIMRISTEM_MAIL_BACKUP_ONCALENDAR="*-*-* 03:15:00"
LIMRISTEM_MAIL_BACKUP_COMPRESSION=gzip
LIMRISTEM_MAIL_BACKUP_INCLUDE_REDIS=yes
LIMRISTEM_MAIL_BACKUP_STORAGE_TYPE=local
LIMRISTEM_MAIL_BACKUP_STORAGE_REMOTE_NAME=limristem-mail-backup
```

`LIMRISTEM_MAIL_BACKUP_REMOTE_TARGETS` uses `rclone`, so remotes can be configured for:
- `FTP`
- `FTPS`
- `SFTP/SSH`
- `S3`
- other backends supported by `rclone`

The web panel can now generate and maintain the rclone profile for `S3`, `SFTP`, `FTP`, and `FTPS` directly from the backup page. When remote storage is disabled (`LIMRISTEM_MAIL_BACKUP_STORAGE_TYPE=local`), `LIMRISTEM_MAIL_BACKUP_REMOTE_TARGETS` is cleared automatically.

Run a backup manually:

```bash
sudo /opt/limristem-mail/bin/backup.sh
```

Restore helper:

```bash
sudo /opt/limristem-mail/bin/restore.sh --source /var/backups/limristem-mail/<backup-dir> --restore-files --restore-db
```

Notes:
- filesystem incrementals require the full backup chain for restore
- logical DB restores are automated
- physical MariaDB backups are staged and then prepared manually with `mariabackup`

## Scheduling

Backup scheduling is managed by:
- `limristem-mail-backup.service`
- `limristem-mail-backup.timer`

Reload after editing `<BASE_DIR>/config/limristem-mail-backup.env`:

```bash
sudo LIMRISTEM_MAIL_BACKUP_ONCALENDAR='*-*-* 02:00:00' bash /opt/limristem-mail/bin/install.sh
```

Notes:
- changing backup mode, retention, remote targets, compression, or Redis inclusion only requires restarting `limristem-mail-backup.service`/`timer`
- changing the schedule itself (`LIMRISTEM_MAIL_BACKUP_ONCALENDAR`) requires re-rendering the timer unit, so re-run `scripts/install.sh` or edit `/etc/systemd/system/limristem-mail-backup.timer` directly

## Performance report

```bash
sudo /opt/limristem-mail/bin/performance-report.sh
```

The report includes:
- service states
- queue length
- mail storage size
- MariaDB object counts and basic status
- Redis memory/client/cache stats
- host disk and memory usage
- Rspamd summary when available

## Deliverability check

Generate the DNS plan first. Keep `MTA-STS` enabled only when the policy endpoint is served with a publicly trusted certificate:

```bash
sudo /opt/limristem-mail/bin/generate-dns-plan.sh example.com mail.example.com
```

Generate the full live bundle for the external rollout:

```bash
sudo /opt/limristem-mail/bin/export-live-bundle.sh example.com mail.example.com 203.0.113.10
```

Then validate the public deployment:

```bash
sudo /opt/limristem-mail/bin/deliverability-check.sh example.com mail.example.com 203.0.113.10
```

The script checks:
- MX, A/AAAA, SPF, DMARC, DKIM
- optional PTR if a public IP is provided
- `MTA-STS` and `TLS-RPT` DNS visibility
- HTTPS health endpoint
- SMTP STARTTLS certificate visibility

To save a timestamped report:

```bash
sudo /opt/limristem-mail/bin/deliverability-report.sh example.com mail.example.com 203.0.113.10
```

If `LIMRISTEM_MAIL_ENABLE_DELIVERABILITY_TIMER=yes`, the installer also enables `limristem-mail-deliverability-report.timer`.

## Cloudflare DNS and DKIM

Limristem eMail can publish the DKIM TXT record for a domain through Cloudflare. Configure a Cloudflare API token with DNS edit permission limited to the target zone:

```bash
sudo /opt/limristem-mail/limristem-mail dns configure-cloudflare example.com \
  --zone-id 0123456789abcdef0123456789abcdef \
  --api-token cloudflare-zone-token \
  --enable-sync
```

Generate or rotate DKIM and publish it:

```bash
sudo /opt/limristem-mail/limristem-mail add domain example.com --generate-dkim
sudo /opt/limristem-mail/limristem-mail dns sync-dkim example.com --json
```

When DNS sync is enabled for the domain, future DKIM rotations publish the updated TXT record automatically. The API token is stored for the domain but never returned by API responses or panel views.

## Queue, bans, limits, and backups

CLI queue management:

```bash
sudo /opt/limristem-mail/limristem-mail queue list
sudo /opt/limristem-mail/limristem-mail queue hold ABC123DEF
sudo /opt/limristem-mail/limristem-mail queue release ABC123DEF
sudo /opt/limristem-mail/limristem-mail queue delete ABC123DEF
```

CLI ban management:

```bash
sudo /opt/limristem-mail/limristem-mail bans list
sudo /opt/limristem-mail/limristem-mail bans ban 203.0.113.5 abuse
sudo /opt/limristem-mail/limristem-mail bans unban 203.0.113.5
```

`manage-bans.sh` now delegates enforcement to fail2ban only. Manual bans are pushed into every active jail, and `list` shows the active jail rows (for example `sshd`, `dovecot`, `postfix`, `nginx-http-auth`) that currently hold the IP.

CLI firewall management:

```bash
sudo /opt/limristem-mail/limristem-mail firewall show
sudo /opt/limristem-mail/limristem-mail firewall set firewall-enabled yes
sudo /opt/limristem-mail/limristem-mail firewall set firewall-rules-json '[{"ports":"22 25 80 443 465 587 993 995","protocol":"tcp","source":"","enabled":"yes"},{"ports":"53 123","protocol":"udp","source":"203.0.113.0/24","enabled":"no"}]'
```

The firewall panel now edits nftables as a rule table with columns for port/group/range, protocol, source IP or subnet, and enabled status.

CLI limits management:

```bash
sudo /opt/limristem-mail/limristem-mail limits show
sudo /opt/limristem-mail/limristem-mail limits set postfix-client-connection-rate-limit 20
sudo /opt/limristem-mail/limristem-mail limits set api-auth-fail-limit 3
```

CLI backup management:

```bash
sudo /opt/limristem-mail/limristem-mail backup show
sudo /opt/limristem-mail/limristem-mail backup list
sudo /opt/limristem-mail/limristem-mail backup set backup-oncalendar $'*-*-* 02:00:00\nMon *-*-* 14:00:00'
sudo /opt/limristem-mail/limristem-mail backup run
```

If `LIMRISTEM_MAIL_ENABLE_WEB_PANEL=yes`, the same operations are also available over dedicated pages under `https://<mail-host>/panel`.

## SRS synchronization

When `LIMRISTEM_MAIL_ENABLE_SRS=yes`, the following timer keeps the `postsrsd` domain list aligned with active domains from MariaDB:

```bash
sudo systemctl status limristem-mail-postsrsd-sync.timer
```

Manual sync:

```bash
sudo /opt/limristem-mail/bin/sync-postsrsd-domains.sh
```

## Troubleshooting

If `sudo` reports `unable to resolve host <mail-host>`, the system hostname is not aligned with `/etc/hosts`. Re-run the installer so it re-applies both:

```bash
cd /opt/limristem-mail
sudo ./install.sh --hostname mail.example.com
```

If Postfix reports `sender_canonical_maps map lookup problem`, `recipient_canonical_maps map lookup problem`, or `connect to srs: No such file or directory`, verify `postsrsd` first:

```bash
sudo systemctl status postsrsd
sudo journalctl -u postsrsd -n 50 --no-pager
sudo grep -E '^(SRS_DOMAIN|SRS_FORWARD_PORT|SRS_REVERSE_PORT|SRS_LISTEN_ADDR|SRS_EXCLUDE_DOMAINS)=' /etc/default/postsrsd
sudo /opt/limristem-mail/bin/sync-postsrsd-domains.sh
```

Current Limristem eMail configures Debian/Ubuntu `postsrsd` through `/etc/default/postsrsd` and Postfix TCP maps on `127.0.0.1:10001/10002`. The installer also refreshes `SRS_DOMAIN` from the full server hostname and synchronizes active Limristem eMail domains from the MariaDB `domains` table into `SRS_EXCLUDE_DOMAINS` (using the same Limristem eMail database credentials configured for Dovecot/Postfix integration), so re-running `./install.sh -u` on an updated tree repairs stale PostSRSd/Postfix wiring without forcing a destructive reinstall.

If `LIMRISTEM_MAIL_SRS_DOMAIN` is different from the primary sender domain, publish an SPF record for that SRS domain as well (for example `test.email.crisle.eu IN TXT "v=spf1 mx a:mail.example.com -all"`), otherwise forwarded mail may still fail SPF checks even when local authenticated mail is no longer rewritten unnecessarily.

If Dovecot 2.4 reports `ssl_cert: Unknown setting: ssl_cert`, `mail_location: Unknown setting: mail_location`, or `quota_grace: Unknown setting: quota_grace`, the host still has pre-2.4 Limristem eMail config snippets. Current Limristem eMail upgrades those files before package installation and rewrites them with the new `ssl_server_cert_file` / `ssl_server_key_file`, `mail_driver` / `mail_path`, and `quota_storage_grace` setting name when the legacy value is still valid. Unsupported percentage-based quota grace values are removed during repair so Dovecot can start cleanly. Update the tree and re-run:

```bash
cd /opt/limristem-mail
sudo ./install.sh -u
sudo dpkg --configure -a
```

If Dovecot reports `Error in configuration file /etc/dovecot/conf.d/auth-sql.conf.ext ... args: Unknown setting: args`, `passdb { } is missing section name`, `passdb sql: sql_driver setting is empty`, `Error in configuration file /etc/dovecot/dovecot-sql.conf.ext ... connect: Unknown setting: connect`, or `passdb sql: sql mysql: mysql { .. } named list filter is missing`, update the tree and re-run `./install.sh -u` as well. Current Limristem eMail rewrites `auth-sql.conf.ext` with the standard `passdb sql` / `userdb sql` blocks, no explicit `args =` lines on Dovecot 2.4.x, an explicit `sql_driver = mysql` entry in `/etc/dovecot/dovecot-sql.conf.ext`, a Dovecot 2.4 `mysql __DB_HOST__ { ... }` named list filter for the MySQL connection settings, and the Dovecot 2.4 `passdb_sql_query` / `userdb_sql_query` setting names.

If Postfix reports warnings about backwards-compatible defaults, `incompatibility_level`, `smtpd_use_tls`, or `smtpd_tls_eecdh_grade`, re-running the updated installer with `./install.sh -u` also rewrites `main.cf` with `compatibility_level = 3.6` and removes the deprecated TLS parameters.

## Health checks

Public:

```bash
curl https://mail.example.com/health
```

Authenticated:

```bash
curl -u admin:'your-bootstrap-password' https://mail.example.com/health/details
```
