Releases: onlime/policyd-rate-guard
Releases · onlime/policyd-rate-guard
v0.7.3
Improved:
- Improved PEP8 Python code style: Added configuration for YAPF and applied yapf formatting rules.
- Upgraded packages: DBUtils 3.1.0, cryptography 42.0.7, PyMySQL 1.1.1, python-dotenv 1.0.1, requests 2.32.2, sentry-sdk 2.2.1
Security:
- It is strongly recommended to upgrade all pip packages, as PyMySQL 1.1.1 fixes a SQL Injection vulnerability (CVE-2024-36039).
v0.7.2
Improved:
- Webhook authentication token type (Simple hashed token vs. JWT token) can now be configured with new env var
WEBHOOK_USE_JWTand no longer depends on whether you pass the token as query param (not recommended for JWT tokens) orAuthorization: Bearerheader. - Webhook JWT token now contains all necessary claims for strict verification:
sub(Subject),iss(Issuer),iat(Issued At),nbf(Not Before),exp(Expiration Time).
Fixed:
- Webhook JWT token is now correctly encoded using base64 decoded secret (
WEBHOOK_SECRET) as key. Previously, we forgot to decode it, but always recommended (and still do!) to use a base64 encoded secret.
v0.7.1
v0.7.0
Improved:
- Updated docker-compose
policydservice Docker image frompython:3.8topython:3.11 - Improved Python code style by fixing all Flake8 linting warnings.
Added:
- Added configurable webhook API call to trigger sender notification when reaching his quota limit (on first block). For authentication, it supports both simple token (passed as query param) and JWT token (passed as
Authorization: Bearerheader). - Added new environment variables for external webhook API:
WEBHOOK_ENABLED,WEBHOOK_URL,WEBHOOK_SECRET
Fixed:
- Prevent multiple logger instances by accessing a static
loggervariable. This fixesResourceWarning: unclosed fileexceptions which could have occurred in testing.
v0.6.1
Improved:
- Code cleanup: Using relative imports.
- Code cleanup: Simplified parsing of data using dict comprehension in
Handler. - Refactoring: moved
PrefixedLoggerclass into its own file.
Added:
- Database cleanup job now also purges old messages, if enabled through
MESSAGE_RETENTIONenv var. - Introduced new environment variable
MESSAGE_RETENTIONto control number of days to keep messages in the database. Defaults to0(keep forever).
v0.6.0
Improved:
- Improved performance and stability by introducing database connection pooling, using DBUtils PooledDB (pooled_db)
- Moved logger and db cleanup code into destructor of
Handler. - Refactored
database.dbtoapp.dbto simplify project structure.
Added:
- Added environment variables
DB_POOL_MINCACHED,DB_POOL_MAXCACHED,DB_POOL_MAXSHARED,DB_POOL_MAXUSAGEfor db connection pooling fine-tuning.
Fixed:
- Fix
Lost connection to MySQL server during queryand ``AttributeError: 'NoneType' object has no attribute 'read'` (on db cursor) connectivity issues by introducing connection pooling.
v0.5.1
Added:
- Added
LOG_MSG_PREFIX(boolean) environment variable which is enabled by default. Prefix all log messages with a prefix containing information about the calling filename, class, and function name, e.g.ratelimit.py Ratelimit.update() -. - Always prepend log messages with message ID (Postfix
queue_id) if available, independent fromLOG_MSG_PREFIXfeature being enabled/disabled.
Fixed:
- Fix
AttributeError: 'NoneType' object has no attribute 'read' in Ratelimit.find()edge case wheresasl_usernamewas set in Postfix DATA but empty. We now bail out early ifsasl_usernameeither does not exist or is empty.
v0.5.0
- Initial release
Features:
- Super easy Postfix integration using
check_policy_serviceinsmtpd_data_restrictions - Set individual sender (SASL username) quotas
- Limit senders to number of recipients per time period
- Automatically fills
ratelimitstable with new senders (SASL username) upon first email sent - Set your own time period (usually 24hrs) by resetting the counters via Systemd cleanup timer (or cronjob)
- Continues to raise counters (
msg_counter,rcpt_counter) even in over quota state, so you know if a sender keeps retrying/spamming. - Keeps totals of all messages/recipients sent for each sender (SASL username)
- Stores both message and recipient counters in database (
ratelimitstable) - Stores detailed information for all sent messages (
msgid, sender, rcpt_count, blocked, from_addr, client ip, client hostname) in database (messagestable) - Logs detailed message information to Syslog (using
LOG_MAILfacility, so the logs end up inmail.log) - Maximum failure safety: On any unexpected exception, the daemon still replies with a
DUNNOaction, so that the mail is not getting rejected by Postfix. This is done both on Postfix integration side and application exception handling side. - Block action message
"Rate limit reached, retry later."can be configured. - Lots of configuration params via a simple
.env - Tuned for high performance, using network or unix sockets, and threading.
- Secure setup, nothing running under
root, only onpostfixuser. - A super slick minimal codebase with only a few dependencies (PyMySQL, python-dotenv, yoyo-migrations), using Python virtual environment for easy
pipinstall. PyMySQL is a pure-Python MySQL client library, so you won't have any trouble on any future major system upgrades. - Provides an Ansible Galaxy role
onlime.policyd_rate_guardfor easy installation on a Debian mailserver. - A well maintained project, as it is in active use at Onlime GmbH, a Swiss webhoster with a rock-solid mailserver architecture.