Changes RSS

**This is an old revision of the document!** ----

A PCRE internal error occured. This might be caused by a faulty plugin

====== OpenBSD SMTPd ====== As of version 4.6 of [[http://www.openbsd.org/|OpenBSD]], a new alternative MTA is available. The new smtpd daemon is named according to the simple naming scheme of most other OpenBSD packages; it's name is simply 'smtpd'. Assuming this will be ported to other *nixes like so many other OpenBSD projects, this will probably in time also be know under the name OpenSMTPd. What fascinated me about this new MTA, and made me want to try it out, is its relatively simple, and very much OpenBSD-like configuration syntax. Stealing the first example config from the man-page of [[http://www.openbsd.org/cgi-bin/man.cgi?query=smtpd.conf&sektion=5&arch=i386&apropos=0&manpath=OpenBSD+Current|smtpd.conf]], it may look somewhat similar to: listen on lo0 accept for local deliver to mbox accept for domain "example.org" relay via "mx1.example.org" accept for domain "example.net" relay This kind of syntax should be really familiar to people having touched pf.conf, snmpd.conf, ntpd.conf and other OpenBSD BNF-based config files. The documentation is at the moment slightly less-than-optimal in my personal view. smtpd is currently still getting new features added, and code is still maturing, so it is not unexpected, and documentation will most likely improve as the project matures. I am willing to accept the lack of early documentation, and dive in nonetheless. A note of caution: the version that shipped along with OpenBSD 4.6 is deemed secure, but the project is quite new, and there is bound to be flaws exploitable for DoS on smtp. I would probably not put this MTA as my frontline SMTP on a production environment quite yet. This ingress was written 24. oct 2009. If you are reading this at a later time, do assume that claims about documentation and flaws have been rendered void. ===== My use of smtpd ===== Currently I am running smtpd on my gateway system, where I also do packet filtering, nat and rdr. The following is my uses of smtpd: * In the home network, all port-25 traffic is transparently redirected to smtpd * No authentication internally is required, but all outgoing mail is relayed via a relay-host that requires auth. * This allows visitors to use any pre-existing MTA setup in their mail clients, I will simply "override" their settings, as long as they do not require TLS Auth. * Externally, smtpd is listening to SMTPS with authentication required. * I am running multiple mutt setups on multiple computers outside my home network. I wanted to have one MTA that I could configure for all those setups, without having to fiddle too much. ===== The setup ===== ==== Remove the old mailer ==== First, we need to change from the default MTA, sendmail, to our new shiny smtpd. Start off by killing sendmail: pkill sendmail Next, change /etc/mailer.conf to reflect smtpd in stead of sendmail: mv /etc/mailer.conf /etc/mailer.conf.sendmail cat > /etc/mailer.conf << EOF # Replacing sendmail with smtpd: sendmail /usr/sbin/smtpctl send-mail /usr/sbin/smtpctl mailq /usr/sbin/smtpctl makemap /usr/libexec/smtpd/makemap newaliases /usr/libexec/smtpd/makemap EOF Rebuild the aliases database: newaliases Append the following to rc.conf.local to disable sendmail, and enable smtpd, at boot: echo "sendmail_flags=NO" >> /etc/rc.conf.local echo "smtpd_flags=" >> /etc/rc.conf.local ==== First config, trying things out: ==== The following sets smtpd up to listen on standard SMTP port 25 on the local loopback interface and the interface rl1, which is an internal interface. All mail created lcoally, destined to "localhost", is to be delivered locally, in mbox format. All mail coming in from the internal IP-range is to be relayed via a relayhost. No authentication is used; not for incoming, and not for relaying. <code> # /etc/mail/smtpd.conf simple example int_if = "rl1" int_net = "10.0.3.0/24" ext_if = "rl0" listen on lo0 listen on $int_if map "aliases" { source db "/etc/mail/aliases.db" } accept for local deliver to mbox accept from $int_net for all relay via smtp.example.com </code> Testing this out, start smtpd with the dead simple command: smtpd ==== Adding authentication for relayhost ==== To add support for SMTP authentication when talking with a relay host, things get a little, but not much, more involved. SMTP relay username/password configuration is not stored in smtpd.conf. Instead, we need to add a secrets file. Create the file /etc/mail/secrets: touch /etc/mail/secrets chown root:_smtpd /etc/mail/secrets chmod 640 /etc/mail/secrets The format of this file allows us to store username/password pairs for multiple SMTP hosts that we want smtpd to talk authenticated TLS/SSL/SMTPS with. The format is to have definitions line by line: smtp.host.name username:password So, in a setup where we only talk to smtp.example.com, with username "theuser" and password "53cre37": echo "smtp.example.com theuser:53cre37" > /etc/mail/secrets After creating the file, with content, we need to make a data map of it: makemap /etc/mail/secrets This map needs to be added to our configuration, along with a statement that makes the relay use authentication: <code> # /etc/mail/smtpd.conf simple relay authentication example int_if = "rl1" int_net = "10.0.3.0/24" ext_if = "rl0" listen on lo0 listen on $int_if map aliases { source db "/etc/mail/aliases.db" } map secrets { source db "/etc/mail/secrets.db" } accept for local deliver to mbox accept from $int_net for all relay via smtp.example.com tls enable auth </code> For sake of clarity, the available options to "relay via" at the moment are: relay via host [port port] [ [tls | smtps | ssl] [certificate name] [enable auth] ] ==== Adding SMTPS with authentication ==== To be able to do authentication of clients connecting, at least a certificate for the interface where the clients will be connecting is required. In my case, the interface that I want to connect to using SMTPS and Auth is rl0. mkdir -p /etc/mail/certs openssl genrsa -out /etc/mail/certs/rl0.key 4096 openssl req -new -x509 -key /etc/mail/certs/rl0.key -out /etc/mail/certs/rl0.crt -days 365 Before adding configuration to use authentication, note the following detail: All authenticated users will be treated as local! This means that all "accept" or "reject" lines in your config needs to account for that. <code> # /etc/mail/smtpd.conf simple relay authentication example int_if = "rl1" int_net = "10.0.3.0/24" ext_if = "rl0" listen on lo0 listen on $int_if listen on $ext_if smtps enable auth map aliases { source db "/etc/mail/aliases.db" } map secrets { source db "/etc/mail/secrets.db" } accept for local deliver to mbox accept from $int_net for all relay via smtp.example.com tls enable auth accept for all relay via smtp.example.com tls enable auth </code> ==== Adding SMTPS without authentication ==== I have a single host where I do not have the option of running TLS, SSL or SMTPS authentication (Mutt setup with limited SMTP support, and no option of installing an MTA helper). So, in addition to accepting SMTPS with authentication, I need to allow this single host to send mail without auth. But, due to firewall restrictions, I need to run on a different port because of firewalling/packetfiltering between my system, and the computer in question. I am still using SMTPS for the heck of it; my mutt does support smtps/tls/ssl, it just does not understand auth... So, expanding on the previous example, with 172.17.18.19 being my strange client: <code> # /etc/mail/smtpd.conf simple relay authentication example int_if = "rl1" int_net = "10.0.3.0/24" ext_if = "rl0" listen on lo0 listen on $int_if listen on $ext_if port 587 smtps enable auth map aliases { source db "/etc/mail/aliases.db" } map secrets { source db "/etc/mail/secrets.db" } accept for local deliver to mbox accept from $int_net for all relay via smtp.example.com tls enable auth accept for all relay via smtp.example.com tls enable auth accept from 172.17.18.19 for all relay via smtp.example.com tls enable auth </code> So, the trick here is that authenticated users are treated as local users, while non-authenticated connections are treated as remote ones, and will have to match an "accept from" rule to pass. To this config set, I have also thrown in a change to what port we are listening on on the external interface. SMTPS by default listens on port 465, here I have changed it to 587.