SlideShare uma empresa Scribd logo
1 de 38
Writing Applications
   with Qpsmtpd



      Fred Moyer

      fred@redhotpenguin.com
Qpsmtpd
●   Perl SMTP daemon written by Ask Bjørn Hansen
●   “mod_perl” of smtp
●   Plugin API makes writing extensions fun
●   Works with Qmail, Postfix, and Exim
●   Stock plugins include spam and virus protection
●   If you've tried to extend a C based smtp
    daemon you've felt pain at some point
Setting it up
●   Read the article by Matt Sergeant [1]
●   Install using RPMs if you can
    http://wiki.qpsmtpd.org/rpm-install_howto
●   Installing from source is easy also
    http://wiki.qpsmtpd.org/quick-install_howto
●   Telnetting to port 25 works for testing...
●   SWAKS is your friend [3]
●   qpsmtpd@perl.org is also your friend
My config file
  /home/smtpd/qpsmtpd/config/plugins
auth/auth_vpopmail_sql # set db auth in the plugin code
denysoft_greylist redhotpenguin.com taperfriendlymusic.org
quit_fortune
check_earlytalker
count_unrecognized_commands 4
check_relay
# require_resolvable_fromhost
# ^^ enable this to prevent zombies
check_delivery normal 1 127.0.0.1 vppmail dbuser dbpass
My config file
  /home/smtpd/qpsmtpd/config/plugins

# rhsbl <- these blacklist plugins blacklist
# dnsbl <- yahoo.com et al. sometimes!
check_badmailfrom
check_badrcptto
check_spamhelo
# sender_permitted_from
rcpt_ok # this is the last rcpt plugin
My config file
  /home/smtpd/qpsmtpd/config/plugins
virus/klez_filter
spamassassin reject_threshold 20 munge_subject_threshold 5
virus/clamav
# here is my first qpsmtpd application
craigslist recipient craig_qp@redhotpenguin.com site 
 http://www.craigslist.org login fred@redhotpenguin.com 
 password fredspass
queue/qmail-queue # leave enabled to forward the email
Many plugins available
●   http://wiki.qpsmtpd.org/plugins
●   Spam
●   Virus
●   Authentication – Vpopmail, PAM, text file, LDAP...
●   Plugins are generally geared towards keeping the
    spam out, and letting the good mail through
Your first plugin
●   Start with good examples

●   Read Matt Sergeant's O'reilly article [1]

●   Read the source for existing plugins

●   perldoc README.plugins ;)
A simple subject filter
 ●   Spam filters don't catch everything
block_subject [ all | [ domain1, domain2 ... ] ]

sub init {
 my ($self, $qp, @domains) = @_;
 unless (defined $domains[0]) {
   die “block_subject needs proper confign”;
 }

 $self->{_args}->{domains} = @domains;
 my $content = <<”SUBJECTS”;
YOUR REPRESENTATIVE ASSISTANCE IS NEEDED
Message From eBay Member
The Ultimate Online Pharmaceutical
SUBJECTS
A simple subject filter
    my @subjects = split(“n”, $block_content);
    $self->{_args}->{subjects} = @subjects;

    $self->log(LOGDEBUG,
     “Blocking subjects $block_content”);
}

sub hook_data_post {
 my ($self, $transaction) = @_;
 if ($self->{_args}->{domains}->[0] eq 'all') {
   if ($self->_blocked_subject($transaction)) {
     return DENY;
   }
 }
 else {
A simple subject filter
    # Check each domain
    my @recip_domains = map { $_->host }
     $transaction->recipients;
    foreach my $domain (@recip_domains) {

     # Deny the email if the subject is in our blacklist
     if (grep { $_ =~ m/^$domain$/ } @{$self->{_args}->{domains}
       && $self->blocked_subject($transaction))
       {
         return DENY;
       }
     }
    }
    return DECLINED;
}
A simple subject filter
sub blocked_subject {
 my ($self, $transaction) = @_;
 my $subject = $transaction->header->get('Subject');
 chomp($subject);

    if (grep { $_ =~ m/$subject$/i } @{$self->{_args}->{subjects}})
      {
        $self->log(LOGINFO, “block_subject invoked for $subject”);
        return 1;
      }
    return;
}
SMTP Applications?

●   SMTP to HTTP Gateways
●   Automate tedious processes
●   Use emails to interact with applications
●   Today's PDAs have IMAP based email
    but aren't very good at serving web pages
A Practical Application
●   The problem at hand
    ●   A couple hundred things we couldn't sell
    ●   Throwing away is bad for the environment
        (and costs money)
    ●   http://www.craigslist.org - someone wants it
●   But taking a picture of everything and posting
    an ad to Craigslist is a lot of clicking
●   I don't like to click, I like to write Perl
A Practical Application
●   Possible solutions
    ●   No internet connection
    ●   I could make a list of the items at hand
    ●   Call a friend and have him post
        ( no images though, and one less friend )
    ●   Or drive to local shop with wireless
        and click away
A Practical Application
●   My phone has a built in camera and
    email client
●   I could take pictures and email them to
    myself with a description, and post from
    home
●   That's repeating myself though, and too
    much work
A Practical Application
●   A Qpsmtpd plugin to solve this problem?
●   It came down to being Lazy
●   Being able to post an item at will is
    preferable to batching transactions
●   Bonus points for a per item picture,
    response rates for items with pictures
    are much higher than without
A Waste of Time?
●   At 3 minutes overhead per item the
    transaction overhead is 7.5 hours for
    150 items
●   At 30 seconds overhead per item the
    transaction overhead is 75 minutes for
    150 items
●   Total time spent thinking, coding,
    testing and deploying was about 3 hours
●   Bonus points for writing fun code!
The Source
  ●   Initialization
use WWW::Mechanize;
use Data::Dumper;

sub init {
  my ($self, $qp, %args) = @_;
  $self->{_args} = %args;
  $self->{_mech} = WWW::Mechanize->new;
  $self->log(LOGDEBUG, “Craigslist plugin init: n” .
   Dumper(%args));
}
The Source
 ● Start processing after all data is received
 ● Check authorization first



sub hook_data_post {
 my ($self, $transaction) = @_;

 return DECLINED unless
  (($transaction->recipients->[0]->address eq
    $self->{_args}->{recipient})
  && $self->qp->connection->relay_client);
The Source
   ●   Get the subject and body

my $subject = $transaction->header->get('Subject');
my $body;
while ( my $line = $transaction->body_getline ) {
  $body .= $line;
}
use Email::MIME;
my $em = Email::MIME->new($subject . $body);
The Source
 ●   Get the attached images and save them
use Email::MIME::Attachment::Stripper;
my $stripper =
  Email::MIME::Attachment::Stripper->new($em);
my $attachments = $stripper->attachments;
if (@attachments) {
  foreach my $at (@attachments) {
    my $fh;
    open($fh, “>”, “/tmp/” . $at->{filename}) || die $!;
    print $fh $at->{payload};
    close($fh);
  }
}
The Source
   ●   Login to http://www.craigslist.org
$self->{_mech}->get($self->{_args}->{site});
$self->{_mech}->submit_form(
  form_name => “login”,
  fields => {
    inputEmailHandle => $self->{_args}->{login},
    inputPassword     => $self->{_args}->{password}
  });
if (! $self->{_mech}->success ) {
  $transaction->body_write(“Error during login”);
  return DECLINED;
}
The Source
   ●   Login to www.craigslist.org
$self->{_mech}->get($self->{_args}->{site});
$self->{_mech}->submit_form(
  form_name => “login”,
  fields => {
    inputEmailHandle => $self->{_args}->{login},
    inputPassword     => $self->{_args}->{password}
  });
if (! $self->{_mech}->success ) {
  $transaction->body_write(“Error during login”);
  return DECLINED;
}
The Source
     ●   Walk the website

$self->{_mech}->follow_link(
  text_regex => qr/wanted/ );
if (! $self->{_mech}->success ) {
  $transaction->body_write(“Error following wanted link”);
  return DECLINED;
}

# ... click through a few more links to get to ad posting
The Source
  ●   Post the ad
$self->{_mech}->submit_form(
  form_number => 1,
  button => 'imagesForm',
  fields => {
    PostingTitle => $subject,
    PostingBody => $body,
    Ask          => 0,
  });
if (! $self->{_mech}->success) {
  $transaction->body_write(“Error, could not post ad”);
  return DECLINED;
}
The Source
 ●   Post the images
foreach my $at (@attachments) {
  $self->{_mech}->submit_form(
    form_number => 1,
    fields => { file1 => '/tmp/' . $at->{filename} }
  );
  if (! $self->{_mech}->success) {
    $transaction->write_body(
      “Error adding image “ . $at->{filename});
    return DECLINED;
  }
  unlink('/tmp/' . $at->{filename});
}
We're done
●   Grab the PDA
●   Take a picture
●   Compose an email
●   Receive a flood of responses
    ( still need to write that part of the app )
Perl did the work
●   No clicking (except taking the photo)
●   No dealing with a cumbersome web
    based application
●   Our energy goes to where it's needed most
●   All we had to do was code up a defined process
Recommended API Practices
●   Run your application last after all other
    plugins, before the queue plugin

●   Forward the email to the sender as a
    receipt

●   Use a separate To: address for each app,
    one that isn't vulnerable to dictionary attacks
Giving feedback to the User
●   Indicate success or failure
●   Let them know why it failed -
    $transaction->write_body(“Why it failed”);
●   Be strict in what you accept – the spammers
    will find your openings eventually
Recommended AAA Approaches
●   Require users to authenticate via SMTP auth
    - as secure as normal SMTP transactions
    $self->qp->connection->relay_client == 1
●   Combine username with To: address and
    match that against sender address, fairly
    secure but not unbreakable
    To: fred_craigslist@domain.com,
    From: fred@fredsdomain.com
●   Greylisting can help here but remember
    that zombies can retry with dictionary attacks
Recommended AAA Approaches
●   Require the user register their email address
    and verify they are a real person
●   Don't use a password in the email -
    most users have one password and will
    blissfully use it here as well
●   Use good judgement in weighing ease of
    use vs. security in authentication – err on
    the side of security.
Recommended AAA Approaches
 ●   Don't use this approach to build secure
     apps unless you _really_ know what you
     are doing. Better yet, just don't do it.
 ●   Don't send sensitive information in plain
     text email
 ●   This approach is about making automated
     tasks easy from insecure clients (PDAs).
     Proceed as such.
More Ideas
●   Reply to those annoying “DO NOT REPLY”
    emails from Bugzilla, et al.
●   Check the weather
●   Check the traffic report
●   Next bus
●   Post to a picture blog from your PDA
●   Any process that is repeatable and boring
Credits
●   The Qpsmtpd community

●   Ask Bjørn Hansen for authoring Qpsmtpd

●   Matt Sergeant and Robert Spier for
    listening to my crazy ideas on #qpsmtpd
References
[1] – Using Qpsmtpd, Matt Sergeant
http://www.oreillynet.com/pub/a/sysadmin/2005/09/15/qpsmtpd.html

[2] – The Qpsmtpd Wiki
http://wiki.qpsmtpd.org

[3] – SWAKS
http://jetmore.org/john/code/#swaks
Slides

These slides are freely available at

 http://www.redhotpenguin.com/talks


       Thank you NPW 2006!

Mais conteúdo relacionado

Mais procurados

Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSHannes Hapke
 
Crafting Quality PHP Applications (ConFoo YVR 2017)
Crafting Quality PHP Applications (ConFoo YVR 2017)Crafting Quality PHP Applications (ConFoo YVR 2017)
Crafting Quality PHP Applications (ConFoo YVR 2017)James Titcumb
 
Cucumber Ru09 Web
Cucumber Ru09 WebCucumber Ru09 Web
Cucumber Ru09 WebJoseph Wilk
 
[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress DevelopmentAdam Tomat
 
Dip Your Toes in the Sea of Security (ConFoo YVR 2017)
Dip Your Toes in the Sea of Security (ConFoo YVR 2017)Dip Your Toes in the Sea of Security (ConFoo YVR 2017)
Dip Your Toes in the Sea of Security (ConFoo YVR 2017)James Titcumb
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecturepostrational
 
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)James Titcumb
 
Webinar: AngularJS and the WordPress REST API
Webinar: AngularJS and the WordPress REST APIWebinar: AngularJS and the WordPress REST API
Webinar: AngularJS and the WordPress REST APIWP Engine UK
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackIgnacio Martín
 
Crafting Quality PHP Applications (PHP Benelux 2018)
Crafting Quality PHP Applications (PHP Benelux 2018)Crafting Quality PHP Applications (PHP Benelux 2018)
Crafting Quality PHP Applications (PHP Benelux 2018)James Titcumb
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceJesse Vincent
 
Thymeleaf Introduction
Thymeleaf IntroductionThymeleaf Introduction
Thymeleaf IntroductionAnthony Chen
 

Mais procurados (20)

Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJS
 
AJAX Transport Layer
AJAX Transport LayerAJAX Transport Layer
AJAX Transport Layer
 
Crafting Quality PHP Applications (ConFoo YVR 2017)
Crafting Quality PHP Applications (ConFoo YVR 2017)Crafting Quality PHP Applications (ConFoo YVR 2017)
Crafting Quality PHP Applications (ConFoo YVR 2017)
 
Cucumber Ru09 Web
Cucumber Ru09 WebCucumber Ru09 Web
Cucumber Ru09 Web
 
[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development
 
jQuery
jQueryjQuery
jQuery
 
Dip Your Toes in the Sea of Security (ConFoo YVR 2017)
Dip Your Toes in the Sea of Security (ConFoo YVR 2017)Dip Your Toes in the Sea of Security (ConFoo YVR 2017)
Dip Your Toes in the Sea of Security (ConFoo YVR 2017)
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
Kicking off with Zend Expressive and Doctrine ORM (ConFoo YVR 2017)
 
Django
DjangoDjango
Django
 
Webinar: AngularJS and the WordPress REST API
Webinar: AngularJS and the WordPress REST APIWebinar: AngularJS and the WordPress REST API
Webinar: AngularJS and the WordPress REST API
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
WCLV13 JavaScript
WCLV13 JavaScriptWCLV13 JavaScript
WCLV13 JavaScript
 
RSpec 2 Best practices
RSpec 2 Best practicesRSpec 2 Best practices
RSpec 2 Best practices
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
 
Keeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and WebpackKeeping the frontend under control with Symfony and Webpack
Keeping the frontend under control with Symfony and Webpack
 
Ruby gems
Ruby gemsRuby gems
Ruby gems
 
Crafting Quality PHP Applications (PHP Benelux 2018)
Crafting Quality PHP Applications (PHP Benelux 2018)Crafting Quality PHP Applications (PHP Benelux 2018)
Crafting Quality PHP Applications (PHP Benelux 2018)
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
 
Thymeleaf Introduction
Thymeleaf IntroductionThymeleaf Introduction
Thymeleaf Introduction
 

Semelhante a Qpsmtpd

PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principlesPerl Careers
 
4.7 Automate Loading Data with Little to No Duplicates!
4.7 Automate Loading Data with Little to No Duplicates!4.7 Automate Loading Data with Little to No Duplicates!
4.7 Automate Loading Data with Little to No Duplicates!TargetX
 
Optimizing AngularJS Application
Optimizing AngularJS ApplicationOptimizing AngularJS Application
Optimizing AngularJS ApplicationMd. Ziaul Haq
 
PHP SA 2014 - Releasing Your Open Source Project
PHP SA 2014 - Releasing Your Open Source ProjectPHP SA 2014 - Releasing Your Open Source Project
PHP SA 2014 - Releasing Your Open Source Projectxsist10
 
Modern Perl Web Development with Dancer
Modern Perl Web Development with DancerModern Perl Web Development with Dancer
Modern Perl Web Development with DancerDave Cross
 
PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)xSawyer
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 
PHP BASIC PRESENTATION
PHP BASIC PRESENTATIONPHP BASIC PRESENTATION
PHP BASIC PRESENTATIONkrutitrivedi
 
Apache Dispatch
Apache DispatchApache Dispatch
Apache DispatchFred Moyer
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::ManagerJay Shirley
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hopeMarcus Ramberg
 
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James WilliamsSF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James WilliamsPhilip Stehlik
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Jonathan Felch
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Creating a Mature Puppet System
Creating a Mature Puppet SystemCreating a Mature Puppet System
Creating a Mature Puppet SystemPuppet
 

Semelhante a Qpsmtpd (20)

Modern Perl
Modern PerlModern Perl
Modern Perl
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
4.7 Automate Loading Data with Little to No Duplicates!
4.7 Automate Loading Data with Little to No Duplicates!4.7 Automate Loading Data with Little to No Duplicates!
4.7 Automate Loading Data with Little to No Duplicates!
 
Optimizing AngularJS Application
Optimizing AngularJS ApplicationOptimizing AngularJS Application
Optimizing AngularJS Application
 
PHP SA 2014 - Releasing Your Open Source Project
PHP SA 2014 - Releasing Your Open Source ProjectPHP SA 2014 - Releasing Your Open Source Project
PHP SA 2014 - Releasing Your Open Source Project
 
Modern Perl Web Development with Dancer
Modern Perl Web Development with DancerModern Perl Web Development with Dancer
Modern Perl Web Development with Dancer
 
PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)PerlDancer for Perlers (FOSDEM 2011)
PerlDancer for Perlers (FOSDEM 2011)
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
PHP BASIC PRESENTATION
PHP BASIC PRESENTATIONPHP BASIC PRESENTATION
PHP BASIC PRESENTATION
 
Apache Dispatch
Apache DispatchApache Dispatch
Apache Dispatch
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::Manager
 
Drupal 8 migrate!
Drupal 8 migrate!Drupal 8 migrate!
Drupal 8 migrate!
 
Mojolicious - A new hope
Mojolicious - A new hopeMojolicious - A new hope
Mojolicious - A new hope
 
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James WilliamsSF Grails - Ratpack - Compact Groovy Webapps - James Williams
SF Grails - Ratpack - Compact Groovy Webapps - James Williams
 
Tatsumaki
TatsumakiTatsumaki
Tatsumaki
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
WordPress APIs
WordPress APIsWordPress APIs
WordPress APIs
 
Creating a Mature Puppet System
Creating a Mature Puppet SystemCreating a Mature Puppet System
Creating a Mature Puppet System
 

Mais de Fred Moyer

Reliable observability at scale: Error Budgets for 1,000+
Reliable observability at scale: Error Budgets for 1,000+Reliable observability at scale: Error Budgets for 1,000+
Reliable observability at scale: Error Budgets for 1,000+Fred Moyer
 
Practical service level objectives with error budgeting
Practical service level objectives with error budgetingPractical service level objectives with error budgeting
Practical service level objectives with error budgetingFred Moyer
 
SREcon americas 2019 - Latency SLOs Done Right
SREcon americas 2019 - Latency SLOs Done RightSREcon americas 2019 - Latency SLOs Done Right
SREcon americas 2019 - Latency SLOs Done RightFred Moyer
 
Scale17x - Latency SLOs Done Right
Scale17x - Latency SLOs Done RightScale17x - Latency SLOs Done Right
Scale17x - Latency SLOs Done RightFred Moyer
 
Latency SLOs Done Right
Latency SLOs Done RightLatency SLOs Done Right
Latency SLOs Done RightFred Moyer
 
Latency SLOs done right
Latency SLOs done rightLatency SLOs done right
Latency SLOs done rightFred Moyer
 
Comprehensive Container Based Service Monitoring with Kubernetes and Istio
Comprehensive Container Based Service Monitoring with Kubernetes and IstioComprehensive Container Based Service Monitoring with Kubernetes and Istio
Comprehensive Container Based Service Monitoring with Kubernetes and IstioFred Moyer
 
Comprehensive container based service monitoring with kubernetes and istio
Comprehensive container based service monitoring with kubernetes and istioComprehensive container based service monitoring with kubernetes and istio
Comprehensive container based service monitoring with kubernetes and istioFred Moyer
 
Effective management of high volume numeric data with histograms
Effective management of high volume numeric data with histogramsEffective management of high volume numeric data with histograms
Effective management of high volume numeric data with histogramsFred Moyer
 
Statistics for dummies
Statistics for dummiesStatistics for dummies
Statistics for dummiesFred Moyer
 
GrafanaCon EU 2018
GrafanaCon EU 2018GrafanaCon EU 2018
GrafanaCon EU 2018Fred Moyer
 
Fredmoyer postgresopen 2017
Fredmoyer postgresopen 2017Fredmoyer postgresopen 2017
Fredmoyer postgresopen 2017Fred Moyer
 
Better service monitoring through histograms sv perl 09012016
Better service monitoring through histograms sv perl 09012016Better service monitoring through histograms sv perl 09012016
Better service monitoring through histograms sv perl 09012016Fred Moyer
 
Better service monitoring through histograms
Better service monitoring through histogramsBetter service monitoring through histograms
Better service monitoring through histogramsFred Moyer
 
The Breakup - Logically Sharding a Growing PostgreSQL Database
The Breakup - Logically Sharding a Growing PostgreSQL DatabaseThe Breakup - Logically Sharding a Growing PostgreSQL Database
The Breakup - Logically Sharding a Growing PostgreSQL DatabaseFred Moyer
 
Learning go for perl programmers
Learning go for perl programmersLearning go for perl programmers
Learning go for perl programmersFred Moyer
 
Surge 2012 fred_moyer_lightning
Surge 2012 fred_moyer_lightningSurge 2012 fred_moyer_lightning
Surge 2012 fred_moyer_lightningFred Moyer
 
Ball Of Mud Yapc 2008
Ball Of Mud Yapc 2008Ball Of Mud Yapc 2008
Ball Of Mud Yapc 2008Fred Moyer
 
Data::FormValidator Simplified
Data::FormValidator SimplifiedData::FormValidator Simplified
Data::FormValidator SimplifiedFred Moyer
 

Mais de Fred Moyer (19)

Reliable observability at scale: Error Budgets for 1,000+
Reliable observability at scale: Error Budgets for 1,000+Reliable observability at scale: Error Budgets for 1,000+
Reliable observability at scale: Error Budgets for 1,000+
 
Practical service level objectives with error budgeting
Practical service level objectives with error budgetingPractical service level objectives with error budgeting
Practical service level objectives with error budgeting
 
SREcon americas 2019 - Latency SLOs Done Right
SREcon americas 2019 - Latency SLOs Done RightSREcon americas 2019 - Latency SLOs Done Right
SREcon americas 2019 - Latency SLOs Done Right
 
Scale17x - Latency SLOs Done Right
Scale17x - Latency SLOs Done RightScale17x - Latency SLOs Done Right
Scale17x - Latency SLOs Done Right
 
Latency SLOs Done Right
Latency SLOs Done RightLatency SLOs Done Right
Latency SLOs Done Right
 
Latency SLOs done right
Latency SLOs done rightLatency SLOs done right
Latency SLOs done right
 
Comprehensive Container Based Service Monitoring with Kubernetes and Istio
Comprehensive Container Based Service Monitoring with Kubernetes and IstioComprehensive Container Based Service Monitoring with Kubernetes and Istio
Comprehensive Container Based Service Monitoring with Kubernetes and Istio
 
Comprehensive container based service monitoring with kubernetes and istio
Comprehensive container based service monitoring with kubernetes and istioComprehensive container based service monitoring with kubernetes and istio
Comprehensive container based service monitoring with kubernetes and istio
 
Effective management of high volume numeric data with histograms
Effective management of high volume numeric data with histogramsEffective management of high volume numeric data with histograms
Effective management of high volume numeric data with histograms
 
Statistics for dummies
Statistics for dummiesStatistics for dummies
Statistics for dummies
 
GrafanaCon EU 2018
GrafanaCon EU 2018GrafanaCon EU 2018
GrafanaCon EU 2018
 
Fredmoyer postgresopen 2017
Fredmoyer postgresopen 2017Fredmoyer postgresopen 2017
Fredmoyer postgresopen 2017
 
Better service monitoring through histograms sv perl 09012016
Better service monitoring through histograms sv perl 09012016Better service monitoring through histograms sv perl 09012016
Better service monitoring through histograms sv perl 09012016
 
Better service monitoring through histograms
Better service monitoring through histogramsBetter service monitoring through histograms
Better service monitoring through histograms
 
The Breakup - Logically Sharding a Growing PostgreSQL Database
The Breakup - Logically Sharding a Growing PostgreSQL DatabaseThe Breakup - Logically Sharding a Growing PostgreSQL Database
The Breakup - Logically Sharding a Growing PostgreSQL Database
 
Learning go for perl programmers
Learning go for perl programmersLearning go for perl programmers
Learning go for perl programmers
 
Surge 2012 fred_moyer_lightning
Surge 2012 fred_moyer_lightningSurge 2012 fred_moyer_lightning
Surge 2012 fred_moyer_lightning
 
Ball Of Mud Yapc 2008
Ball Of Mud Yapc 2008Ball Of Mud Yapc 2008
Ball Of Mud Yapc 2008
 
Data::FormValidator Simplified
Data::FormValidator SimplifiedData::FormValidator Simplified
Data::FormValidator Simplified
 

Último

COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationIES VE
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarPrecisely
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.YounusS2
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Brian Pichman
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 

Último (20)

COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve DecarbonizationUsing IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
Using IESVE for Loads, Sizing and Heat Pump Modeling to Achieve Decarbonization
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
AI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity WebinarAI You Can Trust - Ensuring Success with Data Integrity Webinar
AI You Can Trust - Ensuring Success with Data Integrity Webinar
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 

Qpsmtpd

  • 1. Writing Applications with Qpsmtpd Fred Moyer fred@redhotpenguin.com
  • 2. Qpsmtpd ● Perl SMTP daemon written by Ask Bjørn Hansen ● “mod_perl” of smtp ● Plugin API makes writing extensions fun ● Works with Qmail, Postfix, and Exim ● Stock plugins include spam and virus protection ● If you've tried to extend a C based smtp daemon you've felt pain at some point
  • 3. Setting it up ● Read the article by Matt Sergeant [1] ● Install using RPMs if you can http://wiki.qpsmtpd.org/rpm-install_howto ● Installing from source is easy also http://wiki.qpsmtpd.org/quick-install_howto ● Telnetting to port 25 works for testing... ● SWAKS is your friend [3] ● qpsmtpd@perl.org is also your friend
  • 4. My config file /home/smtpd/qpsmtpd/config/plugins auth/auth_vpopmail_sql # set db auth in the plugin code denysoft_greylist redhotpenguin.com taperfriendlymusic.org quit_fortune check_earlytalker count_unrecognized_commands 4 check_relay # require_resolvable_fromhost # ^^ enable this to prevent zombies check_delivery normal 1 127.0.0.1 vppmail dbuser dbpass
  • 5. My config file /home/smtpd/qpsmtpd/config/plugins # rhsbl <- these blacklist plugins blacklist # dnsbl <- yahoo.com et al. sometimes! check_badmailfrom check_badrcptto check_spamhelo # sender_permitted_from rcpt_ok # this is the last rcpt plugin
  • 6. My config file /home/smtpd/qpsmtpd/config/plugins virus/klez_filter spamassassin reject_threshold 20 munge_subject_threshold 5 virus/clamav # here is my first qpsmtpd application craigslist recipient craig_qp@redhotpenguin.com site http://www.craigslist.org login fred@redhotpenguin.com password fredspass queue/qmail-queue # leave enabled to forward the email
  • 7. Many plugins available ● http://wiki.qpsmtpd.org/plugins ● Spam ● Virus ● Authentication – Vpopmail, PAM, text file, LDAP... ● Plugins are generally geared towards keeping the spam out, and letting the good mail through
  • 8. Your first plugin ● Start with good examples ● Read Matt Sergeant's O'reilly article [1] ● Read the source for existing plugins ● perldoc README.plugins ;)
  • 9. A simple subject filter ● Spam filters don't catch everything block_subject [ all | [ domain1, domain2 ... ] ] sub init { my ($self, $qp, @domains) = @_; unless (defined $domains[0]) { die “block_subject needs proper confign”; } $self->{_args}->{domains} = @domains; my $content = <<”SUBJECTS”; YOUR REPRESENTATIVE ASSISTANCE IS NEEDED Message From eBay Member The Ultimate Online Pharmaceutical SUBJECTS
  • 10. A simple subject filter my @subjects = split(“n”, $block_content); $self->{_args}->{subjects} = @subjects; $self->log(LOGDEBUG, “Blocking subjects $block_content”); } sub hook_data_post { my ($self, $transaction) = @_; if ($self->{_args}->{domains}->[0] eq 'all') { if ($self->_blocked_subject($transaction)) { return DENY; } } else {
  • 11. A simple subject filter # Check each domain my @recip_domains = map { $_->host } $transaction->recipients; foreach my $domain (@recip_domains) { # Deny the email if the subject is in our blacklist if (grep { $_ =~ m/^$domain$/ } @{$self->{_args}->{domains} && $self->blocked_subject($transaction)) { return DENY; } } } return DECLINED; }
  • 12. A simple subject filter sub blocked_subject { my ($self, $transaction) = @_; my $subject = $transaction->header->get('Subject'); chomp($subject); if (grep { $_ =~ m/$subject$/i } @{$self->{_args}->{subjects}}) { $self->log(LOGINFO, “block_subject invoked for $subject”); return 1; } return; }
  • 13. SMTP Applications? ● SMTP to HTTP Gateways ● Automate tedious processes ● Use emails to interact with applications ● Today's PDAs have IMAP based email but aren't very good at serving web pages
  • 14. A Practical Application ● The problem at hand ● A couple hundred things we couldn't sell ● Throwing away is bad for the environment (and costs money) ● http://www.craigslist.org - someone wants it ● But taking a picture of everything and posting an ad to Craigslist is a lot of clicking ● I don't like to click, I like to write Perl
  • 15. A Practical Application ● Possible solutions ● No internet connection ● I could make a list of the items at hand ● Call a friend and have him post ( no images though, and one less friend ) ● Or drive to local shop with wireless and click away
  • 16. A Practical Application ● My phone has a built in camera and email client ● I could take pictures and email them to myself with a description, and post from home ● That's repeating myself though, and too much work
  • 17. A Practical Application ● A Qpsmtpd plugin to solve this problem? ● It came down to being Lazy ● Being able to post an item at will is preferable to batching transactions ● Bonus points for a per item picture, response rates for items with pictures are much higher than without
  • 18. A Waste of Time? ● At 3 minutes overhead per item the transaction overhead is 7.5 hours for 150 items ● At 30 seconds overhead per item the transaction overhead is 75 minutes for 150 items ● Total time spent thinking, coding, testing and deploying was about 3 hours ● Bonus points for writing fun code!
  • 19. The Source ● Initialization use WWW::Mechanize; use Data::Dumper; sub init { my ($self, $qp, %args) = @_; $self->{_args} = %args; $self->{_mech} = WWW::Mechanize->new; $self->log(LOGDEBUG, “Craigslist plugin init: n” . Dumper(%args)); }
  • 20. The Source ● Start processing after all data is received ● Check authorization first sub hook_data_post { my ($self, $transaction) = @_; return DECLINED unless (($transaction->recipients->[0]->address eq $self->{_args}->{recipient}) && $self->qp->connection->relay_client);
  • 21. The Source ● Get the subject and body my $subject = $transaction->header->get('Subject'); my $body; while ( my $line = $transaction->body_getline ) { $body .= $line; } use Email::MIME; my $em = Email::MIME->new($subject . $body);
  • 22. The Source ● Get the attached images and save them use Email::MIME::Attachment::Stripper; my $stripper = Email::MIME::Attachment::Stripper->new($em); my $attachments = $stripper->attachments; if (@attachments) { foreach my $at (@attachments) { my $fh; open($fh, “>”, “/tmp/” . $at->{filename}) || die $!; print $fh $at->{payload}; close($fh); } }
  • 23. The Source ● Login to http://www.craigslist.org $self->{_mech}->get($self->{_args}->{site}); $self->{_mech}->submit_form( form_name => “login”, fields => { inputEmailHandle => $self->{_args}->{login}, inputPassword => $self->{_args}->{password} }); if (! $self->{_mech}->success ) { $transaction->body_write(“Error during login”); return DECLINED; }
  • 24. The Source ● Login to www.craigslist.org $self->{_mech}->get($self->{_args}->{site}); $self->{_mech}->submit_form( form_name => “login”, fields => { inputEmailHandle => $self->{_args}->{login}, inputPassword => $self->{_args}->{password} }); if (! $self->{_mech}->success ) { $transaction->body_write(“Error during login”); return DECLINED; }
  • 25. The Source ● Walk the website $self->{_mech}->follow_link( text_regex => qr/wanted/ ); if (! $self->{_mech}->success ) { $transaction->body_write(“Error following wanted link”); return DECLINED; } # ... click through a few more links to get to ad posting
  • 26. The Source ● Post the ad $self->{_mech}->submit_form( form_number => 1, button => 'imagesForm', fields => { PostingTitle => $subject, PostingBody => $body, Ask => 0, }); if (! $self->{_mech}->success) { $transaction->body_write(“Error, could not post ad”); return DECLINED; }
  • 27. The Source ● Post the images foreach my $at (@attachments) { $self->{_mech}->submit_form( form_number => 1, fields => { file1 => '/tmp/' . $at->{filename} } ); if (! $self->{_mech}->success) { $transaction->write_body( “Error adding image “ . $at->{filename}); return DECLINED; } unlink('/tmp/' . $at->{filename}); }
  • 28. We're done ● Grab the PDA ● Take a picture ● Compose an email ● Receive a flood of responses ( still need to write that part of the app )
  • 29. Perl did the work ● No clicking (except taking the photo) ● No dealing with a cumbersome web based application ● Our energy goes to where it's needed most ● All we had to do was code up a defined process
  • 30. Recommended API Practices ● Run your application last after all other plugins, before the queue plugin ● Forward the email to the sender as a receipt ● Use a separate To: address for each app, one that isn't vulnerable to dictionary attacks
  • 31. Giving feedback to the User ● Indicate success or failure ● Let them know why it failed - $transaction->write_body(“Why it failed”); ● Be strict in what you accept – the spammers will find your openings eventually
  • 32. Recommended AAA Approaches ● Require users to authenticate via SMTP auth - as secure as normal SMTP transactions $self->qp->connection->relay_client == 1 ● Combine username with To: address and match that against sender address, fairly secure but not unbreakable To: fred_craigslist@domain.com, From: fred@fredsdomain.com ● Greylisting can help here but remember that zombies can retry with dictionary attacks
  • 33. Recommended AAA Approaches ● Require the user register their email address and verify they are a real person ● Don't use a password in the email - most users have one password and will blissfully use it here as well ● Use good judgement in weighing ease of use vs. security in authentication – err on the side of security.
  • 34. Recommended AAA Approaches ● Don't use this approach to build secure apps unless you _really_ know what you are doing. Better yet, just don't do it. ● Don't send sensitive information in plain text email ● This approach is about making automated tasks easy from insecure clients (PDAs). Proceed as such.
  • 35. More Ideas ● Reply to those annoying “DO NOT REPLY” emails from Bugzilla, et al. ● Check the weather ● Check the traffic report ● Next bus ● Post to a picture blog from your PDA ● Any process that is repeatable and boring
  • 36. Credits ● The Qpsmtpd community ● Ask Bjørn Hansen for authoring Qpsmtpd ● Matt Sergeant and Robert Spier for listening to my crazy ideas on #qpsmtpd
  • 37. References [1] – Using Qpsmtpd, Matt Sergeant http://www.oreillynet.com/pub/a/sysadmin/2005/09/15/qpsmtpd.html [2] – The Qpsmtpd Wiki http://wiki.qpsmtpd.org [3] – SWAKS http://jetmore.org/john/code/#swaks
  • 38. Slides These slides are freely available at http://www.redhotpenguin.com/talks Thank you NPW 2006!