Microsoft 365 SMTP Filtering

 

This Linux script ensures that a server running MailArchiva only accepts email traffic from Office 365 Exchange Online servers, thus reducing spam and unauthorized access.

 

How it works

 

  • Fetches the latest Office 365 SMTP IP addresses from Microsoft's endpoint API.
  • Updates iptables to allow only those IP addresses for SMTP port 25.
  • Blocks all other SMTP traffic.
  • Saves rules for persistence.

 

Initial test

 

Run the below command to verify that it outputs a list of IP addresses to allow:
 

CLIENT_REQUEST_ID=$(uuidgen) && curl -s "https://endpoints.office.com/endpoints/worldwide?ClientRequestId=$CLIENT_REQUEST_ID" | jq -r '.[] | select(.serviceArea=="Exchange" and .tcpPorts=="25") | .ips[]'

 

Installation & usage

 

  1. Save the below script as /usr/local/bin/restrict_smtp_to_o365.sh
  2. Make it executable with chmod +x /usr/local/bin/restrict_smtp_to_o365.sh
  3. Run manually to apply the rules with sudo /usr/local/bin/restrict_smtp_to_o365.sh
  4. Automate daily updates by adding a cron job using sudo crontab -e and adding the line 0 2 * * * /usr/local/bin/restrict_smtp_to_o365.sh

 

Verification

 

Check applied rules using sudo iptables -L -n and sudo ip6tables -L -n
Test SMTP access using telnet yourserver.com 25

This ensures that only Office 365 servers can send mail to your SMTP server.

 

Script

 

#!/bin/bash

# Ensure required dependencies are installed
REQUIRED_CMDS=("curl" "jq" "uuidgen" "iptables" "iptables-save" "ip")
for cmd in "${REQUIRED_CMDS[@]}"; do
    if ! command -v "$cmd" &> /dev/null; then
        echo "Error: Required command '$cmd' is not installed. Install it and try again."
        exit 1
    fi
done

# Generate a GUID for Microsoft API request
CLIENT_REQUEST_ID=$(uuidgen)

# Fetch only the IPs for SMTP (port 25) from Office 365
O365_IPS=$(curl -s "https://endpoints.office.com/endpoints/worldwide?ClientRequestId=$CLIENT_REQUEST_ID" | jq -r '.[] | select(.serviceArea=="Exchange" and .tcpPorts=="25") | .ips[]' | grep -E "^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(/[0-9]+)?$")

# If no IPs are found, exit
if [ -z "$O365_IPS" ]; then
    echo "Failed to retrieve Office 365 SMTP IPs. Exiting."
    exit 1
fi

# Flush old iptables rules
iptables -F
iptables -X

# Allow loopback traffic (localhost)
iptables -A INPUT -i lo -j ACCEPT

# Allow established and related connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Detect and allow local subnet dynamically
LOCAL_SUBNET=$(ip -o -4 addr show | awk '$2 != "lo" {print $4}' | head -n1)
if [ -n "$LOCAL_SUBNET" ]; then
    echo "Allowing local subnet: $LOCAL_SUBNET"
    iptables -A INPUT -p tcp --dport 25 -s "$LOCAL_SUBNET" -j ACCEPT
else
    echo "Warning: Could not determine local subnet."
fi

# Allow SMTP traffic only from Office 365 Exchange Online servers
echo "Allowing Office 365 SMTP IPs:"
for ip in $O365_IPS; do
    echo "  - $ip"
    if ! iptables -C INPUT -p tcp --dport 25 -s "$ip" -j ACCEPT 2>/dev/null; then
        iptables -A INPUT -p tcp --dport 25 -s "$ip" -j ACCEPT
    else
        echo "(Rule for $ip already exists, skipping)"
    fi
done

# Block all other SMTP traffic
if ! iptables -C INPUT -p tcp --dport 25 -j DROP 2>/dev/null; then
    iptables -A INPUT -p tcp --dport 25 -j DROP
    echo "Added final rule to block all other SMTP traffic."
else
    echo "Final SMTP block rule already exists, skipping."
fi

# Save iptables rules for persistence
iptables-save > /etc/iptables/rules.v4
echo "$(date) - Updated Office 365 SMTP restrictions" >> /var/log/o365_smtp_restrictions.log
echo "Office 365 SMTP restrictions successfully applied!"

 

 

Was this helpful?
© 2005 - 2025 ProProfs

Found this information useful? Visit mailarchiva.com to learn more about MailArchiva.
-