GNU/Linux >> Belajar Linux >  >> Panels >> Docker

Skrip Docker Firewall untuk Rantai iptables DOCKER-USER

Deskripsi:
Karena kami tidak dapat melindungi port yang diiklankan buruh pelabuhan di buruh pelabuhan menggunakan firewall normal seperti UFW terhadap serangan dari Internet, sebuah skrip telah ditulis untuk melakukan hal itu. Membaca komentar dalam skrip memang memberikan gambaran tentang cara kerjanya. Satu-satunya hal yang harus dilakukan adalah mengisi variabel di User Definable variables area skrip dan jalankan. Script akan selalu menghapus semua aturan di dalam Rantai DOCKER-USER sebelum melakukan apa pun, artinya, mengisi aturan yang ditentukan atau kembali ke status penyiapan Docker asli:Membiarkan melewati semuanya.

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

Nama: docker-Firewall.sh
Sintaks:/root/bin/docker-Firewall.sh {ON|OFF}

Tujuan:
Membuat atau menghapus semua aturan di Rantai iptables DOCKER-USER.

CATATAN:
Jika ada kesulitan, lihat log kernel /var/log/kern.log dan cari end-DOCKER-USER misalnya.

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. Apa itu Docker Container:Panduan Pengantar untuk Pemula

  2. Cara Mengatur Firewall dengan iptables di Ubuntu dan CentOS

  3. Skrip transliterasi untuk shell linux

  1. 3 Strategi untuk Penerapan Produksi Otomatis Dengan Docker

  2. Manajemen firewall iptables dasar

  3. Cara Mengubah Zona Waktu Untuk Wadah Docker

  1. Tutorial Iptables – Mengamankan VPS Ubuntu dengan Linux Firewall

  2. Mengapa NTP memerlukan akses firewall dua arah ke port UDP 123?

  3. Iptables - Rantai Bridge dan Forward