Here's the scenario. You host your primary mail server at an ISP that allows SMTP (port 25) into their network. You host your backup mail server at a different ISP that also allows SMTP into their network, but blocks SMTP from leaving their network (to stop spam zombies). Here's the problem with that. When the backup mail server relay's mail to the primary mail server (who's listening on port 25) it will be blocked.
To fix this we will need a way to get the backup mail server to send it's mail to the primary mail server on a higher unblocked port. This means we have to get the primary mail server to listen on it's regular SMTP port and a new higher port.
This example will use Postfix to do this. This test was done with Postfix version 2.5. I'll assume it will work with higher versions.
We will start with the primary mail server. All we need to do is get it to listen on a second port. To do this put the following line in the /etc/postfix/master.cf file. You can put this line under the line that starts with smtpd if you like. It will make Postfix listen on port 2525. Postfix will still listen on port 25 as usual.
2525 inet n - - - - smtpd
Then restart postfix
postfix restart
Now the primary mail server is listening on port 25 and port 2525. On to the backup mail server.
On the backup mail server edit the /etc/postfix/transport file. Put in the line below. Substitute pantz.org for the name of the domain you want to receive mail on. Change mail.pantz.org to the name of your primary mail server.
pantz.org smtp:[mail.pantz.org]:2525
Now make the transport db.
postmap /etc/postfix/transport
That's it. No restarting postfix needed. Now when mail is delivered to the backup mail server for the pantz.org domain it will be sent to the primary mail server on port 2525 which the backup servers ISP allows out.
Don't forget to open any new ports on those firewalls since 2525 is an odd port. It's likely to be blocked.
So I have a Trac install and wanted to be able to open tickets with an email. No problem. Some nice person has written a python script to do so. I download it and go about installing it and configuring it on CentOS 4. After configuring it I need to setup an MTA to feed it. I choose Postfix 2.2.10 since it was already on the machine. To setup Postfix with the script you just put a line in your aliases file that pipes the incoming email to the trac2email script.
Since the Trac files and db's are owned by the web server user apache I need the Trac script to be run as the apache user. Postfix makes this really simple. It's best described by the group that makes the script.
You can run a delivery command as any user just by placing the aliases in a separate file and chowning that aliases file to the user you want the delivery to run as. Then you run postalias /path/to/aliases, which will create /path/to/aliases.db, and you then just add hash:/path/to/aliases to the alias_maps config variable in main.cf. The only caveat is that the user who owns the separate aliases file needs to have write perms to the directory that it's stored in.
So I make an aliase file and put in the following line.
tickets: "|/usr/bin/email2trac [--project=]"
Then chown it to the apache user:group and run my postalias command on it. I put the hash line in the alias_maps config and restarted postfix. That's when the problem started. When sending an email to the alias I was getting the error "db.commit() pysqlite2.dbapi2.OperationalError: database or disk is full".
I check if the disk is full and it is not even near full. I know the SQLite db does not have a set limit so I'm totally perplexed by this error message. I decide to run an strace on the script and see what it's actually doing. To do this you can just put "strace -o /tmp/trace" right after the | in the pipe command. I send another email and look at the trace file. I find the interesting error when the script tries to write to the SQLite db. The error is "write(3, ...)= -1 EFBIG (File too large) --- SIGXFSZ (File size limit exceeded)". (3,...) is the sqlite.db file in the trace.
File to large tells me there is a limit somewhere and I need to find out how to bump it up. Making a new Trac site and running the same script the email goes through fine. Other existing Trac sites on the same server work fine with the emal2trac script also. It's now down to just this one site that does not work.
Finally I start zeroing in on the SQLite db size. Most of the other sites have smaller db's which are like 10 to 40 megs. The Trac site with the problem has a 60meg db. Now why can the script write to a 40meg db but not a 60meg db?
I crack open the Postfix mail.cf file and start looking at different size limits in there for different things. I know I"m looking for something possibly in the over 40meg range. The one that sticks out is the mailbox_size_limit setting. It's set to its default of 51200000 bytes. That's 52meg. I change it to 0 which is unlimited and save and exit. Restart Postfix. Send another test email and BAM! Mail goes right through.
Somehow in Postfix mailbox_size_limit is not just the mailbox size limit. It also seems to be connected to any file the pipe process opens. If a file is opened bigger than the limit set it will not be able to write to the opened file. This process limit by Postfix makes it look to SQLite like the disk is full. I only tested this with 2.2.10 of postfix. It might be different later versions.
Postfix is a free, simple, and secure MTA (e-mail server). It has been ported to most Unixes and it's configuration files are the same across all platforms. It is Sendmail compatible also. The install below will be for OpenBSD 3.8 using Postfix version 2.3. Any of the config files below could be used on any other type of Unix that Postfix has been ported to. Paths, mailowner, setgid, etc will have to be changed to the local systems settings.
I'll leave it up to you to put in the mx records in DNS for this mail servers hostname. If this will be your only mail server then you don't need an MX record. If a mail server recieves an e-mail and there is no corresponding MX record for mail delivery it will default to using the A record for that host. A mx record is best practice though.
A quick description on what Postfix does when it recieves mail. Postfix will be started and listen on port 25 by default. If you have a firewall open port 25. Postfix will eventaully recieve a connection from another mail server on port 25. It will process the e-mail (header and body checks, real time blacklist, RFC compliance, etc) and if all of our checks pass it is handed off to procmail for delivery. Procmail is an mail delivery agent (MDA). Procmail will take the e-mail do any processing it has been told to do (.procmailrc scripts) and place the e-mail into the users mailbox.
Install the latest Postfix and Procmail. For this install example it will be for OpenBSD 3.8.
pkg_add -v http://openbsd.secsup.org/3.8/packages/i386/postfix-2.3.20050716.tgz
pkg_add -v http://openbsd.secsup.org/3.8/packages/i386/procmail-3.22p0.tgz
Now that the software is installed we need to setup the config files. The config files will be listed below. Edit to your configuration needs.
First file is OpenBSD's startup file. It's in /etc/rc.conf. Edit this file and change the lines in it already to look like the lines below. First line will start Postfix when the system boots. The second line will open a socket for Postfix logging.
sendmail_flags="-bd -q30m" syslogd_flags="-a /var/spool/postfix/dev/log"
The postfix setup will be used on a server that will not deliver mail itself but will forward it's mail to another mail server to deliver it. On this host the mail is being sent to what is called a relay host (smarthost). I beleive if you leave this blank postfix will deliver the mail itself. Check your /etc/aliases file and be sure to set up aliases that send mail for root and postmaster to a real person, then run /usr/local/sbin/newaliases. To setup postfix as the primary mailer on the system run: /usr/local/sbin/postfix-enable. To put it back to sendmail run: /usr/local/sbin/postfix-disable. Make sure to change the myorigin/mydestination/mynetworks sections below to your configuration needs.
For procmail to deliver the mail it will need access to the /var/mail directory. Procmail will run as the user to deliver the mail. It will try to place the mail in a file with the users account name on the system. You might have to create this file and give it the correct permissions before procmail will deliver the mail to it. If mail is not being delivered right check the mail logfile or the system log file. If it mentions procmail and permissions blah blah blah then try these commands as root: "touch /var/mail/username" then "chown username.wheel /var/mail/username" then "chmod 600 /var/log/username".
Put the settings below in the file /etc/postfix/main.cf. Remember the config below is for OpenBSD so the directories settings are set for OpenBSD. So are the mail_owner and setgid_group settings. You will need to change these to what your install is using. If your using OpenBSD then you will be ok unless something has changed in later versions. Also be aware of the smtp restricitons area at the bottom. I use these settings to cut down on my spam considerably. They are not conserative by any means but you will have to try them yourself.
### see /usr/share/postfix/main.cf.dist for a commented, fuller ### version of this file. ### Do not change these directory settings - they are critical to Postfix ### operation. biff = no recipient_delimiter = + command_directory = /usr/local/sbin daemon_directory = /usr/local/libexec/postfix program_directory = /usr/local/libexec/postfix alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases ### No one needs to know what we run. So I'll give them this. mail_name = mail.yourdomain.org smtpd_banner = ESMTP $mail_name ### Who delivers the mail (never root for security). mail_owner = _postfix setgid_group = _postdrop ### appending .domain should be the MUA's job. append_dot_mydomain = no append_at_myorigin = yes ### Relay Host this mail server should send its mail to if need be. relayhost = smtp.yourisp.net ### Valid hostname of this system known as the mail server (must be a fqdn !) ### What other mailservers see us as. myhostname = mail.yourdomain.org ### The mydestination parameter specifies what domains this machine will deliver locally, instead ### of forwarding to another machine. The default is to receive mail for the machine itself. mydestination = yourdomain.org,blah.yourdomain.com,$myhostname,localhost.localdomain, ,localhost ### maps for virtual domains virtual_alias_maps = hash:/etc/postfix/virtual ### External Networks to accept RELAYED mail from. mynetworks = 192.168.0.0/24, 127.0.0.0/8 ### Where to send mail that is delivered locally. mailbox_command = procmail -a "$EXTENSION" ### How much of the message in bytes will be bounced back to the sender. bounce_size_limit = 2000 ### No limit on mailbox size. mailbox_size_limit = 0 ### Limit sent/recieved emails to 100 Megs "(header+body+attachment)x(mime-encoding) <= 100 meg" message_size_limit = 102400000 ### How long do messages stay in the queue before being sent back to the sender. (in days) ### By default, postfix attempts to resend the message every (1000 secs)x(# attempts)x(days). maximal_queue_lifetime = 1d bounce_queue_lifetime = 1d ### Parrallel delivery force (local=2 and dest=20 are default) local_destination_concurrency_limit = 2 initial_destination_concurrency = 10 default_destination_concurrency_limit = 50 ### Limits the mail inflow to 100 messages per second above the number of messages delivered per second. in_flow_delay = 1s ###Clients must send a HELO (or EHLO) command at the beginning of an SMTP session. smtpd_helo_required = yes ### No one needs to ask our server who is on it. If you do, you get smacked with the tarpit and then an error. disable_vrfy_command = yes ### Reject immediately. Do not delay until RCPT TO: to reject the email smtpd_delay_reject = yes ### Tarpit those bots/clients/spammers who send errors or scan for accounts smtpd_error_sleep_time = 10 smtpd_soft_error_limit = 2 smtpd_hard_error_limit = 5 smtpd_junk_command_limit = 3 ### Require strict RFC 821-style envelope addresses strict_rfc821_envelopes = yes ### Limit the info given to outside servers show_user_unknown_table_name = no ### Message Limitations. Uncomment and use if needed. #header_checks = regexp:/etc/postfix/header_checks #body_checks = regexp:/etc/postfix/body_checks ### Reject codes access_map_reject_code = 554 defer_code = 554 invalid_hostname_reject_code = 554 maps_rbl_reject_code = 554 non_fqdn_reject_code = 554 reject_code = 554 relay_domains_reject_code = 554 unknown_address_reject_code = 554 unknown_client_reject_code = 554 unknown_hostname_reject_code = 554 unknown_local_recipient_reject_code = 554 unknown_relay_recipient_reject_code = 554 unknown_virtual_alias_reject_code = 554 unknown_virtual_mailbox_reject_code = 554 ### SMTP Restrictions smtpd_client_restrictions = permit_mynetworks, reject_unknown_client, check_client_access regexp:/etc/postfix/client_restrictions smtpd_helo_restrictions = permit_mynetworks, reject_non_fqdn_hostname, check_helo_access hash:/etc/postfix/access, warn_if_reject reject_invalid_hostname smtpd_etrn_restrictions = permit_mynetworks, reject smtpd_sender_restrictions = permit_mynetworks, reject_non_fqdn_sender, reject_unknown_sender_domain, reject_unknown_address smtpd_recipient_restrictions = reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unknown_sender_domain, reject_unknown_recipient_domain, permit_mynetworks, reject_unauth_destination, reject_multi_recipient_bounce, reject_non_fqdn_hostname, reject_invalid_hostname, reject_unknown_client, warn_if_reject reject_unknown_hostname, reject_unauth_pipelining, reject_rhsbl_sender dsn.rfc-ignorant.org reject_rhsbl_sender bogusmx.rfc-ignorant.org, reject_rbl_client bl.spamcop.net, reject_rbl_client sbl-xbl.spamhaus.org, reject_rbl_client list.dsbl.org, # reject_unverified_sender permit smtpd_data_restrictions = reject_unauth_pipelining, reject_multi_recipient_bounce, permit ########################## END #########################################
Client restrictions for postfix. Put these settings in the file /etc/postfix/client_restrictions. Edit to your needs or just don't use. Comment the line in main.cf if you don't use these.
# List taken from http://www.gabacho-net.jp/en/anti-spam/anti-spam-system.html # To test regular expressions below use "grep -e" from the command line. If you see the hostname echo'ed the regex worked. # For example: echo 'blah.hotmail.com' | grep -e '\.hotmail\.com$' ### WHITE LIST ### /\.amazon\.com$/ OK /\.dell\.com$/ OK /\.ibm\.com$/ OK /\.yahoo\.com$/ OK /\.hotmail\.com$/ OK /\.paypal\.com$/ OK # mc1-s3.bay6.hotmail.com, etc. /\.bay[0-9]+\.hotmail\.com$/ OK # Whitelist Examples # # h04-a1.data-hotel.net, etc. # /\.data-hotel\.net$/ OK # # web10902.mail.bbt.yahoo.co.jp # /^web[0-9]+\.mail\.(.+\.)?yahoo\.co\.jp$/ OK # # web35509.mail.mud.yahoo.com # /^web[0-9]+\.mail\.(.+\.)?yahoo\.com$/ OK # # c151240.vh.plala.or.jp # /\.vh\.plala\.or\.jp$/ OK # # n2.59-106-41-68.mixi.jp, etc. # /\.mixi\.jp$/ OK # # mta12.m2.home.ne.jp, etc. # /\.m2\.home\.ne\.jp$/ OK # # mmrts006p01c.softbank.ne.jp, etc. # tgmsmtkn01sc1.softbank.ne.jp, etc. # /\.softbank\.ne\.jp$/ OK # # imt1omta04-s0.ezweb.ne.jp, etc. # /\.ezweb\.ne\.jp$/ OK # # bay-w1-inf5.verisign.net # benicia-w2-inf30.verisign.net # /\.verisign\.net$/ OK # # web10902.mail.bbt.yahoo.co.jp #/^web[0-9]+\.mail\.(.+\.)?yahoo\.co\.jp$/ OK # # ip address # /^202\.222\.18\.17$/ OK ### BLACK LIST ### /\.(internetdsl|adsl|sdi)\.tpnet\.pl$/ 450 domain check tpnet /^user.+\.mindspring\.com$/ 450 domain check mind /[0-9a-f]{4}\.[a-z]+\.pppool\.de$/ 450 domain check pppool /\.dip\.t-dialin\.net$/ 450 domain check t-dialin /\.(adsl|cable)\.wanadoo\.nl$/ 450 domain check wanadoo /\.ipt\.aol\.com$/ 450 domain check aol # 85.155.10.73.dyn.user.ono.com /\.user\.ono\.com$/ 450 domain check ono # Blacklist Examples # # pr86.internetdsl.tpnet.pl # fq217.neoplus.adsl.tpnet.pl # pa148.braniewo.sdi.tpnet.pl #/\.(internetdsl|adsl|sdi)\.tpnet\.pl$/ 450 domain check # # user-0cetcbr.cable.mindspring.com # user-vc8fldi.biz.mindspring.com #/^user.+\.mindspring\.com$/ 450 domain check # # c9531ecc.virtua.com.br (hexadecimal used) #/^[0-9a-f]{8}\.virtua\.com\.br$/ 450 domain check # # catv-5984bdee.catv.broadband.hu (hexadecimal used) #/\.catv\.broadband\.hu$/ 450 domain check # # Edc3e.e.pppool.de # BAA1408.baa.pppool.de #/[0-9a-f]{4}\.[a-z]+\.pppool\.de$/ 450 domain check # # xdsl-5790.lubin.dialog.net.pl #/^xdsl.+\.dialog\.net\.pl$/ 450 domain check # # pD9EB80CB.dip0.t-ipconnect.de (hexadecimal used) #/\.dip[0-9]+\.t-ipconnect\.de$/ 450 domain check # # pD9E799A1.dip.t-dialin.net (hexadecimal used) #/\.dip\.t-dialin\.net$/ 450 domain check # # ool-43511bdc.dyn.optonline.net (hexadecimal used) #/\.dyn\.optonline\.net$/ 450 domain check # # rt-dkz-1699.adsl.wanadoo.nl # c3eea5738.cable.wanadoo.nl (hexadecimal used) #/\.(adsl|cable)\.wanadoo\.nl$/ 450 domain check # # ACBBD419.ipt.aol.com (hexadecimal used) #/\.ipt\.aol\.com$/ ### Generic Block ### /^(pool|cable|dhcp|dialup|ppp|adsl)[^.]*[0-9]/ 450 checking dynamic isp #Generic Examples # # ex: evrtwa1-ar3-4-65-157-048.evrtwa1.dsl-verizon.net # ex: a12a190.neo.rr.com /^[^.]*[0-9][^0-9.]+[0-9]/ 450 S25R check1 # # ex: pcp04083532pcs.levtwn01.pa.comcast.net /^[^.]*[0-9]{5}/ 450 S25R check2 # # ex: 398pkj.cm.chello.no # ex: host.101.169.23.62.rev.coltfrance.com /^([^.]+\.)?[0-9][^.]*\.[^.]+\..+\.[a-z]/ 450 S25R check3 # # ex: wbar9.chi1-4-11-085-222.dsl-verizon.net /^[^.]*[0-9]\.[^.]*[0-9]-[0-9]/ 450 S25R check4 # # ex: d5.GtokyoFL27.vectant.ne.jp /^[^.]*[0-9]\.[^.]*[0-9]\.[^.]+\..+\./ 450 S25R check5 # # ex: dhcp0339.vpm.resnet.group.upenn.edu # ex: dialupM107.ptld.uswest.net # ex: PPPbf708.tokyo-ip.dti.ne.jp # ex: adsl-1415.camtel.net # /^(dhcp|dialup|ppp|adsl)[^.]*[0-9]/ 450 S25R check
Header checks for postfix. Put these settings in the file /etc/postfix/header_checks. Edit to your needs or just don't use. Comment the line in main.cf if you don't use these.
#### Header checks file #### Checks are done in order, top to bottom. #### /etc/postfix/header_checks #### non-RFC Compliance /[^[:print:]]{7}/ REJECT RFC2047 /^.*=20[a-z]*=20[a-z]*=20[a-z]*=20[a-z]*/ REJECT RFC822 /(.*)?\{6,\}/ REJECT RFC822 /(.*)[X|x]\{3,\}/ REJECT RFC822 #### Unreadable NON-acsii un-printable text /^Subject:.*=\?(GB2312|big5|euc-kr|ks_c_5601-1987|koi8)\?/ REJECT Unreadable /^Content-Type:.*charset="?(GB2312|big5|euc-kr|ks_c_5601-1987|koi8|iso-2022-jp)/ REJECT Unreadable #### Subject checks /^Subject:.* / REJECT Space /^Subject:.*r[ _\.\*\-]+o[ _\.\*\-]+l[ _\.\*\-]+e[ _\.\*\-]+x/ REJECT Hidden Words /^Subject:.*p[ _\.\*\-]+o[ _\.\*\-]+r[ _\.\*\-]+n/ REJECT Hidden Words #### Character Set Checks /^(Content-Type:.*|\s+)charset\s*=\s*"?(Windows-1251)\?/ REJECT Bad Content Type #### Attachments /^Content-(Type|Disposition):.*(file)?name=.*\.(ade|adp|asd|asf|asx|bat|bhx|chm|cil|cmd|com|cpl|dll|elm|exe|gif|hlp|hta|jse|lnk|mda|mdb|mde|mdw|mim|msi|msp|nws|ocx|pif|reg|scr|sct|shb|shm|shs|vb|vbe|vbs|vbx|vxd|wmf|wms|wmz|wmd|wsc|wsf|wsh|wsz)/ REJECT Bad Attachment .${3} #### Backscatter mail from virus scanners /^Subject:.*Anti-Virus Notification/ REJECT Virus Notification /^Subject:.*due to virus/ REJECT Virus Notification /^Subject:.*email contains VIRUS/ REJECT Virus Notification /^Subject:.*InterScanMSS/ REJECT Virus Notification /^Subject:.*ScanMail for Lotus/ REJECT Virus Notification /^Subject:.*Symantec AntiVirus/ REJECT Virus Notification /^Subject:.*Virus Detected by Network Associates/ REJECT Virus Notification /^subject:.*virus found/ REJECT Virus Notification /^subject:.*Virus Infection Alert/ REJECT Virus Notification #### Known Spammers or Unsolicited Commercial Email /^Received:.*bellevuellc.com/ REJECT Blacklisted /^Received:.*ccsurvey.com/ REJECT Blacklisted /^Received:.*cmptechdirect.com/ REJECT Blacklisted /^Received:.*constantcontact.com/ REJECT Blacklisted /^Received:.*dartmail.net/ REJECT Blacklisted /^Received:.*ema10.net/ REJECT Blacklisted /^Received:.*evmailer.com/ REJECT Blacklisted /^Received:.*netline.com/ REJECT Blacklisted #/^From:.*163.com/ REJECT Blacklisted
Body checks for Postfix. Put these settings in the file /etc/postfix/body_checks. Edit to your needs or just don't use. Comment the line in main.cf if you don't use these.
# Postfix body_checks # /etc/postfix/body_checks #### General body checks. Uncomment and change examples if needed. #/http:\/\/.*\.info/ REJECT dotinfo #/lottery/ REJECT lottery #/Viagra/ REJECT viagra #/Cialis/ REJECT cialis #/Valium/ REJECT valium #/Xanax/ REJECT xanax #/Tramadol/ REJECT tramadol
Helo checks for Postfix. Put the names and ip's of your domains in the file /etc/postfix/helo_access. No sender should ever give a helo statement with the name of the server or the ip address of the mail server (example uses 1.1.1.1). Uncomment in config if you need to use it. Not a must but the more filters the better. Comment the line in main.cf if you don't use these.
localhost REJECT 554 misconfigured sender mail.yourservername.org REJECT 554 misconfigured sender 1.1.1.1 REJECT 554 misconfigured sender
Alias file for Postfix. Put these settings in the file /etc/aliases. Edit to your needs. It system-wide mechanism to redirect mail for local recipients. You will need to use this.
# Don't forget to run the command "newaliases" after editing this file! postmaster: root abuse: root root: username1 #bob: username2 #everyone: username1,username2 #roger: [email protected]
This is virtual delivery file for Postfix. Put these settings in the file /etc/postfix/virtual. Edit to your needs. The virtual delivery file is designed for virtual mail hosting services. If you have virtual domains put them here. Mail is delivered by the virtual delivery agent in postfix. Virtual alias lookups are useful to redirect mail for virtual alias domains to real user mailboxes, and to redirect mail for domains that no longer exist. Virtual alias lookups can also be used to transform Firstname.Lastname back into UNIX login names, although local aliases may be better for that. Don't forget to run the command: "postmap /etc/postfix/virtual" after editing this file.
#The left hand side are virtual e-mail aliases. The right hand side #are local system login names or names that reference the alias file. #After editing this file run the command: postmap /etc/postfix/virtual # example1.org username [email protected] bob [email protected] roger [email protected] bob # example2.org username [email protected] bob [email protected] roger [email protected] roger [email protected] bob
You can start Postfix with the "postfix start" command. It should start if you setup all your paths and configs correctly. If not check the mail log file. OpenBSD's is /var/log/mail. Other systems use this also so look in it for any errors. Thats it. You should be close to rolling. There are some hints and tips below to check out.
Check out a perl script called pflogsumm. It will e-mail you very helpful Postfix stats everyday. Fantastic program.
Here is a list some helpful postfix commands that I don't want to forget. They are below with comments.
postfix start # start postfix postfix stop # stop postfix postfix reload # reload postfix like after changing the main.conf file mailq # see what mail is in the mail queue. same as command: postqueue -p postqueue -f # do a mail queue run and try to deliver the mail in the queue postqueue -s site # do a queue run for a certain "site" (domain) postsuper -d queue_id # delete a specific message from the mail queue by it's id. postsuper -d ALL # delete all mail from the mail queue postsuper -h queue_id # put a message in the mail queue on hold postsuper -H queue_id # take a message off hold postconf # shows you all the parameters (settings) of the running postfix