Improve support for listening to multiple ports and/or multiple IP addresses.
Document using plugins/tls to handle SMTPS (port 465). git-svn-id: https://svn.perl.org/qpsmtpd/branches/0.3x@625 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
2c683f22ef
commit
4a824a2e7d
10
plugins/tls
10
plugins/tls
@ -12,7 +12,15 @@ tls - plugin to support STARTTLS
|
|||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
This plugin implements basic TLS support.
|
This plugin implements basic TLS support. It can also be used to support
|
||||||
|
port 465 (SMTP over SSL), but only with qpsmtpd-forkserver. In this case,
|
||||||
|
be sure to load plugins/tls before any other connect plugins and start
|
||||||
|
qpsmtpd like this:
|
||||||
|
|
||||||
|
qpsmtpd-forkserver --port 25 --port 465
|
||||||
|
|
||||||
|
You can also specify multiple --listen-address options as well; see the help
|
||||||
|
for qpsmtpd-forkserver for more details.
|
||||||
|
|
||||||
If TLS is successfully negotiated then the C<tls_enabled> field in the
|
If TLS is successfully negotiated then the C<tls_enabled> field in the
|
||||||
Connection notes is set. If you wish to make TLS mandatory you should check
|
Connection notes is set. If you wish to make TLS mandatory you should check
|
||||||
|
@ -19,7 +19,7 @@ $| = 1;
|
|||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
my $MAXCONN = 15; # max simultaneous connections
|
my $MAXCONN = 15; # max simultaneous connections
|
||||||
my $PORT = 2525; # port number
|
my @PORT; # port number(s)
|
||||||
my @LOCALADDR; # ip address(es) to bind to
|
my @LOCALADDR; # ip address(es) to bind to
|
||||||
my $USER = 'smtpd'; # user to suid to
|
my $USER = 'smtpd'; # user to suid to
|
||||||
my $MAXCONNIP = 5; # max simultaneous connections from one IP
|
my $MAXCONNIP = 5; # max simultaneous connections from one IP
|
||||||
@ -31,8 +31,9 @@ sub usage {
|
|||||||
usage: qpsmtpd-forkserver [ options ]
|
usage: qpsmtpd-forkserver [ options ]
|
||||||
-l, --listen-address addr : listen on specific address(es); can be specified
|
-l, --listen-address addr : listen on specific address(es); can be specified
|
||||||
multiple times for multiple bindings. Default is
|
multiple times for multiple bindings. Default is
|
||||||
0.0.0.0 (all interfaces).
|
0.0.0.0 (all interfaces).
|
||||||
-p, --port P : listen on a specific port; default 2525
|
-p, --port P : listen on a specific port; default 2525; can be
|
||||||
|
specified multiple times for multiple bindings.
|
||||||
-c, --limit-connections N : limit concurrent connections to N; default 15
|
-c, --limit-connections N : limit concurrent connections to N; default 15
|
||||||
-u, --user U : run as a particular user (default 'smtpd')
|
-u, --user U : run as a particular user (default 'smtpd')
|
||||||
-m, --max-from-ip M : limit connections from a single IP; default 5
|
-m, --max-from-ip M : limit connections from a single IP; default 5
|
||||||
@ -46,22 +47,36 @@ GetOptions('h|help' => \&usage,
|
|||||||
'l|listen-address=s' => \@LOCALADDR,
|
'l|listen-address=s' => \@LOCALADDR,
|
||||||
'c|limit-connections=i' => \$MAXCONN,
|
'c|limit-connections=i' => \$MAXCONN,
|
||||||
'm|max-from-ip=i' => \$MAXCONNIP,
|
'm|max-from-ip=i' => \$MAXCONNIP,
|
||||||
'p|port=i' => \$PORT,
|
'p|port=s' => \@PORT,
|
||||||
'u|user=s' => \$USER,
|
'u|user=s' => \$USER,
|
||||||
'pid-file=s' => \$PID_FILE,
|
'pid-file=s' => \$PID_FILE,
|
||||||
'd|detach' => \$DETACH,
|
'd|detach' => \$DETACH,
|
||||||
) || &usage;
|
) || &usage;
|
||||||
|
|
||||||
# detaint the commandline
|
# detaint the commandline
|
||||||
if ($PORT =~ /^(\d+)$/) { $PORT = $1 } else { &usage }
|
|
||||||
@LOCALADDR = ( '0.0.0.0' ) if !@LOCALADDR;
|
@LOCALADDR = ( '0.0.0.0' ) if !@LOCALADDR;
|
||||||
|
@PORT = ( 2525 ) if !@PORT;
|
||||||
|
|
||||||
|
my @LISTENADDR;
|
||||||
for (0..$#LOCALADDR) {
|
for (0..$#LOCALADDR) {
|
||||||
if ($LOCALADDR[$_] =~ /^([\d\w\-.]+)(?::(\d+))?$/) {
|
if ($LOCALADDR[$_] =~ /^([\d\w\-.]+)(?::(\d+))?$/) {
|
||||||
$LOCALADDR[$_] = { 'addr' => $1, 'port' => $2 || $PORT };
|
if ( defined $2 ) {
|
||||||
|
push @LISTENADDR, { 'addr' => $1, 'port' => $2 };
|
||||||
|
} else {
|
||||||
|
my $addr = $1;
|
||||||
|
for (0..$#PORT) {
|
||||||
|
if ( $PORT[$_] =~ /^(\d+)$/ ) {
|
||||||
|
push @LISTENADDR, { 'addr' => $addr, 'port' => $1 };
|
||||||
|
} else {
|
||||||
|
&usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
&usage;
|
&usage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { &usage }
|
if ($USER =~ /^([\w\-]+)$/) { $USER = $1 } else { &usage }
|
||||||
if ($MAXCONN =~ /^(\d+)$/) { $MAXCONN = $1 } else { &usage }
|
if ($MAXCONN =~ /^(\d+)$/) { $MAXCONN = $1 } else { &usage }
|
||||||
|
|
||||||
@ -93,7 +108,7 @@ $SIG{TERM} = \&HUNTSMAN;
|
|||||||
my $select = new IO::Select;
|
my $select = new IO::Select;
|
||||||
|
|
||||||
# establish SERVER socket(s), bind and listen.
|
# establish SERVER socket(s), bind and listen.
|
||||||
for my $listen_addr (@LOCALADDR) {
|
for my $listen_addr (@LISTENADDR) {
|
||||||
my $server = IO::Socket::INET->new(LocalPort => $listen_addr->{'port'},
|
my $server = IO::Socket::INET->new(LocalPort => $listen_addr->{'port'},
|
||||||
LocalAddr => $listen_addr->{'addr'},
|
LocalAddr => $listen_addr->{'addr'},
|
||||||
Proto => 'tcp',
|
Proto => 'tcp',
|
||||||
@ -137,7 +152,7 @@ my $groups = "$qgid $qgid";
|
|||||||
while (my ($name,$passwd,$gid,$members) = getgrent()) {
|
while (my ($name,$passwd,$gid,$members) = getgrent()) {
|
||||||
my @m = split(/ /, $members);
|
my @m = split(/ /, $members);
|
||||||
if (grep {$_ eq $USER} @m) {
|
if (grep {$_ eq $USER} @m) {
|
||||||
$groups .= " $gid";
|
$groups .= " $gid";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$) = $groups;
|
$) = $groups;
|
||||||
@ -149,13 +164,13 @@ $> = $quid;
|
|||||||
|
|
||||||
$qpsmtpd->load_plugins;
|
$qpsmtpd->load_plugins;
|
||||||
|
|
||||||
foreach my $local_addr ( @LOCALADDR ) {
|
foreach my $listen_addr ( @LISTENADDR ) {
|
||||||
::log(LOGINFO,"Listening on $local_addr->{'addr'}:$local_addr->{'port'}");
|
::log(LOGINFO,"Listening on $listen_addr->{'addr'}:$listen_addr->{'port'}");
|
||||||
}
|
}
|
||||||
::log(LOGINFO, 'Running as user '.
|
::log(LOGINFO, 'Running as user '.
|
||||||
(getpwuid($>) || $>) .
|
(getpwuid($>) || $>) .
|
||||||
', group '.
|
', group '.
|
||||||
(getgrgid($)) || $)));
|
(getgrgid($)) || $)));
|
||||||
|
|
||||||
if ($DETACH) {
|
if ($DETACH) {
|
||||||
open STDIN, '/dev/null' or die "/dev/null: $!";
|
open STDIN, '/dev/null' or die "/dev/null: $!";
|
||||||
@ -225,8 +240,8 @@ while (1) {
|
|||||||
my $pid = safe_fork();
|
my $pid = safe_fork();
|
||||||
if ($pid) {
|
if ($pid) {
|
||||||
# parent
|
# parent
|
||||||
$childstatus{$pid} = $iaddr; # add to table
|
$childstatus{$pid} = $iaddr; # add to table
|
||||||
# $childstatus{$pid} = 1; # add to table
|
# $childstatus{$pid} = 1; # add to table
|
||||||
$running++;
|
$running++;
|
||||||
close($client);
|
close($client);
|
||||||
next;
|
next;
|
||||||
|
Loading…
Reference in New Issue
Block a user