This commit is contained in:
zand
2026-09-08 17:18:05 +02:00
commit 364544d77e
11 changed files with 704 additions and 0 deletions
+193
View File
@@ -0,0 +1,193 @@
# Mastodon Email Blocker
Small maintenance tool for Mastodon instances that keeps the local `EmailDomainBlock` table in sync with public disposable-email domain lists.
It supports two existing Mastodon layouts:
- a normal source installation where `bin/rails` and `bin/tootctl` are available on the host;
- an existing Docker Compose installation, where the commands are executed inside the Mastodon application container with `docker compose exec`.
The tool does not use the Mastodon Admin API, so importing a large list does not generate one HTTP request per domain and does not run into API rate limits.
## What it changes
The blocklists are downloaded, normalized and merged. Domains already present in Mastodon are skipped; missing domains are added with Mastodon's own `tootctl email-domain-blocks add` command.
By default the tool also turns existing `allow_with_approval` email-domain records into hard deny records. Use `--no-force-deny` if that is not wanted.
MX records are never blocked automatically. `--mx-mode report` can be used for occasional DNS analysis, but the result is informational only. Shared mail infrastructure is common and blocking an MX hostname can affect unrelated, legitimate domains.
## Sources
The default set is built from:
- mehrtat/disposable-email-domain
- FFraud-com/disposable-email-domains
- disposable/disposable-email-domains
If a source is temporarily unavailable, the other successful sources are still used. If every source fails, the run stops before changing Mastodon.
## Requirements
- Python 3.10 or newer
- access to the Mastodon administration commands
- `dnspython` only when MX reporting is enabled
Create a virtual environment:
```sh
python3 -m venv /opt/mastodon-email-blocker/venv
/opt/mastodon-email-blocker/venv/bin/pip install -r requirements.txt
```
Install the script:
```sh
install -d /opt/mastodon-email-blocker
install -m 0755 bin/mastodon-email-blocker.py /opt/mastodon-email-blocker/mastodon-email-blocker.py
install -d /etc/mastodon-email-blocker /var/lib/mastodon-email-blocker
install -m 0644 config/allowlist.example.txt /etc/mastodon-email-blocker/allowlist.txt
```
The account running the tool must be able to run the Mastodon commands and write to `/var/lib/mastodon-email-blocker`.
## Source installation
Run a dry run first:
```sh
/opt/mastodon-email-blocker/venv/bin/python \
/opt/mastodon-email-blocker/mastodon-email-blocker.py \
--backend native \
--mastodon-dir /path/to/mastodon/live \
--ruby-bin /path/to/ruby/bin \
--mx-mode off \
--dry-run
```
`--ruby-bin` can be omitted when the correct Ruby is already in `PATH`.
Apply the changes:
```sh
/opt/mastodon-email-blocker/venv/bin/python \
/opt/mastodon-email-blocker/mastodon-email-blocker.py \
--backend native \
--mastodon-dir /path/to/mastodon/live \
--ruby-bin /path/to/ruby/bin \
--mx-mode off
```
Do not source Mastodon's `.env.production` from this script. Rails should load the application's production configuration in the same way it does for normal Mastodon commands.
## Existing Docker Compose installation
Nothing is installed inside the Mastodon image. The Python tool runs on the Docker host and invokes Rails/tootctl in the existing application service.
For the standard Mastodon Compose layout the application service is normally named `web`. If the local Compose file uses another service name, pass it with `--compose-service`.
Dry run:
```sh
/opt/mastodon-email-blocker/venv/bin/python \
/opt/mastodon-email-blocker/mastodon-email-blocker.py \
--backend docker \
--compose-dir /path/to/mastodon-compose \
--compose-service web \
--mx-mode off \
--dry-run
```
Apply the changes:
```sh
/opt/mastodon-email-blocker/venv/bin/python \
/opt/mastodon-email-blocker/mastodon-email-blocker.py \
--backend docker \
--compose-dir /path/to/mastodon-compose \
--compose-service web \
--mx-mode off
```
For installations still using the old standalone binary, use:
```sh
--compose-command "docker-compose"
```
The Docker user running the tool must have permission to use Docker. No database password, Mastodon secret, `.env.production` file or API token is read by the Python program; the existing application container already has its normal environment.
## Allowlist
Put exceptions in `/etc/mastodon-email-blocker/allowlist.txt`, one domain per line:
```text
example.org
mail.example.net
```
The allowlist only prevents the tool from adding those domains. It does not delete a block that already exists in Mastodon.
## MX report
DNS/MX analysis is intentionally disabled for scheduled runs because resolving a large domain set is slow and MX providers are often shared.
Run it manually when useful:
```sh
/opt/mastodon-email-blocker/venv/bin/python \
/opt/mastodon-email-blocker/mastodon-email-blocker.py \
--backend native \
--mastodon-dir /path/to/mastodon/live \
--mx-mode report
```
or, for Compose:
```sh
/opt/mastodon-email-blocker/venv/bin/python \
/opt/mastodon-email-blocker/mastodon-email-blocker.py \
--backend docker \
--compose-dir /path/to/mastodon-compose \
--compose-service web \
--mx-mode report
```
The report is written to `/var/lib/mastodon-email-blocker/last-report.json`. MX entries in that file have `REPORT_ONLY` status and are not sent to Mastodon.
## systemd
Examples are in `systemd/`. Copy the matching service and the common timer, then create the corresponding environment file from `config/native.env.example` or `config/docker.env.example`.
For example:
```sh
install -m 0644 systemd/mastodon-email-blocker-docker.service /etc/systemd/system/mastodon-email-blocker.service
install -m 0644 systemd/mastodon-email-blocker.timer /etc/systemd/system/mastodon-email-blocker.timer
install -m 0644 config/docker.env.example /etc/mastodon-email-blocker/docker.env
```
Edit `/etc/mastodon-email-blocker/docker.env`, then enable the timer:
```sh
systemctl daemon-reload
systemctl enable --now mastodon-email-blocker.timer
```
A manual service run is useful before enabling the timer:
```sh
systemctl start mastodon-email-blocker.service
journalctl -u mastodon-email-blocker.service -n 100 --no-pager
```
## Interrupting and re-running
A run can be interrupted with `Ctrl+C`. Completed batches stay in Mastodon. On the next run the existing records are read again, so already-added domains are skipped and only the remaining ones are submitted.
## Files written
- `/var/lib/mastodon-email-blocker/last-report.json` — last run report
- `/var/lib/mastodon-email-blocker/state.json` — small state summary
The tool does not store Mastodon credentials or API tokens.