logo
Free, unlimited AI code reviews that run on commit
git-lrc git-lrc GitHub Install Now We'd appreciate a star git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

Mail::MtPolicyd::Cookbook::HowtoAccountingQuota - How to setup smtp level accounting and quotas

Author

       Markus Benning <ich@markusbenning.de>

Name

       Mail::MtPolicyd::Cookbook::HowtoAccountingQuota - How to setup smtp level accounting and quotas

Smtp Level Accounting And Quotas With Mtpolicyd

       The mtpolicyd could be used to implement a smtp level accounting and quota system.

       This guide explains how to setup accounting and quotas based on the sender ip on a monthly base and
       configurable quota limits.

       The how to expects that mtpolicyd is already installed, working and assumes a MySQL database is used to
       hold accounting data and quota configuration.

   SetupAccounting
       The accounting and quota checks should be implemented in postfix smtpd_end_of_data_restrictions. If
       you're already using mtpolicyd for other check it may be necessary to setup a second virtual host for the
       accounting/quota configuration. Otherwise you can use the default port 12345 virual host.

       Setupasecondvirtualhost

       First tell mtpolicyd to also listen on an addition port. In the global configuration add the new port to
       the port option:

         port="127.0.0.1:12345,127.0.0.1:12346"

       Then add a new virtual host at the end of the configuration file:

         <VirtualHost 12346>
           name="accounting"
           # TODO: add plugins...
         </VirtualHost>

       ConfiguretheAccountingplugin

       Now add the Accounting plugin to your virtual host:

         <Plugin AcctIP>
           module = "Accounting"
           fields = "client_address"
           # time_pattern = "%Y-%m"
           # table_prefix = "acct_"
         </Plugin>

       And the restart mtpolicyd to reload the configuration.

       The plugin will create a table for every field listed in "fields". By default the table prefix is acct_
       so the table name will be acct_client_address in our example. The plugin will create a row within this
       table for every client_address and expanded time_pattern:

         mysql> select * from acct_client_address;
         +----+-------------------+---------+-------+------------+---------+-----------+
         | id | key               | time    | count | count_rcpt | size    | size_rcpt |
         +----+-------------------+---------+-------+------------+---------+-----------+
         |  1 | 2604:8d00:0:1::3  | 2015-01 |    18 |         18 |   95559 |     95559 |
         |  2 | 2604:8d00:0:1::4  | 2015-01 |    21 |         21 |   99818 |     99818 |
         ...
         +----+-------------------+---------+-------+------------+---------+-----------+

       Activatethecheckinpostfix

       To active the check add the policyd to your smtpd_end_of_data_restrictions in main.cf:

         smtpd_end_of_data_restrictions = check_policy_service inet:127.0.0.1:12346

       If you have multiple smtpd process configured in a smtp-filter setup make sure only one smtpd is doing
       accounting/quota checks. Deactivate the restrictions by adding the following option the the re-inject
       smtpd processes in master.cf:

         -o smtpd_end_of_data_restrictions=

   Setupquotalimits
       To limit the number of messages a client_address is allowed to send add the following Quota plugin to
       your virtual host configuration before the Accounting plugin:

         <Plugin QuotaIP>
           module = "Quota"
           field = "client_address"
           metric = "count"
           threshold = 1000
           action = "defer you exceeded your monthly limit, please insert coin"
           # time_pattern = "%Y-%m"
           # table_prefix = "acct_"
         </Plugin>

   Usingperclient_addressquotalimits
       Create the following table structure in your MySQL database:

         CREATE TABLE `relay_policies` (
           `id` int(11) NOT NULL auto_increment,
           `desc` VARCHAR(64) NOT NULL,
           `config` TEXT NOT NULL,
           PRIMARY KEY  (`id`)
         ) ENGINE=InnoDB;

         INSERT INTO relay_policies VALUES(1, 'standard relay host', '{"quota_count":"10000"}');
         INSERT INTO relay_policies VALUES(2, 'premium relay host', '{"quota_count":"100000"}');

         CREATE TABLE `relay_hosts` (
           `id` int(11) NOT NULL auto_increment,
           `client_address` VARCHAR(64) NOT NULL,
           `relay_policy` int(11) NOT NULL,
           PRIMARY KEY  (`id`),
           KEY `relay_policy` (`relay_policy`),
           CONSTRAINT `relay_hosts_ibfk_1` FOREIGN KEY (`relay_policy`) REFERENCES `relay_policies` (`id`)
         ) ENGINE=InnoDB;

         INSERT INTO relay_hosts VALUES(NULL, '2604:8d00:0:1::3', 1);
         INSERT INTO relay_hosts VALUES(NULL, '2604:8d00:0:1::4', 2);

       You can use the following SELECT statement to retrieve the configuration for a relay_host:

         mysql> SELECT p.config FROM relay_policies p JOIN relay_hosts h ON (h.relay_policy = p.id) WHERE h.client_address = '2604:8d00:0:1::4';
         +--------------------------+
         | config                   |
         +--------------------------+
         | {"quota_count":"100000"} |
         +--------------------------+
         1 row in set (0.00 sec)

       To load the (JSON) configuration into the mtpolicyd session variables use the SqlUserConfig plugin and
       this SQL statement:

         <Plugin QuotaPolicyConfig>
           module = "SqlUserConfig"
           sql_query = "SELECT p.config FROM relay_policies p JOIN relay_hosts h ON (h.relay_policy = p.id) WHERE h.client_address=?"
           field = "client_address"
         </Plugin>

       This plugin must be added before your Accounting and Quota plugins.

       To use the quota_count value instead of the default threshold adjust your Quota plugin configuration:

         <Plugin QuotaIP>
           module = "Quota"
           field = "client_address"
           metric = "count"
           threshold = 1000
           uc_threshold = "quota_count"
           action = "defer you exceeded your monthly limit, please insert coin"
           # time_pattern = "%Y-%m"
           # table_prefix = "acct_"
         </Plugin>

       If the session variable quota_count is defined it will be used as threshold instead of the value
       configured in mtpolicyd.conf.

Version

       version 2.05

See Also