Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mmitech/f8a7db4e31820cc0dd25e27db0085dee to your computer and use it in GitHub Desktop.
Save mmitech/f8a7db4e31820cc0dd25e27db0085dee to your computer and use it in GitHub Desktop.

Revisions

  1. @rafaelfelix rafaelfelix revised this gist Jun 9, 2016. 1 changed file with 12 additions and 4 deletions.
    16 changes: 12 additions & 4 deletions sync_cloudflare_ips_with_aws_security_group.sh
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@

    # show usage
    show_usage() {
    echo "usage: $0 -s <SECURITY-GROUP-ID> -p <tcp|udp|icmp> -t <PORT-NUMBER> -n <SNS-TOPIC>"
    echo "usage: $0 -r <REGION> -s <SECURITY-GROUP-ID> -p <tcp|udp|icmp> -t <PORT-NUMBER> -n <SNS-TOPIC>"
    }

    # log message to STDOUT
    @@ -40,8 +40,11 @@ execute_command() {

    ## MAIN
    # ARGS parse
    while getopts ":s:p:t:n:" opt; do
    while getopts ":r:s:p:t:n:" opt; do
    case $opt in
    r)
    REGION=$OPTARG
    ;;
    s)
    SECURITY_GROUP_ID=$OPTARG
    ;;
    @@ -77,12 +80,17 @@ if [ -z $SNS_TOPIC ]; then
    SNS_TOPIC=false
    fi

    # if REGION is not passed, set to us-east-1
    if [ -z $REGION ]; then
    REGION="us-east-1"
    fi

    TMP=$(mktemp)
    ALLOWED_IP_RANGES=$(mktemp)
    CLOUDFLARE_IP_RANGES=$(mktemp)

    # Get current ingress rules for port 80, protocol tcp for the given security group id (sorted by ip address range)
    execute_command "aws ec2 describe-security-groups --group-id $SECURITY_GROUP_ID" $TMP $SNS_TOPIC false
    execute_command "aws ec2 describe-security-groups --group-id $SECURITY_GROUP_ID --region $REGION" $TMP $SNS_TOPIC false

    cat $TMP | jq ".SecurityGroups[].IpPermissions[] | select(.FromPort == ${PORT} and .ToPort == ${PORT} and .IpProtocol == \"${PROTOCOL}\") | .IpRanges[] | .CidrIp" | tr -d '"' | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n > $ALLOWED_IP_RANGES
    log "security group ip ranges allowed for protocol $PROTOCOL and port $PORT: $(cat $ALLOWED_IP_RANGES)"
    @@ -99,7 +107,7 @@ log "issuing diff -u between security group existing ip addresses and cloudflare
    MISSING_CF_IP_RANGES=$(diff -u $ALLOWED_IP_RANGES $CLOUDFLARE_IP_RANGES | grep '^+' | grep -v '+++' | tr -d '+')
    log "missing Cloudflare IP Ranges: $MISSING_CF_IP_RANGES"
    for IP_RANGE in $MISSING_CF_IP_RANGES; do
    execute_command "aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol $PROTOCOL --port $PORT --cidr $IP_RANGE" $TMP $SNS_TOPIC true
    execute_command "aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol $PROTOCOL --port $PORT --cidr $IP_RANGE --region $REGION" $TMP $SNS_TOPIC true
    done

    log "clean up"
  2. @rafaelfelix rafaelfelix created this gist Nov 9, 2015.
    106 changes: 106 additions & 0 deletions sync_cloudflare_ips_with_aws_security_group.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,106 @@
    #!/bin/bash

    #
    # Adds Cloudflare IPV4 addresses to the Inbound rules of a AWS Security Group
    #

    ## defining helper functions first

    # show usage
    show_usage() {
    echo "usage: $0 -s <SECURITY-GROUP-ID> -p <tcp|udp|icmp> -t <PORT-NUMBER> -n <SNS-TOPIC>"
    }

    # log message to STDOUT
    log() {
    echo "[$(date)]: $*"
    }

    # wraps command execution to log possible failures and publish sns topics
    execute_command() {
    CMD="$1"
    TMP_FILE="$2"
    SNS_TOPIC="$3"
    SEND_ON_SUCCESS="$4"
    log "issuing $CMD"
    OUTPUT=$($CMD 2>&1 > $TMP_FILE)
    CMD_EXIT_STATUS=$?
    if [ $CMD_EXIT_STATUS -ne 0 ]; then
    MESSAGE="$CMD failed with status $CMD_EXIT_STATUS: $OUTPUT"
    log $MESSAGE
    [ $SNS_TOPIC != false ] && aws sns publish --topic-arn $SNS_TOPIC --message "$MESSAGE" --subject "[INFRA] - $0 failed"
    rm -fv $TMP $ALLOWED_IP_RANGES $CLOUDFLARE_IP_RANGES
    exit 1
    elif [ $SEND_ON_SUCCESS != false ]; then
    MESSAGE="$CMD executed sucessfully"
    [ $SNS_TOPIC != false ] && aws sns publish --topic-arn $SNS_TOPIC --message "$MESSAGE" --subject "[INFRA] - $0 successful output"
    fi
    }


    ## MAIN
    # ARGS parse
    while getopts ":s:p:t:n:" opt; do
    case $opt in
    s)
    SECURITY_GROUP_ID=$OPTARG
    ;;
    p)
    PROTOCOL=$OPTARG
    ;;
    t)
    PORT=$OPTARG
    ;;
    n)
    SNS_TOPIC=$OPTARG
    ;;
    ?)
    show_usage
    exit 1
    ;;
    :)
    echo "Option -$OPTARG requires an argument." >&2
    show_usage
    exit 1
    ;;
    esac
    done

    # test for required args
    if [ -z $SECURITY_GROUP_ID ] || [ -z $PROTOCOL ] || [ -z $PORT ]; then
    show_usage
    exit 1
    fi

    # if SNS_TOPIC is not passed, set to false
    if [ -z $SNS_TOPIC ]; then
    SNS_TOPIC=false
    fi

    TMP=$(mktemp)
    ALLOWED_IP_RANGES=$(mktemp)
    CLOUDFLARE_IP_RANGES=$(mktemp)

    # Get current ingress rules for port 80, protocol tcp for the given security group id (sorted by ip address range)
    execute_command "aws ec2 describe-security-groups --group-id $SECURITY_GROUP_ID" $TMP $SNS_TOPIC false

    cat $TMP | jq ".SecurityGroups[].IpPermissions[] | select(.FromPort == ${PORT} and .ToPort == ${PORT} and .IpProtocol == \"${PROTOCOL}\") | .IpRanges[] | .CidrIp" | tr -d '"' | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n > $ALLOWED_IP_RANGES
    log "security group ip ranges allowed for protocol $PROTOCOL and port $PORT: $(cat $ALLOWED_IP_RANGES)"

    # Get Cloudflare IP Ranges (sorted by ip address range)
    execute_command "curl -sS https://www.cloudflare.com/ips-v4" $TMP $SNS_TOPIC false

    cat $TMP | sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n > $CLOUDFLARE_IP_RANGES
    log "cloudflare ip ranges: $(cat $CLOUDFLARE_IP_RANGES)"

    # Get the missing IP ranges and add them to the security group
    log "issuing diff -u between security group existing ip addresses and cloudflare addresses: diff -u $ALLOWED_IP_RANGES $CLOUDFLARE_IP_RANGES"
    # Add missing cloudflare ip ranges to the security group allowed ingress rule table
    MISSING_CF_IP_RANGES=$(diff -u $ALLOWED_IP_RANGES $CLOUDFLARE_IP_RANGES | grep '^+' | grep -v '+++' | tr -d '+')
    log "missing Cloudflare IP Ranges: $MISSING_CF_IP_RANGES"
    for IP_RANGE in $MISSING_CF_IP_RANGES; do
    execute_command "aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol $PROTOCOL --port $PORT --cidr $IP_RANGE" $TMP $SNS_TOPIC true
    done

    log "clean up"
    rm -fv $TMP $ALLOWED_IP_RANGES $CLOUDFLARE_IP_RANGES