pqm/README.md

125 lines
6.9 KiB
Markdown

# Postfix (cluster) queue manager
CLI tool to manage postfix queues (optionally across multiple hosts through ssh).
It uses [trio](https://trio.readthedocs.io/en/stable/) for asynchronous operations (i.e. parallel handling of many nodes in a cluster).
It also has proper readline support with history of commands.
## Workflow
Start with `health` to get a feeling for the queue state.
Show the list of deferred mails with `list`, or show all mails from a certain user (maybe `health` showed a suspicious user) with `list from bob@example.com`.
Note that `list` (contrary to `list-verbose`) only shows the last (remaining) recipient of a mail (and how many targets are remaining).
Build up filters to match only certain mails - e.g. start with `select from MAILER-DAEMON` to search for bounces, and then limit those to no-reply targets with `select to ~reply`. Use `list` or `list-verbose` to see which mails remain, and what the problem is.
Use `show mailid` to show headers of suspicious emails, or `show -hb mailid` to show the body too if really necessary.
Use `hold` to hold all currently selected mails (e.g. spam/...), and then delete them later with `delete`. Or use `delete mailid` to delete specific mails directly.
Use `expire` to return mails to the sender (because you think the error from `list-verbose` is permanent, even if postfix doesn't know it yet).
`delete` and `expire` operations prompt for confirmation after showing affected mails.
## List of commands
There is an interactive help command.
```
# help
clear Clear all filters
clear <arg> Clear filter with given index (zero based; first filter is at index 0)
current Show current filters
delete Delete selected mails from the hold queue
delete <arg> Delete mails with given IDs from the queues
delete-all Delete selected mails from all queues
exit Exit pqm (or press Ctrl-D on empty prompt)
expire Expire mails and flush them (return error to sender).
expire <arg> Expire mails (return error to sender) with given IDs and flush them.
expire-noflush Expire mails (return error to sender on next delivery attempt).
expire-noflush <arg> Expire mails (return error to sender on next delivery attempt) with given IDs.
expire-release Expire mails and flush them (return error to sender); release if mails are on hold.
expire-release <arg> Expire mails (return error to sender) with given IDs and flush them; release if mails are on hold.
flush Flush (deferred) selected mails in the queue: attempt to deliver them
flush <arg> Flush (deferred) mails with given IDs: attempt to deliver them
flush-all Flush the queue: attempt to deliver all queued mail.
health Show generic stats for queues and overly active address
help Show all available commands
help <arg> Show detailed help for a command
hold Put selected mails on hold
hold <arg> Put mails with given IDs on hold
list [<arg>] List all mails (single line per mail); if no filter is configured hide active and hold queue
list-all [<arg>] List all mails (including active + hold queue, single line per mail)
list-verbose [<arg>] List all mails (verbose output); if no filter is configured hide active and hold queue
list-verbose-all [<arg>] List all mails (including active + hold queue, verbose output)
pop Remove last filter
release Release mail that was put "on hold".
release <arg> Release mails with given IDs that were put "on hold".
requeue Requeue mail (move to "maildrop"; get reprocessed)
requeue <arg> Requeue mail with given IDs (move to "maildrop"; get reprocessed)
select <arg> Add filter for mails that other commands work on
show <arg> usage: show [-b] [-e] [-h] ID [ID ...]
```
Available filter expressions are show in the help for `select`:
```
# help select
>>>> select <args>
Add filter for mails that other commands work on
Filter syntax:
- `from bob@example.com`, `from alice@example.com,bob@example.com,@example.net`, `from "alice@example.com" "bob@example.com"`
Multiple address can be given to match any of them; either unquoted and comma separated, or quoted and whitespace
separated. In the unquoted case the (comma separated) pattern must not include any whitespace.
An address starting with `@` only checks the domain name and ignores the local part.
- `from ~regex.*@example.(com|net)`, `from ~"regex.*@example.(com|net)" "other@example.com`
To use regular expressions either put `~` in front of an unquoted pattern (need to repeat for each regex in a
comma separated pattern list) or before the quotes of a quoted pattern.
- `to ...` and `address ...` (matching both to and from) work the same as `from ...`
- `queue hold,deferred`
Comma separated list of queues a mail must be in. For single queue names `queue` can be omitted, e.g. `hold`.
- `$expr1 and $expr2`
- `$expr1 or $expr2` (`a and b or c` is parsed as `a and (b or c)`)
- `($expr)`
- `not $expr`
```
The select expressions use the data provided by `postqueue -j` - which is why it doesn't support filtering by subject/other headers.
## Installation
Dependencies:
- python3, probably >= 3.10
- [trio](https://trio.readthedocs.io/en/stable/)
- [pyparsing](https://github.com/pyparsing/pyparsing/)
- [PyYAML](https://github.com/yaml/pyyaml)
On Debian: `apt install python3-trio python3-pyparsing python3-yaml`
Put the pqm script into your path and make it executable.
## Configuration
Configuration is optional; by default it tries to use `~/.config/pqm.yaml` and `/etc/pqm.yaml` (picking the first one that exists).
Also see `pqm.example.yaml` in this repository.
### Source (hosts load load mails from)
By default it will use the local queue; it probably needs to run as root for that.
Use `remote-sources` in the config to use remote hosts instead ("cluster" mode). Each remote source has a unique alias that is used in the `pqm` output (by default the first DNS label in the hostname).
`pqm` uses `ssh -oBatchMode=yes root@remotesource ...` to execute postfix tools on the remote nodes; this means you'll probably want a public-key based authentication to the postfix nodes, and the server keys must already be trusted.
You'll also want to make sure the ssh login is fast; `UseDNS no` (should be the default) on the server and ed25519 keys should help with that.
## Queue IDs
Each mail in the postfix queues has an ID; when using the local source `pqm` will use this ID directly. With remote sources it will prepend `alias/` to the ID.