Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

10.4: An alternative postfix/smtpd solution on port 25 System 10.4
Tiger only hintThis hint provides an alternative mechanism to create an SMTP daemon that listens and accepts connections on port 25 (the standard SMTP port) that is (more) appropriate for desktop/laptop users, without disturbing much of the out-of-the-box 10.4 setup and behavior.

Motivation

I suffer from mild obsessive-compulsive disorder when it comes to system administration, especially on my own machines. While I appreciate the simplicity of tools like Postfix Enabler, I naturally distrust their ability to do The Right Thing™, especially since tools like these typically hide the details of what they change "under the covers."

There are already a few hints (e.g., here and here) which explicitly advise how to set up postfix in such a way that it will provide a SMTP daemon that listens and accepts connections on port 25. Many of these use launchd, but (IMHO) do so in a way that doesn't quite seem to be in complete harmony with either postfix or launchd (at least how they were intended to be used on a desktop machine).

I wanted to create a solution that modified the 10.4 "stock" postfix behavior and configuration as little as possible, without suffering from some of the problems identified in other hints (e.g., aggravating the ability of a notebook to honor its sleep settings). I thought having the postfix master process exit after 60 seconds was a good idea and wanted to preserve that behavior. I also wanted to use launchd (as I believe it was intended) to be able to launch services on an as-needed basis (rather than force them to run all the time).

Overview

We will implement a solution which will use the (mostly) default configuration of the postfix master program to handle mail as it was intended: by monitoring /var/spool/postfix/maildrop (and that's all) for new mail and handle sending it. In addition, we will use launchd to run an inetd-like daemon, on an as-needed basis, to listen for connections on port 25 and put new mail in /var/spool/postfix/maildrop.

Implementation

From a fresh installation, there are three files which must be edited/created to implement this solution. They are as follows: The first change is simple and is consistent with other hints. We must make sure that /etc/hostconfig includes the following line:
MAILSERVER=-YES-
This tells OS X to automatically turn on various aspects of handling of sent mail. Ideally, this would be all we needed, but the default configuration is to only handle mail being sent via files created in the /var/spool/postfix/maildrop directory (e.g., the via the mail and sendmail Unix commands). The good news is that this is the exact behavior of which we intend to take advantage in order to disturb the default settings as little as possible.

After completing this step (if any change was required), then you should reboot to have the change take effect. There is probably a way to tell OS X to re-read /etc/hostconfig and adopt its changes, but I do not know what that is, so (at least for now) a reboot is my only prescribable option.

The second change is equally simple. We must make sure that the following line in /etc/postfix/master.cf is commented out (i.e., that the start of the line begins with a #) -- it's line 83 in my version of the file:
#smtp      inet  n       -       n       -       -       smtpd
This tells postfix that when it runs master, it should not listen on port 25 when it's running.

The default behavior of OS X 10.4 is that when launchd detects a new file in /var/spool/postfix/maildrop, it fires up the postfix master program to handle the sending of the file to its intended destination. It indicates to master that it should hang around for 60 seconds (just in case the user is sending more than one file), and then exit (so that it doesn't use up system resources and keep your notebook from sleeping, etc.).

However, the default configuration of master in /etc/postfix/master.cf tells it that while it's running, it should also listen on port 25 for incoming SMTP requests. If you'd like to see this in action (once you've changed your /etc/hostconfig file and rebooted), try the following in a shell (via Terminal):
$ telnet localhost 25
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
$ echo hello | mail your_email_address
$ telnet localhost 25
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 matt.local ESMTP Postfix
quit
221 Bye
Connection closed by foreign host.
Now wait 60 seconds or more before typing the next command:
$ telnet localhost 25
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host
I believe this behavior doesn't make very much sense and is not what is intended (i.e., that it is an oversight by Apple). After commenting the above line out and waiting 60 or more seconds for any existing master processes to exit, you should not be able to connect to your local port 25 regardless if any new master processes run or not.

Note for users who have already modified their mail configuration: as indicated above, the required line change was on line 83 in my default configuration, but yours may be different. If you've got other SMTP-related services running via the /etc/postfix/master.cf file, you may wish to comment those out as well. Also, if you've configured your master process not to exit (i.e., run all the time), you may wish to kill it (or restart it) once you make the above changes. You'll also want to return to the default /System -> Library -> LaunchDaemons -> org.postfix.master.plist file, which tells postfix to monitor the /var/spool/postfix/maildrop directory for new mail.

The third and final change is actually the creation of a new launchd service configuration file. The new /System/Library/LaunchDaemons/smtp.plist file needs to hold this code. The easiest way to do this (if you're not familiar with how to create a file in a directory not owned by you) is probably to do the following in a shell (via Terminal):
$ sudo cat >/System/Library/LaunchDaemons/smtp.plist
Now copy the source from the window that the above link will open, and paste it into the Terminal. Then hit COntrol-D to close the file and write it.

This creates an entry for launchd which will, on an as-needed basis, run sendmail in single-run daemon mode (via the -bs option) as user nobody on port 25. Running as nobody is important, since running it as root is a security risk (and actually doesn't work in the 10.4 default version of postfix). All that's left now is to tell launchd about its new service (this is to enable it without rebooting; launchd will automatically load this file on subsequent reboots):
$ sudo launchctl load /System/Library/LaunchDaemons/smtp.plist
$ sudo launchctl start org.postfix.sendmail
Now, every time you attempt to connect to port 25, launchd will spawn a new sendmail process which, when completed, will put new mail into /var/spool/postfix/maildrop which will trigger the default configuration of postfix to sweep it up and take care of it as needed.

Conclusion

Although rather verbose, I hope this hint has illustrated how both launchd and master work in a default 10.4 system, as well as how to tread as lightly as possible in modifying their behavior to create a usable port 25 on a desktop machine without suffering from some of the problems associated with running full-time daemons.

Acknowledgements

Despite my preference for an alternative, I must make it clear that other hints on this forum were invaluable in both inspiration and a platform from which to launch the approach described above. Without those authors' contributions, I would have never made this approach.
    •    
  • Currently 2.00 / 5
  You rated: 1 / 5 (4 votes cast)
 
[39,436 views]  

10.4: An alternative postfix/smtpd solution on port 25 | 20 comments | Create New Account
Click here to return to the '10.4: An alternative postfix/smtpd solution on port 25' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
10.4: An alternative postfix/smtpd solution on port 25
Authored by: n8gray on Sep 14, '05 01:05:30PM

Nice hint, but why do you use sudo to launch sendmail instead of the UserName property?

Also, don't you want RunAtLoad to be set?



[ Reply to This | # ]
10.4: An alternative postfix/smtpd solution on port 25
Authored by: mbogosian on Sep 14, '05 02:52:17PM

Nice hint, but why do you use sudo to launch sendmail instead of the UserName property?

Kudos! You caught this before I could post to correct it. The only reason the UserName key was not used in the original hint was because I was ignorant of the launchd.plist format and did not learn of it until after I had already submitted. To use UserName instead of sudo, change these lines in the /System/Library/LaunchDaemons/smtp.plist file...

    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/sudo</string>
        <string>-u</string>
        <string>nobody</string>
        <string>/usr/sbin/sendmail</string>
        <string>-bs</string>
    </array>

...to read...


    <key>UserName</key>
    <string>nobody</string>
    <key>GroupName</key>
    <string>nobody</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/sbin/sendmail</string>
        <string>-bs</string>
    </array>

Also, don't you want RunAtLoad to be set?

Actually, I don't believe we want that. If I understand the behavior of the RunAtLoad key correctly, setting it in this case would tell launchd to run a sendmail process on port 25 at boot time without a user being connected.

sendmail -bs exits at the end of each session/connection. After a user connected the first time (and completed a session), that sendmail process would exit and no further sendmail process would run until the next user tried to connect on port 25. All subsequent requests on port 25 would behave as if RunAtLoad was not set.

launchd seems to be Apple's solution for running processes on certain triggers (e.g., opening ports, creation of files, etc.). It is like inetd with some additional features. It is my understanding that typically one does not want to use RunAtLoad when one is trying to use launchd as an inetd replacement/alternative (i.e., for port-listening), which is what we're doing in this implementation.* See Apple's own ssh and telnet configurations as additional examples.

If your intention was to run an MTA daemon that listened to port 25 all the time (instead of having launchd do it on-demand), then this hint would be inappropriate. You would be better served by not using launchd at all, but instead configuring postfix (or another MTA) to stay alive and handle connections on port 25 directly.

This hint was intended to handle requests on port 25 only on an as-needed basis, while not requiring postfix's master to run all the time (much like 10.4's default behavior). For a desktop/notebook solution, I believe this is the correct behavior.


* As an aside, 10.4 also comes with xinetd (an inetd-like daemon) which we could have used instead of launchd to implement this hint. However (to my knowledge) it is not running by default. I can only assume it is present for backward compatibility or for system administrators who prefer it over launchd, though launchd seems like it is where everything is moving to the future. In fact, there is a specific directory /etc/xinetd.d-migrated2launchd (which is empty on my machine).

It would certainly be nice if Apple chose to release launchd under an OSI-approved license, since it seems like a nice abstraction to inetd, certain types of cron jobs, etc., from which other operating systems (e.g., Linux, *BSD, etc.) could benefit.



[ Reply to This | # ]
10.4: An alternative postfix/smtpd solution on port 25
Authored by: Skurfer on Sep 14, '05 02:44:44PM

Great hint. This is exactly what I wanted to do. A couple of notes…

I did have to use the UserName key as mentioned in the last comment. Using sudo gave an error.

Another thing I noticed - it seems that Thunderbird is too impatient to wait for smtpd to launch. It claims there's no server available, though if you watch with the process viewer, you can see smtpd pop up when you try to send. This is a problem with Thunderbird I suspect, not the config in this hint.



[ Reply to This | # ]
10.4: An alternative postfix/smtpd solution on port 25
Authored by: mbogosian on Sep 14, '05 03:15:07PM

I did have to use the UserName key as mentioned in the last comment. Using sudo gave an error.

It does appear that using sudo is somewhat of a hack. this comment has the corrected lines in the /System/Library/LaunchDaemons/smtp.plist file to use UserName instead of sudo.

Another thing I noticed - it seems that Thunderbird is too impatient to wait for smtpd to launch. It claims there's no server available, though if you watch with the process viewer, you can see smtpd pop up when you try to send. This is a problem with Thunderbird I suspect, not the config in this hint.

This seems strange to me. A good way to test your connection is to use telnet:

$ telnet localhost 25
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 YOUR_MACHINE_NAME ESMTP Postfix
ehlo localhost
250-YOUR_MACHINE_NAME
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250 8BITMIME
mail from: YOUR_EMAIL_ADDRESS
250 Ok
rcpt to: YOUR_EMAIL_ADDRESS
250 Ok
data
354 End data with <CR><LF>.<CR><LF>
From: YOUR_EMAIL_ADDRESS
To: YOUR_EMAIL_ADDRESS 
Subject: telnet test

This is a test. Thanks!
.
250 Ok: queued as 5BADA12A865
quit
221 Bye
Connection closed by foreign host.

On my machine (iBook G4) it doesn't take very long at all to come up:

$ time (echo -n quit$'\r'$'\n' ; sleep 1) | telnet localhost 25
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 YOUR_MACHINE_NAME ESMTP Postfix
221 Bye
Connection closed by foreign host.
zsh: done       (; echo quit$'\r'$'\n'; sleep 1; ) | 
zsh: exit 1     telnet localhost 25
(; echo quit$'\r'$'\n'; sleep 1; )  0.00s user 0.01s system 0% cpu 1.013 total
telnet localhost 25  0.01s user 0.02s system 11% cpu 0.237 total

If your configuration behaves like mine, and Thunderbird really has a problem with a connection time of less than 0.237 seconds, I'm not sure it would ever connect to a slow ISP's SMTP server (especially over dialup). It's likely that it's something else.



[ Reply to This | # ]
10.4: An alternative postfix/smtpd solution on port 25
Authored by: Skurfer on Sep 15, '05 01:39:40PM

Yeah, I tested with telnet several times before doing anything with a mail client. Everything looked fine there. Things also seem to work fine in Mail. It's just Thunderbird.



[ Reply to This | # ]
10.4: An alternative postfix/smtpd solution on port 25
Authored by: ssevenup on Dec 11, '05 11:36:52PM

Same here for TBird 1.5RC :-(

---
Mark Moorcroft
ELORET Corp. - NASA/Ames RC
Sys. Admin.



[ Reply to This | # ]
10.4: An alternative postfix/smtpd solution on port 25
Authored by: mbogosian on Sep 14, '05 03:49:22PM

Hint update:

After reading Apple's Getting Started with launchd more thoroughly, I now know that /System/Library/LaunchDaemons is probably not the right place for the new smtp.plist file. It most likely belongs in /Library/LaunchDaemons.

If you've already implemented this hint in its original form, you can do the following to migrate to /Library/LaunchDaemons:

$ sudo launchctl stop org.postfix.sendmail
Password: ********
$ sudo launchctl unload /System/Library/LaunchDaemons/smtp.plist
$ sudo mv /System/Library/LaunchDaemons/smtp.plist /Library/LaunchDaemons
$ sudo launchctl load /Library/LaunchDaemons/smtp.plist
$ sudo launchctl start org.postfix.sendmail

You may also want to see this comment on how to use the UserName key instead of sudo.



[ Reply to This | # ]
/etc/hostconfig modifications unnecssary?
Authored by: t0fukrunch on Sep 14, '05 11:01:11PM

Thanks for the excellent hint. I wrote one of the enabling postfix under Tiger hints , and my initial intent had been to do just what your hint accomplishes. I think my mistake had been trying to launch '/usr/libexec/postfix/smtpd' on demand via a launchd service rather than launching 'sendmail -bs' as you suggest.

I just wanted to point out that as far as I can tell, the "MAILSERVER" key in '/etc/hostconfig' is a red herring and uncessary in Tiger. This used to be checked by the SystemStarter scripts for sendmail and postfix in Jaguar and Panther, respectively, but seems to be no longer used with launchd. The only file I could find that refers to it is '/sbin/service', which is essentially a wrapper around launchd that does a few extra things like unconditionally start/stop postfix and the fax receiving service.



[ Reply to This | # ]
/etc/hostconfig modifications unnecssary?
Authored by: mbogosian on Sep 15, '05 10:13:12PM

I just wanted to point out that as far as I can tell, the "MAILSERVER" key in '/etc/hostconfig' is a red herring and uncessary in Tiger. This used to be checked by the SystemStarter scripts for sendmail and postfix in Jaguar and Panther, respectively, but seems to be no longer used with launchd. The only file I could find that refers to it is '/sbin/service', which is essentially a wrapper around launchd that does a few extra things like unconditionally start/stop postfix and the fax receiving service.

I'm wondering what other /etc/hostconfig items are no longer applicable. It's nice to hear that this unnecessary now (at least in the context of this hint), since one only has to edit/create two files (there is no step three), and one doesn't have to reboot midway through the process.



[ Reply to This | # ]
/etc/hostconfig modifications unnecssary?
Authored by: blgrace on Sep 20, '05 03:30:05AM

One more time for dummies - thanks for the step by step set-up - everything works as it should but I just don't know how to read mail sent by scripts running under Cron.
when I login to a terminal session it tells me I have mail - but how do I read this mail in Mail.app as opposed to the unix "Mail" ?

What type of account do I need to set up in Mail.app to read this mail?



[ Reply to This | # ]
SMTP AUTH
Authored by: bjarthur on Sep 30, '05 12:49:42PM

very nice hint. i'm curious as to whether you know if the default installation of postfix on tiger client (NOT server) has SMTP AUTH ability compiled into it. my ISP is forcing me to start using authorization and i'm afraid i might have to do a recompile to get it to work. any hints or HOWTOs on the details of this process would be greatly appreciated.



[ Reply to This | # ]
10.4: An alternative postfix/smtpd solution on port 25
Authored by: Johnny_B on Dec 03, '05 05:31:15AM

Will this approach preserve a PowerBooks sleep ? You didn't mention tp modifiy the line

pickup fifo n - n 60 1 pickup

Which will launch the pickup cmd every 60 second and prevent sleep.



[ Reply to This | # ]
pickup
Authored by: sjk on Dec 03, '05 10:09:34PM

I'm not sure it matters since it's set like that on a couple of my desktop systems that automatically sleep (if nothing else keeps them awake when they seem idle, which sometimes happens). But this comment in /etc/postfix/master.cf mentions pickup:

# Note: wakeup times for pickup, qmgr and flush are set to never to
# allow for OS X desktop sleep.

And only the wakeup times for qmgr and flush are set to never (-); pickup is still 60.



[ Reply to This | # ]
pickup
Authored by: Johnny_B on Dec 05, '05 03:16:54AM

I am refering to this hint:

http://www.macosxhints.com/article.php?story=20050504131428334



[ Reply to This | # ]
postfix/master[1497]: fatal: bind 127.0.0.1 port 25:
Authored by: rsnyder on May 10, '06 09:27:11AM
I followed the instructions, checked them at least twice, and now I keep getting the following in my /var/log/mail.log

May 10 12:02:37 RobertG5 postfix/master[1497]: fatal: bind 127.0.0.1 port 25: Address already in use

What am I doing wrong?

Even before that, I never got the email that I tried to send by entering:

echo hello | mail your_email_address

And, yes, I did put in my real email address.

Before doing the hint, my Mail log was full of attempted sends of emails that kept trying to connect to an email server that I have not used for years. They all failed because I shut that mail server down.

Help!

[ Reply to This | # ]

postfix/master[1497]: fatal: bind 127.0.0.1 port 25:
Authored by: PeteS on May 26, '06 05:20:49AM

Can't get this to work - anyone still commenting on this hint?



[ Reply to This | # ]
Port 25 listening and master.cf
Authored by: Rainy Day on Jun 04, '06 12:01:57PM
I believe that Apple's configuration (i.e. to listen to port 25) is correct, and that what your procedure is doing is disabling that feature (in master.cf), only to re-enable it again another way.

While Apple's default configuration listens to port 25, it only accepts connections from localhost! That behavior is exactly what would be desired to only allow local outgoing mail through the SMTP server, and it is set toward the end of main.cf with this line:

inet_interfaces = localhost

So it looks to me that Apple has Postfix properly configured and all that you need to do is configure launchd to call Postfix whenever a local connection to Port 25 is attempted. Your procedure should be able to be reduced to just that; everything else seems to be unnecessary (e.g. changes to /etc/postfix/master.cf and /etc/hostconfig). And that configuration should be made easier by using /Developer/Applications/Utilities/Property List Editor.app/, if you have the Developer Tools installed.

I didn't test this out, however, because my application is for Postfix to run as a deamon to constantly accept connections from the outside world (this is how i learned that Apple disabled external connections by their $inet_interfaces setting). For my application, i had to disable this by commenting out Apple's setting, and also set the variables $myhostname, $mydomain and $mydestination.

Important note for those running Postifx daemons: When changing the setting of $inet_interfaces, issuing a postfix reload will not do the trick; you must do a postfix stop followed by postfix start!

[ Reply to This | # ]

Port 25 listening and master.cf
Authored by: airbedman on Nov 21, '07 05:02:52PM

Hi,

I'm trying to implement this is Leopard, but its not working and I keep getting the following error in my mail.log

postfix/smtpd[269]: error: incorrect SMTP server privileges: uid=xxx euid=xxx
postfix/smtpd[269]: fatal: the Postfix SMTP server must run with $mail_owner privileges

any ideas??



[ Reply to This | # ]
Solution for 10.5?
Authored by: mbogosian on Jan 15, '10 08:12:20PM
I believe this will get you where you need to go on 10.5 (I'm not sure about 10.6 yet):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>smtp</string>

    <key>Program</key>
    <string>/usr/libexec/postfix/master</string>

    <key>ProgramArguments</key>
    <array>
        <string>master</string>
    </array>

    <key>WorkingDirectory</key>
    <string>/var/spool/postfix</string>
</dict>
</plist>
Just beware that most other mail hosts won't accept mail from your local machine if it doesn't meet certain criteria (which most personal computers do not).

[ Reply to This | # ]
Solution for 10.5?
Authored by: mbogosian on Jan 15, '10 08:25:42PM