Commit ed1ff6fa authored by Micah's avatar Micah
Browse files

Add initial rate-limiting for outgoing SMTP, using postfwd (#5972)

Change-Id: I6a6e68908b71d7499eb3ef3c7f0173b3d5b7baa2
parent e97a9d38
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
### This file managed by Puppet
# Global options for postfwd(8).

# Set to '1' to enable startup (daemon mode)
STARTUP=1

# Config file
CONF=/etc/postfix/postfwd.cf
# IP where listen to
INET=127.0.0.1
# Port where listen to
PORT=10040
# run as user postfwd
RUNAS="postfw"
# Arguments passed on start (--daemon implied)
# RISEUP disable summary and cache-no-size
#ARGS="--summary=600 --cache=600 --cache-rdomain-only --cache-no-size"
ARGS="--cache=600 --cache-rdomain-only --no-rulestats"
+49 −0
Original line number Diff line number Diff line
# This class provides rate-limiting for outgoing SMTP, using postfwd
# it is configured with some limits that seem reasonable for a generic
# use-case. Each of the following applies to sasl_authenticated users:
#
# . 150 recipients at a time
# . no more than 50 messages in 60 minutes
# . no more than 250 recipients in 60 minutes.
#
# This class could be easily extended to add overrides to these rules,
# maximum sizes per client, or additional rules
class postfwd {

  ensure_packages(['libnet-server-perl', 'libnet-dns-perl', 'postfwd'])

  file {
    '/etc/default/postfwd':
      source  => 'puppet:///modules/postfwd/postfwd',
      mode    => '0644',
      owner   => root,
      group   => root,
      require => Package['postfwd'];

    '/etc/postfix/postfwd.cf':
      content => template('postfwd/postfwd.cf.erb'),
      mode    => '0644',
      owner   => root,
      group   => root,
      require => File['/etc/postfix'];
  }

  exec {
    '/etc/init.d/postfwd reload':
      refreshonly => true,
      subscribe   => [ File['/etc/postfix/postfwd.cf'],
                       File['/etc/default/postfwd'] ];
  }

  service {
    'postfwd':
      ensure     => running,
      name       => postfwd,
      pattern    => '/usr/sbin/postfwd',
      enable     => true,
      hasrestart => true,
      hasstatus  => false,
      require    => [ File['/etc/default/postfwd'],
                      File['/etc/postfix/postfwd.cf']];
  }
}
+31 −0
Original line number Diff line number Diff line
### This file managed by Puppet
# Before deploying a rule
# 1. test with an additional "sender==test@domain.org;" in the rule so it
#   only applies to your test account
# 2. then when ready to test for all users, use WARN and watch the logs
#   for a few days and make sure it working the way you like
# 3. Then when ready to deploy for real set a proper error code

## Overrides - make like the following example
# id=exampleuser; sasl_username==exampleuser; action=dunno

## Rules that apply to all senders
# Recipient Per Message Limit
# We only receive mail via smtp from sasl authenticated users
# directly. We want to limit to a lower amount to prevent phished accounts
# spamming
id=RCPTSENDER; recipient_count=150; action=REJECT Too many recipients, please try again. Contact http://<%= @domain %>/tickets/new if this is in error. ERROR:RCPTSENDER 

# Message Rate Limit
# This limits sasl authenticated users to no more than 50/60mins
# NOTE: sasl_username needs to be set to something or this check will fail
id=MSGRATE ; sasl_username=!!(^$); action==rate($$sasl_username/100/3600/450 4.7.1 exceeded message rate. Contact Contact http://<%= @domain %>/tickets/new if this is in error. ERROR:MSGRATE)

# Total Recipient Rate Limit
# This adds up the recipients for all the sasl authenticated users messages
# and can't exceed more than 250/60min
# NOTE: sasl_username needs to be set to something or this check will fail
id=RCPTRATE ; sasl_username=!!(^$); action==rcpt($$sasl_username/500/3600/450 4.7.1 exceeded message rate. Contact http://<%= @domain %>/tickets/new if this is in error. ERROR:RCPTRATE)

# Size per client Limit
id=SENDSIZE ;  state==END_OF_DATA ;  client_address==!!(10.0.1.0/24); action==size($$client_address/314572800/3600/450 4.7.1 Sorry you have sent too much data. Contact http://<%= @domain %>/tickets/new if this is in error. ERROR:SENDSIZE)
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ class site_postfix::mx {
  include site_postfix::mx::static_aliases
  include site_postfix::mx::rewrite_openpgp_header
  include clamav
  include postfwd

  # greater verbosity for debugging, take out for production
  #include site_postfix::debug