How to Block All Amazon AWS IP Ranges Using iptables on Ubuntu 14.04 LTS


4 views

Amazon Web Services publishes their current IP ranges in JSON format, which gets updated regularly. The official documentation can be found at AWS IP Ranges. This JSON file contains all the IP prefixes for AWS services globally, organized by region and service.

First, we need to fetch and process the JSON file to extract the IP ranges:

#!/bin/bash
# Download AWS IP ranges
wget -q -O aws-ip-ranges.json http://ip-ranges.amazonaws.com/ip-ranges.json

# Extract IPv4 ranges and convert to iptables format
jq -r '.prefixes[] | .ip_prefix' aws-ip-ranges.json > aws-ipv4-ranges.txt

# Alternatively for IPv6:
jq -r '.ipv6_prefixes[] | .ipv6_prefix' aws-ip-ranges.json > aws-ipv6-ranges.txt

We'll create a dedicated chain for AWS blocking to keep our rules organized:

#!/bin/bash
# Create a new chain for AWS blocking
iptables -N AWS_BLOCK
iptables -I INPUT -j AWS_BLOCK

# Add rules for each IP range
while read -r ip_range; do
    iptables -A AWS_BLOCK -s "$ip_range" -j DROP
done < aws-ipv4-ranges.txt

# For IPv6 (if needed)
while read -r ip_range; do
    ip6tables -A AWS_BLOCK -s "$ip_range" -j DROP
done < aws-ipv6-ranges.txt

Since AWS updates their IP ranges periodically, we should create a cron job to update our rules:

#!/bin/bash
# Save current rules
iptables-save > /etc/iptables.rules

# Flush AWS_BLOCK chain
iptables -F AWS_BLOCK

# Recreate rules with updated IP ranges
wget -q -O /tmp/aws-ip-ranges.json http://ip-ranges.amazonaws.com/ip-ranges.json
jq -r '.prefixes[] | .ip_prefix' /tmp/aws-ip-ranges.json | while read -r ip_range; do
    iptables -A AWS_BLOCK -s "$ip_range" -j DROP
done

# Save new rules
iptables-save > /etc/iptables.rules

Add this script to cron to run weekly:

0 3 * * 0 root /usr/local/bin/update-aws-iptables.sh

For better performance with large IP ranges, consider using ipset:

#!/bin/bash
# Create ipset
ipset create AWS_BLOCK hash:net

# Add IP ranges
while read -r ip_range; do
    ipset add AWS_BLOCK "$ip_range"
done < aws-ipv4-ranges.txt

# Create iptables rule referencing the ipset
iptables -I INPUT -m set --match-set AWS_BLOCK src -j DROP

To test if the blocking works:

# Check if rules are loaded
iptables -L AWS_BLOCK -n --line-numbers

# Test with an AWS IP (replace with actual AWS IP)
ping -c 1 52.95.110.1
  • Monitor your logs for false positives
  • Consider whitelisting specific AWS IPs if needed
  • Remember this will block all AWS services including EC2, S3, etc.
  • For production systems, implement this carefully with monitoring

Amazon Web Services (AWS) publishes its current IP address ranges in JSON format, which is regularly updated. These ranges cover all AWS services including EC2, S3, and CloudFront. You can access this data at:

http://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html

For Ubuntu 14.04 LTS servers, iptables is the most effective way to block traffic. We'll create a script that:

  1. Downloads the latest AWS IP ranges
  2. Generates iptables rules
  3. Applies them in a dedicated chain

First, create a script to fetch and process AWS IP ranges:

#!/bin/bash
# Script to update AWS IP block rules
RULES_FILE="/etc/iptables/aws-block.rules"
TEMP_FILE="/tmp/aws-ips.json"

# Download current AWS IP ranges
wget -qO $TEMP_FILE https://ip-ranges.amazonaws.com/ip-ranges.json

# Create new rules file
echo "*filter" > $RULES_FILE
echo ":AWS-BLOCK - [0:0]" >> $RULES_FILE

# Parse JSON and create rules
jq -r '.prefixes[] | .ip_prefix' $TEMP_FILE | while read ip; do
  echo "-A AWS-BLOCK -s $ip -j DROP" >> $RULES_FILE
done

echo "COMMIT" >> $RULES_FILE

After generating the rules file, apply them with:

# Flush existing AWS-BLOCK chain if it exists
iptables -F AWS-BLOCK 2>/dev/null

# Create new chain if needed
iptables -N AWS-BLOCK 2>/dev/null || true

# Apply new rules
iptables-restore < /etc/iptables/aws-block.rules

# Reference the chain from INPUT
iptables -I INPUT -j AWS-BLOCK

To keep your rules current, set up a cron job:

# Add to crontab (run weekly)
0 3 * * 0 /usr/local/bin/update-aws-iptables.sh

For better performance with many IP ranges, consider using ipset:

# Create ipset
ipset create aws-block hash:net

# Add IP ranges
jq -r '.prefixes[] | .ip_prefix' ip-ranges.json | while read ip; do
  ipset add aws-block $ip
done

# Reference in iptables
iptables -I INPUT -m set --match-set aws-block src -j DROP

Check that the rules are properly applied:

iptables -L AWS-BLOCK -n --line-numbers
ipset list aws-block  # if using ipset
  • Test rules in a non-production environment first
  • Consider maintaining an allowlist for essential AWS services you might need
  • Monitor your system logs after implementation
  • Be aware that AWS IP ranges change frequently