Difference between revisions of "Postfix policyd template"

(How to configure quotas for Postfix policyd (sqlite).)
(How to configure quotas for Postfix policyd (sqlite).)
Line 1: Line 1:
== '''How to configure quotas for Postfix policyd (sqlite).''' ==
 
  
 
 
 
 
'''PolicyD''' v2 (codenamed "cluebringer") is a multi-platform policy server for popular MTAs. The main goal is to implement as many spam combating and email compliance features as possible. The configuration of policyd under Zimbra is done by editing the sqlite database as shown in the examples below.
 
 
NOTE: ''Currently the only supported way of configuring policyd is through the CLI. The policyd gui that comes with the package is not supported.''
 
 
 
 
Sqlite contains couple of tables, which are used for the configuration of policyd:
 
 
sqlite> .tables
 
access_control            greylisting_tracking
 
accounting                greylisting_whitelist
 
accounting_tracking        policies
 
checkhelo                  policy_group_members
 
checkhelo_blacklist        policy_groups
 
checkhelo_tracking        policy_members
 
checkhelo_whitelist        quotas
 
checkspf                  quotas_limits
 
greylisting                quotas_tracking
 
greylisting_autoblacklist  session_tracking
 
greylisting_autowhitelist
 
 
 
We will predominantly work with the '''policies''', '''policy_members''', '''policy_groups''', '''policy_group_members''', '''quotas''' and '''quotas_limits''' tables. First, we need to navigate to and enter the sqlite database:
 
 
$ cd /opt/zimbra/data/cbpolicyd/db/
 
$ sqlite3 cbpolicyd.sqlitedb
 
SQLite version 3.6.20
 
Enter ".help" for instructions
 
Enter SQL statements terminated with a ";"
 
sqlite>
 
 
 
To configure policyd is important to understand the logic flow and the schema structure of the tables, as it might be confusing at the beginning. With the examples below I will also include the schema structure to understand the flow better. There are two possibilities: to configure policy with groups or without groups.
 
 
For both possibilities we need to do these two steps first:
 
1. Create a policy in the '''policies''' tables.
 
2. Configure the policy members of the newly created policy in the '''policy_members''' table.
 
 
a) If we are not to use groups, then after configuring the policy and policy members, we edit the '''quota''' and '''quotas_limits''' tables.
 
b) If you are to configure groups, then after configuring the policies, we configure the groups and then the quotas.
 
 
----
 
 
*'''Creating a policy'''
 
 
The following command creates policy with name "test_policy", with priority 0 and is enabled:
 
 
sqlite> insert into policies(Name,Priority,Disabled) VALUES ('test_policy',0,0);
 
 
 
Priority '''0''', means it will be picked up first from the list of the policies. The priorities goes as 1, then 2 and so on.
 
 
Example of our newly created policy (the ID,Name etc are not included in the normal view, but I put them to see the column name and corresponding data):
 
 
sqlite> select * from policies;
 
ID|Name      |Priority|Description |Disabled
 
  1|test_policy|0      |            |0
 
 
----
 
*'''Creating policy members'''
 
 
The next thing to do is to edit the policy_members table, to specify the members that will be included in the policy. We will give two examples: one using group and without.
 
 
'''+ group'''
 
 
sqlite> insert into policy_members(PolicyID,Source,Destination,Disabled) VALUES (1,'%test_group','any',0);
 
 
 
'''- group'''
 
 
sqlite> insert into policy_members(PolicyID,Source,Destination,Disabled) VALUES (1,'user@mydomain.com','any',0);
 
 
The result from these two commands is:
 
 
sqlite> select * from policy_members;
 
ID|PolicyID|Source          |Destination |Comment|Disabled
 
  1|1      |%test_group      |any        |      |0
 
  2|1      |user@mydomain.com|any        |      |0
 
 
Important to note here is the second column of the policy_members table. It points to the ID number of the policies table. In this case, both entries in the policies_members table point to the same policy: 1, from the policies table.
 
 
Here are the possible options that can be in the Source and Destination columns:
 
NULL = any''
 
a.b.c.d/e = IP address with optional /e
 
@domain = domain specification,
 
%xyz = xyz group,
 
abc@domain = abc user specification
 
all options support negation using !<key>
 
 
To get these values for any of the tables, you can use the '''.schema''' command:
 
 
sqlite> .schema policy_members
 
CREATE TABLE policy_members (
 
        ID                      INTEGER PRIMARY KEY AUTOINCREMENT,
 
        PolicyID                INT8,
 
        /*
 
                Format of key:
 
                NULL = any
 
                a.b.c.d/e = IP address with optional /e
 
                @domain = domain specification,
 
                %xyz = xyz group,
 
                abc@domain = abc user specification
 
                all options support negation using !<key>
 
        */
 
        Source                  TEXT,
 
        Destination            TEXT,
 
        Comment                VARCHAR(1024),
 
        Disabled                SMALLINT NOT NULL DEFAULT '0',
 
        FOREIGN KEY (PolicyID) REFERENCES policies(ID)
 
);
 
 
----
 
*'''Adding group/s'''
 
 
'''1.''' Adding group is similar to adding policies, just the table columns' names are different. In our previous example, we have entered a group (test_group) in the policy_members table. However the group is not created yet. Here is how to do it:
 
 
sqlite> insert into policy_groups(Name,Disabled) VALUES ('test_group',0);
 
 
Here is the group in sqlite:
 
 
sqlite> select * from policy_groups;
 
ID|Name      |Disabled|Comment
 
  1|test_group|0      |
 
 
 
