Support guidelines
I've found a bug and checked that ...
Description
I did notice in my installation with BLOCKLIST_API_ALLOWED_IPS and BLOCKLIST_API_SECRET unset, but also with BLOCKLIST_API_ALLOWED_IPS="127.0.0.1", that entries in the blocklist where ignored. After a bit of debugging, I did see this in the log (email addresses changed):
addy | 172.20.0.1 - - [06/Jul/2026:19:50:41 +0000] "GET /api/blocklist-check?recipient=ttt%40ttt.de&from_email=zzz%40zzz.com HTTP/1.1" 403 52 "-" "rspamd-3.14.0"
The 403 makes sense, since of course that IP is NOT in the list. After a bit of digging, I did find this line:
local blocklist_api_url = '${APP_URL}/api/blocklist-check'
(https://github.com/anonaddy/docker/blob/master/rootfs/etc/cont-init.d/14-config-rspamd.sh#L246)
In my opinion, this should look like this, so it does connect via 127.0.0.1:
local blocklist_api_url = 'http://127.0.0.1:8000/api/blocklist-check'
Especially in Docker you can't even really count on the IP always being the same, so it would make sense to just use localhost. This also makes sure, the request does not have to make the unneccessary roundtrip over an external reverse proxy with SSL handshake, etc.
Expected behaviour
The API call to the blocklist-check runs on localhost.
Actual behaviour
The API call to the blocklist-check is using the external URL (env API_URL).
Steps to reproduce
- Add a domain or e-mail to the blocklist
- Add an alias
- send an e-mail from the blocked address to the alias
- check logs
Docker info
Client: Docker Engine - Community
Version: 29.6.1
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.35.0
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v5.3.0
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 11
Running: 11
Paused: 0
Stopped: 0
Images: 10
Server Version: 29.6.1
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
CDI spec directories:
/etc/cdi
/var/run/cdi
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: e53c7c1516c3b2bff98eb76f1f4117477e6f4e66
runc version: v1.3.6-0-g491b69ba
init version: de40ad0
Security Options:
apparmor
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.8.0-134-generic
Operating System: Ubuntu 24.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.73GiB
Name: midgard
ID: d3086ab3-0e94-468c-a07a-f7832a80a03a
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
::1/128
127.0.0.0/8
Live Restore Enabled: false
Firewall Backend: iptables
EnableUserlandProxy: true
UserlandProxyPath: /usr/bin/docker-proxy
Docker Compose config
name: anonaddy
services:
acme:
build:
context: /srv/docker/anonaddy/acme
dockerfile: Dockerfile
command:
- daemon
container_name: addy_acme
environment:
HETZNER_TOKEN: <CENSORED>
networks:
default: null
restart: unless-stopped
volumes:
- type: volume
source: acme_data
target: /acme.sh
- type: volume
source: certs
target: /certs
- type: bind
source: /var/run/docker.sock
target: /var/run/docker.sock
addy:
container_name: addy
depends_on:
acme:
condition: service_started
restart: true
required: true
database:
condition: service_healthy
restart: true
required: true
redis:
condition: service_started
restart: true
required: true
environment:
ANONADDY_BANDWIDTH_LIMIT: "209715200"
ANONADDY_DKIM_SELECTOR: zaddy
ANONADDY_DKIM_SIGNING_KEY: /data/dkim/<CENSORED>.private
ANONADDY_DOMAIN: <CENSORED>
ANONADDY_ENABLE_REGISTRATION: "false"
ANONADDY_HOSTNAME: mx.<CENSORED>
ANONADDY_NEW_ALIAS_LIMIT: "60"
ANONADDY_SECRET: <CENSORED>
ANONADDY_SIGNING_KEY_FINGERPRINT: ""
APP_KEY: base64:<CENSORED>
APP_NAME: <CENSORED>
APP_URL: https://<CENSORED>
BLOCKLIST_API_ALLOWED_IPS: 127.0.0.1
DB_DATABASE: addy
DB_HOST: addy_database
DB_PASSWORD: <CENSORED>
DB_USERNAME: addy
LOG_IP_VAR: http_x_forwarded_for
MAIL_FROM_NAME: <CENSORED>
POSTFIX_SMTP_TLS: may
POSTFIX_SMTPD_TLS: may
POSTFIX_SMTPD_TLS_CERT_FILE: /certs/tls.crt
POSTFIX_SMTPD_TLS_KEY_FILE: /certs/tls.key
POSTFIX_SPAMHAUS_DQS_KEY: <CENSORED>
REAL_IP_FROM: 172.20.0.0/16
REDIS_HOST: addy_redis
RSPAMD_ENABLE: "true"
RSPAMD_WEB_PASSWORD: <CENSORED>
image: anonaddy/anonaddy:latest
labels:
traefik.enable: "true"
traefik.http.middlewares.redirect-https.redirectScheme.permanent: "true"
traefik.http.middlewares.redirect-https.redirectScheme.scheme: https
traefik.http.routers.anonaddy-http.entrypoints: web
traefik.http.routers.anonaddy-http.middlewares: redirect-https
traefik.http.routers.anonaddy-http.rule: Host(`<CENSORED>`)
traefik.http.routers.anonaddy-http.service: anonaddy
traefik.http.routers.anonaddy-https.entrypoints: websecure
traefik.http.routers.anonaddy-https.rule: Host(`<CENSORED>`)
traefik.http.routers.anonaddy-https.service: anonaddy
traefik.http.routers.anonaddy-https.tls: "true"
traefik.http.routers.anonaddy-https.tls.certresolver: letsencrypt
traefik.http.routers.anonaddy-rspamd-http.entrypoints: web
traefik.http.routers.anonaddy-rspamd-http.middlewares: redirect-https
traefik.http.routers.anonaddy-rspamd-http.rule: Host(`<CENSORED>.<CENSORED>`)
traefik.http.routers.anonaddy-rspamd-http.service: anonaddy-rspamd
traefik.http.routers.anonaddy-rspamd-https.entrypoints: websecure
traefik.http.routers.anonaddy-rspamd-https.rule: Host(`<CENSORED>.<CENSORED>`)
traefik.http.routers.anonaddy-rspamd-https.service: anonaddy-rspamd
traefik.http.routers.anonaddy-rspamd-https.tls: "true"
traefik.http.routers.anonaddy-rspamd-https.tls.certresolver: letsencrypt
traefik.http.services.anonaddy-rspamd.loadbalancer.server.port: "11334"
traefik.http.services.anonaddy.loadbalancer.server.port: "8000"
networks:
default: null
traefik: null
ports:
- mode: ingress
target: 25
published: "25"
protocol: tcp
restart: unless-stopped
volumes:
- type: volume
source: addy_data
target: /data
- type: volume
source: certs
target: /certs
read_only: true
database:
container_name: addy_database
environment:
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: "1"
MARIADB_AUTO_UPGRADE: "1"
MARIADB_DATABASE: addy
MARIADB_ROOT_PASSWORD: <CENSORED>
healthcheck:
test:
- CMD
- healthcheck.sh
- --connect
- --innodb_initialized
timeout: 5s
interval: 10s
retries: 3
start_period: 10s
image: mariadb:latest
networks:
default: null
read_only: true
restart: unless-stopped
volumes:
- type: volume
source: mariadb_data
target: /var/lib/mysql
- type: tmpfs
target: /tmp
- type: tmpfs
target: /run/mysqld
redis:
container_name: addy_redis
image: redis:8-alpine
networks:
default: null
restart: unless-stopped
networks:
default:
name: anonaddy_default
traefik:
name: traefik
external: true
volumes:
acme_data:
name: anonaddy_acme_data
addy_data:
name: anonaddy_addy_data
certs:
name: anonaddy_certs
mariadb_data:
name: anonaddy_mariadb_data
Logs
addy | 172.20.0.1 - - [06/Jul/2026:19:50:41 +0000] "GET /api/blocklist-check?recipient=ttt%40ttt.de&from_email=zzz%40zzz.com HTTP/1.1" 403 52 "-" "rspamd-3.14.0"
Additional info
No response
Support guidelines
I've found a bug and checked that ...
Description
I did notice in my installation with
BLOCKLIST_API_ALLOWED_IPSandBLOCKLIST_API_SECRETunset, but also with BLOCKLIST_API_ALLOWED_IPS="127.0.0.1", that entries in the blocklist where ignored. After a bit of debugging, I did see this in the log (email addresses changed):The 403 makes sense, since of course that IP is NOT in the list. After a bit of digging, I did find this line:
(https://github.com/anonaddy/docker/blob/master/rootfs/etc/cont-init.d/14-config-rspamd.sh#L246)
In my opinion, this should look like this, so it does connect via 127.0.0.1:
Especially in Docker you can't even really count on the IP always being the same, so it would make sense to just use localhost. This also makes sure, the request does not have to make the unneccessary roundtrip over an external reverse proxy with SSL handshake, etc.
Expected behaviour
The API call to the blocklist-check runs on localhost.
Actual behaviour
The API call to the blocklist-check is using the external URL (env
API_URL).Steps to reproduce
Docker info
Docker Compose config
Logs
Additional info
No response