======Configure SRS======
In VPOP3 8.8 and later, you can use Lua scripting to implement 'SRS' (Sender Rewriting Scheme') in VPOP3
This involves adding a couple of functions to rewrite outgoing return paths in 'relayout.lua' or 'mxout.lua' as appropriate and a couple of functions to redirect rewritten bounce message recipients in 'smtpsvr.lua'
In earlier versions of VPOP3 (or if you don't want the bounce-redirection function of SRS), you can use basic Sender Rewriting using the 'Return path Settings' tab of the Mail Sender in the VPOP3 settings. Set 'SMTP Return Path:' to 'If the original address is not local, set to', and enter a local email address which won't have forwarding or autoresponders set - eg postmaster@yourdomain.com
The below is a basic implementation based on https://www.libsrs2.net/srs/srs.pdf
====relayout.lua or mxout.lua====
Use relayout.lua if VPOP3 is sending through a smart host, or mxout.lua if VPOP3 is sending using SMTP Direct
Edit 'mydomain' to be your domain, and 'mykey' to be a secret code for security hashing
mydomain = "example.com";
mykey = "bobble";
function ModifyReturnPath(mailfrom, origmailfrom)
local srch = "@" .. string.gsub(mydomain, "%.", "%%.") .. "$";
if not string.find(origmailfrom, srch) then
local lastAt = origmailfrom:find("[^%@]+$")
local localPart = origmailfrom:sub(1, (lastAt - 2)) -- Returns the substring before '@' symbol
local domainPart = origmailfrom:sub(lastAt, #origmailfrom)
local timestamp = math.floor((os.time()/ (60 * 60 * 24)) % 1024);
local timestampMod32 = Mod32(math.floor(timestamp / 32)) .. Mod32(timestamp % 32);
local hash = VPOP3.Base64(VPOP3.SHA1(origmailfrom .. timestampMod32 .. mykey)):sub(1,4);
return "SRS0=" .. hash .. "=" .. timestampMod32 .. "=" .. domainPart .. "=" .. localPart .. "@" .. mydomain;
end
print("nosub " .. origmailfrom);
end
function Mod32(x)
return string.sub("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", x + 1, x + 1);
end
====smtpsvr.lua====
Edit 'mydomain' to be your domain, and 'mykey' to be a secret code for security hashing. These should be the same values as in the other script
mydomain = "example.com";
mykey = "bobble";
function MapRecipient(rcpt, rcptlist, mailfrom)
if mailfrom == "" then
local srch = "^SRS[01]=([^=]+)=([^=]+)=([^=]+)=(.-)@" .. string.gsub(mydomain, "%.", "%%.") .. "$";
local hash, ts, domainPart, localPart;
_, _, hash, ts, domainPart, localPart = rcpt:find(srch);
if hash then
local calcHash = VPOP3.Base64(VPOP3.SHA1(localPart .. "@" .. domainPart .. ts .. mykey)):sub(1,4);
if calcHash == hash then
local rcptTimestamp = UnMod32(ts:sub(1,1)) * 32 + UnMod32(ts:sub(2,2));
local timestamp = math.floor((os.time()/ (60 * 60 * 24)) % 1024);
if timestamp < rcptTimestamp then
timestamp = timestamp + 1024;
end
if timestamp - rcptTimestamp > 5 then
return rcpt, "500 SRS Timestamp expired";
end
return localPart .. "@" .. domainPart;
else
return rcpt, "500 SRS Hash invalid";
end
end
end
end
function UnMod32(x)
return string.find("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", x) - 1;
end