summaryrefslogtreecommitdiff
path: root/src/Securing_a_Postfix_Smtp_Server.ascii
blob: 79f20f575164cc52ded711915e82e9d4665616a6 (plain)
    1 Securing a Postfix Smtp Server
    2 ==============================
    3 :author: Aaron Ball
    4 :email: nullspoon@iohq.net
    5 
    6 
    7 == {doctitle}
    8 
    9 I must start this post with the acknowledgement that I know only what I've
   10 experienced on this topic.
   11 
   12 I recently set up my own mail server for the fun of it. I figured it was
   13 something I'd never done, so why not, right?
   14 
   15 Well, one day later, spammers discovered my server and began using it to send
   16 out spam mail (curse you spammers!). I didn't notice this until I received a
   17 notification from my hosting provider that my network IO was over the threshold
   18 I had set. I promptly logged in, tailed the mail logs and discovered
   19 unbelievable amounts of mail being rejected by Google, Yahoo, Aol, and Hotmail.
   20 Why? Spam.
   21 
   22 With that, I spent the next day figuring out how to better secure my smtp
   23 server. I'd like to detail some of the exploits that the spammers used to get
   24 in to my server, how I failed in configuring my server properly, and how I
   25 fixed it.
   26 
   27 [[leaving-an-open-relay]]
   28 Leaving an Open Relay
   29 ~~~~~~~~~~~~~~~~~~~~~
   30 
   31 An open relay is basically an smtp server that requires no authentication
   32 and/or allows connections from outside ip addresses, so anyone can send emails
   33 from anywhere to anywhere. The settings in question specific to this issue in
   34 my configuration were the following:
   35 
   36 ----
   37 smtpd_recipient_restrictions = permit_mynetworks, check_relay_domains
   38 ...
   39 mynetworks = 0.0.0.0/0 127.0.0.0/8 [::fff:127.0.0.0]/104 [::1]/128
   40 ----
   41 
   42 Basically that is an open relay.  Here's why.
   43 
   44 * Firstly, *smtpd_recipient_restrictions = permit_mynetworks* allows any
   45   email to be sent without any restrictions as long as the email originated
   46   from a box in the IP ranges specified in the mynetworks variable.
   47 
   48 * Secondly, *mynetworks = 0.0.0.0/0* allows emails to be sent through my
   49   smtp server from any client within the ip range of 0.0.0.0-255.255.255.255.
   50   This is bad because any computer can try to send emails through my smtp
   51   server and succeed because of the permit_mynetworks restriction (or lack
   52   therof).
   53 
   54 [[specifying-incorrect-configuration-parameters]]
   55 Specifying Incorrect Configuration Parameters
   56 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   57 
   58 One of my first mistakes when configuring Postfix was misspelling some smtpd
   59 parameters using smtp_ instead of smtpd_ to prefix them. As it turns out, if
   60 you do this, Postfix ignores your attempted configuration without a peep. This
   61 one went on for a long time before I noticed that two of my smtpd_ fields were
   62 missing the 'd'. As soon as I put those in there, everything started working as
   63 it should, albeit still insecure, but at least it was following the
   64 specifications of my config file.
   65 
   66 
   67 [[not-specifying-a-correct-smtpd_sasl_path]]
   68 Not Specifying a Correct smtpd_sasl_path
   69 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   70 
   71 This one took me a while. The *smtpd_sasl_path* is a path to the socket file
   72 for your SASL server. In my case, this is Dovecot.
   73 
   74 As it turns out, Postfix defaults to running in chroot mode which makes its
   75 root directory /var/spool/postfix/. This was my first mistake. I was specifying
   76 
   77 ----
   78 smtpd_sasl_path = /var/spool/postfix/private/auth-client
   79 ----
   80 
   81 and it was not starting up because it couldn't find the socket file. This was
   82 because it was looking for the file at
   83 /var/spool/postfix/var/spool/postfix/private/auth-client a path which clearly
   84 does not exist. The solution to this is to simply specify a relative path.
   85 
   86 ----
   87 smtpd_sasl_path = private/auth-client
   88 ----
   89 
   90 I decided that I would get smart though and shave off some text from the field
   91 value by configuring Dovecot to place the socket file at
   92 /var/spool/postfix/auth-client rather than at
   93 /var/spool/postfix/private/auth-client (speaking in absolute terms despite
   94 running in chroot mode). This returned the following error
   95 
   96 ----
   97 warning: when SASL type is "dovecot", SASL path "auth-client" should be a socket pathname
   98 ----
   99 
  100 As it turns out, postfix won't operate with the SASL socket file path outside
  101 of the private directory. So with that, I placed my auth-client file back in
  102 the private directory and Postfix started up fine.
  103 
  104 
  105 [[not-specifying-the-allowed-senders-file]]
  106 Not Specifying the Allowed Senders File
  107 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  108 
  109 Even if you do have authentication required, you still need to specify which
  110 users can send email with what addresses. This was a bit of a surprise to me
  111 initially because I was under the impression that a password is associated with
  112 an email address, not an email address(s) associated with a username and
  113 password. To keep users from being able to send email as addresses that are not
  114 theirs (specifically randomly generated addresses in my case), you need to
  115 create a mapping file that maps usernames to the addresses they are authorized
  116 to send mail as. In my case, this is a one to one relationship (one address per
  117 username).  Before my example I'd like to note that the filename is not
  118 required to be the one I use (though my filename is the one used in the Postfix
  119 setup documentation).
  120 
  121 Okay. Let's create the map file. To do this, open up and edit
  122 /etc/postfix/controlled_envelope_senders (this file likely doesn't exist yet)
  123 
  124 ----
  125 vim /etc/postfix/controlled_envelope_senders
  126 ----
  127 
  128 Once you've got that open, you simply need to put the maps in there.
  129 
  130 ----
  131 # envelope sender owners jcricket@example0.com jimminey
  132 ----
  133 
  134 Now that we've done that, we need to turn it into a binary. Run the following
  135 command and it will generate a <filename>.db binary map file in the same
  136 directory as the original file.
  137 
  138 ----
  139 postmap /etc/postfix/controlled_envelope_senders
  140 ----
  141 
  142 Presto! Now the user jimminey can send email as jcricket@example0.com. However,
  143 so can everyone else...still.
  144 
  145 Now that we have our controlled envelope senders file, we need to reference it
  146 in our postfix main.cf and set postfix up to restrict access to the maps
  147 specified in that file. Crack er open in your favorite editor and put the
  148 following line in somewhere after *smtpd_sasl_auth_enable*
  149 
  150 ----
  151 smtpd_sasl_auth_enable = yes
  152 ...
  153 # This line specifies our map file for use by postfix
  154 # Note that this does NOT reference controlled_envelope_senders.db
  155 smtpd_sender_login_maps = hash:/etc/postfix/controlled_envelope_senders
  156 # This line sets postfix to reject anyone who authenticates but tries to send email as an address they aren't permitted to use
  157 smtpd_recipient_restrictions = reject_sender_login_mismatch, permit_sasl_authenticated, reject_unauth_destination
  158 ----
  159 
  160 So what we've just done is tell Postfix where our map file is
  161 (smtpd_sender_login_maps). After that, we tell Postfix to reject any users that
  162 have been authenticated but are trying to send with an address they aren't
  163 authorized to send with in our map file (smtpd_recipient_restrictions). Please
  164 note that *reject_sender_login_mismatch* comes at the beginning of the
  165 smtpd_recipient_strictions field. This is key. It is so key in fact, that I
  166 missed it (I only miss the key stuff of course thanks Murphy).  This was the
  167 forth exploit attempt that got me.
  168 
  169 
  170 [[misordering-smtpd_recipient_restrictions]]
  171 Misordering smtpd_recipient_restrictions
  172 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  173 
  174 This one is the final bit that let the spammers in (so far at least).
  175 
  176 The smtpd_recipient_restrictions are restrictions that you can place on
  177 the users and their emails based on various things. In my case, I had
  178 the following restrictions string
  179 
  180 ----
  181 smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_sender_login_mismatch, reject_unauth_destination
  182 ----
  183 
  184 Postfix applies these restrictions in the order in which they are specified. As
  185 they put it <blockquote>Restrictions are applied in the order as specified; the
  186 first restriction that matches wins.</blockquote> As soon as one restriction
  187 matches, then the ones that follow don't get applied.  This was very
  188 problematic because in my case permit_mynetworks is first.  So that I can log
  189 in from my cell phone which has an IP address that changes, I set
  190 
  191 ----
  192 mynetworks = 0.0.0.0/0 127.0.0.0/8 [::fff:127.0.0.0]/104 [::1]/128
  193 ----
  194 
  195 which allows any IP address to connect to my SMTP server. Since Postfix takes
  196 the first match and goes no further and any IP address is in 0.0.0.0/0, anyone
  197 can send mail through my SMTP server. This = bad.
  198 
  199 What you should do is start your restrictions with the the most strict
  200 restrictions followed by the less strict. In my case, that looks like
  201 
  202 ----
  203 smtpd_recipient_restrictions = reject_sender_login_mismatch, permit_sasl_authenticated, reject_unauth_destination
  204 ----
  205 
  206 In the event someone tries to send an email, first they must login. If they
  207 don't log in, they are rejected due to reject_sender_login_mismatch (we can't
  208 do a match if we don't have a sender username). Secondly, once logged in, the
  209 user must be authorized to use the address they are trying to send as as
  210 specified in the smtpd_sender_login_maps line.  Finally, once the user has been
  211 authenticated and they have permissions to use the address they are trying to
  212 send as, their email is not rejected. It follows that they are then filtered
  213 through permit_sasl_authenticated. This basically runs a check to see if they
  214 are authenticated (which we know they already are because of the previous
  215 filter) and since they are, they are permitted and Postfix stops looking for
  216 more matches because it's found one that permits the user to perform their
  217 requested action.
  218 
  219 As chef Elzar says, "Bam!"
  220 
  221 
  222 Category:Linux
  223 Category:Postfix
  224 
  225 
  226 // vim: set syntax=asciidoc:

Generated by cgit