v1.3, 25 October 2003
This document contains information on rewriting your mail header and mail
envelope through sendmail for mailing through your ISP. You should still
read the sendmail docs and Sendmail-Offline howto.
0. ChangeLog
- Sat Oct 25 2003 Philip S Tellis v1.3
- Updated the patch for sendmail v 8.12.9
- Moved the ChangeLog to the start of the file
- Added URLs to References and Further Reading
- Fixed wording a little
- Tue Jan 1 2003 Philip S Tellis v1.2
- Updates for sendmail 8.11
- Sat Dec 8 2001 Philip S Tellis v1.1
- Added patch file
- genericsdomain file is same as sendmail.cw
- changed from dgenerics to egenerics
- Sun Aug 26 2001 Philip S Tellis v1.0
1. About this document
1.1. Copyright
Copyright © Philip S Tellis.
Permission is granted to make and distribute copies of this manual
provided the copyright notice and this permission notice are preserved on
all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the
derived work is distributed under the terms of a permission notice
identical to this one. Translations fall under the catagory of "modified
versions".
1.2. Disclaimer
The information in this document is based on my own experience. It works
on my system, but may not work on yours. No guarantees are made on its
accuracy. The users of this information take full responsibility for any
damage that may occur through its use.
1.3. Feedback
If you have questions or comments about this document, please feel free to
contact me by email at <philip DOT tellis AT gmail DOT com>.
Please, do not ask me questions about sendmail, m4 or sendmail.cf. Do not
ask me questions about receiving mail.
2. Introduction
2.1. The problem
You connect to your ISP to send and receive mail. You have an email
account with another email service provider (not your ISP). You want
outgoing mails to appear to come from your other account, but you want to
use your ISP's mail gateway to send the mail.
You must use your ISP's mail gateway, because you are not permanently
connected to the Internet. Your ISP does not allow relay - i.e. only mail
coming from or going to an email address in your ISP's domain will be
allowed through their gateway.
You also want that mails sent out from the system do not have any local
addresses in the header (To:, Cc:, From: lines), while mails between two
local users always have the local addresses - i.e. you want rewrite to
work only on mails leaving the system.
Finally, you want that local mails are delivered immediately, while remote
mails are stored in a queue until you are connected to the Internet.
2.2. Software Environment
I use Sendmail v 8.9.3, 8.11 and 8.12.11 with the corresponding versions
of sendmail-cf. I also use GNU m4 1.4 for macro processing of sendmail.mc.
This HOWTO will assume that all configuration files, including sendmail.cf
are stored in /etc/mail. It also assume that the sendmail binary is
/usr/sbin/sendmail, that the m4 binary is in your path, and that the cf
directories are correctly installed.
NOTE: Some systems keep the sendmail.cf file at /etc/sendmail.cf, in that
case, you should do the same. An easy way would be to either symlink
/etc/sendmail.cf to /etc/mail/sendmail.cf or copy /etc/mail/sendmail.cf to
/etc/sendmail.cf after you've generated it. The latter method can be more
reliable as it sort of ensures that you don't have a half generated cf file
when sendmail runs. YMMV.
If you have installed from rpm, you will need the sendmail-cf rpm, if you
installed from source, then these will be in your source tree. For debian,
the sendmail/cf directory is installed as part of the sendmail package.
I use pine as my mail client, in particular, pine uses `sendmail -bs' to
send mail. There shouldn't be any difference with a client that connects
to your smtp port.
3. Configuring Sendmail
3.1. Creating the mc file
Sendmail's configuration file - /etc/sendmail.cf is not necessarily human
readable. In an earlier version of this Howto, I listed changes that were
needed in sendmail.cf. While it isn't important to understand what those
changes were, I've decided to get rid of that, and just write some m4 files
that you can use. For the main part, we will edit a sendmail.mc file, and
use m4 along with these additional files to generate the sendmail.cf file.
This has the added advantage of being easier to maintain when you update
your sendmail.mc file and need to regenerate sendmail.cf.
The patch for sendmail-cf's macro files is attached at the end of this
document.
At this point, it may be be wise to read the cf/README (or README.cf) file
that came with your sendmail/sendmail-cf package. It explains the mc file
well.
You should already have a file called /etc/mail/sendmail.mc, but if you
don't, now is a good time to create it. You can use mine as a template:
divert(-1)
dnl This is the macro configuration file used to generate the /etc/sendmail.cf
dnl file. If you modify this file you will have to regenerate the
dnl /etc/sendmail.cf by running this macro configuration through the m4
dnl preprocessor:
dnl
dnl m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
dnl
dnl You will need to have the sendmail-cf package installed for this to
dnl work.
include(`/usr/lib/sendmail-cf/m4/cf.m4')
define(`confDEF_USER_ID',``8:12'')dnl
OSTYPE(`linux')dnl
undefine(`UUCP_RELAY')dnl
undefine(`BITNET_RELAY')dnl
define(`confAUTO_REBUILD')dnl
define(`confPRIVACY_FLAGS', `goaway authwarnings')dnl
dnl
define(`SMART_HOST', `esmtp:isp.com')dnl
define(`confCON_EXPENSIVE', `True')dnl
define(`SMTP_MAILER_FLAGS', `e')dnl
define(`confTO_QUEUEWARN', `')dnl
define(`confTO_INITIAL', `10s')dnl
define(`confTO_CONNECT', `10s')dnl
define(`confTO_ICONNECT', `10s')dnl
define(`confCW_FILE', `/etc/mail/local_host_names')dnl
dnl
FEATURE(`smrsh',`/usr/sbin/smrsh')dnl
FEATURE(`always_add_domain')dnl
FEATURE(`use_cw_file')dnl
FEATURE(`nocanonify')dnl
dnl
FEATURE(`masquerade_envelope')dnl
FEATURE(`allmasquerade')dnl
FEATURE(`genericstable', `hash -o /etc/mail/genericstable')dnl
GENERICS_DOMAIN_FILE(`/etc/mail/local_host_names')dnl
dnl
dnl The egenericstable is a feature that will be added through
dnl my patch for the macro files
dnl
FEATURE(`egenericstable', `hash -o /etc/mail/egenericstable')dnl
dnl
FEATURE(`access_db')dnl
FEATURE(`blacklist_recipients')dnl
FEATURE(`accept_unresolvable_domains')dnl
dnl
MAILER(`local')dnl
MAILER(`smtp')dnl
First of all, change the path in the include line to whatever it is on
your system. If you've installed from source or using apt on a debian
system, this would be /usr/share/sendmail/cf. Also, replace isp.com
with the host-name of your isp's smtp server.
I will now attempt to explain the important parts of this file. Most of
these things are documented in the README file, so I'll skip those. I
will only explain the masquerading options.
Before that, if you're wondering what all the dnl commands are. It simply
means delete till new line. Since m4 is a stream processor, it does not
care about newlines, and will read and write all white space. These
commands just tell it to skip the extra white space. You can also place
comments after a dnl.
define(`confCON_EXPENSIVE', `True')dnl
define(`SMTP_MAILER_FLAGS', `e')dnl
These two lines tell sendmail that SMTP mailers are expensive (the e
flag), and not to try expensive mailers on the first try. This will cause
sendmail to put any mail that requires a connect to a remote smtp server
to stay in a queue until you flush the queue with `sendmail -q'.
Local mails will be delivered immediately, because the local mailer is not
marked as expensive.
Furthermore, since we are not always connected to the Internet, we don't
want warnings of mail being stuck in the queue too long (because that's a
perfectly valid situation).
define(`confTO_QUEUEWARN', `')dnl
tells sendmail to unset the QUEUE WARN TimeOut. Set it if you want
notifications of mail not being sent for more than a day. You can set it
to 1d for 1 day or 1m for 1 minute, etc.
This solves the third part of our problem - mail delivery.
FEATURE(`always_add_domain')dnl
FEATURE(`use_cw_file')dnl
define(`confCW_FILE', `/etc/mail/local_host_names')dnl
These lines tell sendmail to add a domain name to all mails, even if they
are sent locally. The cw file is a file containing a list of aliases for
your system. It is /etc/local_host_names by default, but we tell sendmail to
use /etc/mail/local_host_names through confCW_FILE. This is so that all mail
related sub-configuration files are in a common subdirectory.
FEATURE(`nocanonify')dnl
This line tells sendmail not to do DNS (Domain Name System) look ups on
host names. Since we are not permanently connected to the Internet, this
is required to prevent sendmail from locking up until it gets a DNS
time-out.
FEATURE(`masquerade_envelope')dnl
FEATURE(`allmasquerade')dnl
By default, sendmail will only masquerade addresses in the mail header,
i.e. the From:, To:, Cc: lines. masquerade_envelope tells sendmail to
also masquerade the address used to make the smtp connection with the
remote host. In our case, this would be the smart host.
We need this address to be the one that our isp has given us.
`allmasquerade'
tells sendmail to also rewrite recipient addresses.
Normally, local recipients would receive mail will the local domain name
attached to their address. This will cause their masqueraded name to
appear.
The advantage of this is that if you send a mail to both, a remote and a
local user, then the remote user will see all valid addresses in the To:
line, because all local addresses have been masqueraded. He can reply to
all, and the mail will reach correctly.
Unfortunately, local users receive mail with all foreign domains, so their
replies will take longer to reach (as they will go to the masquerade host
instead).
There is a workaround for this, as we shall see later.
FEATURE(`genericstable', `hash -o /etc/mail/genericstable')dnl
GENERICS_DOMAIN_FILE(`/etc/mail/local_host_names')dnl
The generics table gives us a very high level of flexibility in setting
aliases for outgoing mails. The genericsdomain file tells sendmail which
hosts the genericstable applies to. Since we already have a local_host_names
file, which contains a list of domains we accept mail for, it makes sense
to use the same for outgoing domains.
Finally, we add our own rule, which tells sendmail how to rewrite the
envelope (hence the `e' prefix).
FEATURE(`egenericstable', `hash -o /etc/mail/egenericstable')dnl
This rule will add the code to sendmail.cf that v1 of this document required
you to add manually.
3.2. Generics tables
My /etc/mail/genericstable looks like this:
philip philip.tellis@mydomain.com
While my /etc/mail/egenericstable looks like this:
philip tellis@isp.com
My local_host_names file is:
tae.tellis.home
which is the output of hostname -f
Once you've made your tables, you have to convert them to hash databases
using the make map command:
makemap -r hash genericstable.db < genericstable
makemap -r hash egenericstable.db > egenericstable
These are the files that are actually read by sendmail.
3.3. Making sendmail.cf
Finally, convert your sendmail.mc file to sendmail.cf using m4:
m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
It's actually a good idea to write this to a different file, and then move
that to sendmail.cf. You could first check the file for errors, and also,
you won't overwrite a file that is currently being processed. However,
since you're on a home machine with presumably only one person using the
machine at a time, this isn't such an issue. You decide what you need to
do.
3.4. Restart sendmail
Now, restart sendmail using whatever method you normally use. On systems
using SysV startup scripts, this would be /etc/init.d/sendmail restart
4. Further configuration
4.1. Flushing the queue
Since I connect to the net using a ppp link, I have this in
/etc/ppp/ip-up.local:
/usr/sbin/sendmail -q3m
which tells sendmail to process the queue every three minutes.
I also have this in /etc/ppp/ip-down.local:
/usr/sbin/sendmail -q1d
which tells sendmail to process the queue once a day if not connected.
Make it more if you want.
4.2. A Makefile
Some distributions have a makefile to regenerate all databases and the
sendmail.cf file. You'll have to add an entry for your egenericstable
there. You're on your own for this.
5. Acknowledgements
- Thanks to my ISP for forcing me to do this
- Thanks to some of the members of Ilug-Bom for ideas
6. References
- cf/README
Sendmail distribution
- Sendmail - friend or foe?
by Matthew Palmer, talk for Manchester Lug
http://ieee.uow.edu.au/~mjp16/sendmail/
- The Sendmail+Dialup mini-HOWTO v 1.00
by Leif Erlingsson <leif AT lege.com>,
Jan P Tietze <jptietze AT mail.hh.provi.de>,
Vincent Zweije <zweije AT xs4all.nl>
http://www.lege.com/Sendmail+Dialup.v1.00.html
- Configuring Sendmail for Offline Use mini-HOWTO
by Simone Govoni <simgov AT tin.it>
http://www.thinkunix.net/unix/email/sendmail/sendmail-offline.html
- A quick HOWTO for genericstable (on comp.mail.sendmail)
by Chris Johnston
7. Further Reading
Apart from the references above, you may want to check all the
documentation that comes with sendmail.
- Eric Allman, Sendmail: Installation and Operation Guide, file
doc/op/op.ps in sendmail source archive.
- Thomas Roessler, Sendmail Address Rewriting mini-HOWTO.
http://www.guug.de/~roessler/genericstable.html
- sendmail.org: Sendmail FAQ, especially the section on virtual users and
generics table.
- Sendmail on a dialup by Suresh Ramasubramanian
http://www.hserus.net/sendmail.html
8. The patchfile
IMPORTANT: This patch is for sendmail v 8.12, if your version is different,
this may not work. Have a look at older versions of this document for older
versions of sendmail.
Most versions of the patch utility can patch your directories straight from
this howto itself.
First change to the directory where your sendmail-cf m4 macros and
documentation is. On RedHat this is /usr/share/sendmail-cf while on debian
or source installs, it is /usr/share/sendmail/cf. Some older systems used
/usr/lib/sendmail-cf - the patch would most likely not work with these
systems.
To verify that you are in the correct directory, check that the feature, m4
and mailer directories are listed in there.
Then, run the patch command on this file:
patch -p0 < Hdr-Env-Masq-miniHOWTO.txt
That's it. Don't worry about all the stuff before the actual patch. The
patch util knows to ignore everything until it finds the actual patch.
If the patch doesn't work for you, then you might have to revert to the steps
outlined in version 1 of this document. If you have sendmail v 8.9, you can
use the patch in version 1.1 of this document, for sendmail v 8.11, use version
1.2 of this Howto.
diff -Pru feature/egenericstable.m4 feature/egenericstable.m4
--- feature/egenericstable.m4 1970-01-01 01:00:00.000000000 +0100
+++ feature/egenericstable.m4 2003-10-25 14:30:34.000000000 +0200
@@ -0,0 +1,20 @@
+divert(-1)
+#
+# Copyright (c) 2001-2003 Philip S Tellis. All rights reserved.
+#
+# This file added by Philip S Tellis for envelope rewriting.
+# Licence is the same as that of Sendmail.
+#
+#
+
+divert(0)
+VERSIONID(`@(#)egenericstable.m4, 1.2 2003/01/07 23:00:00 philip')
+divert(-1)
+
+define(`_EGENERICS_TABLE_', `')
+
+LOCAL_CONFIG
+# EGenerics table (mapping outgoing addresses in envelopes)
+Kegenerics ifelse(defn(`_ARG_'), `',
+ DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`egenericstable',
+ `_ARG_')
diff -Pru m4/proto.m4 m4/proto.m4
--- m4/proto.m4 2003-10-25 13:41:48.000000000 +0200
+++ m4/proto.m4 2003-10-25 14:30:34.000000000 +0200
@@ -1333,6 +1333,25 @@
R<lt; $+ > $* $#_LOCAL_ $@ $2 $: $1
###################################################################
+### Ruleset EnvRewrite -- convert envelope names to masq form ###
+###################################################################
+SEnvRewrite
+
+ifdef(`_EGENERICS_TABLE_', `dnl
+# handle generics database for envelope
+ifdef(`_GENERICS_ENTIRE_DOMAIN_',
+`R$+ <lt; @ $* $=G . > $: <lt; $1@$2$3 > $1 <lt; @ $2$3 . > @ mark',
+`R$+ <lt; @ $=G . > $: <lt; $1@$2 > $1 <lt; @ $2 . > @ mark')
+R$+ <lt; @ *LOCAL* > $: <lt; $1@$j > $1 <lt; @ *LOCAL* > @ mark
+R<lt; $+ > $+ <lt; $* > @ $: <lt; $( egenerics $1 $: $) > $2 <lt; $3 >
+R<lt; > $+ <lt; @ $+ > $: <lt; $( egenerics $1 $: $) > $1 <lt; @ $2 >
+R<lt; $* @ $* > $* <lt; $* > $@ $>3 $1 @ $2 found qualified
+R<lt; $+ > $* <lt; $* > $: $>3 $1 @ *LOCAL* found unqualified
+R<lt; > $* $: $1 not found',
+`dnl')
+
+
+###################################################################
### Ruleset 93 -- convert header names to masqueraded form ###
###################################################################
@@ -1401,7 +1420,9 @@
SMasqEnv=94
ifdef(`_MASQUERADE_ENVELOPE_',
-`R$+ $@ $>MasqHdr $1',
+ifdef(`_EGENERICS_TABLE_',
+`R$+ $@ $>EnvRewrite $1',
+`R$+ $@ $>MasqHdr $1'),
`R$* <lt; @ *LOCAL* > $* $: $1 <lt; @ $j . > $2')
###################################################################
diff -Pru mailer/local.m4 mailer/local.m4
--- mailer/local.m4 2003-10-25 13:41:48.000000000 +0200
+++ mailer/local.m4 2003-10-25 14:32:28.000000000 +0200
@@ -42,7 +42,8 @@
R@ <lt;@ $*> $n temporarily bypass Sun bogosity
R$+ $: $>AddDomain $1 add local domain if needed
ifdef(`_LOCAL_NO_MASQUERADE_', `dnl', `dnl
-R$* $: $>MasqEnv $1 do masquerading')
+ifdef(`_EGENERICS_TABLE_', `dnl', `dnl
+R$* $: $>MasqEnv $1 do masquerading')')
#
# Envelope recipient rewriting