diff options
Diffstat (limited to 'src/Securing_a_Postfix_Smtp_Server.adoc')
-rw-r--r-- | src/Securing_a_Postfix_Smtp_Server.adoc | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/Securing_a_Postfix_Smtp_Server.adoc b/src/Securing_a_Postfix_Smtp_Server.adoc new file mode 100644 index 0000000..79f20f5 --- /dev/null +++ b/src/Securing_a_Postfix_Smtp_Server.adoc @@ -0,0 +1,226 @@ +Securing a Postfix Smtp Server +============================== +:author: Aaron Ball +:email: nullspoon@iohq.net + + +== {doctitle} + +I must start this post with the acknowledgement that I know only what I've +experienced on this topic. + +I recently set up my own mail server for the fun of it. I figured it was +something I'd never done, so why not, right? + +Well, one day later, spammers discovered my server and began using it to send +out spam mail (curse you spammers!). I didn't notice this until I received a +notification from my hosting provider that my network IO was over the threshold +I had set. I promptly logged in, tailed the mail logs and discovered +unbelievable amounts of mail being rejected by Google, Yahoo, Aol, and Hotmail. +Why? Spam. + +With that, I spent the next day figuring out how to better secure my smtp +server. I'd like to detail some of the exploits that the spammers used to get +in to my server, how I failed in configuring my server properly, and how I +fixed it. + +[[leaving-an-open-relay]] +Leaving an Open Relay +~~~~~~~~~~~~~~~~~~~~~ + +An open relay is basically an smtp server that requires no authentication +and/or allows connections from outside ip addresses, so anyone can send emails +from anywhere to anywhere. The settings in question specific to this issue in +my configuration were the following: + +---- +smtpd_recipient_restrictions = permit_mynetworks, check_relay_domains +... +mynetworks = 0.0.0.0/0 127.0.0.0/8 [::fff:127.0.0.0]/104 [::1]/128 +---- + +Basically that is an open relay. Here's why. + +* Firstly, *smtpd_recipient_restrictions = permit_mynetworks* allows any + email to be sent without any restrictions as long as the email originated + from a box in the IP ranges specified in the mynetworks variable. + +* Secondly, *mynetworks = 0.0.0.0/0* allows emails to be sent through my + smtp server from any client within the ip range of 0.0.0.0-255.255.255.255. + This is bad because any computer can try to send emails through my smtp + server and succeed because of the permit_mynetworks restriction (or lack + therof). + +[[specifying-incorrect-configuration-parameters]] +Specifying Incorrect Configuration Parameters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +One of my first mistakes when configuring Postfix was misspelling some smtpd +parameters using smtp_ instead of smtpd_ to prefix them. As it turns out, if +you do this, Postfix ignores your attempted configuration without a peep. This +one went on for a long time before I noticed that two of my smtpd_ fields were +missing the 'd'. As soon as I put those in there, everything started working as +it should, albeit still insecure, but at least it was following the +specifications of my config file. + + +[[not-specifying-a-correct-smtpd_sasl_path]] +Not Specifying a Correct smtpd_sasl_path +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This one took me a while. The *smtpd_sasl_path* is a path to the socket file +for your SASL server. In my case, this is Dovecot. + +As it turns out, Postfix defaults to running in chroot mode which makes its +root directory /var/spool/postfix/. This was my first mistake. I was specifying + +---- +smtpd_sasl_path = /var/spool/postfix/private/auth-client +---- + +and it was not starting up because it couldn't find the socket file. This was +because it was looking for the file at +/var/spool/postfix/var/spool/postfix/private/auth-client a path which clearly +does not exist. The solution to this is to simply specify a relative path. + +---- +smtpd_sasl_path = private/auth-client +---- + +I decided that I would get smart though and shave off some text from the field +value by configuring Dovecot to place the socket file at +/var/spool/postfix/auth-client rather than at +/var/spool/postfix/private/auth-client (speaking in absolute terms despite +running in chroot mode). This returned the following error + +---- +warning: when SASL type is "dovecot", SASL path "auth-client" should be a socket pathname +---- + +As it turns out, postfix won't operate with the SASL socket file path outside +of the private directory. So with that, I placed my auth-client file back in +the private directory and Postfix started up fine. + + +[[not-specifying-the-allowed-senders-file]] +Not Specifying the Allowed Senders File +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Even if you do have authentication required, you still need to specify which +users can send email with what addresses. This was a bit of a surprise to me +initially because I was under the impression that a password is associated with +an email address, not an email address(s) associated with a username and +password. To keep users from being able to send email as addresses that are not +theirs (specifically randomly generated addresses in my case), you need to +create a mapping file that maps usernames to the addresses they are authorized +to send mail as. In my case, this is a one to one relationship (one address per +username). Before my example I'd like to note that the filename is not +required to be the one I use (though my filename is the one used in the Postfix +setup documentation). + +Okay. Let's create the map file. To do this, open up and edit +/etc/postfix/controlled_envelope_senders (this file likely doesn't exist yet) + +---- +vim /etc/postfix/controlled_envelope_senders +---- + +Once you've got that open, you simply need to put the maps in there. + +---- +# envelope sender owners jcricket@example0.com jimminey +---- + +Now that we've done that, we need to turn it into a binary. Run the following +command and it will generate a <filename>.db binary map file in the same +directory as the original file. + +---- +postmap /etc/postfix/controlled_envelope_senders +---- + +Presto! Now the user jimminey can send email as jcricket@example0.com. However, +so can everyone else...still. + +Now that we have our controlled envelope senders file, we need to reference it +in our postfix main.cf and set postfix up to restrict access to the maps +specified in that file. Crack er open in your favorite editor and put the +following line in somewhere after *smtpd_sasl_auth_enable* + +---- +smtpd_sasl_auth_enable = yes +... +# This line specifies our map file for use by postfix +# Note that this does NOT reference controlled_envelope_senders.db +smtpd_sender_login_maps = hash:/etc/postfix/controlled_envelope_senders +# This line sets postfix to reject anyone who authenticates but tries to send email as an address they aren't permitted to use +smtpd_recipient_restrictions = reject_sender_login_mismatch, permit_sasl_authenticated, reject_unauth_destination +---- + +So what we've just done is tell Postfix where our map file is +(smtpd_sender_login_maps). After that, we tell Postfix to reject any users that +have been authenticated but are trying to send with an address they aren't +authorized to send with in our map file (smtpd_recipient_restrictions). Please +note that *reject_sender_login_mismatch* comes at the beginning of the +smtpd_recipient_strictions field. This is key. It is so key in fact, that I +missed it (I only miss the key stuff of course thanks Murphy). This was the +forth exploit attempt that got me. + + +[[misordering-smtpd_recipient_restrictions]] +Misordering smtpd_recipient_restrictions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This one is the final bit that let the spammers in (so far at least). + +The smtpd_recipient_restrictions are restrictions that you can place on +the users and their emails based on various things. In my case, I had +the following restrictions string + +---- +smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_sender_login_mismatch, reject_unauth_destination +---- + +Postfix applies these restrictions in the order in which they are specified. As +they put it <blockquote>Restrictions are applied in the order as specified; the +first restriction that matches wins.</blockquote> As soon as one restriction +matches, then the ones that follow don't get applied. This was very +problematic because in my case permit_mynetworks is first. So that I can log +in from my cell phone which has an IP address that changes, I set + +---- +mynetworks = 0.0.0.0/0 127.0.0.0/8 [::fff:127.0.0.0]/104 [::1]/128 +---- + +which allows any IP address to connect to my SMTP server. Since Postfix takes +the first match and goes no further and any IP address is in 0.0.0.0/0, anyone +can send mail through my SMTP server. This = bad. + +What you should do is start your restrictions with the the most strict +restrictions followed by the less strict. In my case, that looks like + +---- +smtpd_recipient_restrictions = reject_sender_login_mismatch, permit_sasl_authenticated, reject_unauth_destination +---- + +In the event someone tries to send an email, first they must login. If they +don't log in, they are rejected due to reject_sender_login_mismatch (we can't +do a match if we don't have a sender username). Secondly, once logged in, the +user must be authorized to use the address they are trying to send as as +specified in the smtpd_sender_login_maps line. Finally, once the user has been +authenticated and they have permissions to use the address they are trying to +send as, their email is not rejected. It follows that they are then filtered +through permit_sasl_authenticated. This basically runs a check to see if they +are authenticated (which we know they already are because of the previous +filter) and since they are, they are permitted and Postfix stops looking for +more matches because it's found one that permits the user to perform their +requested action. + +As chef Elzar says, "Bam!" + + +Category:Linux +Category:Postfix + + +// vim: set syntax=asciidoc: |