npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

haraka-plugin-limit

v1.2.3

Published

enforce various types of limits on remote MTAs

Downloads

6,745

Readme

haraka-plugin-limit

Tests Code Climate

NPM

Apply many types of limits to SMTP connections:

- concurrent connections
- max recipients
- max unrecognized commands
- max SMTP errors
- outbound concurrency
- rate limits
    - max connections / period
    - max recipients / period
        - by host
        - by sender
    - max null recipients / period

Installation

cd /etc/haraka
npm i haraka-plugin-limit
grep -q ^redis config/plugins || echo 'redis' >> config/plugins
echo 'limit' >> config/plugins

Configure

Each limit type has values that can be defined in limit.ini. See the default limit.ini in this packages config directory.

Each limit type is disabled until enabled=true is set within its block in limit.ini.

Haraka's config loader loads the defaults from limit.ini within this plugins installed config directory and applies any overrides found in the limit.ini within your Haraka install/config directory.

[main]

  • tarpit_delay = seconds (optional)

Set this to the length in seconds that you want to delay every SMTP response to a remote client that has exceeded the rate limits.

[redis]

Redis is the cluster-safe storage backend for maintaining the counters necessary to impose limits reliably.

  • host (default: 127.0.0.1)
  • port (default: 6379)
  • db (default: 0)

If this [redis] section or any values are missing, the defaults from redis.ini are used.

concurrency

When [concurrency]max is defined, it limits the maximum number of simultaneous connections per IP address. Connection attempts in excess of the limit are optionally delayed before being disconnected.

This works well in conjunction with a history / reputation database, so that one can assign very low concurrency (1) to bad or unknown senders and higher limits for reputable mail servers.

History

History: when enabled, the history setting is the name of a plugin that stores IP history / reputation results. The result store must have a positive value for good connections and negative integers for poor / undesirable connections. Karma is one such plugin.

recipients

When [recipients]max is defined, each connection is limited to that number of recipients. The limit is imposed against all recipient attempts. Attempts in excess of the limit are issued a temporary failure.

unrecognized_commands

When [unrecognized_commands]max is set, a connection that exceeeds the limit is disconnected.

Unrecognized commands are normally SMTP verbs invalidly issued by the client. Examples:

  • issuing AUTH when we didn't advertise AUTH extension
  • issuing STARTTLS when we didn't advertise STARTTLS
  • invalid SMTP verbs

Limitations

The unrecognized_command hook is used by the tls and auth plugins, so running this plugin before those would result in valid operations getting counted against that connections limits. The solution is simple: list limit in config/plugins after those.

errors

When [errors]max is set, a connection that exceeeds the limit is disconnected. Errors that count against this limit include:

  • issuing commands out of turn (MAIL before EHLO, RCPT before MAIL, etc)
  • attempting MAIL on port 465/587 without AUTH
  • MAIL or RCPT addresses that fail to parse

Rate Limits

By default DENYSOFT will be returned when rate limits are exceeded. You can also tarpit the connection delaying every response.

Missing sections disable that particular test.

They all use a common configuration format:

  • <lookup> = <limit>[/time[unit]] (optional)

'lookup' is based upon the limit being enforced and is either an IP address, rDNS name, sender address or recipient address either in full or part.

The lookup order is as follows and the first match in this order is returned and is used as the record key in Redis (except for 'default' which always uses the full lookup for that test as the record key):

IPv4/IPv6 address or rDNS hostname:

   fe80:0:0:0:202:b3ff:fe1e:8329
   fe80:0:0:0:202:b3ff:fe1e
   fe80:0:0:0:202:b3ff
   fe80:0:0:0:202
   fe80:0:0:0
   fe80:0:0
   fe80:0
   fe80
   1.2.3.4
   1.2.3
   1.2
   1
   host.part.domain.com
   part.domain.com
   domain.com
   com
   default

Sender or Recipient address:

   [email protected]
   host.sub.part.domain.com
   sub.part.domain.com
   part.domain.com
   domain.com
   com
   default

In all tests 'default' is used to specify a default limit if nothing else has matched.

'limit' specifies the limit for this lookup. Specify 0 (zero) to disable limits on a matching lookup.

'time' is optional and if missing defaults to 60 seconds. You can optionally specify the following time units (case-insensitive):

  • s (seconds)
  • m (minutes)
  • h (hours)
  • d (days)

[rate_conn]

This section limits the number of connections per interval from a given host or set of hosts.

IP and rDNS names are looked up by this test.

[rate_rcpt_host]

This section limits the number of recipients per interval from a given host or set of hosts.

IP and rDNS names are looked up by this test.

[rate_rcpt_sender]

This section limits the number of recipients per interval from a sender or sender domain.

The sender is looked up by this test.

[rate_rcpt]

This section limits the rate which a recipient or recipient domain can receive messages over an interval.

Each recipient is looked up by this test.

[rate_rcpt_null]

This section limits the rate at which a recipient can receive messages from a null sender (e.g. DSN, MDN etc.) over an interval.

Each recipient is looked up by this test.

[outbound]

enabled=true ; delay=30 ;example.com=10

The number after the domain is the maximum concurrency limit for that domain.

Delay is the number of seconds to wait before retrying this message. Outbound concurrency is checked on every attempt to deliver.

CAUTION

Applying strict connection and rate limits is an effective way to reduce spam delivery. It's also an effective way to inflict a stampeding herd on your mail server. When spam/malware is delivered by MTAs that have queue retries, if you disconnect early (which the rate limits do) with a 400 series code (a sane default), the remote is likely to try again. And again. And again. And again. This can cause an obscene rise in the number of connections your mail server handles. Plan a strategy for handling that.

Strategies

  • Don't enforce limits early. I use karma and wait until DATA before disconnecting. By then, the score of the connection is determinate and I can return a 500 series code telling the remote not to try again.
  • enforce rate limits with your firewall instead