No description, website, or topics provided.
Ruby
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
README.md

README.md

smtp-dos-detector

Detect huge number of emails on pmiler using mruby scirpt.

Install pmilter

Install smtp-dos-detector

  • clone this repository

  • edit pmilter.conf

     : (snip)
    [handler]
    # connection info filter hhandler/connect.rb"
    mruby_connect_handler = "handler/smtp-dos-detector/src/smtp_dos_detector.rb"
     : (snip)

Usage smtp-dos-detector

  • handler/smtp-dos-detector/src/smtp_dos_detector.rb

     : (snip DosDetector class)
    
    #
    target = Pmilter::Session.new.client_ipaddr
    
    config = {
      :counter_key       => target,
      :threshold_time    => 10,
      :threshold_counter => 5,
      :expire_time       => 30,
      :behind_counter    => -10,
    }
    
    timeout = global_mutex.try_lock_loop(50000) do
      dos = DosDetector.new config
      data = dos.analyze
      p "smtp-dos-detector: analyze: #{data}"
      begin
        if dos.detect?
          p "smtp-dos-detector: detect: #{data}"
          Pmilter.status = Pmilter::SMFIS_REJECT
        end
      rescue => e
        raise "smtp-dos-detector: fail: #{e}"
      ensure
        global_mutex.unlock
      end
    end
    p "smtp-dos-detector: get timeout mutex lock, #{data}" if timeout
  • detail description config

     : (snip)
    config = {
      :counter_key       => target,
      :threshold_time    => 10,
      :threshold_counter => 5,
      :expire_time       => 30,
      :behind_counter    => -10,
    }
     : (snip)
    • Target (counter_key) will block 10 emails (behind_counter) for 30 seconds (expire_time) if you send 5 emails (threshold_counter) in 10 seconds (threshold_time)

pmilter + smtp-dos-detector works

  • send some mails

    echo "test" | mail -s "test" user@hoge.local
    
  • pmilter log

    # 1 mail is permit
    "smtp-dos-detector: analyze: {:time_diff=>0, :counter=>0, :counter_key=>\"127.0.0.1\"}"
    # 2 mail is permit
    "smtp-dos-detector: analyze: {:time_diff=>2, :counter=>1, :counter_key=>\"127.0.0.1\"}"
    # 3 mail is permit
    "smtp-dos-detector: analyze: {:time_diff=>4, :counter=>2, :counter_key=>\"127.0.0.1\"}"
    # 4 mail is permit
    "smtp-dos-detector: analyze: {:time_diff=>4, :counter=>3, :counter_key=>\"127.0.0.1\"}"
    # 5 mail is permit
    "smtp-dos-detector: analyze: {:time_diff=>6, :counter=>4, :counter_key=>\"127.0.0.1\"}"
    # 6 mail is reject
    "smtp-dos-detector: analyze: {:time_diff=>7, :counter=>5, :counter_key=>\"127.0.0.1\"}"
    "smtp-dos-detector: detect: {:time_diff=>7, :counter=>5, :counter_key=>\"127.0.0.1\"}"
    
    • 6 mail: reject log from postfix

      Dec 12 14:14:43 pmilter sendmail[5143]: uBCEEhjZ005143: to=postmaster, delay=00:00:00, xdelay=00:00:00, mailer=relay, pri=32273, relay=[127.0.0.1], dsn=5.0.0, stat=Service unavailable
      
    # 7 mail is reject
    "smtp-dos-detector: analyze: {:time_diff=>0, :counter=>-9, :counter_key=>\"127.0.0.1\"}"
    "smtp-dos-detector: detect: {:time_diff=>0, :counter=>-9, :counter_key=>\"127.0.0.1\"}"
      :
    # 15 mail is reject
    "smtp-dos-detector: analyze: {:time_diff=>8, :counter=>-1, :counter_key=>\"127.0.0.1\"}"
    "smtp-dos-detector: detect: {:time_diff=>8, :counter=>-1, :counter_key=>\"127.0.0.1\"}"
    # 16 mail is permit
    "smtp-dos-detector: analyze: {:time_diff=>9, :counter=>0, :counter_key=>\"127.0.0.1\"}"
    # 17 mail is permit
    "smtp-dos-detector: analyze: {:time_diff=>10, :counter=>1, :counter_key=>\"127.0.0.1\"}"
      :
      :