Configuration
There are three separate servers:
- Policy
Rejecting incoming mails before they are received - Content Filter
Works on the contents of the received mails - Log Parser
Parsing and preparing created log files for examination/reporting
All three of them are “self-sufficient”. You can start each of them “stand alone” – it is not required to run each server on any mail server instance.
Configuration Syntax^
All decency servers use YAML files. YAML (short for: YAML Ain’t Markup Language) is a very easy but very powerful configuration language (not only!!) which was designed to represent complex data structures while still being easily accessible by human maintainers. I will provide a short introduction, for a complete description visit the official YAML website, read the Wikipedia article or try google.
Datatypes^
YAML understands three basic data types: hash, list and scalar. First of, a short example in YAML:
--- keyname: value # another scalar otherkey: "other value" # list example list: - 1 - 2 - 3 # hash example hash: key1: value1 key2: value2
This example shows all the mentioned data types. The values on the right side could be in double or single quotations, but as long as they do not contain special characters, you can elide them. There are no punctuation marks as comma or dots at the end of a line.
Scalar^
keyname: value
This is the scalar data type. A classical key = value construct, where the left side, before the colon, represents a parameter name for identification. The right side, after the colon, represents the actual data/content. The value can be quoted (single or double).
List^
list: - 1 - 2 - 3
In this list (or array) example a core YAML concept is introduced: the indention. First, there is the parameter name “list”, then there are the values 1, 2 and 3. The parameter name is written in the same format as for scalars, but has no value on the right side. The values are below, prefixed with a dash “-” and indented in the same left justification (this is important). The actual amount of spaces (not tabs!) is arbitrary, as long you use the same amount for all list items.
You can write lists also in a shorter, but less readable, manner like this:
list: [ 1, 2, 3 ]
Hash^
hash: key1: value1 key2: value2
A hash or associative array is akin to lists, but different. In opposition to lists, each item has a parameter name associated with it. Again, the indention is required but the amount of spaces is optional as long as you use the same for all items.
Here is also a short notation:
hash: { key1: "value1", key2: "value2" }
You should now ..^
- A YAML file should end with an empty line
- A YAML file should begin with a line containing three dashes
--- - There are no punctuation marks at the end of a YAML line (like “;” or “.” or “,”)
- YAML is not JSON, but the short notation is very similar – but not the same
- Hashes and lists could be nested in each other. Scalars could be nested in hashes or lists
- Values might be quoted (single or double), but don’t have to be
Basic configuration^
Each server has its unique configuration options. Those are explained in detail on their configuration pages.
Folder structure^
If you’ve used the debian or the installer package, you would have a configuration directory in /etc/decency, a spool directory in /var/spool/decency, a log file directory in /var/log/decency and a run directory in /var/run/decency. If you’ve installed via CPAN, you should create this for you self as required.
The structure from the installer is quite simple and should look like this:
- /etc/decency/
Contains all server and global configuration options.- content-filter/
All content filter module configuration - policy/
All policy moule configurations - log-parser/
All syslog parser moule configurations - templates/
Contains all notification templates
- cache.yml
Configurations concerning caches, used for all modules as well - content-filter.yml
Server configurations for the content filter; module includes are here - database.yml
Configurations concerning databases, used for all modules as well - defaults.yml
Common settings which are excluded to keep server config smaller - logging.yml
Log settings - log-parser.yml
LogParser server configurations
- policy.yml
Server configurations for the policy server; module includes are here - sign.key
The sign RSA key (private) - sign.pub
The verification RSA key (public)
- content-filter/
- /vars/spool/decency
contains all created data (temporary or not)- archive/
Containing mails saved with the Archive module - failure/
Mails that could not be re-injected back to the mail server. Should be re-injected manually (for now) - honey/
Mails collected by the HoneyCollector module, if tagged by the HoneyPot module - logs/
Logs created by the LogParser, eg CSV logs - mime/
Temporary MIME files. Each of them resides in a temporary directory - quarantine/
Virus infected mails recognized by the virus filters - queue/
Temporary files created by the ContentFilter while passing through - temp/
Modules should create their temporary files here
- archive/
- /var/log/decency
Contains all log files, if directory logging is enabled for the server- error.log
All error logs. Watch those.. - debug.log
Debugging informations. Only if log level is high enough
- info.log
Anything between errors and debug messages
- error.log
Here are some things you can do in any server configuration file:
Include Configurations^
You can include additional YAML files in the base configuration of each server like this:
include: - /path/to/file.yml - in-same-directory-as-main-config.yml
Module configurations^
All module configurations can be outsourced, as well as written in the main configuration file.
Example for included module config^
For a policy server, but same concept for the other two.
policy: - DNSBL: policy/dnsbl.yml
One-file-config VS multi-file-config^
Instead of the configuration structure above you could use a single configuration file for each server which contains all your config parameters. But for the sake of re-use and smaller config files i tend to a folder structure rather then a huge file. You can adjust this easily if you prefer otherwise.
Shared server configuration^
All servers are capable of three basic configurations: logging, cache and database. The content filter and the policy server implement also exclusions.
database^
Allowed values: Database Hash
Default: none
Required: yes
Many policy modules require databases. If you enable persistent statistics, the policy server itself requires a database. Therefore it is mandatory to provide a database – even if your policy server does not require any. If the latter is true, simple provide a simple SQLite database, and ignore it (maybe in /tmp-folder).
See Databases and caches for more detailed informations.
database:
type: DBD
args:
- 'dbi:SQLite:dbname=/tmp/decency.db'
cache^
Allowed values: Database Hash
Default: none
Required: yes
The cache is very important, because it increases the performance a lot. Nearly any module requires a cache, therefore it is mandatory to provide some.
See Databases and caches for more detailed informations.
cache:
class: FastMmap
share_file: /tmp/decency.mmap
expire_time: 24h
cache_size: 64m
logging^
Default: -
Required: yes
You can enable/disable logging facilities. There are three: syslog, console and directory.
logging.syslog
Can be set to 1 or 0. If enabled, the syslog will be used.
Default: 0
logging.console
If enabled, the STDERR console will be used for logging. Either 1 or 0.
Default: 0
logging.directory
Can be set to a path, eg ‘/var/log/decency/’. Will write three log files: info.log, error.log and debug.log – depending on the log level.
logging.log_level
- 0 = error only
- 1 = error and info
- 2-5 = additional debug logs debug0 to debug3
---
logging:
syslog: 1
console: 1
log_level: 20
directory: /var/log/decency
exclusions^
Default: -
Required: no
Exclusions are rules to elide a certain module for a determined sender/recipient domain/address. Eg, if you use DNSBL module in the Policy server but want to disable DNSBL checks for all mails to recpientdomain.tld, then you define an exclusion.
There are three different ways to define those exclusions, trying to match most use cases.
- Config
Those you define directly in the config file. Should be used for all never-changing exclusions. They are kind of “hard coded” and require a server restart on change. - Plain text file
For easy administration. They should contain a very small amount of often changing exclusions. The whole file will be parsed on any test, so keep it small (let’s say up to two hundred or so). - Database
These are implemented for big sets of exclusion rules. No server restart is required and you can put in as much as you require.
exclusions.modules
The config exclusions reside here.
modules:
DNSBL:
sender_domain:
- sender.tld
- somedomain.tld
recipient_domain:
- recipient.tld
- anotherdomain.tld
sender_address:
- some@sender.tld
recipient_address:
- bla@recipient.tld
exclusions.file
Path to the plain text file containing exclusions. Example of file contents:
sender_domain:DNSBL:sender.tld sender_domain:DNSBL:somedomain.tld recipient_domain:GeoWeight:recipient.tld recipient_domain:GeoWeight:anotherdomain.tld sender_address:SPF:some@sender.tld recipient_address:SPF:bla@recipient.tld
exclusions.database
Bool value. Either 0 or 1.
ContentFilter SQL Example (SQLite)
-- TABLE: exclusions_contentfilter (SQLITE): CREATE TABLE EXCLUSIONS_CONTENTFILTER (value varchar(255), type varchar(20), module varchar(32), id INTEGER PRIMARY KEY); CREATE UNIQUE INDEX EXCLUSIONS_CONTENTFILTER_MODULE_TYPE_VALUE ON EXCLUSIONS_CONTENTFILTER (module, type, value);
Policy SQL Example (SQLite):
-- TABLE: exclusions_contentfilter (SQLITE): CREATE TABLE EXCLUSIONS_POLICY (value varchar(255), type varchar(20), module varchar(32), id INTEGER PRIMARY KEY); CREATE UNIQUE INDEX EXCLUSIONS_POLICY_MODULE_TYPE_VALUE ON EXCLUSIONS_CONTENTFILTER (module, type, value);
Shared module configuration^
Those configuration parameters can be set to any module
disabled^
Default: 0
Required: no
Allowed values: Bool (0 or 1)
Each module can be disabled. Set this value to 1 in the module configuration (inline or file) and the module will not be loaded. This is useful, if you want to disable a module but not remove it from the configuration.
timeout^
Default: 15 (policy), 30 (content filter)
Required: no
Allowed values: Integer (seconds)
Timeout for a single module check. For policy server, this should not be to long cause it delays the mail server and reduces the amount of receivable mails. Content filters does not slow down the amount of receivable mail, but could increase the amount of mails in the queue.
My Name is Ulrich Kautz and this is my private blog about server administration, perl programming and some other stuff that is on my mind. I study part-time computer sience at FU Berlin and work as sys admin and web developer at our hosting company