
This document describes how to use popbsmtpd to allow email users to
send outbound mail through their home server when they are away from their local
network.
Table of Contents
WARNING: This is new software. While it has been written with security
in mind and has been tested, it has not yet endured the rigors of constant use
in multiple settings. Consider this before installing it on a valuable
production server. Note: After several hundred downloads, this warning is
probably less applicable now.
WARNING: Under some circumstances, this software is not suitable for
use on high-volume mail servers (where "high volume" is defined as routinely
getting more than one POP login every second or so). If the system log spreads the
IP address and the login success information over multiple log records, it is
possible to mix up user/ip information when simultaneous (or near simultaneous)
logins occur. This can result in failing to grant relay access to a user who should
have it, or it can result in granting relay access to an unauthorized user. This
unauthorized user would have relay access until the authorization expires (after
a configurable timeout).
Scope
This document describes installing, testing, and configuring popbsmtpd
in an Engarde Secure
Linux environment. It also describes some configuration and testing
necessary to successfully retrieve and send mail regardless of pop-before-smtp,
but not in any depth.
Depending on user feedback, this document may someday be more generic and
platform- and distribution-independent.
Back to top
Background
One of the banes of the modern internet is the people who abuse it to send
their mass mailings. To reduce their own costs and to hide the origin of their
mail, they will try to identify servers that they can hijack. These victim
servers are known as "open relays", and it is considered extremely poor
nettiquette to run one. For more information on why this is a bad thing and why
they get blacklisted, visit ORDB.org.
Closing an open relay restricts who may send mail through your mail server.
Typically, only users from a specific range of network addresses, i.e. your own, are
permitted to relay mail. This has the unfortunate side effect of denying your own
users the right to send mail through your server when they are away from the
office.
If the server could securely identify the user attempting to send mail, it could
permit relaying regardless of the user's location. However, SMTP (the protocol used
for sending mail) does not accommodate this validation.
(Check out SASL for an alternative.)
This is where POP-before-SMTP validation comes in. Clearly, you must
identify yourself to pick up your mail, so at this point the mail server knows that
a known valid user is at that IP address. All that is needed is some way to convey
this information from the POP server to the SMTP server. This is exactly what
popbsmtpd does.
Back to top
Installation and Setup
Note: At present, there is no RPM-based package available, but this is
planned for the future. In the meantime, the manual installation procedure
described here is fairly trivial.
Download, Unpack, and Install Components
Get the current version via FTP from
here,
and put it into root's home directory. Login as root, and unpack it:
[root@host /root]# tar xzvf popbsmtpd-<version>.tar.gz
This will create a directory called popbsmtpd, which contains the project files.
There are three files that need to be installed; the executable, the
configuration file, and the init script. The configuration file is no problem,
but you will need to disable LIDS (if you are using it) to install the other
two. If LIDS is enabled, /usr/sbin and /etc/init.d appear to be on a read-only
device, and cannot be written to. To install the files:
[root@host /root]# /sbin/lidsadm -S -- -LIDS_GLOBAL
SWITCH
enter password:
[root@host /root]# mv popbsmtpd /usr/sbin
[root@host /root]# chmod 750 /usr/sbin/popbsmtpd
[root@host /root]# chown root.root /usr/sbin/popbsmtpd
[root@host /root]# mv popbsmtpd.init /etc/init.d/popbsmtpd
[root@host /root]# chmod 700 /etc/init.d/popbsmtpd
[root@host /root]# chown root.root /etc/init.d/popbsmtpd
[root@host /root]# mv popbsmtpd.conf /etc
[root@host /root]# chmod 640 /etc/popbsmtpd.conf
[root@host /root]# chown root.root /etc/popbsmtpd.conf
[root@host /root]# /usr/sbin/config_lids.pl
Cleared all rules.
Setting up READ permissions...
Setting up WRITE permissions...
Setting up DENY permissions...
Setting up subject/object associations...
Setting up certificate/key protection...
Reloading LIDS configuration...
[root@host /root]# /sbin/lidsadm -S -- +LIDS_GLOBAL
SWITCH
enter password:
[root@host /root]#
There are shell scripts in the distribution-specific directories to perform
these installation steps.
Enable POP3 Access
If you are already running POP, all you need to do is ensure that the service
is available regardless of where the user logs in from. This is accomplished with
the following line in the /etc/hosts.allow file:
---Begin---
#
# hosts.allow
#
spop3: ALL
----End----
If you are not already running POP, you will also need to start it, and ensure
that it starts up again each time the machine boots:
[root@host /root]# /etc/init.d/stunnel-pop3 start
[root@host /root]# chkconfig --add stunnel-pop3
If you have trouble with the POP server certificate, some documentation is
available here
to help you sort it out.
CHECKPOINT: Before continuing, make sure you can successfully retrieve
mail with POP from outside your local network.
Modify the Postfix Configuration
This is the core of the matter, because Postfix decides whether or not your
mail is accepted for sending.
What is required is to build a configuration that permits relaying from outside
locations if and only if an authorization record exists. These authorization
records are conveniently looked up by Postfix in a hash table, so they are written
by popbsmtpd in that format to /etc/postfix/pop-before-smtp.db.
A new test needs to be made in two places in the Postfix configuration: one at
smtpd_client_restrictions, and one at smtpd_recipient_restrictions.
In each case, the new test is:
check_client_access hash:/etc/postfix/pop-before-smtp
The test at smtpd_client_restrictions ensures that the client is not
rejected on the basis of who it is, or where it is connecting from.
The test at smtpd_recipient_restrictions ensures that the client is
not rejected on the basis of who the mail is addressed to. Normally, any
destination not on the local server is rejected.
If your configuration does not use these restrictions, an alternative is to
add this database to the mynetworks parameter, like this (assuming your
network is in the 192.168.1 range):
mynetworks = 192.168.1.0/24, hash:/etc/postfix/pop-before-smtp
Note: the .db suffix is never specified in Postfix configuration files.
/etc/postfix/pop-before-smtp.db should be created before reloading the
Postfix configuration. This can all be done with the following commands:
[root@host postfix]# touch /etc/postfix/pop-before-smtp
[root@host postfix]# postmap hash:/etc/postfix/pop-before-smtp
[root@host postfix]# postfix reload
CHECKPOINT: Before continuing, ensure that everything is working as it
did before any changes were made, because nothing should behave any differently
until an IP address appears in /etc/postfix/pop-before-smtp.db. Especially,
make sure you are not an open relay (i.e. you do not by default relay mail
from anywhere outside your local network).
Now, test whether adding an IP address to the authorization database has
the desired effect:
- From a mail client connected to the internet using an IP address outside
of your own range, attempt to send mail through your own server to a non-local
destination, such as a Yahoo or Hotmail account. This should FAIL.
- On your mail server, add the IP address of the mail client used in Step 1 to
/etc/postfix/pop-before-smtp.db (see below).
- Repeat the test in step 1. This should SUCCEED.
If the test in Step 1 lets you send mail, or the test in Step 3 does not, check
your logs and your configuration to determine what the problem is, and fix it.
If this is not working correctly, popbsmtpd won't work.
Note: To manually add an IP address to /etc/postfix/pop-before-smtp.db, add a
line to the text file /etc/postfix/pop-before-smtp (created above) with a line
containing the IP address, a space or a tab, and the string "OK", like this:
---Begin---
192.168.1.1 OK
----End----
Then rebuild the database:
[root@host postfix]# postmap hash:/etc/postfix/pop-before-smtp
To later remove the IP address, you can use popbsmtpd:
[root@host postfix]# popbsmtpd --rebuild
Modify the syslog-ng Configuration
The popbsmtpd daemon needs access to the login information available from the
POP server. This information is written to the system logs, so that is a
convenient place to retrieve it from.
Instead of following one of the existing logs, popbsmtpd expects its own
dedicated stream of information to be available on a named pipe. To do this,
add the following lines to /etc/syslog-ng.conf after their similar neighbours:
---Begin---
#
# syslog-ng.conf
#
...
###########################################################
# DEFINE AVAILABLE LOG DESTINATIONS TO CHOOSE FROM
###########################################################
...
destination mail_login { pipe("/var/log/pop-imap-login.log"); };
###########################################################
# DEFINE AVAILABLE LOG FILTERS TO CHOOSE FROM
###########################################################
...
filter f_mail_login { program("stunnel") or program("spop3") or program("simap"); };
###########################################################
# DEFINE LOGGING - (sources; filters; destinations)
###########################################################
...
#### log secure pop/imap activity for pop-before-smtp processing
log { source(src); filter(f_mail_login); destination(mail_login); };
----End----
Now create the pipe, and cause syslog-ng to re-read its configuration:
[root@host /root]# mkfifo /var/log/pop-imap-login.log
[root@host /root]# killall -HUP syslog-ng
CHECKPOINT: Before continuing, make sure that syslog is in fact
writing to the pipe. You can do this by running
"cat /var/log/pop-imap-login.log", and then logging in with POP as you
did earlier. You should see the log entries appear as they arrive.
(Use Ctrl+C to exit.)
Because this is a pipe and not a file, this log does not need to be rotated.
As long as popbsmtpd is running, the pipe will never accumulate data or grow.
Start popbsmtpd
First, check the configuration in /etc/popbsmtpd.conf. The reference
manual contains the information you need in order to do this.
You can try out the program interactively, to make sure that everything is
working. Run the following command, and initiate some mail activity:
[root@host /root]# popbsmtpd --loglevel=3
You should see the configuration information, and then the processing of
system log entries that have been directed to it. When you are satisfied,
press Ctrl+C to gracefully end the program.
Now that everything has been configured, tested, and is known to work, the
monitoring daemon can be started:
[root@host /root]# /etc/init.d/popbsmtpd start
[root@host /root]# chkconfig --add popbsmtpd
Back to top
Summary
The installation procedure can be summed up as follows:
- Download the current version of popbsmtpd and unpack it.
- Install 3 files; the executable, the configuration file, and the init script.
- Enable POP3 access from any location (preferably through stunnel)
and test.
- Modify the Postfix configuration to check the authorization database
and test.
- Modify the syslog-ng configuration to feed login information to popbsmtpd
and test.
- Start popbsmtpd.
Back to top
Configuration Files
Sample popbsmtpd.conf
---Begin---
#
# Configuration file for POP-Before-SMTP Daemon
#
# The log file (pipe) to examine for successful POP authorizations.
source_log = /var/log/pop-imap-login.log
# The database to which we write the IP addresses.
auth_db = /etc/postfix/pop-before-smtp.db
# The database to which we write login information.
login_db = /etc/postfix/pop-before-smtp-logins.db
# The IP addresses of our own networks, so not time is wasted authorizing
# IP addresses that are allowed to relay anyway. This is a space-separated
# list of network addresses, with trailing periods.
# The current maximum number of networks you can specify is 8.
#
# Example: mynetworks = 192.168.1. 192.168.2. 10.
#
mynetworks =
# The number of minutes before a POP validation expires.
# For low-risk sites, 8 hours (480 minutes) is good.
auth_duration = 30
# The maximum number of seconds to sleep.
# The monitor wakes up whenever an entry is due to expire, and also wakes up
# whenever a new log entry arrives in its pipe, so there is no good reason
# to make this duration short (other than debugging).
# One hour (3600 seconds) is a reasonable time.
sleep_duration = 3600
# The facility to use for logging to the system log; default LOG_MAIL.
log_facility = LOG_MAIL
# The verbosity of the logging.
# This value ranges from 0 to 6; the higher the number, the more output.
# Default is 1; a value of zero turns off logging (except for errors).
# Note: This configuration variable has no effect until a SIGHUP is caught
# by the running daemon (so you can start or stop logging while active).
log_level = 1
# The following sections define how to extract login information from
# the system logs. There is a section for each of the four supported
# protocols; pop3, imap, secure pop, and secure imap.
#
# The meaning of the options within the sections is:
#
# multi-line - Set to "1" if both the IP address and the user id are
# found on the same line; else "0".
# daemon - The name of the daemon that writes the first line indicating
# that a login is in process.
# string - A constant string that occurs somewhere in the start line.
#
# ip_daemon - The daemon that writes the line containing the IP address.
# ip_string - A constant string to identify the line.
# ip_scan - A sscanf(3)-compatible format string to extract the IP
# address from the line. This should extract the IP address
# as a single string, with no surrounding delimiters or
# extraneous characters.
# WARNING: If you get this wrong, you can crash the daemon,
# or WORSE YET, give an attacker full access.
#
# user_* - Same as described for ip_* above, but for the user id.
#
# fail_daemon - The daemon that writes the login failure message.
#
# fail_string - A constant string that identifies a login failure.
#
# Note: The current release has only a rudimentary configuration parser,
# so make sure that the section start and end markers
# "pop { enable" and "}" are each on a separate line by themselves.
# If you get it wrong or leave off the end marker, the parser will
# ignore some or all of the sections.
#
# To disable/ignore a section without deleting it, change the "enable" on the
# on the start marker to "disable".
#
# If you are using more than one of these sections, they each get a look at
# every log entry in the order that they are specified here.
#
secure-pop { enable
multiline = 1
daemon = "stunnel"
string = "spop3 connected from"
ip_daemon = "stunnel"
ip_string = "spop3 connected from"
ip_scan = "spop3 connected from %[^:]:%*d"
user_daemon = "spop3"
user_string = "Login user="
user_scan = "Login user=%s host=%*s [%*[^]]]"
fail_daemon = "spop3"
fail_string = "Login failure user="
}
pop { disable
multiline = 0
daemon = "spop3"
string = "Login user="
ip_daemon = "spop3"
ip_string = "Login user="
ip_scan = "Login user=%*s host=%*s [%[^]]]"
user_daemon = "spop3"
user_string = "Login user="
user_scan = "Login user=%s host=%*s [%*[^]]]"
fail_daemon = "spop3"
fail_string = "Login failure user="
}
----End----
Sample Postfix main.cf
For those who are less familiar with Postfix configuration, here is a sample
main.cf that is known to work. Study it carefully, and either modify your
existing configuration or adapt this sample to suit your situation. For
documentation, see www.postfix.org.
---Begin---
# Global Postfix Configuration File
# Where things live on this system.
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
virtual_maps = hash:/etc/postfix/virtual
relocated_maps = hash:/etc/postfix/relocated
transport_maps = hash:/etc/postfix/transport
alias_maps = hash:/etc/postfix/aliases
alias_database = hash:/etc/postfix/aliases
# Identification - user, hostname, networks.
mail_owner = postfix
myhostname = mail.domain.tld
mynetworks = 127.0.0.0/8, 192.168.1.0/24
inet_interfaces = all
myorigin = $myhostname
mydestination = $myhostname, localhost.$mydomain, $mydomain
relay_domains = $mydestination
masquerade_domains = $mydomain
masquerade_exceptions = root
# The blacklists tested before accepting inbound mail.
maps_rbl_domains = relays.ordb.org, relays.osirusoft.com
# Restrictions on who is allowed to connect.
smtpd_client_restrictions = permit_mynetworks,
check_recipient_access hash:/etc/postfix/recipient_access,
check_client_access hash:/etc/postfix/pop-before-smtp,
check_sender_access hash:/etc/postfix/sender_access,
reject_invalid_hostname,
reject_non_fqdn_hostname,
reject_unknown_client,
reject_maps_rbl,
check_relay_domains
# Restrictions on what is accepted in the MAIL FROM: command.
smtpd_sender_restrictions = permit_mynetworks,
check_recipient_access hash:/etc/postfix/recipient_access,
check_sender_access hash:/etc/postfix/sender_access,
reject_non_fqdn_sender,
reject_unknown_sender_domain,
permit
# Restrictions on what is accepted in the RCPT TO: command.
smtpd_recipient_restrictions = permit_mynetworks,
check_recipient_access hash:/etc/postfix/recipient_access,
check_client_access hash:/etc/postfix/pop-before-smtp,
reject_non_fqdn_recipient,
reject_unauth_pipelining,
check_relay_domains
# Content restrictions.
header_checks = regexp:/etc/postfix/regex-header-checks
# Some limits to behaviour.
biff = no
disable_vrfy_command = yes
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 10
message_size_limit = 10240000
delay_warning_time = 4
smtpd_banner = $myhostname ESMTP
----End----
Back to top
Researched and written by
Marcus Redivo.
Permission to use this document for any purpose is hereby granted, providing
this copyright information and disclaimer is retained. Author accepts no
responsibility for any consequences arising from the use of this information.
|