diff --git a/docker.sh b/docker.sh index aa78932..b678e62 100644 --- a/docker.sh +++ b/docker.sh @@ -12,6 +12,27 @@ chain_exists() { iptables $table -n --list "$chain_name" >/dev/null 2>&1 } +add_to_forward() { + local docker_int=$1 + + if [ `iptables -nvL FORWARD | grep ${docker_int} | wc -l` -eq 0 ]; then + iptables -A FORWARD -o ${docker_int} -j DOCKER + iptables -A FORWARD -o ${docker_int} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + iptables -A FORWARD -i ${docker_int} ! -o ${docker_int} -j ACCEPT + iptables -A FORWARD -i ${docker_int} -o ${docker_int} -j ACCEPT + fi +} + +add_to_docker_isolation() { + local int_in=$1 + local int_out=$2 + + iptables -C -A DOCKER-ISOLATION -i ${int_in} -o ${int_out} -j DROP > /dev/null 2>&1 + if [ $? -eq 0 ]; then + iptables -A DOCKER-ISOLATION -i ${int_in} -o ${int_out} -j DROP + fi +} + DOCKER_INT="docker0" DOCKER_NETWORK="172.17.0.0/16" @@ -20,41 +41,52 @@ chain_exists DOCKER && iptables -X DOCKER chain_exists DOCKER nat && iptables -t nat -X DOCKER iptables -N DOCKER -iptables -t nat -N DOCKER - iptables -N DOCKER-ISOLATION +iptables -t nat -N DOCKER + +iptables -A DOCKER-ISOLATION -j RETURN iptables -A FORWARD -j DOCKER-ISOLATION -iptables -A FORWARD -o ${DOCKER_INT} -j DOCKER -iptables -A FORWARD -o ${DOCKER_INT} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -iptables -A FORWARD -i ${DOCKER_INT} ! -o ${DOCKER_INT} -j ACCEPT -iptables -A FORWARD -i ${DOCKER_INT} -o ${DOCKER_INT} -j ACCEPT +add_to_forward ${DOCKER_INT} iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER iptables -t nat -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER iptables -t nat -A POSTROUTING -s ${DOCKER_NETWORK} ! -o ${DOCKER_INT} -j MASQUERADE -iptables -A DOCKER-ISOLATION -j RETURN - containers=`docker ps -q` -if [ `echo ${containers} | wc -c` -gt "1" ] ; then - for container in ${containers} ; do +if [ `echo ${containers} | wc -c` -gt "1" ]; then + for container in ${containers}; do + netmode=`docker inspect -f "{{.HostConfig.NetworkMode}}" ${container}` + + if [ $netmode == "default" ]; then + DOCKER_NET_INT=${DOCKER_INT} + ipaddr=`docker inspect -f "{{.NetworkSettings.IPAddress}}" ${container}` + else + DOCKER_NET_INT="br-$(docker inspect -f \"{{.NetworkSettings.Networks.${netmode}.NetworkID}}\" ${container} | cut -c -12)" + ipaddr=`docker inspect -f "{{.NetworkSettings.Networks.${netmode}.IPAddress}}" ${container}` + + add_to_docker_isolation ${DOCKER_INT} ${DOCKER_NET_INT} + add_to_docker_isolation ${DOCKER_NET_INT} ${DOCKER_INT} + + for net in `docker network ls | awk '{ print $2 }' | grep -Ev "bridge|host|null|ID|${netmode}"`; do + DINT="br-$(docker network inspect -f '{{.Id}}' ${net} | cut -c -12)" + + add_to_docker_isolation ${DOCKER_NET_INT} ${DINT} + done + + add_to_forward ${DOCKER_NET_INT} + + iptables -C -t nat -I DOCKER -i ${DOCKER_NET_INT} -j RETURN > /dev/null 2>&1 + if [ $? -eq 0 ]; then + iptables -t nat -I DOCKER -i ${DOCKER_NET_INT} -j RETURN + fi + fi + rules=`docker port ${container} | sed 's/ //g'` - if [ `echo ${rules} | wc -c` -gt "1" ] ; then - netmode=`docker inspect -f "{{.HostConfig.NetworkMode}}" ${container}` - - if [ $netmode == "default" ]; then - DOCKER_NET_INT=${DOCKER_INT} - ipaddr=`docker inspect -f "{{.NetworkSettings.IPAddress}}" ${container}` - else - networkid=`docker inspect -f "{{.NetworkSettings.Networks.${netmode}.NetworkID}}" ${container} | cut -c -12` - DOCKER_NET_INT="br-${networkid}" - ipaddr=`docker inspect -f "{{.NetworkSettings.Networks.${netmode}.IPAddress}}" ${container}` - fi - - for rule in ${rules} ; do + if [ `echo ${rules} | wc -c` -gt "1" ]; then + for rule in ${rules}; do src=`echo ${rule} | awk -F'->' '{ print $2 }'` dst=`echo ${rule} | awk -F'->' '{ print $1 }'` @@ -68,7 +100,7 @@ if [ `echo ${containers} | wc -c` -gt "1" ] ; then iptables -t nat -A POSTROUTING -s ${ipaddr}/32 -d ${ipaddr}/32 -p ${dst_proto} -m ${dst_proto} --dport ${dst_port} -j MASQUERADE - if [ $src_ip == "0.0.0.0" ] ; then + if [ $src_ip == "0.0.0.0" ]; then iptables -t nat -A DOCKER ! -i ${DOCKER_NET_INT} -p ${dst_proto} -m ${dst_proto} --dport ${src_port} -j DNAT --to-destination ${ipaddr}:${dst_port} else iptables -t nat -A DOCKER -d ${src_ip}/32 ! -i ${DOCKER_NET_INT} -p ${dst_proto} -m ${dst_proto} --dport ${src_port} -j DNAT --to-destination ${ipaddr}:${dst_port}