#!/bin/bash
# /etc/init.d/vimmau-whitelist
# Controls access to aztek banana and jersey server ports.
# Allows us to whitelist a lot more ip ranges than AWS
# security groups allow.
# To be run only on vimmau hosts.
# AWS security groups will grant full access to banana server--$BANANA_PORT,
# and jersey server--$JERSEY_PORT. We control whitelists here.
# banana and jersey servers may or may not be on the same box. And we may move
# them around. Currently all aztek services run on a single box. We may
# move banana and/or jersey off to a separate box. So this script needs to
# always turn off access on boxes that don't have banana or jersey running
# as well as turn on access if they do.
# NOTE: We assume we are the only one that does anything with iptables on
# a given box. We broadly nuke all chains in all tables, etc.
# whitelist of current customer ip ranges
CUST_WHITELIST=/home/ubuntu/customer.whitelist
# whitelist for rfc1918 addresses and
# whitelist for other special access like the vpn endpoint
RFC1918_WHITELIST=/home/ubuntu/rfc1918-custom.whitelist
HASHSIZE=4096
if [ -z "$ALLOW_BANANA" ]; then
# so since we currently run banana and jersey on same server we will
# just hard code this to true. we will need to get more fancy if
# banana and jersey on different servers.
ALLOW_BANANA=true
fi
if [ -z "$ALLOW_JERSEY" ]; then
# so since we currently run banana and jersey on same server we will
# just hard code this to true. we will need to get more fancy if
# banana and jersey on different servers.
ALLOW_JERSEY=true
fi
if [ -z "$BANANA_PORT" ]; then
BANANA_PORT=4959
fi
if [ -z "$JERSEY_PORT" ]; then
JERSEY_PORT=4960
fi
echo "ALLOW_BANANA: $ALLOW_BANANA"
echo "ALLOW_JERSEY: $ALLOW_JERSEY"
echo "BANANA_PORT: $BANANA_PORT"
echo "JERSEY_PORT: $JERSEY_PORT"
start() {
echo "start"
# nuke all rules in all chains which essentially allows everything.
open
port80and443
whitelist
if [ "$ALLOW_BANANA" = true ] ; then
allow_port $BANANA_PORT
else
echo "not allowing banana $BANANA_PORT"
fi
if [ "$ALLOW_JERSEY" = true ] ; then
allow_port $JERSEY_PORT
else
echo "not allowing jersey $JERSEY_PORT"
fi
block_port $BANANA_PORT
block_port $JERSEY_PORT
}
# So this redirects 80 to 4959 and 443 to 4960 -- doh. The way this works
# customers can use either port and it will work. No need to set or configure
# per customer ports. We will of course have to set port per customer for
# vimmau receptor, but not for server side.
# We can allow all 4 in AWS security groups or just the two we know the
# customer will use.
port80and443() {
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 4959
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 4960
}
# opens all ports and deletes the whitelist.
open() {
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
ipset destroy whitelist &>/dev/null || true
}
# blocks 'all' ports and deletes the whitelist.
stop() {
open
block_port $BANANA_PORT
block_port $JERSEY_PORT
}
whitelist() {
echo "whitelist"
ipset flush whitelist &>/dev/null || true
load_whitelist $CUST_WHITELIST
load_whitelist $RFC1918_WHITELIST
}
load_whitelist() {
if [ -f $1 ] ; then
# make sure there's an ipset named 'whitelist'.
# this command seems to be idempotent.
ipset -exist create whitelist hash:net hashsize $HASHSIZE
# loop over lines in file
while read rule; do
# skip lines that start with #
if [[ ${rule:0:1} == '#' ]]; then
echo "skipping $rule"
else
ipset -exist add whitelist $rule
fi
done <"$1"
else
echo "$1 not found"
fi
}
allow_port() {
echo "allowing port: $1"
iptables -v -A INPUT -m set --match-set whitelist src -p TCP --dport $1 -j ACCEPT
}
block_port() {
echo "blocking port: $1"
iptables -v -A INPUT -p TCP --dport $1 -j LOG --log-prefix "IPTABLES DROPPED: "
iptables -v -A INPUT -p TCP --dport $1 -j DROP
}
status() {
echo ""
iptables -t nat -nvL
echo ""
iptables -nvL
echo ""
ipset list
}
if [ "$1" == "start" ]; then
start
elif [ "$1" == "reload" ]; then
whitelist
elif [ "$1" == "stop" ]; then
stop
elif [ "$1" == "open" ]; then
open
elif [ "$1" == "status" ]; then
status
else
echo "whitelist.sh <start|stop|reload|status>"
echo " start - allow only whitelisted ports and ips"
echo " stop - block both ports for all ips"
echo " reload - reload list of whitelisted ips"
echo " open - allow all ips for both ports (DANGER)"
echo " status - show rules and whitelist"
fi