Releases: anonaddy/anonaddy
v1.6.1
- Fixed missing
quarantinedcast to bool causing mobile app crash - anonaddy/addy-android#61 - Fixed catch-all on root domains - #862
v1.6.0
- Added inbound quarantined to failed deliveries for emails that were previously rejected as spam
- Added failed delivery notification preferences, allowing you to turn off failed delivery notifications
- Added modal confirmation for downloading a quarantined email
- Improved some failed delivery error codes to be more clear
- Added quarantine action to rules
- Recipients are no longer detached from aliases when the alias is deleted
Breaking Changes
In order to quarantine spam emails detected by Rspamd instead of rejecting them we need to make some changes to Rspamd config.
Edit /etc/rspamd/local.d/milter_headers.conf and update the add_should_quarantine_header routine (this should already be present):
add_should_quarantine_header = <<EOD
return function(task, common_meta)
local metric = task:get_metric_score('default')
local score = metric and metric[1] or 0
local reject_threshold = 15.0
local should_quarantine = false
local quarantine_reason = nil
if score >= reject_threshold then
should_quarantine = true
quarantine_reason = quarantine_reason or '5.7.1 Spam message rejected'
end
if should_quarantine then
return nil,
{
['X-AnonAddy-Should-Quarantine'] = 'Yes',
['X-AnonAddy-Quarantine-Reason'] = quarantine_reason or '5.7.1 Spam message rejected'
},
{
['X-AnonAddy-Should-Quarantine'] = 0,
['X-AnonAddy-Quarantine-Reason'] = 0
},
{}
end
return nil,
{},
{
['X-AnonAddy-Should-Quarantine'] = 0,
['X-AnonAddy-Quarantine-Reason'] = 0
},
{}
end
EOD;
}
Then edit (or create) /etc/rspamd/local.d/actions.conf and set a high score threshold for the rejection action. This is to prevent Rspamd rejecting messages outright so that we can instead quarantine them:
reject = 500; # disable hard reject in order to quarantine
Then run sudo service rspamd reload to reflect these changes.
v1.5.1
- Upgraded to Laravel 13
- Added pagination to Blocklist entries
- Added filters and sorting to blocklist
- Improved parsing of mail log, 4.X.X deferrals are no longer stored, fixed an issue with IPv6 addresses
- Upgraded Webauthn package
Full Changelog: v1.5.0...v1.5.1
v1.5.0
- Added inbound rejections to failed deliveries. This means that attempts to send emails to your aliases that were rejected by the addy.io mail servers can now be seen.
- Added pagination to failed deliveries
- Added inbound/outbound filter to failed deliveries
- Added an email notification when an alias is deactivated or deleted via one-click unsubscribe
- Performance improvements to AccessPolicy and recipient lookups
- Updated self-hosting guide with these breaking changes
Breaking Changes
In order to parse the Postfix log files and display inbound rejections for your aliases you will need to give web app system user (e.g. johndoe) permission to view the mail log:
sudo setfacl -m u:johndoe:r /var/log/mail.logRun sudo apt install acl if the above command fails.
You may also need to add the following to the postrotate hook of logrotate so that this is reapplied when you mail log is rotated:
sudo vim /etc/logrotate.d/rsyslog/var/log/mail.log
{
...
postrotate
/usr/lib/rsyslog/rsyslog-rotate
[ -f /var/log/mail.log ] && setfacl -m u:johndoe:r /var/log/mail.log
endscript
}
If your mail log is at a location other than /var/log/mail.log you can set this in your .env file:
POSTFIX_LOG_PATH=/path/to/mail.log
v1.4.1
- π Added pinned aliases feature. Pinned aliases will always appear at the top of your alias list.
- Added new
alias_countfilter to the recipients API endpoint, set it tofalseto omit alias count for a faster response.
v1.4.0
- Added new blocklist feature that allows you to block senders by their email address or entire domain
- Added List-Unsubscribe behaviour setting
- Added quick option to add sender to blocklist from failed deliveries page
Breaking Changes
- The new blocklist feature requires an update to Rspamd config in order to work.
You must create a new file named addy_blocklist.lua at /etc/rspamd/lua.local.d/addy_blocklist.lua, in this file enter the following contents (making sure to change blocklist_api_url and blocklist_secret to your own values):
--[[
Rspamd Lua script: user blocklist check via Laravel HTTP API.
Deploy this on each mail server that runs Rspamd. Point blocklist_api_url
at your Laravel app.
Required: rspamd_http (built-in). Symbol BLOCKLIST_USER is set when the
API returns block=true; map this symbol to an action (reject/discard) in
your Rspamd actions config.
--]]
local blocklist_api_url = 'https://your-addy-instance.com/api/blocklist-check'
local blocklist_secret = '' -- same as BLOCKLIST_API_SECRET in .env, or leave '' if unset
-- Simple percent-encode for query parameter values (rspamd_http has no escape)
local function url_encode(s)
if s == nil or s == '' then return '' end
s = tostring(s)
return (s:gsub('[^%w%-_.~ ]', function(c)
return string.format('%%%02X', string.byte(c))
end):gsub(' ', '%%20'))
end
local logger = require "rspamd_logger"
local rspamd_http = require 'rspamd_http'
rspamd_config:register_symbol({
name = 'BLOCKLIST_USER',
callback = function(task)
local rcpts = task:get_recipients('smtp')
local from_env = task:get_from('smtp')
if not rcpts or #rcpts == 0 then
logger.infox('blocklist: skip - missing recipient')
return false
end
local recipient = (rcpts[1].addr and rcpts[1].addr:lower()) or ''
local sender = ''
if from_env and from_env.addr then
sender = from_env.addr:lower()
end
local from_email = ''
local from_hdr = task:get_header('From')
if from_hdr then
local raw = (type(from_hdr) == 'table') and (from_hdr[1] or from_hdr) or from_hdr
raw = tostring(raw)
from_email = raw:match('<([^>]+)>') or raw:match('%S+@%S+') or ''
from_email = from_email:lower()
end
if from_email == '' then
from_email = sender
end
if recipient == '' or (sender == '' and from_email == '') then
logger.infox('blocklist: skip - missing recipient or from (recipient=%1, sender=%2, from_email=%3)', recipient, sender, from_email)
return false
end
local url = blocklist_api_url
.. '?recipient=' .. url_encode(recipient)
.. '&from_email=' .. url_encode(from_email)
local req_headers = {}
if blocklist_secret ~= '' then
req_headers['X-Blocklist-Secret'] = blocklist_secret
end
rspamd_http.request({
url = url,
headers = req_headers,
timeout = 2.0,
task = task,
callback = function(err_message, code, body, _headers)
if err_message then
logger.warnx('blocklist: HTTP error - %1', err_message)
return
end
if code == 200 and body and body:match('"block"%s*:%s*true') then
task:set_pre_result('reject', '550 5.1.1 Address not found')
task:insert_result(true, 'BLOCKLIST_USER', 1000.0, '550 5.1.1 Address not found')
logger.infox('blocklist: BLOCKLIST_USER set for recipient=%1 from_email=%2', recipient, from_email)
end
end,
})
return false -- do not match symbol here; only HTTP callback may add it via insert_result
end,
score = 1000.0,
})You also need to update your .env file with the following new values:
# Blocklist API (Rspamd): comma-separated IPs allowed to call /api/blocklist-check; optional shared secret
BLOCKLIST_API_ALLOWED_IPS=127.0.0.1
BLOCKLIST_API_SECRET=
Make sure to add your own server's IP to the list above. If you have chosen to set a shared secret then make sure BLOCKLIST_API_SECRET is the same value as whatever you've chosen above in addy_blocklist.lua.
- Upgrade to Vite 8 may require you to update your node version to
20.19+.
v1.3.8
v1.3.7
- Merged Proxy authentication support (eq. oauth2-proxy) by @nielscil
- Added option to disable removal of PGP keys/signatures in replies/sends, these options can be found by clicking "Edit" on any individual Recipient.
v1.3.6
- Added dark mode
- Added Rules that allow you to forward to multiple recipients
- Added ability to use both 2FA methods at the same time
- Increased Rule condition values from 10 to 50
- Fixed credentialId length issue in webauthn_keys table
v1.3.5
- Fixed missing fillable property in
v1.3.4