'''2.''' The next step is to create the members for the test_group. Below is a part of the .schema command for this table, which shows us the correct syntax for the policy_group_members table:
 
 
/* Format of member: a.b.c.d/e = ip,  @domain = domain, %xyz = xyz group, abc@domain = abc user */
 
 
To add couple of members, we can run the following commands:
 
 
sqlite> insert into policy_group_members(PolicyGroupID,Member,Disabled) VALUES (1,'testuser@mydomain',0);
 
sqlite> insert into policy_group_members(PolicyGroupID,Member,Disabled) VALUES (1,'192.168.56.10/24',0);
 
 
And the result is:
 
 
sqlite> select * from policy_group_members;
 
ID|PolicyGroupID  |Member          |Disabled|Comment
 
  1|1              |testuser@mydomain|0      |
 
  2|1              |192.168.56.10/24 |0      |
 
 
 
The above is showing that all quotas, pointing to policy ID 1, will be forcing their rules on testuser@mydomain, machine with ip 192.168.56.10 and user@mydomain.com, specified as ID 2 in the policy_members table. Also as in the previous example, the PolicyGroupID is pointing to a specific policy_groups entry ID. In our case it's pointing to ID 1.
 
 
----
 
*'''Configure quotas'''
 
 
To configure quotas, we will have to edit two tables: '''quotas''' and '''quotas_limits'''. First we will edit the quotas table, but before that we need to check the formatting:
 
 
/* Tracking Options */''
 
/* Format:  <type>:<spec>''
 
'''SenderIP''' - This takes a bitmask to mask the IP with. A good default is /24''
 
'''Sender''' & '''Recipient''' - Either "user@domain" (default), "user@" or "@domain" for the entire''
 
email addy or email addy domain respectively.''
 
*/''
 
 
And the command to create a quota:
 
 
sqlite> insert into quotas(PolicyID,Name,Track,Period,Verdict,Data,Disabled) VALUES (1,'test_quota','Sender:user@domain',120,'DEFER','User has been deferred for two minutes',0);
 
 
 
Followed by command to edit the quota_limits table:
 
 
sqlite> insert into quotas_limits(QuotasID,Type,CounterLimit,Disabled) VALUES (1,'MessageCount',2,0);
 
 
The above commands are enforcing quota that is restricting all users in %test_group and user@mydomain.com to send no more than two messages in a time frame of two minutes. Notice that the quota is pointing to a specific policy. We have only one policy, so its pointing to policy ID 1. The quota_limits table has an entry that is pointing to the quota from the quota table. Instead of "Sender", we can specify "Recipient", which will limit the emails received by user/group.
 
 
 
 
----
 
*Below is a little example of already created policy/group/quota:
 
 
 
sqlite> select * from policies;
 
        ID|Name      |Priority|Description|Disabled
 
sqlite> '''1'''|test_policy|0      |          |0
 
-
 
sqlite> select * from policy_members;
 
        ID|PolicyID|Source          |Destination|Comment|Disabled''
 
sqlite> 1|'''1'''      |%test_group      |any        |      |0
 
sqlite> 2|'''1'''      |user@mydomain.com|any        |      |0
 
-
 
sqlite> select * from policy_groups;
 
        ID|Name      |Disabled|Comment
 
sqlite> '''1'''|test_group|0      |
 
-
 
sqlite> select * from policy_group_members;
 
        ID|PolicyGroupID|Member          |Disabled|Comment
 
sqlite> 1|'''1'''            |%group2        |0      |
 
sqlite> 2|'''1'''            |192.168.56.10/24|0      |
 
-
 
sqlite> select * from quotas;
 
        ID|PolicyID|Name      |Track            |Period|Verdict|Data                                  |LastQuota|Comment|Disabled
 
sqlite> '''1'''|1      |test_quota|Sender:user@domain|120  |DEFER  |User has been deferred for two minutes|0        |      |0
 
-
 
sqlite> select * from quotas_limits;
 
        ID|QuotasID|Type        |CounterLimit|Comment|Disabled
 
sqlite> 1|'''1'''      |MessageCount|2          |      |0
 
 
 
 
Let's try to explain the above configuration:
 
 
-'''1.''' We have one policy: test_policy.
 
-'''2.''' In the policy_members table, we have two members pointing to the test_policy. (notice  the PolicyID number being the same as the ID of the policy). In the same table we have specified one group (indicated by the % sign). This group is created in the policy_groups table. 
 
-'''4.''' policy_group_members table contains the ips, domains, groups to which to apply the quotas.
 
-'''5.''' The quotas table specify the name of the quota, to which property (track) to apply the quotas, the time period for which the quota is applied, Verdict as to what to do if the quota has a match and if its disabled or not.
 
-'''6.''' The quota_limits, specifies the messages limits that could be sent/received.
 
 
 
There are couple of other options that can be configured. They can be seen if you check the schema for the table you would like to modify. For example:
 
 
sqlite> .schema quotas_limits
 
CREATE TABLE quotas_limits (
 
        ID                      INTEGER PRIMARY KEY AUTOINCREMENT,
 
        QuotasID                INT8,
 
        Type                    VARCHAR(255),  /* "MessageCount" or "MessageCumulativeSize" */
 
        CounterLimit            UNSIGNED BIG INT,
 
        Comment                VARCHAR(1024),
 
        Disabled                SMALLINT NOT NULL DEFAULT '0',
 
        FOREIGN KEY (QuotasID) REFERENCES quotas(ID)
 
);
 
 
 
As we can see, for the quota_limits we can also specify "MessageCumulativeSize", which means
 
"Cumulative size of email messages, or you could say bandwidth quota. This is in bytes."
 
 
 
*For additional information on policyd please visit the following links:
 
*http://wiki.policyd.org
 
*http://wiki.zimbra.com/wiki/Postfix_Policyd
 

Revision as of 09:23, 12 November 2014

Jump to: navigation, search