On Mon, Sep 21, 2015 at 07:25:53AM +0100, Kianoosh Kashefi wrote: > I use Postfix with Postfwd as policy service. and I want to limit all > outgoing messages with exceptions for several SASL users with HOLD verdict. > I'm new to postfwd so I need configuration example for rate-limiting with > HOLD verdict (for instance limit all users outgoing messages to 10 messages > per minute and HOLD messages exceeding that limit) also I need the same > configuration to apply only to certain SASL users again with HOLD verdict > (for example limit a certain user's outgoing messages to 100 message per > minute and HOLD messages exceeding that limit). I appreciate if you reply > with full configuration examples for these two cases.
It can be done with the Accounting/Quota support of mtpolicyd: https://www.mtpolicyd.org/getting-started.html#Mail::MtPolicyd::Cookbook::HowtoAccountingQuota First you'll have to setup an SQL database and configure it in mtpolicyd: db_dsn="dbi:mysql:mail" db_user=mtpolicyd db_password=secret Then configure the a VirtualHost with the accounting plugin to record mails sent based on sasl_username: <VirtualHost 12345> name="rate-limit" <Plugin AcctUser> module = "Accounting" fields = "sasl_username" time_pattern = "%Y-%m-%d %H:%M" </Plugin> # more plugins come here later... </VirtualHost> Then add a query to this policyd vhost in your postfix configuration: smtpd_end_of_data_restrictions = check_policy_service inet:127.0.0.1:12345 At this point mtpolicyd will create a table acct_sasl_username with the first recieved mail and record accounting data in it. To limit the rate add the following Quota plugin configuration: <Plugin QuotaIP> module = "Quota" field = "sasl_username" metric = "count" threshold = 10 action = "hold" time_pattern = "%Y-%m-%d %H:%M" </Plugin> This should limit the message count per sasl_username. To add different limits per user you can use the per user configuration features of mtpolicyd. Create a database schema for it: CREATE TABLE `user_policy` ( `id` int(11) NOT NULL auto_increment, `desc` VARCHAR(64) NOT NULL, `config` TEXT NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB; // configuration is expected as JSON format hash INSERT INTO user_policy VALUES(1, 'privileged user', '{"rate-limit":"100"}'); CREATE TABLE `users` ( `id` int(11) NOT NULL auto_increment, `sasl_username` VARCHAR(64) NOT NULL, `user_policy` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `user_policy` (`user_policy`), CONSTRAINT `users_ibfk_1` FOREIGN KEY (`user_policy`) REFERENCES `user_policy` (`id`) ) ENGINE=InnoDB; INSERT INTO users VALUES(NULL, 'kianoosh@saslauth', 1); Add a query to retrieve the user configuration _before_ the Quota plugin: <Plugin UserConfiguration> module = "SqlUserConfig" sql_query = "SELECT p.config FROM user_policy p JOIN users u ON (u.relay_policy = p.id) WHERE u.sasl_username=?" field = "sasl_username" </Plugin> That will retrieve the user configuration by the sasl_username. Then edit the Quota plugin and add uc_threshold parameter: uc_threshold="rate-limit" This will overwrite the threshold option if there is a value for "rate-limit" defined in the current session. In my option the time slice is a little bit small with 1 minute. I would use a per hour or per day limit. Markus -- Markus Benning, https://markusbenning.de/