policyd-weight.conf(5)
πΈ policyd-weight.conf(5) πΈ
okay bestie, so this whole thing lives in the File Formats Manual section, and it's literally the manual page for policyd-weight.conf β aka the config file that runs your whole policyd-weight setup. sit down, grab a strawberry π, we're going through every single setting, no skips, no skimming, fr fr.
β¨ NAME β¨
policyd-weight.conf β the configuration parameters for policyd-weight. that's it, that's the name, iconic π
π¦ STATUS π¦
Beta, and the documentation is incomplete. yeah. we know. it's giving "work in progress but make it fashion" π
π DESCRIPTION π
policyd-weight reads a perl(1)-style configuration file, and it does that on startup, like clockwork.
and here's the cute part: the cache re-reads the config after $MAINTENANCE_LEVEL (default: 5) queries. so it keeps itself fresh. β¨
now, if you don't pass -f, it goes hunting for config files in these spots, in this order:
/etc/policyd-weight.conf
/usr/local/etc/policyd-weight.conf
./policyd-weight.conf
π CACHE SETTINGS π
$CACHESIZE(default:2000) β sets the minimum size of the SPAM cache.$CACHEMAXSIZE(default:4000) β sets the maximum size of the SPAM cache.$CACHEREJECTMSG(default:550 temporarily blocked because of previous errors)) β this is the SMTP status code plus an explanatory message you send when you reject mail because of cached results.$NTTL(default:1) β the client gets penalized for that many retries.$NTIME(default:30) β the$NTTLcounter only decrements if the client waits at least$NTIMEseconds. patience is a virtue bestie π§$POSCACHESIZE(default:1000) β sets the minimum size of the HAM cache.$POSCACHEMAXSIZE(default:2000) β sets the maximum size of the HAM cache.$PTTL(default:60) β after that many queries, the HAM entry has to succeed one full run through the RBL checks again.$PTIME(default:3h) β after$PTIMEin the HAM cache, the client has to pass the RBL checks one time again. values must be non-fractal. accepted time-units are:s(econds),m(inutes),h(ours),d(ays).$TEMP_PTIME(default:1d) β the client has to pass the RBL checks for this long to be listed as hard-HAM. after this time, the client passes immediately forPTTLwithinPTIME. values must be non-fractal. accepted time-units:s(econds),m(inutes),h(ours),d(ays).
π₯ DEBUG SETTINGS π₯
$DEBUG(default:0) β turns debugging on (1) or off (0). simple as.
π DNS SETTINGS π
$DNS_RETRIES(default:2) β how many times a single DNS query may be repeated.$DNS_RETRY_IVAL(default:2) β retry a query that got no response after that many seconds.$MAXDNSERR(default:3) β if that many queries fail, the mail gets accepted with$MAXDNSERRMSG. in total DNS queries, that means:$MAXDNSERR * $DNS_RETRIES.$IGNORE_RFC1918_A(default:0) β if enabled (1), A records with RFC1918 addresses are not treated as bogus addresses by policyd-weight, which meansbogus_mx_scoreisn't added. lowkey handy if you're doing internal stuff π
π MISC SETTINGS π
$MAINTENANCE_LEVEL(default:5) β after that many policy requests, the cache (and, in daemon mode, the child processes) checks for configuration file changes.$MAXIDLECACHE(default:60) β after that many seconds of being idle, the cache checks for configuration file changes. self-care check-in β¨$PIDFILE(default:/var/run/policyd-weight.pid) β path and filename where the master pid gets stored (daemon mode).$LOCKPATH(default:/tmp/.policyd-weight/) β directory where policyd-weight stores sockets and lock-files/directories. its argument must contain a trailing slash.$SPATH(default:$LOCKPATH.'/polw.sock') β path and filename that the cache has to use for communication.$TCP_PORT(default:12525) β TCP port the policy server listens on (daemon mode).$BIND_ADDRESS(default:'127.0.0.1') β IP address policyd-weight binds to. currently either only one or all IPs are supported. specify'all'if you want to listen on every IP.$SOMAXCONN(default:1024) β maximum connections policyd-weight accepts. this is set high enough to cover most scenarios.$USER(default:polw) β sets the user under which policyd-weight runs.$GROUP(default:$USER) β sets the group under which policyd-weight runs.
π OUTPUT AND LOG SETTINGS π
$ADD_X_HEADER(default:1) β inserts anX-policyd-weight:header with evaluation messages.1= on,0= off.$LOG_BAD_RBL_ONLY(default:1) β only inserts RBL results into logging strings if the RBL score actually changes the overall score. so RBLs with a GOOD SCORE of0don't show up in logging strings if that RBL returned no BAD hit.1= on,0= off.$MAXDNSBLMSG(default:550 Your MTA is listed in too many DNSBLs) β the message sent to the client if it was rejected because of$MAXDNSBLHITSand/or$MAXDNSBLSCORE.$REJECTMSG(default:550 Mail appeared to be SPAM or forged. Ask your Mail/DNS-Adminisrator to correct HELO and DNS MX settings or to get removed from DNSBLs) β sets the SMTP status code for rejected mails, plus a message explaining why the action was taken.
π§ RESOURCE AND OPTIMIZATIONS π§
$CHILDIDLE(default:120) β how many seconds a child may be idle before it dies (daemon mode).$MAX_PROC(default:50) β process limit on how many processes policyd-weight will spawn (daemon mode).$MIN_PROC(default:2) β minimum child processes kept alive during idle times (daemon mode).$PUDP(default:0) β sets persistent UDP connections used for DNS queries on (1) or off (0).
π SCORE SETTINGS π
just so we're clear on the vibes: positive values = a bad (SPAM) score, negative values = a good (HAM) score. got it? good. π
@bogus_mx_score(2.1,0) β if the sender domain has neither MX nor A records, or those records resolve to a bogus IP-address (private networks, for instance), then this check assigns the full score ofbogus_mx_score. if there's no MX but there is an A record for the sender domain, then it only receives a penalty if it's DNSBL-listed.
Log Entries:
BOGUS_MXβ the sender A and MX records are bogus or empty.BAD_MXβ the sender domain has an empty or bogus MX record and the client is DNSBL listed.
Related RFCs:
[1918]Address Allocation for Private Internets[2821]Simple Mail Transfer Protocol (Sect 3.6 and Sect 5)
@client_ip_eq_helo_score(1.5,-1.25) β defines the scores for a match of the reverse record (hostname) against the HELO argument. reverse lookups are done if the forward lookups failed, and they are not trusted.
Log Entries:
REV_IP_EQ_HELOβ the Client's PTR matched the HELO argument.REV_IP_EQ_HELO_DOMAINβ domain portions of Client PTR and HELO argument matched.RESOLVED_IP_IS_NOT_HELOβ Client PTRs found but did not match the HELO argument.
@helo_score(1.5,-2) β defines scores for a match of the Client IP and its/24subnet against the A records of the HELO or MAIL FROM domain/host. it also holds the bad score for MX verifications.
Log Entries:
CL_IP_EQ_HELO_NUMERICβ Client IP matches the[IPv4]HELO.CL_IP_EQ_FROM_IPβ Client IP matches the A record of the MAIL FROM sender domain/host.CL_IP_EQ_HELO_IPβ Client IP matches the A record of the HELO argument.CL_IP_NE_HELOβ the IP and the/24subnet did not match A/MX records of HELO and MAIL FROM arguments and their subdomains.
@helo_from_mx_eq_ip_score(1.5,-3.1) β defines scores for a match of Client IP against MX records. positive (SPAM) values are used when the MAIL FROM doesn't match the HELO argument AND the client seems to be dynamic AND the client is no MX for the HELO and MAIL FROM arguments. the total DNSBL score gets added to its bad score.
Log Entries:
CL_IP_EQ_FROM_MXβ Client IP matches the MAIL FROM domain/host MX record.CL_IP_EQ_HELO_MXβ Client IP matches the HELO domain/host MX record.CLIENT_NOT_MX/A_FROM_DOMAINβ Client is not a verified HELO and doesn't match A/MX records of the MAIL FROM argument.CLIENT/24_NOT_MX/A_FROM_DOMAINβ Client's subnet does not match A/MX records of the MAIL FROM argument.
$dnsbl_checks_only(default:0) β disables HELO/RHSBL verifications and the like. does only RBL checks.1= on,0= off.@dnsbl_score(default: see below) β a list of RBLs to be checked. if you want a host to not be evaluated any further when it's listed on several lists, or on a very trustworthy list, you can trigger an immediate REJECT with$MAXDNSBLHITSand/or$MAXDNSBLSCORE. a list of RBLs must be built like this:
@dnsbl_score = (
RBLHOST1, HIT SCORE, MISS SCORE, LOG NAME,
RBLHOST2, HIT SCORE, MISS SCORE, LOG NAME,
...
);
the default is:
@dnsbl_score = (
"pbl.spamhaus.org", 3.25, 0, "DYN_PBL_SPAMHAUS",
"sbl-xbl.spamhaus.org", 4.35, -1.5, "SBL_XBL_SPAMHAUS",
"bl.spamcop.net", 3.75, -1.5, "SPAMCOP",
"ix.dnsbl.manitu.net", 4.35, 0, "IX_MANITU"
);
@rhsbl_score(default: see below) β defines a list of RHSBL hosts which get queried for the sender domain. results additionally get scores of0.5 * DNSBL resultsand@rhsbl_penalty_score. a list of RHSBL hosts to be queried must be built like this:
@rhsbl_score = (
RHSBLHOST1, HIT SCORE, MISS SCORE, LOG NAME,
RHSBLHOST2, HIT SCORE, MISS SCORE, LOG NAME,
...
);
the default is:
@rhsbl_score = (
"multi.surbl.org", 4, 0, "SURBL"
);
@rhsbl_penalty_score(3.1,0) β this score gets added to each RHSBL hit if the following criteria are met:- Sender has a random local-part (i.e.
yztrzgb@example.tld) - or MX records of sender domain are bogus
- or FROM matches not HELO
- or HELO is untrusted (Forward record matched, reverse record did not match)
- Sender has a random local-part (i.e.
$MAXDNSBLHITS(default:2) β if the client is listed in more than$MAXDNSBLHITSRBLs, it gets rejected immediately with$MAXDNSBLMSGand with no further evaluation. results are cached by default.$MAXDNSBLSCORE(default:8) β if the BAD SCOREs of the@dnsbl_score-listed RBLs reach a level greater than$MAXDNSBLSCORE, the client gets rejected immediately with$MAXDNSBLMSGand with no further evaluation. results are cached by default.$REJECTLEVEL(default:1) β score results equal to or greater than this level get rejected with$REJECTMSG.
okay and that's where part 1 wraps, bestie β there's more coming, don't go anywhere π«Ά
β¨ SEE ALSO β¨
okay so if you wanna go deeper (and bestie, you should), go read these:
policyd-weight(8)β the Policyd-weight daemon itself, the main character πperl(1)β Practical Extraction and Report Language, aka the language this whole thing is living in πperlsyn(1)β Perl syntax, for when you're like "wait what does that line even mean" π¦access(5)β the Postfix SMTP access control table
π LICENSE π
GNU General Public License. that's it, that's the vibe, go forth and be free π«Ά
π AUTHOR π
Robert Felber <r.felber@ek-muc.de> Autohaus Erich Kuttendreier 81827 Munich, Germany
and that's the whole page, bestie!! this version is from Aug 25th, 2006 and it's the manual for policyd-weight.conf(5) β iconic, timeless, literally a piece of history π
β¨ go configure something slay, ily, bye ππ¦π
π¦ where this page comes from
- debian bookworm: policyd-weight 0.1.15.2-12.1 Β· GPL-2.0-or-later
- debian trixie: policyd-weight 0.1.15.2-13 Β· GPL-2.0-or-later
- ubuntu jammy: policyd-weight 0.1.15.2-12 Β· GPL-2.0-or-later
- ubuntu noble: policyd-weight 0.1.15.2-12.1 Β· GPL-2.0-or-later
- ubuntu questing: policyd-weight 0.1.15.2-13
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms