regigate rule engine file format
Introduction
This document describes and explains the file format used by the regigate rule engine. The rule-file is to be used in the regigate appliance menu (SSH) and must be inserted there for every rule.
File format
File format specification
The configuration file is JSON encoded. This is the general specification for the configuration file:
{
"$schema": "http://json-schema.org/draft-06/schema#",
"definitions": {
"field": {
"type": "string",
"enum": ["srcIp", "sender", "recip", "recipDomain", "header",
"attName", "attType"]
},
"meet": {
"type": "string",
"enum": ["regex", "inList", "allInList", "contains", "equals"]
}
},
"type": "object",
"properties": {
"matchingConditions": {
"type": "object",
"patternProperties": {
".+": {
"type": "object",
"properties": {
"desc": {"type": "string", "description": "optional comment"},
"field": {"$ref": "#/definitions/field"},
"meet": {"$ref": "#/definitions/meet"},
"criterium": {"type": "string"},
"caseMatters": {"type": "boolean", "description": "default false"}
},
"required": ["field", "meet", "criterium"]
}
}
},
"rules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"desc": {"type": "string", "description": "optional comment"},
"conditions": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"desc": {"type": "string",
"description": "optional comment"},
"does": {"type": "boolean"},
"field": {"$ref": "#/definitions/field"},
"meet": {"$ref": "#/definitions/meet"},
"criterium": {"type": "string"},
"caseMatters": {"type": "boolean",
"description": "default false"}
},
"required": ["does", "field", "meet", "criterium"]
},
{
"type": "object",
"properties": {
"desc": {"type": "string",
"description": "optional comment"},
"does": {"type": "boolean"},
"match": {"type": "string",
"description": "existing matchingConditions key"}
},
"required": ["does", "match"]
}
]
}
},
"action": {
"type": "string",
"enum": ["encrypt", "decrypt", "pass", "reject"]
},
"tags": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"addHeader": {"type": "string",
"description": "header name"},
"desc": {"type": "string",
"description": "optional comment"},
"value": {"type": "string", "description": "header value"}
},
"required": ["addHeader", "value"]
},
{
"type": "object",
"properties": {
"modHeader": {"type": "string",
"description": "header name"},
"desc": {"type": "string",
"description": "optional comment"},
"match": {"type": "string",
"description": "regular expression to match"},
"caseMatters": {"type": "boolean",
"description": "default false"},
"replace": {"type": "string",
"description": "replacement for matched regex"}
},
"required": ["modHeader", "match", "replace" ]
}
]
}
},
"active": {"type": "boolean"}
}
},
"required": ["name", "action", "active"]
}
}
}
The above scheme follows the official syntax defined here:
http://json-schema.org/
Matching Conditions
A matchingCondition allows you to define rules faster and more comfortably. A matchingCondition is a predefined condition which can be used later by a simple "does" or "does not" variation using the match property pointing to its name.
Look at this example rule without using a matchingCondition (in the "rules" section of the JSON file):
{ "name" : "encrypt outgoing",
"desc" : "encrypt everything outgoing except rgf files",
"conditions" : {
"does" : false,
"desc" : "has an rgf file",
"field" : "attType",
"meet" : "equals",
"criterium" : "application/vnd.regify"
},
"action" : "encrypt",
"active" : true
}
The rule below is exactly the same, but uses a matchingCondition named "hasRgf".
Now, the matchingCondition is defined like this (in the "matchingConditions" section of the JSON file):
{
"hasRgf" : {
"desc" : "has an rgf file",
"field" : "attType",
"meet" : "equals",
"criterium" : "application/vnd.regify"
}
}
The rule itself now looks like this (in the "rules" section of the JSON file):
{ "name" : "encrypt outgoing",
"desc" : "encrypt everything outgoing except rgf files",
"conditions" : {
"does" : false, "match" : "hasRgf"
},
"action" : "encrypt",
"active" : true
}
matchingConditions can be reused many times and therefore have the following benefits:
-
If you have to use a value/condition many times (eg IP address of an MTA as source), you have a single point where it is defined.
-
Less text to type.
-
Rules are much easier to read and understand.
Rules
How rules are applied
- Paradigm 1
-
Rules are applied from top to bottom.
- Paradigm 2
-
The first rule that applies stops the rule execution. Any subsequent rules below are ignored.
- Paradigm 3
-
If no rule applies until the end, the message is passed through by default.
Therefore, if you simply define an empty rule file like "{ }", all messages are simply passed through unaltered. This is the default behaviour of a newly created route.
If you prefer to let a regigate route reject all messages that were not handled by a rule, you may add a final blocking rule to reject everything that has not been handled above:
{
"name": "reject everything",
"desc": "reject all messages that have not been handled by any previous rule",
"action": "reject",
"active": true
}
Rule attributes
The following table shows the possible elements of a rule including their description and default values:
Property | Description |
---|---|
name |
The name of the rule. |
desc |
A short description and intent of the rule. You may also add some comments about the conditions here. Optional. |
conditions |
One or more matchingCondition for this rule. Please see the separate "Rule conditions" section below. If no conditions are defined, the rule will match and its action will be performed. |
action |
Specifies the action this rule would trigger. Possible values are:
|
tags |
Optional. One or more tag rules for this message. Please see the separate tags section below. |
active |
If the rule is used or not. Set this to false if you do not want this rule to apply. This is handy for testing or if you like to have a rule as a template, but don’t want it to actually apply. |
Rule conditions
Every rule may have of one or more conditions. Every condition is an entry in the conditions value of the JSON file. Whenever there are multiple inputs to match, like recipients, headers or attachments, any one match will make the condition match. Multiple conditions are *AND*ed.
There are two ways of defining a condition. You can either:
-
define all condition parameters directly or
-
use a matchingCondition (see extra chapter above for matchingConditions).
This table shows you the properties of a complete condition:
Property | Description | ||
---|---|---|---|
desc |
A short description of the condition. Optional. |
||
does |
Boolean value as negotiator. If it is true, the criteria must match. If it is false, the criteria must not match. |
||
field |
One of the following fields to check in this condition:
|
||
meet |
The comparison function. These are the available comparison functions:
|
||
criterium |
The comparison field used for the comparison function defined in the meet property. If you have chosen regex, this is the regular expression to use on field. If you have chosen inList or allInList, this is the name of the list to use. If you have chosen contains, this value must be found in the field content. If you have chosen equals, the field content hat to match this criteria completely. |
||
caseMatters |
Boolean value (true/false) if the case matters on the criteria or not. Optional, defaults to false. It is ignored and defaults to false for e-mail addresses. It is also ignored but defaults to true for lists. |
This table shows you the properties of a condition that is using a matchingCondition:
Property | Description |
---|---|
desc |
A short description of the condition. Optional. |
does |
Boolean value as negotiator. If it is true, the matchingCondition must match. If it is false, the matchingCondition must not match. |
match |
The name of the matchingCondition to use. |
Rule tags
Another feature of rules are tags. Tags are applied when the rule containing them matches. The tags object contains one or more objects that operate on a MIME’s headers. With headers we mean the headers that come before the body of the e-mail. Attachment headers are not affected by this. There are 2 kinds of header rules. addHeader adds a header and modHeader modifies an existing header if the regular expression in match matches. Both can use the following predefined general tokens in their values:
Token | Description |
---|---|
$A |
The action that was taken. One of encrypt, decrypt or pass. There is no reject, because rejected messages are not altered. |
$H |
The host name of the regigate machine that processed the message. |
$I |
The IP number the postfix instance, that processed the message, bound to. |
$D |
The processing date in RFC 2822 format. (Example "Mon, 14 Aug 2006 02:34:56 -0600") |
Here are the details of addHeader:
Property | Description |
---|---|
addHeader |
The name of a header to unconditionally add. |
value |
The value of the added header. The entire header will read like the values of addHeader: value. |
desc |
An optional description which merely serves as a comment. |
These are the details of modHeader:
Property | Description |
---|---|
modHeader |
The name of a header to potentially replace. Only the first header is replaced. Subsequent headers by the same name are ignored. |
match |
A regular expression used to match all or parts of the given header. |
caseMatters |
Whether the expression given in match is case sensitive or not. Defaults to false. |
replace |
An expression to replace the header value with if it matched. Valid replacement tokens are $0-$9 for the groups as well as the general tokens. |
desc |
An optional description which merely serves as a comment. |
Example inbound configuration
The following example file shows various rules for an inbound route. You may use it as a starting template for your own rule set.
{
"matchingConditions" : {
"hasRgfMime" : {
"desc" : "has an rgf file mime-type",
"field" : "attType",
"meet" : "equals",
"criterium" : "application/vnd.regify"
},
"hasRgfFile" : {
"desc" : "attachment name *.rgf",
"field" : "attName",
"meet" : "regex",
"criterium" : "\\.rgf$"
}
},
"rules" : [
{ "name" : "decrypt in",
"desc" : "decrypt incoming regimail based on mime",
"conditions" : [
{ "does" : true, "match" : "hasRgfMime" }
],
"action" : "decrypt",
"tags" : [
{"addHeader" : "X-regigate", "value" : "Action: $A by $H ($I) on $D"},
{"modHeader" : "Subject", "desc" : "tag the subject with decryption",
"match" : "(.*?)( \\(decrypted\\))?$", "caseMatters" : false,
"replace" : "$1 (decrypted)"}
],
"active" : true
},
{ "name" : "decrypt in",
"desc" : "decrypt incoming regimail based on extension",
"conditions" : [
{ "does" : true, "match" : "hasRgfFile" }
],
"action" : "decrypt",
"active" : true
},
{ "name" : "pass in",
"desc" : "pass other incoming email",
"action" : "pass",
"active" : true
}
]
}
Example outbound configuration
The following example file shows various rules for an outbound route. You may use it as a starting template for your own rule set.
{
"matchingConditions" : {
"hasRgfMime" : {
"desc" : "has an rgf file mime-type",
"field" : "attType",
"meet" : "equals",
"criterium" : "application/vnd.regify"
},
"hasRgfFile" : {
"desc" : "attachment name *.rgf",
"field" : "attName",
"meet" : "regex",
"criterium" : "\\.rgf$"
}
},
"rules" : [
{ "name" : "encrypt all in list",
"desc" : "ecnrypt outgoing email to regify recipients in list",
"conditions" : [
{ "does" : false, "match" : "hasRgfMime" },
{ "does" : false, "match" : "hasRgfFile" },
{ "desc" : "in regify user list",
"does" : true,
"field" : "recip",
"meet" : "allInList",
"criterium" : "regifyUsers"
}
],
"action" : "encrypt",
"active" : true
},
{ "name" : "encrypt list",
"desc" : "ecnrypt outgoing email to regify recipients in list",
"conditions" : [
{ "does" : false, "match" : "hasRgfMime" },
{ "does" : false, "match" : "hasRgfFile" },
{ "desc" : "in regify user list",
"does" : true,
"field" : "recip",
"meet" : "inList",
"criterium" : "regifyUsers"
}
],
"action" : "encrypt",
"active" : true
},
{ "name" : "encrypt domains",
"desc" : "ecnrypt outgoing email to specified domains",
"conditions" : [
{ "does" : false, "match" : "hasRgfMime" },
{ "does" : false, "match" : "hasRgfFile" },
{ "desc" : "emails with domain...",
"does" : true,
"field" : "recipDomain",
"meet" : "inList",
"criterium" : "regifyDomains"
}
],
"action" : "encrypt",
"active" : true
},
{ "name" : "encrypt domains",
"desc" : "ecnrypt outgoing email to @bank.com",
"conditions" : [
{ "does" : false, "match" : "hasRgfMime" },
{ "does" : false, "match" : "hasRgfFile" },
{ "desc" : "emails to @bank.com",
"does" : true,
"field" : "recip",
"meet" : "contains",
"criterium" : "@bank.com"
}
],
"action" : "encrypt",
"active" : true
},
{ "name" : "encrypt !rf",
"desc" : "ecnrypt outgoing where subject starts with !rf",
"conditions" : [
{ "does" : false, "match" : "hasRgfMime" },
{ "does" : false, "match" : "hasRgfFile" },
{ "desc" : "Subject starts with !rf ",
"does" : true,
"field" : "header",
"meet" : "regex",
"criterium" : "^Subject:\\s*!rf ",
"caseMatters" : true
}
],
"action" : "encrypt",
"tags" : [
{"modHeader" : "Subject", "desc" : "remove the !rf prefix",
"match" : "^(?:\\s*!rf\\s+)(.*?)$", "caseMatters" : false,
"replace" : "$1"}
],
"active" : true
},
{ "name" : "encrypt X-doEncrypt",
"desc" : "ecnrypt outgoing where X-doEncrypt header is set",
"conditions" : [
{ "does" : false, "match" : "hasRgfMime" },
{ "does" : false, "match" : "hasRgfFile" },
{ "desc" : "X-doEncrypt set",
"does" : true,
"field" : "header",
"meet" : "regex",
"criterium" : "^X-doEncrypt:",
"caseMatters" : true
}
],
"action" : "encrypt",
"tags" : [
{"modHeader" : "X-doEncrypt", "desc" : "Detail out the X-doEncrypt header",
"match" : "^.*$", "caseMatters" : false,
"replace" : "Encrypted by $H ($I) on $D"}
],
"active" : true
},
{ "name" : "pass out",
"desc" : "pass outgoing email not meant to be encrypted",
"action" : "pass",
"active" : true
},
{ "name" : "reject out",
"desc" : "sample deactivated rule",
"conditions" : [
{ "does" : false, "match" : "hasRgfMime" },
{ "does" : false, "match" : "hasRgfFile" },
{ "desc" : "not in regify user list",
"does" : false,
"field" : "recip",
"meet" : "inList",
"criterium" : "regifyUsers"
}
],
"action" : "reject",
"active" : false
}
]
}