main
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user