Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@stevejenkins
Last active June 10, 2017 00:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevejenkins/b8898f3632561f9999f4 to your computer and use it in GitHub Desktop.
Save stevejenkins/b8898f3632561f9999f4 to your computer and use it in GitHub Desktop.
Script for creating a Postfix whitelist for MSFT servers (Hotmail, Outlook.com)
#! /bin/sh
#
# Copyright (c) 2015 Steve Jenkins <steve@stevejenkins.com>
#
# Based on gwhitelist script by Mike Miller <mmiller@mgm51.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# a quick script to output the current list of Outlook.com outbound smtp servers
# in a format suitable for Postfix's postscreen whitelist CIDR file.
#
# the list of CIDR-formatted addresses, each followed by the word "permit"
# is printed to stdout. It is up to you to mesh this output into your
# postscreen processing on a recurring basis.
#
# version history
# 20151122 1.0 sj - initial release
# 20151124 1.1 sj - added spf.protection.outlook.com queries
# 20151125 1.1 sj - made postfix reload optional
#
# make sure the mktemp command syntax is appropriate for your OS.
# this works on FreeBSD 9.1 and Debian GNU/Linux 6.0.6
tmpBase=`basename $0`
tmpNetBlocks1=`mktemp -q /tmp/${tmpBase}.XXXXXX`
if [ $? -ne 0 ]; then
echo "$0: Can't create temp file, exiting..."
exit 1
fi
tmpNetBlocks2=`mktemp -q /tmp/${tmpBase}.XXXXXX`
if [ $? -ne 0 ]; then
echo "$0: Can't create temp file, exiting..."
exit 1
fi
# abort on any error
set -e
# Identify nameservers
nameServer1="ns1.msft.net"
nameServer2="ns1a.o365filtering.com"
# obtain and format the netblocks for subsequent look-ups
spfString1=`dig @${nameServer1} outlook.com txt | grep spf1 | cut -f6`
spfString2=`dig @${nameServer2} spf.protection.outlook.com txt | grep spf1 | cut -f4`
spfString3=`dig @${nameServer2} spfa.protection.outlook.com txt | grep spf1 | cut -f3`
spfString4=`dig @${nameServer2} spfb.protection.outlook.com txt | grep spf1 | cut -f3`
printf "%s\n" ${spfString1} | grep "^include" | cut -c9- | \
sed s/^/' @'$nameServer1' '/ | sed s/$/' txt'/ > ${tmpNetBlocks1}
# get the IP addresses from the netblocks
nbString1=`dig -f ${tmpNetBlocks1} | grep ^spf- | cut -f5`
nbString2=`dig -f ${tmpNetBlocks1} | grep ^_spf | cut -f4`
printf "%s\n" ${nbString1} | grep "^ip" | cut -c5- | \
sed s/$/" permit"/
printf "%s\n" ${nbString2} | grep "^ip" | cut -c5- | \
sed s/$/" permit"/
# get the IP addresses directly from the SPF records
printf "%s\n" ${spfString2} | grep "^ip" | cut -c5- | \
sed s/$/" permit"/
printf "%s\n" ${spfString3} | grep "^ip" | cut -c5- | \
sed s/$/" permit"/
printf "%s\n" ${spfString4} | grep "^ip" | cut -c5- | \
sed s/$/" permit"/
# clean up
test -e ${tmpNetBlocks1} && rm ${tmpNetBlocks1}
# Uncomment if you want this script to reload Postfix config
#/usr/sbin/postfix reload
@jcbf
Copy link

jcbf commented Nov 25, 2015

Hi ,
For shell scripting and SPF I use spa-tools ( https://github.com/jsarenik/spf-tools ). Avoids using the hardcoded spfX stuff.

@stevejenkins
Copy link
Author

Thanks, @jcbf. I'll check it out!

@stevejenkins
Copy link
Author

Very slick! WIsh I'd seen this sooner! LOL

Planning to modify my scripts to take advantage of this. Maybe I'll move these over to a full GitHub repo for easier tracking. Thx. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment