packages/utils/docker-ce/files/dockerd.init
Florian Eckert 1af5593568 docker-ce: make docker-ce firewall handling configurable
Openwrt has a own firewall service called fw3, that supports firewall zones.
Docker can bypass the handling of the zone rules in openwrt via custom
tables. These are "always" processed before the openwrt firewall.
Which is prone to errors!

Since not everyone is aware that the firewall of openwrt will
not be passed. And this is a security problem because a mapped port is
visible on all interfaces and so also on the WAN side.
If the firewall handling in docker is switched off, then the port in
fw3 must be explicitly released and it cannot happen that the
port is accidentally exported to the outside world via the interfaces on
the WAN zone.

So all rules for the containers should and so must be made in fw3.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
2020-11-19 14:20:02 +01:00

258 lines
7.4 KiB
Bash
Executable file

#!/bin/sh /etc/rc.common
USE_PROCD=1
START=25
extra_command "uciadd" "<interface> <device> <zone> Add docker bridge configuration to network and firewall uci config"
extra_command "ucidel" "<interface> <device> <zone> Delete docker bridge configuration from network and firewall uci config"
DOCKER_CONF_DIR="/tmp/dockerd"
DOCKERD_CONF="${DOCKER_CONF_DIR}/daemon.json"
uci_quiet() {
uci -q "${@}" >/dev/null
}
json_add_array_string() {
json_add_string "" "${1}"
}
boot() {
uciadd
rc_procd start_service
}
uciupdate() {
local net="${1}"
uci_quiet get network.docker || {
logger -t "dockerd-init" -p warn "No network uci config section for docker default bridge (docker0) found"
return
}
[ -z "${net}" ] && {
logger -t "dockerd-init" -p notice "Removing network uci config options for docker default bridge (docker0)"
uci_quiet delete network.docker.netmask
uci_quiet delete network.docker.ipaddr
uci_quiet commit network
return
}
eval "$(ipcalc.sh "${net}")"
logger -t "dockerd-init" -p notice "Updating network uci config option \"${net}\" for docker default bridge (docker0)"
uci_quiet set network.docker.netmask="${NETMASK}"
uci_quiet set network.docker.ipaddr="${IP}"
uci_quiet commit network
}
uciadd() {
local iface="$1"
local device="$2"
local zone="$3"
[ -z "$iface" ] && {
iface="docker"
device="docker0"
zone="docker"
}
/etc/init.d/dockerd running && {
echo "Please stop dockerd service first"
exit 0
}
# Add network interface
if ! uci_quiet get network.${iface}; then
logger -t "dockerd-init" -p notice "Adding docker default interface to network uci config (${iface})"
uci_quiet add network interface
uci_quiet rename network.@interface[-1]="${iface}"
uci_quiet set network.@interface[-1].ifname="${device}"
uci_quiet set network.@interface[-1].proto="static"
uci_quiet set network.@interface[-1].auto="0"
uci_quiet commit network
fi
# Add docker bridge device
if ! uci_quiet get network.${device}; then
logger -t "dockerd-init" -p notice "Adding docker default bridge device to network uci config (${device})"
uci_quiet add network device
uci_quiet rename network.@device[-1]="${device}"
uci_quiet set network.@device[-1].type="bridge"
uci_quiet set network.@device[-1].name="${device}"
uci_quiet add_list network.@device[-1].ifname="${device}"
uci_quiet commit network
fi
# Add firewall zone
if ! uci_quiet get firewall.${zone}; then
logger -t "dockerd-init" -p notice "Adding docker default firewall zone to firewall uci config (${zone})"
uci_quiet add firewall zone
uci_quiet rename firewall.@zone[-1]="${zone}"
uci_quiet set firewall.@zone[-1].network="${iface}"
uci_quiet set firewall.@zone[-1].input="REJECT"
uci_quiet set firewall.@zone[-1].output="ACCEPT"
uci_quiet set firewall.@zone[-1].forward="REJECT"
uci_quiet set firewall.@zone[-1].name="${zone}"
uci_quiet commit firewall
fi
reload_config
}
ucidel() {
local iface="$1"
local device="$2"
local zone="$3"
[ -z "$iface" ] && {
iface="docker"
device="docker0"
zone="docker"
}
/etc/init.d/dockerd running && {
echo "Please stop dockerd service first"
exit 0
}
if uci_quiet get network.${device}; then
logger -t "dockerd-init" -p notice "Deleting docker default bridge device from network uci config (${device})"
uci_quiet delete network.${device}
uci_quiet commit network
fi
if uci_quiet get network.${iface}; then
logger -t "dockerd-init" -p notice "Deleting docker default interface from network uci config (${iface})"
uci_quiet delete network.${iface}
uci_quiet commit network
fi
if uci_quiet get firewall.${zone}; then
logger -t "dockerd-init" -p notice "Deleting docker firewall zone from firewall uci config (${zone})"
uci_quiet delete firewall.${zone}
uci_quiet commit firewall
fi
reload_config
}
process_config() {
local alt_config_file data_root log_level iptables bip
[ -f /etc/config/dockerd ] || {
# Use the daemon default configuration
DOCKERD_CONF=""
return 0
}
# reset configuration
rm -fr "${DOCKER_CONF_DIR}"
mkdir -p "${DOCKER_CONF_DIR}"
config_load 'dockerd'
config_get alt_config_file globals alt_config_file
[ -n "${alt_config_file}" ] && [ -f "${alt_config_file}" ] && {
ln -s "${alt_config_file}" "${DOCKERD_CONF}"
return 0
}
config_get data_root globals data_root "/opt/docker/"
config_get log_level globals log_level "warn"
config_get_bool iptables globals iptables "1"
config_get bip globals bip ""
. /usr/share/libubox/jshn.sh
json_init
json_add_string "data-root" "${data_root}"
json_add_string "log-level" "${log_level}"
[ -z "${bip}" ] || json_add_string "bip" "${bip}"
json_add_array "registry-mirrors"
config_list_foreach globals registry_mirrors json_add_array_string
json_close_array
json_add_array "hosts"
config_list_foreach globals hosts json_add_array_string
json_close_array
json_add_boolean iptables "${iptables}"
[ "${iptables}" -ne "0" ] && config_foreach iptables_add_blocking_rule firewall
json_dump > "${DOCKERD_CONF}"
uciupdate "${bip}"
}
start_service() {
local nofile=$(cat /proc/sys/fs/nr_open)
process_config
procd_open_instance
procd_set_param stderr 1
if [ -z "${DOCKERD_CONF}" ]; then
procd_set_param command /usr/bin/dockerd
else
procd_set_param command /usr/bin/dockerd --config-file="${DOCKERD_CONF}"
fi
procd_set_param limits nofile="${nofile} ${nofile}"
procd_close_instance
}
reload_service() {
process_config
procd_send_signal dockerd
}
service_triggers() {
procd_add_reload_trigger 'dockerd'
}
add_docker_firewall_rules() {
. /lib/functions/network.sh
local device interface="${1}"
# Ignore errors as it might already be present
iptables --table filter --new DOCKER-USER 2>/dev/null
network_get_physdev device "${interface}"
if ! iptables --table filter --check DOCKER-USER --in-interface "${device}" --out-interface docker0 --jump DROP 2>/dev/null; then
iptables --table filter --insert DOCKER-USER --in-interface "${device}" --out-interface docker0 --jump DROP
fi
}
ip4tables_remove_nat() {
iptables --table nat --delete OUTPUT ! --destination 127.0.0.0/8 --match addrtype --dst-type LOCAL --jump DOCKER
iptables --table nat --delete PREROUTING --match addrtype --dst-type LOCAL --jump DOCKER
iptables --table nat --flush DOCKER
iptables --table nat --delete-chain DOCKER
}
ip4tables_remove_filter() {
iptables --table filter --delete FORWARD --jump DOCKER-USER
iptables --table filter --delete FORWARD --jump DOCKER-ISOLATION-STAGE-1
iptables --table filter --delete FORWARD --out-interface docker0 --jump DOCKER
iptables --table filter --delete FORWARD --out-interface docker0 --match conntrack --ctstate RELATED,ESTABLISHED --jump ACCEPT
iptables --table filter --delete FORWARD --in-interface docker0 --out-interface docker0 --jump ACCEPT
iptables --table filter --delete FORWARD --in-interface docker0 ! --out-interface docker0 --jump ACCEPT
iptables --table filter --flush DOCKER
iptables --table filter --flush DOCKER-ISOLATION-STAGE-1
iptables --table filter --flush DOCKER-ISOLATION-STAGE-2
iptables --table filter --flush DOCKER-USER
iptables --table filter --delete-chain DOCKER
iptables --table filter --delete-chain DOCKER-ISOLATION-STAGE-1
iptables --table filter --delete-chain DOCKER-ISOLATION-STAGE-2
iptables --table filter --delete-chain DOCKER-USER
}
ip4tables_remove() {
ip4tables_remove_nat
ip4tables_remove_filter
}
stop_service() {
if /etc/init.d/dockerd running; then
service_stop "/usr/bin/dockerd"
ip4tables_remove
fi
}