BOGOFILTER(1)
๐ BOGOFILTER(1) โ Bogofilter Reference Manual ๐
okay bestie, sit down, we're learning about bogofilter ๐ this is the manual page for it, and it's a lot, so hydrate first. it's the Bogofilter Reference Manual, section 1 of the manual, and it is genuinely so good. no cap.
โจ NAME โจ
bogofilter โ fast Bayesian spam filter ๐ฆ
๐ธ SYNOPSIS ๐ธ
bogofilter [help options | classification options | registration options
| parameter options | info options] [general options]
[config file options]
where
help options are:
[-h] [--help] [-V] [-Q]
classification options are:
[-p] [-e] [-t] [-T] [-u] [-H] [-M] [-b] [-B object ...] [-R]
[general options] [parameter options] [config file options]
registration options are:
[-s | -n] [-S | -N] [general options]
general options are:
[-c filename] [-C] [-d dir] [-k cachesize] [-l] [-L tag] [-I filename]
[-O filename]
parameter options are:
[-E value[,value]] [-m value[,value][,value]] [-o value[,value]]
info options are:
[-v] [-y date] [-D] [-x flags]
config file options are:
[--option=value]
Note: Use bogofilter --help to display the complete list of options. like, actually do it, it's free ๐
๐ DESCRIPTION ๐
Bogofilter is a Bayesian spam filter, periodt. In its normal mode of operation, it takes an email message or other text on standard input, does a statistical check against lists of "good" and "bad" words, and returns a status code indicating whether or not the message is spam. ๐ต๏ธโ๏ธ
Bogofilter is designed with a fast algorithm, uses the Berkeley DB for fast startup and lookups, coded directly in C, and tuned for speed, so it can be used for production by sites that process a lot of mail. she's fast, she's C, she's built different ๐ฅ
๐ง THEORY OF OPERATION ๐ง
Bogofilter treats its input as a bag of tokens. Each token is checked against a wordlist, which maintains counts of the numbers of times it has occurred in non-spam and spam mails. These numbers are used to compute an estimate of the probability that a message in which the token occurs is spam. Those are combined to indicate whether the message is spam or ham. ๐
While this method sounds crude compared to the more usual pattern-matching approach, it turns out to be extremely effective. Paul Graham's paper A Plan For Spam<sup>[1]</sup> is recommended reading. ๐
This program substantially improves on Paul's proposal by doing smarter lexical analysis. Bogofilter does proper MIME decoding and a reasonable HTML parsing. Special kinds of tokens like hostnames and IP addresses are retained as recognition features rather than broken up. Various kinds of MTA cruft such as dates and message-IDs are ignored so as not to bloat the wordlist. Tokens found in various header fields are marked appropriately. ๐
Another improvement is that this program offers Gary Robinson's suggested modifications to the calculations (see the parameters robx and robs below). These modifications are described in Robinson's paper Spam Detection<sup>[2]</sup>.
Since then, Robinson (see his Linux Journal article A Statistical Approach to the Spam Problem<sup>[3]</sup>) and others have realized that the calculation can be further optimized using Fisher's method. Another improvement<sup>[4]</sup> compensates for token redundancy by applying separate effective size factors (ESF) to spam and nonspam probability calculations. โจ
In short, this is how it works: The estimates for the spam probabilities of the individual tokens are combined using the "inverse chi-square function". Its value indicates how badly the null hypothesis that the message is just a random collection of independent words with probabilities given by our previous estimates fails. This function is very sensitive to small probabilities (hammish words), but not to high probabilities (spammish words); so the value only indicates strong hammish signs in a message. Now using inverse probabilities for the tokens, the same computation is done again, giving an indicator that a message looks strongly spammish. Finally, those two indicators are subtracted (and scaled into a 0-1-interval). This combined indicator (bogosity) is close to 0 if the signs for a hammish message are stronger than for a spammish message and close to 1 if the situation is the other way round. If signs for both are equally strong, the value will be near 0.5. Since those message don't give a clear indication there is a tristate mode in bogofilter to mark those messages as unsure, while the clear messages are marked as spam or ham, respectively. In two-state mode, every message is marked as either spam or ham. ๐ญ the drama of it all
Various parameters influence these calculations, the most important are:
robx: the score given to a token which has not seen before.robxis the probability that the token is spammish.robs: a weight onrobxwhich moves the probability of a little seen token towardsrobx.min-dev: a minimum distance from.5for tokens to use in the calculation. Only tokens farther away from0.5than this value are used.spam-cutoff: messages with scores greater than or equal to will be marked as spam.ham-cutoff: If zero orspam-cutoff, all messages with values strictly belowspam-cutoffare marked as ham, all others as spam (two-state). Else values less than or equal toham-cutoffare marked as ham, messages with values strictly betweenham-cutoffandspam-cutoffare marked as unsure; the rest as spam (tristate)sp-esf: the effective size factor (ESF) for spam.ns-esf: the ESF for nonspam. These ESF values default to1.0, which is the same as not using ESF in the calculation. Values suitable to a user's email population can be determined with the aid of thebogotuneprogram. ๐ง
โจ OPTIONS โจ
okay bestie this is the big one, grab a snack ๐
๐ HELP OPTIONS
-hโ prints the help message and dips. that's it, that's the whole job.-Vโ prints the version number and dips.-Qโ the query option, and it's giving main character energy fr: it prints bogofilter's whole configuration out loud, like registration parameters, parsing options, the bogofilter directory, all of it. a full selfie of its own settings ๐
๐ CLASSIFICATION OPTIONS
-pโ the passthrough option, and it outputs your message with anX-Bogosityline tacked onto the end of the message header. the catch? this requires keeping the ENTIRE message in memory when it's read fromstdin(or from a pipe or socket), so keep that in mind. if the message is read from a file that can be rewound, bogofilter will just read it a second time. no biggie ๐ฆ-eโ the embed option. tells bogofilter to exit with code0if the message can be classified, i.e. if there is not an error. normally bogofilter uses different codes for spam, ham, and unsure classifications, but this simplifies using bogofilter withprocmailormaildrop. it's giving "just make it work with my mail setup" ๐-tโ the terse option. bogofilter prints an abbreviated spamicity message containing 1 letter and the score. spam is indicated with"Y", ham by"N", and unsure by"U". note: the formatting can be customized using the config file. cute and compact ๐-Tโ an invariant terse mode for scripts to use, so it won't change on you. bogofilter will print an abbreviated spamicity message containing 1 letter and the score. spam is indicated with"S", ham by"H", and unsure by"U". script-safe bestie ๐ค-TTโ also an invariant terse mode for scripts. bogofilter prints only the score, and displays it to 16 significant digits. just the number, no letter, no fluff, no small talk. that's the whole vibe ๐ฅ-uโ tells bogofilter to register the message's text after classifying it as spam or non-spam. a spam message gets registered on the spamlist and a non-spam message goes on the goodlist. if the classification is"unsure", the message will not be registered. effectively this option runs bogofilter with the-sor-nflag, as appropriate.
caution is urged in the use of this capability, bestie, fr fr ๐ญ any classification errors bogofilter may make will be preserved and will accumulate until manually corrected with the-Snand-Nsoption combinations. also note this option causes the database to be opened for write access, which can entail massive slowdowns through lock contention and synchronous I/O operations. like, it's not a vibe, it's a bottleneck.
-Hโ tells bogofilter to not tag tokens from the header. this option is for testing, and you should not use it in normal operation. it's giving lab experiment ๐งช don't ship it.-Mโ tells bogofilter to process its input as anmboxformatted file. if the-vor-toption is also given, a spamicity line will be printed for each message. one line per message, periodt.-bโ the streaming bulk mode option. tells bogofilter to classify multiple objects whose names are read fromstdin. if the-vor-toption is also given, bogofilter will print a line giving file name and classification information for each file. this is an alternative to-B, which lists objects on the command line. pick your fave, both slay ๐
An object in this context shall be a maildir (autodetected), or if it's not a maildir, a single mail unless -M is given โ in that case it's processed as mbox. (the Content-Length: header is not taken into account currently, just so you know ๐)
When reading mbox format, bogofilter relies on the empty line after a mail. if needed, formail -es will ensure this is the case. lowkey crucial detail ๐
-Bobject ... โ the bulk mode option. tells bogofilter to classify multiple objects named on the command line. the objects may be filenames (for single messages), mailboxes (files with multiple messages), or directories (ofmaildirandMHformat). if the-vor-toption is also given, bogofilter will print a line giving file name and classification information for each file. this is an alternative to-b, which lists objects onstdin. same energy, different door ๐ชโจ-Rโ tells bogofilter to output anRdata frame in text form on the standard output. see the section on integration withR, below, for further detail. stats girlies rise up ๐
๐ฆ REGISTRATION OPTIONS
-sโ tells bogofilter to register the text presented as spam. the database is created if absent. no database? we build one, we're resourceful ๐-nโ tells bogofilter to register the text presented as non-spam.- bogofilter doesn't detect if a message registered twice. if you do this by accident, the token counts will off by 1 from what you really want and the corresponding spam scores will be slightly off. given a large number of tokens and messages in the wordlist, this doesn't matter. the problem can be corrected by using the
-Soption or the-Noption. so like, not a crisis, just messy ๐ -Sโ tells bogofilter to undo a prior registration of the same message as spam. if a message was incorrectly entered as spam by-sor-uand you want to remove it and enter it as non-spam, use-Sn. if-Sis used for a message that wasn't registered as spam, the counts will still be decremented. it does not check your receipts, it just decrements ๐ญ-Nโ tells bogofilter to undo a prior registration of the same message as non-spam. if a message was incorrectly entered as non-spam by-nor-uand you want to remove it and enter it as spam, then use-Ns. if-Nis used for a message that wasn't registered as non-spam, the counts will still be decremented. same deal, same energy ๐ซถ
๐ธ GENERAL OPTIONS
-cfilename โ tells bogofilter to read the config file named. yes, that one specifically, not the usual suspects.-Cโ prevents bogofilter from reading configuration files. at all. none. icon of independence ๐-ddir โ lets you set the directory for the database. see the ENVIRONMENT section for other directory setting options.-kcachesize โ sets the cache size for theBerkeleyDBsubsystem, in units of 1 MiB (1,048,576 bytes). properly sizing the cache improves bogofilter's performance โ the recommended size is one third of the size of the database file. you can run thebogotunescript (in thetuningdirectory) to determine the recommended size. math bestie, do the math ๐-lโ writes an informational line to the system log each time bogofilter is run. the information logged depends on how bogofilter is run. journaling era โ๏ธ-Ltag โ configures a tag which can be included in the information being logged by the-loption, but it requires a custom format that includes the%lstring for now. this option implies-l. (yes,%l, exactly like that, don't @ me)-Ifilename โ tells bogofilter to read its input from the specified file, rather than fromstdin. choose your own adventure ๐-Ofilename โ tells bogofilter where to write its output in passthrough mode. note that this only works when-pis explicitly given. no-p, no output redirection, that's the rule ๐
๐ PARAMETER OPTIONS
-Evalue[,value] โ allows setting thesp-esfvalue and thens-esfvalue. with two values, bothsp-esfandns-esfare set. if only one value is given, parameters are set as described in the note below.-mvalue[,value][,value] โ allows setting themin-devvalue and, optionally, therobsandrobxvalues. with three values,min-dev,robs, androbxare all set. if fewer values are given, parameters are set as described in the note below.-ovalue[,value] โ allows setting thespam-cutoffham-cutoffvalues. with two values, bothspam-cutoffandham-cutoffare set. if only one value is given, parameters are set as described in the note below.
Note: all of these options allow fewer values to be provided. values can be skipped by using just the comma delimiter, in which case the corresponding parameter(s) won't be changed. if only the first value is provided, then only the first parameter is set. trailing values can be skipped, in which case the corresponding parameters won't be changed. within the parameter list, spaces are not allowed after commas. not even one. not even a lil one. be normal about commas ๐ค
๐ง INFO OPTIONS
-vโ produces a report to standard output on bogofilter's analysis of the input. each additionalvwill increase the verbosity of the output, up to a maximum of 4. with-vv, the report lists the tokens with highest deviation from a mean of0.5association with spam. the more v's, the more it spills the tea ๐ซ-ydate โ can be used to override the current date when timestamping tokens. a value of zero (0) turns off timestamping. time travel but make it tokens โฐ-Dโ redirects debug output tostdout. where it belongs, honestly.-xflags โ allows setting of debug flags for printing debug information. see header filedebug.hfor the list of usable flags. the lore is in the header file ๐
๐ CONFIG FILE OPTIONS
using GNU longopt -- syntax, a config file's name=value statement becomes a command line's --option=value. use command bogofilter --help for a list of options and see bogofilter.cf.example for more info on them. for example, to change the X-Bogosity header to "X-Spam-Header", use:
--spam-header-name=X-Spam-Header
๐ ENVIRONMENT
bogofilter uses a database directory, which can be set in the config file. if not set there, bogofilter will use the value of BOGOFILTER_DIR. both can be overridden by the -d dir option. if none of that is available, bogofilter will use directory $HOME/.bogofilter. it's giving "we'll figure it out, worst case we crash at home" ๐
โ๏ธ CONFIGURATION
the bogofilter command line allows setting of many options that determine how bogofilter operates. file /etc/bogofilter.cf can be used to set additional parameters that affect its operation. file /etc/bogofilter.cf.example has samples of all of the parameters. status and logging messages can be customized for each site. site-specific customization?? we love a personal touch ๐
๐ฏ RETURN VALUES
0for spam1for non-spam2for unsure3for I/O or other errors
if both -p and -e are used, the return values are: 0 for spam or non-spam; 3 for I/O or other errors.
error 3 usually means that the wordlist file bogofilter wants to read at startup is missing or the hard disk has filled up in -p mode. so if you see a 3, check your wordlist and check your disk space, bestie ๐ซ
๐ INTEGRATION WITH OTHER TOOLS ๐
okay bestie, this is where bogofilter starts fitting into your whole mail flow, and honestly? iconic. โจ
๐ธ Use with procmail ๐ธ
so this recipe is a whole vibe: (a) it spam-bins anything that bogofilter rates as spam, (b) it registers the words in messages rated as spam as such, and (c) it registers the words in messages rated as non-spam as such. once you've got this in place, it will normally only be necessary for the user to intervene (with -Ns or -Sn) when bogofilter miscategorizes something. no cap.
# filter mail through bogofilter, tagging it as Ham, Spam, or Unsure,
# and updating the wordlist
:0fw
| bogofilter -u -e -p
# if bogofilter failed, return the mail to the queue;
# the MTA will retry to deliver it later
# 75 is the value for EX_TEMPFAIL in /usr/include/sysexits.h
:0e
{ EXITCODE=75 HOST }
# file the mail to spam-bogofilter if it's spam.
:0:
* ^X-Bogosity: Spam, tests=bogofilter
spam-bogofilter
# file the mail to unsure-bogofilter
# if it's neither ham nor spam.
:0:
* ^X-Bogosity: Unsure, tests=bogofilter
unsure-bogofilter
# With this recipe, you can train bogofilter starting with an empty
# wordlist. Be sure to check your unsure-folder regularly, take the
# messages out of it, classify them as ham (or spam), and use them to
# train bogofilter.
the following procmail rule will take mail on stdin and save it to file spam if bogofilter thinks it's spam:
:0HB:
* ? bogofilter
spam
and this similar rule will also register the tokens in the mail according to the bogofilter classification:
:0HB:
* ? bogofilter -u
spam
if bogofilter fails (returning 3) the message will be treated as non-spam. periodt.
this one is for maildrop, it automatically defers the mail and retries later when the xfilter command fails, use this in your ~/.mailfilter:
xfilter "bogofilter -u -e -p"
if (/^X-Bogosity: Spam, tests=bogofilter/)
{
to "spam-bogofilter"
}
the following .muttrc lines will create mutt macros for dispatching mail to bogofilter. so handy fr fr.
macro index d "<enter-command>unset wait_key\n\
<pipe-entry>bogofilter -n\n\
<enter-command>set wait_key\n\
<delete-message>" "delete message as non-spam"
macro index \ed "<enter-command>unset wait_key\n\
<pipe-entry>bogofilter -s\n\
<enter-command>set wait_key\n\
<delete-message>" "delete message as spam"
๐ Integration with Mail Transport Agent (MTA) ๐
- bogofilter can also be integrated into an MTA to filter all incoming mail. while the specific implementation is MTA dependent, the general steps are as follows:
- install bogofilter on the mail server
- prime the bogofilter databases with a spam and non-spam corpus. since bogofilter will be serving a larger community, it is important to prime it with a representative set of messages.
- set up the MTA to invoke bogofilter on each message. while this is an MTA specific step, you'll probably need to use the
-p,-u, and-eoptions. - set up a mechanism for users to register spam/non-spam messages, as well as to correct mis-classifications. the most generic solution is to set up alias email addresses to which users bounce messages.
- see the
docandcontribdirectories for more information. iykyk โจ
๐ฌ Use of R to verify bogofilter's calculations ๐ฌ
the -R option tells bogofilter to generate an R data frame. the data frame contains one row per token analyzed. each such row contains the token, the sum of its database "good" and "spam" counts, the "good" count divided by the number of non-spam messages used to create the training database, the "spam" count divided by the spam message count, Robinson's f(w) for the token, the natural logs of (1 - f(w)) and f(w), and an indicator character (+ if the token's f(w) value exceeded the minimum deviation from 0.5, - if it didn't). there is one additional row at the end of the table that contains a label in the token field, followed by the number of words actually used (the ones with + indicators), Robinson's P, Q, S, s and x values and the minimum deviation.
the R data frame can be saved to a file and later read into an R session (see the R project website[5] for information about the mathematics package R). provided with the bogofilter distribution is a simple R script (file bogo.R) that can be used to verify bogofilter's calculations. instructions for its use are included in the script in the form of comments. cute.
๐ LOG MESSAGES ๐
bogofilter writes messages to the system log when the -l option is used. what is written depends on which other flags are used.
a classification run will generate (we are not showing the date and host part here):
bogofilter[1412]: X-Bogosity: Ham, spamicity=0.000227
bogofilter[1415]: X-Bogosity: Spam, spamicity=0.998918
using -u to classify a message and update a wordlist will produce (all on a single line):
bogofilter[1426]: X-Bogosity: Spam, spamicity=0.998918,
register -s, 329 words, 1 messages
registering words (-l and -s, -n, -S, or -N) will produce:
bogofilter[1440]: register-n, 255 words, 1 messages
a registration run (using -s, -n, -N, or -S) will generate messages like:
bogofilter[17330]: register-n, 574 words, 3 messages
bogofilter[6244]: register-s, 1273 words, 4 messages
๐ FILES ๐
/etc/bogofilter.cfโ system configuration file.~/.bogofilter.cfโ user configuration file.~/.bogofilter/wordlist.dbโ combined list of good and spam tokens.
๐ AUTHOR ๐
- Eric S. Raymond
<esr@thyrsus.com> - David Relson
<relson@osagesoftware.com> - Matthias Andree
<matthias.andree@gmx.de> - Greg Louis
<glouis@dynamicro.on.ca>
for updates, see the bogofilter project page[6].
๐ SEE ALSO ๐
bogolexer(1), bogotune(1), bogoupgrade(1), bogoutil(1)
๐ NOTES ๐
- A Plan For Spam โ
http://www.paulgraham.com/spam.html - Spam Detection โ
http://radio-weblogs.com/0101454/stories/2002/09/16/spamDetection.html - A Statistical Approach to the Spam Problem โ
http://www.linuxjournal.com/article/6467 - Another improvement โ
http://www.garyrobinson.net/2004/04/improved%5fchi.html - the R project website โ
http://cran.r-project.org/ - bogofilter project page โ
http://bogofilter.sourceforge.net/
and that's a wrap, bestie! this page is from the Bogofilter manual, dated 05/19/2019, and it's the BOGOFILTER(1) page. stay slay ๐ โจ๐ฆ
๐ฆ where this page comes from
- alpine 3.24: bogofilter-doc 1.2.5-r4 ยท GPL-2.0-or-later
- centos-stream 9: bogofilter 1.2.5-8.el9 ยท GPLv2
- debian bookworm: bogofilter-common 1.2.5-1+b2 ยท GPL-2.0-or-later
- debian trixie: bogofilter-common 1.2.5-1+b4 ยท GPL-2.0-or-later
- epel 10: bogofilter 1.2.5-19.el10_1 ยท GPL-2.0-only
- fedora 43: bogofilter 1.2.5-20.fc43 ยท GPL-2.0-only
- fedora 44: bogofilter 1.2.5-22.fc44 ยท GPL-2.0-only
- ubuntu jammy: bogofilter-common 1.2.5-1build2 ยท GPL-2.0-or-later
- ubuntu noble: bogofilter-common 1.2.5-1build4 ยท GPL-2.0-or-later
- ubuntu questing: bogofilter-common 1.2.5-1build5
- ubuntu resolute: bogofilter-common 1.2.5-1build6 ยท GPL-2.0-or-later
- ubuntu stonking: bogofilter-common 1.2.5-1build6 ยท GPL-2.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms