GNU/Linux >> Znalost Linux >  >> Panels >> Docker

Docker Firewall skript pro DOCKER-USER iptables Chain

Popis:
Protože nemůžeme chránit inzerované porty dockeru na dockeru pomocí běžného firewallu, jako je UFW, před útoky z internetu, byl k tomu napsán skript. Čtení komentářů ve skriptu dává představu o tom, jak to funguje. Jediné, co musíte udělat, je vyplnit proměnné v User Definable variables oblast skriptu a spusťte jej. Skript vždy smaže všechna pravidla v řetězci DOCKER-USER Chain, než něco udělá, což znamená, že buď vyplní definovaná pravidla, nebo se vrátí k původnímu stavu nastavení Dockeru:Nechat vše projít.

Odkazy:
https://docs.docker.com/network/iptables/#restrict-connections-to-the-docker-host

Jméno: docker-Firewall.sh
Syntaxe:/root/bin/docker-Firewall.sh {ON|OFF}

Účel:
Vytváří nebo smaže všechna pravidla v řetězci DOCKER-USER iptables.

POZNÁMKA:
V případě potíží se podívejte do protokolu jádra /var/log/kern.log a vyhledejte end-DOCKER-USER např.

grep 'end-DOCKER-USER' /var/log/kern.log

SCRIPT:

#!/bin/bash
# Name: docker-Firewall.sh
# Purpose: Setting up comfortably the DOCKER-USER iptables chain to protect docker advertised ports from attacks from Internet
# docker-Firewall.sh {ON|OFF}
# Since this DOCKER-USER iptables chain is called at the very beginning of FORWARD chain.
# it only affects the incoming packets destined to Docker advertised internal addresses & ports
# and not any packets destined to local applications like SSH, HTTP etc.
# Changes: 26.05.2020   Initial creation of script
# Author: Michel Bisson([email protected])
#-----------------------------------------------------------------------------
# Constants
#set -x -e
iptables=$(which iptables)
ext_if="eth0"
# ---------------------- User Definable variables -------------------------
# Internal networks: 127.0.0.0/16 192.168.0.0/16 172.16.0.0/12
internal_networks="127.0.0.0/16 192.168.0.0/16 172.16.0.0/12"
# Needed for returning connections
docker_network="172.16.0.0/12"

# Hosts that are trusted and allowed to access all Docker advertised ports
# Format: IPAddr[:{udp|tcp}:port]
# This can be:
# Single host address(eg. 197.206.101.184): This Internet host will have full access to all docker advertised ports
# Network(eg. 123.123.123.0/24): All Internet hosts in the network will have full access
# Network or Host with port type & port number: (eg. 197.206.101.184:tcp:1205 123.123.123.0/24:udp:3000): Internet Host or all hosts in network will be limited to access to defined port type and port number. 

# In the following examples of 'trusted_hosts' are:
# (56.143.177.17) host get full access to all docker advertised ports
# (18.175.184.18:udp:3001) host gets access to only udp port 3001
# (123.123.123.12/31:tcp:3000) both hosts 123.123.123.12 and 123.123.123.13 get access to only tcp port 3000

trusted_hosts="56.143.177.178 18.175.184.18:udp:3001 123.123.123.12/31:tcp:3000"

# Ports (separated by spaces) that are allowed to be access by the whole Internet.
# This can be used for temporarily test a container from an not-trusted host or simply permanently open it to Internet
open_UDP_ports="10000 12000"
open_TCP_ports="8013 8028"
# ------------------------- END User Definable variables -----------------------

#Functions
function usage() {
    echo "ERROR: Wrong number of arguments(URLs)."
    echo "Syntax: docker-Firewall.sh {ON|OFF}"
    exit 1
}

valid_cidr_network() {
  local ip="${1%/*}"    # strip bits to leave ip address
  local bits="${1#*/}"  # strip ip address to leave bits
  local IFS=.; local -a a=($ip)

  # Sanity checks (only simple regexes)
  [[ $ip =~ ^[0-9]+(\.[0-9]+){3}$ ]] || return 1
  [[ $bits =~ ^[0-9]+$ ]] || return 1
  [[ $bits -le 32 ]] || return 1

  # Create an array of 8-digit binary numbers from 0 to 255
  local -a binary=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})
  local binip=""

  # Test and append values of quads
  for quad in {0..3}; do
    [[ "${a[$quad]}" -gt 255 ]] && return 1
    printf -v binip '%s%s' "$binip" "${binary[${a[$quad]}]}"
  done

  # Fail if any bits are set in the host portion
  [[ ${binip:$bits} = *1* ]] && return 1

  return 0
}

# check the arguments, min 1
if [ $# -lt 1 ]; then usage ; fi

# Convert the argument to capital letters
arg=$(echo $1 | tr 'a-z' 'A-Z')

# The script first wipes out any already existing rules
$iptables -F DOCKER-USER

case $arg in
    ON) # Activate the firewall

        # ------------- Start Firewall here

        # Here are the rules to fill into the empty chain DOCKER-USER

        # Allow Internal Networks
        for network in $internal_networks ; do
            $iptables -A DOCKER-USER -s $network -j RETURN
        done

       # Allow already estabilished connection - returning packets
       $iptables -A DOCKER-USER -d $docker_network -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN

        # Allow trusted hosts or networks with or without ports
        if (echo $trusted_hosts | grep -q '[0-9]'); then
            for host in $trusted_hosts ; do
                if (echo $host | grep -q ':'); then
                    addr=$(echo $host | cut -d: -f1)
                    type=$(echo $host | cut -d: -f2)
                    port=$(echo $host | cut -d: -f3)
                    # Verifying the validity of the info and entering the rule if all ok
                    # Add /32 to single non-CIDR address
                    if ! (echo $addr | grep -q '/'); then addr=${addr}/32; fi
                    if (valid_cidr_network $addr) ; then
                        ptype=$(echo $type | tr 'A-Z' 'a-z')
                        if $(echo $ptype | egrep -q 'tcp|udp'); then
                            if (echo "$port" | egrep -q '^[0-9]+$'); then
                                $iptables -A DOCKER-USER -i $ext_if -s $addr -p $ptype --dport $port -j RETURN
                            else
                                echo "ERROR: Wrong port number:$port. It should be a pure integer. e. '1234'"
                            fi
                        else
                            echo "ERROR: Wrong 'type' of port:$ptype. Should be 'tcp' or 'udp'"
                        fi 
                    else
                        echo "Error: Wrong type of CIDR host/network address:$addr. Should be CIDR conform eg. '123.123.123.0/24' or '123.123.123.123'"
                    fi
                else
                    $iptables -A DOCKER-USER -i $ext_if -s $host -j RETURN
                fi
            done
        fi

        # open UDP ports
        if (echo $open_UDP_ports | grep -q '[0-9]'); then
            for UDP_port in $open_UDP_ports; do
                $iptables -A DOCKER-USER -i $ext_if -p udp --dport $UDP_port -j RETURN
            done
        fi

        # open TCP ports
        if (echo $open_TCP_ports | grep -q '[0-9]'); then
            for TCP_port in $open_TCP_ports; do
                $iptables -A DOCKER-USER -i $ext_if -p udp --dport $TCP_port -j RETURN
            done
        fi

        # Last rules: log remaining packets and DROP ALL ------------
        $iptables -A DOCKER-USER -j LOG --log-prefix "end-DOCKER-USER "
        $iptables -A DOCKER-USER -j DROP
        ;;

    OFF) # Turn OFF the firewall and let all packet through(RETURN)
        $iptables -A DOCKER-USER -j RETURN
        ;;

    *) usage
        ;;
esac

# Show content of DOCKER-USER Chain
$iptables -S DOCKER-USER
#eof

Docker
  1. Jak změnit časové pásmo pro kontejner Docker

  2. Transliterační skript pro linuxové prostředí

  3. Iptables – řetězec Bridge a Forward

  1. Co je Docker Container:Úvodní příručka pro začátečníky

  2. 3 strategie pro automatizované produkční nasazení s Dockerem

  3. Jak nastavit bránu firewall s iptables na Ubuntu a CentOS

  1. Iptables Tutorial – Zabezpečení Ubuntu VPS pomocí Linux Firewall

  2. Základní správa firewallu iptables

  3. Proč NTP vyžaduje obousměrný přístup brány firewall k portu UDP 123?