COURIERPERLFILTER(8)
π COURIERPERLFILTER(8) β the courierperlfilter page, bestie edition π
okay so this is courierperlfilter from S. Varshavchik, and it's literally the glow-up guide for a Sample Perl-based mail filter. sit down, grab a snack, we're doing systems programming π
β¨ SYNOPSIS β¨
filterctl [[start] | [stop]] [perlfilter]
πΈ DESCRIPTION πΈ
So this is an example global mail filter that runs an embedded Perl script. And bestie, "embedded" here does not mean cute little Pinterest-embedded, it means the Perl interpreter gets loaded once, and then that same Perl code keeps getting called over and over to accept or reject incoming messages, one by one, slay.
ngl, Perl filtering is relatively time consuming (think: compared to filtering in C or C++, no cap), and excessive delays in mail filters result in incoming mail being deferred β which is when it gets rejected with a temporary error code π. So to fix that, the perlfilter wrapper can spin up multiple perlfilter processes, so that multiple processes are out here filtering incoming mail at the same time. teamwork makes the dream work fr fr π«Ά
perlfilter requires Perl 5.10 or higher. The best way to create a Perl filter is to start with the sample filter, /usr/lib/courier/perlfilter-example.pl. That filter rejects messages that contain an excessively long Date: header (it's designed to crash certain poorly-written mail clients, iconic honestly π). Use it as your basis for writing your own filter. You can install your filter in any convenient location, then initialize the /etc/courier/filters/perlfilter configuration file, as described below. Run filterctl start perlfilter to activate filtering β and if necessary, run courierfilter start to start the mail filtering subsystem. go off π
π Setting up a Perl script π
Most of the ugly details of connecting the Perl script to Courier's mail filtering engine is taken care of by the sample perlfilter-example.pl script. But there's one big no-no: the script MAY NOT change the current directory. that's the line. do not cross it π« Anything else goes, for the most part. Loading other modules and classes, pretty much anything else you can do with Perl, is allowed. the freedom, the range π
The Perl script, just like any other mail filtering module, receives a pointer to a data file and one or more control files, each time a message is submitted to Courier for delivery. The sample script calls the filterdata() function to process the data file. The data file contains the actual message. The filtercontrol() function is called to process each control file. The control file contains recipient and message metadata. And heads up β there may be more than one control file for each message. The example script includes an implementation of filterdata() that blocks messages with corrupted headers. The example script doesn't do anything interesting with filtercontrol(). it's giving minimal effort and honestly, same π
filterdata() and filtercontrol() must return an empty string if no serious objections are raised for this message. Any other return string is interpreted as an SMTP-style error code that is used to reject the message. Care must be taken that any error messages are formatted strictly according to the format of SMTP error messages (even though the message may not actually come in via SMTP). yes this is the part where formatting matters, sorry bestie, rules are rules β
π CREDITS π
A lot of the Perl glue code is based on examples from the perlembed manual page, and other sources. credit where credit is due π«‘
π FILES π
perlfilter uses the following configuration files. Changes to the following files do not take effect until the filter has been stopped and restarted. no hot reloading here, bestie, we restart π
/etc/courier/filters/perlfilter-modeβ If this file exists and contains the word"all",perlfilterwill create its socket in/var/lib/courier/allfilters, otherwise the socket will be created in/var/lib/courier/filters, seecourierfilter(8)[1]for more information./etc/courier/filters/perlfilter-numprocsβ This file contains a number that sets how manyperlfilterprocesses are created. The default is 5 processes. There's always an extraperlfilterprocess that's used to clean up crashed child processes. that one's just doing damage control, respect π«Ά/etc/courier/filters/perlfilterβ This file MUST exist and it must contain a single line of text with the filename of the Perl script to load. no file, no filter, periodt./usr/lib/courier/perlfilter-example.plβ This is a sample Perl script of the kind that/etc/courier/filters/perlfilterpoints to. Use it as an example of writing your own Perl filters./usr/lib/courier/perlfilter-ratelimit.plβ This is a complete Perl-based filter that implements basic rate-limiting features. she's fully functional, she's booked and busy β¨
Please exercise good judgment in writing Perl-based filters. They should be reasonably fast, and do not allocate megabytes of memory. They should not be very promiscuous in creating global Perl variables, and should clean up after themselves. The current Perl wrapper does not destroy the Perl symbol table after each call to the filter script. However, do not take that for granted. This may change in the future.
β οΈ okay so lowkey important: that last bit about the symbol table not being destroyed? don't build your whole personality around it, because it may change in the future. the future is unpredictable bestie π
π SEE ALSO π
courierfilter(8)[1].
π AUTHOR π
Sam Varshavchik Author
π NOTES π
and that's the whole page, bestie!! you understood it, you ate, no crumbs left π this icon was brought to you by Courier Mail Server, dated 01/10/2026, and yes the manual name is COURIERPERLFILTER(8) β now go configure your filter and be the main character of your own mail server ππ¦π
π¦ where this page comes from
- ubuntu stonking: courier-mta 2.0.6-1 Β· GPL-3+~with-OpenSSL-exception
- Copyright 1998 - 2007 S. Varshavchik. See COPYING for -->
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms