Red Hat Topics - Simple question - setting up services

This is Interesting: Free IT Magazines  
Home > Archive > Red Hat Topics > December 2004 > Simple question - setting up services





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Simple question - setting up services
justin.harper

2004-12-29, 2:45 am

I am trying to set up postfix using smtpprox as a proxy that will later
include a content filter, and it's working really well for me. The
only problem I'm having is that I'm new to linux, and I'm not totally
sure how I can start it so that it runs in the background like a
service. Right now, smtpprox is a PERL script, so what I'm doing is
starting postfix and then running 'smtpprox localhost:10025
localhost:10026' from the shell. The only problem is, when I launch it
this way, it locks up the shell (i.e. just the command, and then
nothing until I ctrl-c...but I know it's working because the email is
working fine when I run it this way). I was hoping that you could
please let me know what a better way to start it to run in the
background would be. Thanks for your help! For anyone not familiar
with smtpprox, I'll copy the script below.


#!/usr/bin/perl -w
#
# This code is Copyright (C) 2001 Morgan Stanley Dean Witter, and
# is distributed according to the terms of the GNU Public License
# as found at <URL:http://www.fsf.org/copyleft/gpl.html>.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Written by Bennett Todd <bet@rahul.net>

use strict;
use Getopt::Long;
use IO::File;
use lib '.';
use MSDW::SMTP::Server;
use MSDW::SMTP::Client;

=head1 NAME

smtprox -- Transparent SMTP proxy

=head1 SYNOPSIS

smtpprox [options] listen.addr:port talk.addr:port
options:
--children=16
--minperchild=100
--maxperchild=200
--debugtrace=filename_prefix

=head1 DESCRIPTION

smtpprox listens on the addr and port specified by its first arg,
and sends the traffic unmodified to the SMTP server whose addr and
port are listed as its second arg. The SMTP dialogue is propogated
literally, all commands from the client are copied to the server and
the responses from the server are copied back from to the client,
but the envelope info and message bodies are captured for analysis,
and code has the option of modifying the body before sending it on,
manipulating the envelope, or intervening in the SMTP dialogue to
reject senders, recipients, or content at the SMTP level. The
children option, defaulting to 16, allows adjusting how many child
processes will be maintained in the service pool. Each child will
kill itself after servicing some random number of messages between
minperchild and maxperchild (100-200 default), after which the
parent will immediately fork another child to pick up its share of
the load. If debugtrace is specified, the prefix will have the PID
appended to it for a separate logfile for each child, which will
capture all the SMTP dialogues that child services. It looks like a
snooper on the client side of the proxy. And if debugtracefile is
defined, it returns its own banner including its PID for debugging
at startup, otherwise it copies the server's banner back to the
client transparently.

=head1 EXAMPLE

smtpprox 127.0.0.1:10025 127.0.0.1:10026

=head1 WARNING

While the richness or lack thereof in the SMTP dialect spoken lies
in the hands of the next SMTP server down the chain, this proxy was
not designed to run on the front lines listening for traffic from
the internet; neither its performance characteristics nor its
paranoia were tuned for that role. Rather, it's designed as an
intermediate component, suitable for use as the framework for a
content-scanning proxy for use with Postfix's content-filtering
hooks.

=head1 PERFORMANCE NOTES

This proxy is tuned to some specific assumptions: execing PERL is
wickedly expensive, forking PERL is fairly expensive, messages will
vary rather widely in size, and memory footprint efficiency is
somewhat more important than CPU utilization. It uses Apache-style
preforking to almost entirely eliminate the need to fork perls,
with controlled child restart to defend against resource leaks in
children; it stores the body of the message in an unlinked file
under /tmp, which should be a tmpfs; this prevents the allocation
overhead associated with large strings (often 2-3x) and ensures that
space will be returned to the OS as soon as it's not needed.

=cut

my $syntax = "syntax: $0 [--children=16] [--minperchild=100] ".
"[--maxperchild=200] [--debugtrace=undef] ".
"listen.addr:port talk.addr:port\n";

my $children = 16;
my $minperchild = 100;
my $maxperchild = 200;
my $debugtrace = undef;
GetOptions("children=n" => \$children,
"minperchild=n" => \$minperchild,
"maxperchild=n" => \$maxperchild,
"debugtrace=s" => \$debugtrace) or die $syntax;

die $syntax unless @ARGV == 2;
my ($srcaddr, $srcport) = split /:/, $ARGV[0];
my ($dstaddr, $dstport) = split /:/, $ARGV[1];
die $syntax unless defined($srcport) and defined($dstport);

my $server = MSDW::SMTP::Server->new(interface => $srcaddr, port =>
$srcport);

# This should allow a kill on the parent to also blow away the
# children, I hope
my %children;
use vars qw($please_die);
$please_die = 0;
$SIG{TERM} = sub { $please_die = 1; };

# This block is the parent daemon, never does an accept, just herds
# a pool of children who accept and service connections, and
# occasionally kill themselves off
PARENT: while (1) {
while (scalar(keys %children) >= $children) {
my $child = wait;
delete $children{$child} if exists $children{$child};
if ($please_die) { kill 15, keys %children; exit 0; }
}
my $pid = fork;
die "$0: fork failed: $!\n" unless defined $pid;
last PARENT if $pid == 0;
$children{$pid} = 1;
select(undef, undef, undef, 0.1);
if ($please_die) { kill 15, keys %children; exit 0; }
}

# This block is a child service daemon. It inherited the bound
# socket created by SMTP::Server->new, it will service a random
# number of connection requests in [minperchild..maxperchild] then
# exit

my $lives = $minperchild + (rand($maxperchild - $minperchild));
my %opts;
if (defined $debugtrace) {
$opts{debug} = IO::File->new(">$debugtrace.$$");
$opts{debug}->autoflush(1);
}

while (1) {
$server->accept(%opts);
my $client = MSDW::SMTP::Client->new(interface => $dstaddr, port =>
$dstport);
my $banner = $client->hear;
$banner = "220 $debugtrace.$$" if defined $debugtrace;
$server->ok($banner);
while (my $what = $server->chat) {
if ($what eq '.') {
$client->yammer($server->{data});
} else {
$client->say($what);
}
$server->ok($client->hear);
}
$client = undef;
delete $server->{"s"};
exit 0 if $lives-- <= 0;
}

Reynolds McClatchey

2004-12-29, 5:45 pm

justin.harper wrote:
> I am trying to set up postfix using smtpprox as a proxy that will later
> include a content filter, and it's working really well for me. The
> only problem I'm having is that I'm new to linux, and I'm not totally
> sure how I can start it so that it runs in the background like a
> service. Right now, smtpprox is a PERL script, so what I'm doing is
> starting postfix and then running 'smtpprox localhost:10025
> localhost:10026' from the shell. The only problem is, when I launch it
> this way, it locks up the shell (i.e. just the command, and then
> nothing until I ctrl-c...but I know it's working because the email is
> working fine when I run it this way). I was hoping that you could
> please let me know what a better way to start it to run in the
> background would be. Thanks for your help! For anyone not familiar
> with smtpprox, I'll copy the script below.
>
>
> #!/usr/bin/perl -w
> #
> # This code is Copyright (C) 2001 Morgan Stanley Dean Witter, and
> # is distributed according to the terms of the GNU Public License
> # as found at <URL:http://www.fsf.org/copyleft/gpl.html>.
> #
> #
> # This program is distributed in the hope that it will be useful,
> # but WITHOUT ANY WARRANTY; without even the implied warranty of
> # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> # GNU General Public License for more details.
> #
> # Written by Bennett Todd <bet@rahul.net>
>
> use strict;
> use Getopt::Long;
> use IO::File;
> use lib '.';
> use MSDW::SMTP::Server;
> use MSDW::SMTP::Client;
>
> =head1 NAME
>
> smtprox -- Transparent SMTP proxy
>
> =head1 SYNOPSIS
>
> smtpprox [options] listen.addr:port talk.addr:port
> options:
> --children=16
> --minperchild=100
> --maxperchild=200
> --debugtrace=filename_prefix
>
> =head1 DESCRIPTION
>
> smtpprox listens on the addr and port specified by its first arg,
> and sends the traffic unmodified to the SMTP server whose addr and
> port are listed as its second arg. The SMTP dialogue is propogated
> literally, all commands from the client are copied to the server and
> the responses from the server are copied back from to the client,
> but the envelope info and message bodies are captured for analysis,
> and code has the option of modifying the body before sending it on,
> manipulating the envelope, or intervening in the SMTP dialogue to
> reject senders, recipients, or content at the SMTP level. The
> children option, defaulting to 16, allows adjusting how many child
> processes will be maintained in the service pool. Each child will
> kill itself after servicing some random number of messages between
> minperchild and maxperchild (100-200 default), after which the
> parent will immediately fork another child to pick up its share of
> the load. If debugtrace is specified, the prefix will have the PID
> appended to it for a separate logfile for each child, which will
> capture all the SMTP dialogues that child services. It looks like a
> snooper on the client side of the proxy. And if debugtracefile is
> defined, it returns its own banner including its PID for debugging
> at startup, otherwise it copies the server's banner back to the
> client transparently.
>
> =head1 EXAMPLE
>
> smtpprox 127.0.0.1:10025 127.0.0.1:10026
>
> =head1 WARNING
>
> While the richness or lack thereof in the SMTP dialect spoken lies
> in the hands of the next SMTP server down the chain, this proxy was
> not designed to run on the front lines listening for traffic from
> the internet; neither its performance characteristics nor its
> paranoia were tuned for that role. Rather, it's designed as an
> intermediate component, suitable for use as the framework for a
> content-scanning proxy for use with Postfix's content-filtering
> hooks.
>
> =head1 PERFORMANCE NOTES
>
> This proxy is tuned to some specific assumptions: execing PERL is
> wickedly expensive, forking PERL is fairly expensive, messages will
> vary rather widely in size, and memory footprint efficiency is
> somewhat more important than CPU utilization. It uses Apache-style
> preforking to almost entirely eliminate the need to fork perls,
> with controlled child restart to defend against resource leaks in
> children; it stores the body of the message in an unlinked file
> under /tmp, which should be a tmpfs; this prevents the allocation
> overhead associated with large strings (often 2-3x) and ensures that
> space will be returned to the OS as soon as it's not needed.
>
> =cut
>
> my $syntax = "syntax: $0 [--children=16] [--minperchild=100] ".
> "[--maxperchild=200] [--debugtrace=undef] ".
> "listen.addr:port talk.addr:port\n";
>
> my $children = 16;
> my $minperchild = 100;
> my $maxperchild = 200;
> my $debugtrace = undef;
> GetOptions("children=n" => \$children,
> "minperchild=n" => \$minperchild,
> "maxperchild=n" => \$maxperchild,
> "debugtrace=s" => \$debugtrace) or die $syntax;
>
> die $syntax unless @ARGV == 2;
> my ($srcaddr, $srcport) = split /:/, $ARGV[0];
> my ($dstaddr, $dstport) = split /:/, $ARGV[1];
> die $syntax unless defined($srcport) and defined($dstport);
>
> my $server = MSDW::SMTP::Server->new(interface => $srcaddr, port =>
> $srcport);
>
> # This should allow a kill on the parent to also blow away the
> # children, I hope
> my %children;
> use vars qw($please_die);
> $please_die = 0;
> $SIG{TERM} = sub { $please_die = 1; };
>
> # This block is the parent daemon, never does an accept, just herds
> # a pool of children who accept and service connections, and
> # occasionally kill themselves off
> PARENT: while (1) {
> while (scalar(keys %children) >= $children) {
> my $child = wait;
> delete $children{$child} if exists $children{$child};
> if ($please_die) { kill 15, keys %children; exit 0; }
> }
> my $pid = fork;
> die "$0: fork failed: $!\n" unless defined $pid;
> last PARENT if $pid == 0;
> $children{$pid} = 1;
> select(undef, undef, undef, 0.1);
> if ($please_die) { kill 15, keys %children; exit 0; }
> }
>
> # This block is a child service daemon. It inherited the bound
> # socket created by SMTP::Server->new, it will service a random
> # number of connection requests in [minperchild..maxperchild] then
> # exit
>
> my $lives = $minperchild + (rand($maxperchild - $minperchild));
> my %opts;
> if (defined $debugtrace) {
> $opts{debug} = IO::File->new(">$debugtrace.$$");
> $opts{debug}->autoflush(1);
> }
>
> while (1) {
> $server->accept(%opts);
> my $client = MSDW::SMTP::Client->new(interface => $dstaddr, port =>
> $dstport);
> my $banner = $client->hear;
> $banner = "220 $debugtrace.$$" if defined $debugtrace;
> $server->ok($banner);
> while (my $what = $server->chat) {
> if ($what eq '.') {
> $client->yammer($server->{data});
> } else {
> $client->say($what);
> }
> $server->ok($client->hear);
> }
> $client = undef;
> delete $server->{"s"};
> exit 0 if $lives-- <= 0;
> }
>

Here is how I start a daemon. Use /etc/rc.d/rc.local.
Consider su for the correct user. Add "&" at end of line.
=============rc.local=============================
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

cd /home/rey/downloads/popfile; /usr/bin/perl
/home/rey/downloads/popfile/popfile.pl&
====================end rc.local=============================

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com