Table of Contents

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

relayout.lua
  1. mydomain = "example.com";
  2. mykey = "bobble";
  3.  
  4. function ModifyReturnPath(mailfrom, origmailfrom)
  5.  
  6. local srch = "@" .. string.gsub(mydomain, "%.", "%%.") .. "$";
  7.  
  8. if not string.find(origmailfrom, srch) then
  9. local lastAt = origmailfrom:find("[^%@]+$")
  10. local localPart = origmailfrom:sub(1, (lastAt - 2)) -- Returns the substring before '@' symbol
  11. local domainPart = origmailfrom:sub(lastAt, #origmailfrom)
  12.  
  13. local timestamp = math.floor((os.time()/ (60 * 60 * 24)) % 1024);
  14. local timestampMod32 = Mod32(math.floor(timestamp / 32)) .. Mod32(timestamp % 32);
  15.  
  16. local hash = VPOP3.Base64(VPOP3.SHA1(origmailfrom .. timestampMod32 .. mykey)):sub(1,4);
  17.  
  18. return "SRS0=" .. hash .. "=" .. timestampMod32 .. "=" .. domainPart .. "=" .. localPart .. "@" .. mydomain;
  19. end
  20. print("nosub " .. origmailfrom);
  21. end
  22.  
  23. function Mod32(x)
  24. return string.sub("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", x + 1, x + 1);
  25. 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

smtpsvr.lua
  1. mydomain = "example.com";
  2. mykey = "bobble";
  3.  
  4. function MapRecipient(rcpt, rcptlist, mailfrom)
  5. if mailfrom == "" then
  6. local srch = "^SRS[01]=([^=]+)=([^=]+)=([^=]+)=(.-)@" .. string.gsub(mydomain, "%.", "%%.") .. "$";
  7. local hash, ts, domainPart, localPart;
  8.  
  9. _, _, hash, ts, domainPart, localPart = rcpt:find(srch);
  10.  
  11. if hash then
  12. local calcHash = VPOP3.Base64(VPOP3.SHA1(localPart .. "@" .. domainPart .. ts .. mykey)):sub(1,4);
  13. if calcHash == hash then
  14.  
  15. local rcptTimestamp = UnMod32(ts:sub(1,1)) * 32 + UnMod32(ts:sub(2,2));
  16. local timestamp = math.floor((os.time()/ (60 * 60 * 24)) % 1024);
  17.  
  18. if timestamp < rcptTimestamp then
  19. timestamp = timestamp + 1024;
  20. end
  21.  
  22. if timestamp - rcptTimestamp > 5 then
  23. return rcpt, "500 SRS Timestamp expired";
  24. end
  25.  
  26. return localPart .. "@" .. domainPart;
  27.  
  28. else
  29. return rcpt, "500 SRS Hash invalid";
  30. end
  31. end
  32.  
  33. end
  34. end
  35.  
  36. function UnMod32(x)
  37. return string.find("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", x) - 1;
  38. end