![]() |
|
| Daemon News Ezine | BSD News | BSD Mall | BSD Support Forum | BSD Advocacy | BSD Updates |
Postfix with SASL Authentication over TLSGrzegorz Czapliñski <gregory@prioris.mini.pw.edu.pl>In today's internet there is a lot of spam, forged mails and people who make use of this. It is importatnt to be secure, secure your users and the rest of the community from your users as well. It's better to be secure than to be sorry if an accident happens. You may not know that your users send spam until you get on the spamming list. I hope I don't have to explain why mechanisms such as: identification, authentication and authorization have to be implemented. In this article I will show you how to force users to authenticate before sending mail through Postfix. Ready? Postfix installationTo install postfix-current, go to /usr/ports/mail/postfix. Before making anything check your umask. Preferably it should be set to 022. Now type make. You should get a "Postfix configuration options" screen. Select: PCRE, SASL2, DB3, TLS. If you need any other options just mark them with "X" by pressing space. If your system is 5.0-RELEASE, remember there is no PERL installed by default. Now type make. The installation will take a while so sit back and relax but don't go away. Before the installation of cyrus-sasl your system will prompt you to set "Additional SASL options". Choose DB3, SASLAUTHD and accept. If the build process finished without any problems type make install. The installation script will add postfix user and group. It will also ask you about changing contents of the /etc/mail/mailer.conf. Accept the change and don't worry, you can find the old file under /etc/mail/mailer.conf.old. All configuration files you will find in the /usr/local/etc/postfix directory. To disable sendmail set these variables in /etc/rc.conf: sendmail_enable="NONE" mta_start_script="" sendmail_outbound_enable="NO" sendmail_submit_enable="NO" sendmail_msp_queue_enable="NO" Create a simple postfix.sh script for starting/stopping postfix and save it in /usr/local/etc/rc.d. It may look like: #!/bin/sh case $1 in start) if [ -x /usr/local/sbin/postfix ]; then /usr/local/sbin/postfix start fi ;; stop) /usr/local/sbin/postfix stop ;; reload) /usr/local/sbin/postfix reload ;; *) echo "USAGE $0 (start|stop|reload)" exit 1 esac Postfix configurationAfter the installation I usually create a link from /etc/postfix to /usr/local/etc/postfix. Just for simplicity. tahoe# ln -s /usr/local/etc/postfix /etc/postfix To make aliases work correctly, create a link from /etc/aliases to /usr/local/etc/postfix/aliases. tahoe# ln -s /usr/local/etc/postfix/aliases /etc/aliases Change aliases as appropriate to your site and type newaliases. You should see two files: tahoe# ls -l /etc/aliases* lrwxr-xr-x 1 root wheel 20 Feb 15 18:00 /etc/aliases -> /usr/local/etc/postfix/aliases -rw-r--r-- 1 root wheel 49152 Feb 15 18:00 /etc/aliases.db Now edit main.cf file to configure postfix. Set: myhostname, myorigin equal to the output of the hostname command. myhostname = Your hostname here myorigin = Your hostname here inet_interfaces = $myhostname, localhost mydestination = $myhostname, localhost.$mydomain, $mydomain mynetworks_style = host local_recipient_maps = $alias_maps unix:passwd.byname mail_spool_directory = /var/mail - That is default. Remember that your configuration may need different options. Consult an original main.cf file as the comments are superb. Start postfix with this command: /usr/local/sbin/postfix start or if it's already running type: /usr/local/sbin/postfix reload If you make any changes to main.cf file, remember to reload Postfix! Otherwise the changes will not take effect. Check the configSend a test mail to yourself to check that everything is OK before we start SASL configuration. Now connect to port 25 on your machine and see if ESMTP is working. prioris% telnet tahoe.acn.waw.pl 25 Trying 212.76.41.193... Connected to tahoe.acn.waw.pl. Escape character is '^]'. 220 tahoe.acn.waw.pl ESMTP Postfix ehlo prioris.mini.pw.edu.pl 250-tahoe.acn.waw.pl 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-STARTTLS 250-XVERP 250 8BITMIME If you see similar output, it's okay. Type quit to disconnect. SASL configurationNow go to /usr/local/lib/sasl2, create smtpd.conf file with these contents: pwcheck_method: saslauthd mech_list: plain login Edit /usr/local/etc/rc.d/saslauthd.sh and change sasl_saslauthd_flags variable from "-a pam" to "-a getpwent". The correct line will now look like: sasl_saslauthd_flags="-a getpwent" stop and start saslauthd again. /usr/local/etc/rc.d/saslauthd.sh stop /usr/local/etc/rc.d/saslauthd.sh start Tweak PostfixNow, go back and edit main.cf again. Somewhere at the end add: enable_sasl_authentication = yes smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, check_relay_domains smtpd_sasl_auth_enable = yes smtpd_sasl_security_options = noanonymous smtpd_sasl_local_domain = broken_sasl_auth_clients = yes Now you have to edit master.cf for postfix. Change the smtp line to look like: smtp inet n n n - - smtpd Yes, we don't chroot smtpd. Otherwise it will not work. Test Postfix with SASLBefore testing SASL authentication we have to encode our credentials with Base64. To do that let's issue a command:
tahoe% perl -MMIME::Base64 -e 'print encode_base64("gregory\0gregory\0test");'
Z3JlZ29yeQBncmVnb3J5AHRlc3Q=
The syntax is:
perl -MMIME::Base64 -e 'print encode_base64("username\0username\0password");'
Don't forget to put "\0" before username and password. Reload your new Postfix configuration and telnet again to port 25. prioris% telnet tahoe.acn.waw.pl 25 Trying 212.76.41.193... Connected to tahoe.acn.waw.pl. Escape character is '^]'. 220 tahoe.acn.waw.pl ESMTP Postfix ehlo prioris.mini.pw.edu.pl 250-tahoe.acn.waw.pl 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN PLAIN 250-XVERP 250 8BITMIME AUTH PLAIN Z3JlZ29yeQBncmVnb3J5AHRlc3Q= 235 Authentication successful quit 221 Bye Connection closed by foreign host. Hullawrerrr! It's working! Not so fast, what about TLS? Not so fast, all of the credentials are sent in cleartext which means they can be sniffed out from the wire. Here comes TLS into play. Before we put it to work we need a certificate. Either you get it from a Certificate Authority whom you have to pay, or you create it for yourself. I will not describe how to become a Certificate Authority; instead I will show you how you can create a self signed .pem certificate. TLS configurationOpenSSL is installed by default, so these are the steps you have to take to put TLS to work. Create /usr/local/etc/postfix/ssl directory. tahoe# mkdir /usr/local/etc/postfix/ssl tahoe# chmod 700 /usr/local/etc/postfix/ssl Because /etc/postfix is a symlink to /usr/local/etc/postfix I will use shorter names here. Create a configuration file for your certificate. Name it pst.cnf. RANDFILE = /etc/postfix/ssl/post.rand [ req ] default_bits = 1024 encrypt_key = yes distinguished_name = req_dn x509_extensions = cert_type prompt = no [ req_dn ] C=countryName Two letters! ST=stateOrProvinceName L=localityName O=organizationName OU=OrganizationalUnitName CN=commonName emailAddress=emailAddress [ cert_type ] nsCertType = server Generate certificate: tahoe# dd if=/dev/urandom of=/etc/postfix/ssl/post.rand count=1 2>/dev/null tahoe# /usr/bin/openssl req -new -x509 -days 365 -nodes \ -config /etc/postfix/ssl/pst.cnf -out /etc/postfix/ssl/post.pem \ -keyout /etc/postfix/ssl/post.pem tahoe# /usr/bin/openssl gendh -rand /etc/postfix/ssl/post.rand 512 \ >>/etc/postfix/ssl/post.pem tahoe# /usr/bin/openssl x509 -subject -dates -fingerprint -noout -in \ /etc/postfix/ssl/post.pem Now you should have a valid certificate in /etc/postfix/ssl directory under post.pem name. Tweak Postfix againAnd of course we have to add some config options to our main.cf file: #TLS smtp_use_tls = yes smtpd_use_tls = yes smtpd_tls_auth_only = yes smtp_tls_note_starttls_offer = yes smtpd_tls_key_file = /etc/postfix/ssl/post.pem smtpd_tls_cert_file = /etc/postfix/ssl/post.pem smtpd_tls_CAfile = /etc/postfix/ssl/post.pem smtpd_tls_loglevel = 3 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s tls_random_source = dev:/dev/urandom Save the file, reload postfix and enjoy SASL authentication over TLS. Are we safe now?Default postfix installation is not an open relay. No one can relay through your Postfix unless you allow so. The problem occurs when a spammer obtains a valid list of usernames and aliases on your server. For example he may know there are accounts for root and user gregory. It is enough for him to telnet to your Postfix, issue helo instead of ehlo and forge mail from gregory to root. And root might be disappointed with gregory especially when he is a BOFH. How to solve the problem? Edit main.cf and add: smtpd_sender_restrictions = permit_mynetworks, reject_sender_login_mismatch smtpd_sender_login_maps = hash:/usr/local/etc/postfix/sender_login_maps /usr/local/etc/postfix/sender_login_maps is a hash map which consists of valid usernames and aliases. If my login is gregory and I have an alias G.Czaplinski I have put both values into the map. It might be like this: gregory gregory G.Czaplinski gregory The second column in the map is a username you are logged in via SASL. That indicates user gregory owns the alias. This simple script may give you an idea how to generate the map automatically from /etc/passwd:
#!/bin/sh -
username=`cat /etc/passwd | awk -F: '{print $1}'`
for i in `echo $username`
do
echo "$i $i"
done
To create a map do: tahoe# postmap /usr/local/etc/postfix/sender_login_maps Now every user wanting to send a mail has to authenticate. No forged mails from gregory to root! Remember to consult the manual or howto on UCE controls. Read the Postfix documentation at http://www.postfix.org, especially Configuration. I hope someone will find this article useful and the hints given here will save you time. Good luck and till the next time... Important! After the publication, several questions were asked and also I came up with some useful conclusions. Follow the link to find how to make the config even more secure. |