From 59d49e13605a268fe532f29de2759c215ec8a8a1 Mon Sep 17 00:00:00 2001 From: gdm85 Date: Tue, 5 Aug 2014 13:29:58 +0200 Subject: [PATCH] Added script to fix auto-published Docker container ports on host --- docker/scripts/docker-iplock | 90 ++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100755 docker/scripts/docker-iplock diff --git a/docker/scripts/docker-iplock b/docker/scripts/docker-iplock new file mode 100755 index 0000000..1f4d4ef --- /dev/null +++ b/docker/scripts/docker-iplock @@ -0,0 +1,90 @@ +#!/bin/bash +## @author gdm85 +## +## provide IP-locking of all exposed ports of docker container from a specific whitelist address +## NOTE: iptables rules will be stale once container is stopped/killed/removed +# + +SCRIPTS=$(dirname $(readlink -m $0)) || exit $? + +if ! type jq 2>&1 >/dev/null; then + echo "jq command is not available" 1>&2 + exit 1 +fi + +if [[ $# -lt 2 ]]; then + echo "Usage: docker-iplock container-name whitelist_ipv4_1 [whitelist_ipv4_2] [...whitelist_ipv4_n]" + exit 1 +fi + +function ipt_forward_update() { + local CID="$1" + if [[ "$CID" == "" ]]; then + echo "Invalid container ID" 1>&2 + return 1 + fi + local WHITELIST4="$2" + + local CONTAINER_IPv4=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' $CID) + if [[ -z "$CONTAINER_IPv4" ]]; then + return 1 + fi + + test ! -z "$DEBUG" && echo "ipt_forward_update: $CID" + + local STANZA="$(docker inspect --format '{{json .HostConfig.PortBindings }}' $CID)" || return $? + test ! -z "$DEBUG" && echo "Bindings: $STANZA" + + local I=0 + for P in $(echo "$STANZA" | jq -M 'keys' | tail -n+2 | head -n-1 | sed s/,$// | sed 's/"//g' ); do + ## port on container + local SRCPORT="$(echo $P | awk -F/ '{ print $1 }')" + test ! -z "$DEBUG" && echo "$CID source port: $SRCPORT" + + ## get port binding (if any) + local SNIP=$(echo $STANZA | jq -M "to_entries | .[$I].value") + + if [[ -z "$SNIP" || "$SNIP" == "null" ]]; then + let I=I+1 + continue + fi + test ! -z "$DEBUG" && echo "$CID binding: $SNIP" + + local HOSTIP="$(echo $SNIP | jq -M -r '.[0].HostIp')" + test ! -z "$DEBUG" && echo "$CID host ip: $HOSTIP" + + ## match only bindings on docker host + if [[ -z "$HOSTIP" || "$HOSTIP" == '0.0.0.0' ]]; then + local HOSTPORT="$(echo $SNIP | jq -M -r '.[0].HostPort')" + + local TOREMOVE="-d ${CONTAINER_IPv4}/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport $SRCPORT -j ACCEPT" + iptables -D FORWARD $TOREMOVE --wait || return $? + + test ! -z "$DEBUG" && echo "$CID: iptables rule removed: $TOREMOVE" + local IPv4 + for IPv4 in $WHITELIST4; do + local TOADD="-s ${IPv4}/32 -d ${CONTAINER_IPv4}/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport $SRCPORT -j ACCEPT" + iptables -I FORWARD 1 $TOADD --wait || return $? + test ! -z "$DEBUG" && echo "$CID: iptables rule added: $TOADD" + done + fi + + let I=I+1 + done +} + +CONTAINER="$1" + +shift 1 + +WHITELIST4="$@" + +if [ -z "$WHITELIST4" ]; then + echo "Invalid whitelist addresses specified" 1>&2 + exit 1 +fi + +CID=$(docker inspect --format '{{ .Id }}' $CONTAINER) || exit $? + +## now run rules update +ipt_forward_update "$CID" "$WHITELIST4"