Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile.leash
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
dnsutils \
iproute2 \
iptables \
nftables \
iputils-ping \
less \
libbpf1 \
Expand Down
11 changes: 9 additions & 2 deletions internal/assets/apply-ip6tables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,23 @@ fi

# Block target container from reaching leashd control plane on any interface (IPv6).
# This prevents a compromised agent from accessing the leashd API.
# SECURITY: This is a REQUIRED security control - failure is fatal.
# SECURITY: This is a REQUIRED security control - failure is fatal unless
# LEASH_CGROUP_ISOLATION=optional is set.
# Requires --cgroupns=host on the container to see host cgroup paths.
CGROUP_ISOLATION=${LEASH_CGROUP_ISOLATION:-required}

if [ -n "$TARGET_CGROUP" ] && [ -n "$LEASH_PORT" ]; then
if ! ensure_rule -t filter -C OUTPUT -m cgroup --path "$TARGET_CGROUP" -p tcp --dport "$LEASH_PORT" -j REJECT; then
if ip6tables_cmd -t filter -A OUTPUT -m cgroup --path "$TARGET_CGROUP" -p tcp --dport "$LEASH_PORT" -j REJECT --reject-with tcp-reset 2>&1; then
echo "leash: blocked target cgroup $TARGET_CGROUP from reaching control plane port $LEASH_PORT (ip6tables)"
else
elif [ "$CGROUP_ISOLATION" = "required" ]; then
echo "leash: FATAL: could not apply cgroup-based control plane isolation (IPv6)" >&2
echo "leash: This security control is required to prevent target container from accessing leashd API" >&2
echo "leash: Set LEASH_CGROUP_ISOLATION=optional to run without cgroup isolation" >&2
exit 1
else
echo "leash: WARNING: cgroup-based control plane isolation unavailable (ip6tables); continuing without it" >&2
RULE_ERRORS=$((RULE_ERRORS + 1))
fi
fi
fi
Expand Down
12 changes: 10 additions & 2 deletions internal/assets/apply-iptables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,24 @@ fi

# Block target container from reaching leashd control plane on any interface.
# This prevents a compromised agent from accessing the leashd API.
# SECURITY: This is a REQUIRED security control - failure is fatal.
# SECURITY: This is a REQUIRED security control - failure is fatal unless
# LEASH_CGROUP_ISOLATION=optional is set (e.g. for Docker Desktop where
# the kernel lacks xt_cgroup / nft socket cgroupv2 support).
# Requires --cgroupns=host on the container to see host cgroup paths.
CGROUP_ISOLATION=${LEASH_CGROUP_ISOLATION:-required}

if [ -n "$TARGET_CGROUP" ] && [ -n "$LEASH_PORT" ]; then
if ! ensure_rule -t filter -C OUTPUT -m cgroup --path "$TARGET_CGROUP" -p tcp --dport "$LEASH_PORT" -j REJECT; then
if iptables_cmd -t filter -A OUTPUT -m cgroup --path "$TARGET_CGROUP" -p tcp --dport "$LEASH_PORT" -j REJECT --reject-with tcp-reset 2>&1; then
echo "leash: blocked target cgroup $TARGET_CGROUP from reaching control plane port $LEASH_PORT"
else
elif [ "$CGROUP_ISOLATION" = "required" ]; then
echo "leash: FATAL: could not apply cgroup-based control plane isolation" >&2
echo "leash: This security control is required to prevent target container from accessing leashd API" >&2
echo "leash: Set LEASH_CGROUP_ISOLATION=optional to run without cgroup isolation" >&2
exit 1
else
echo "leash: WARNING: cgroup-based control plane isolation unavailable (iptables); continuing without it" >&2
RULE_ERRORS=$((RULE_ERRORS + 1))
fi
fi
fi
Expand Down
12 changes: 9 additions & 3 deletions internal/assets/apply-nftables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ ensure_rule() {
if nft_cmd list chain "$fam" "$tbl" "$chain" 2>/dev/null | grep -F "comment \"$comment\"" >/dev/null; then
return 0
fi
if ! nft_cmd add rule "$fam" "$tbl" "$chain" "$@" comment "$comment" 2>/dev/null; then
if ! nft_cmd add rule "$fam" "$tbl" "$chain" "$@" comment "\"$comment\"" 2>/dev/null; then
echo "leash: WARNING: failed to add nftables rule $comment" >&2
RULE_ERRORS=$((RULE_ERRORS + 1))
return 1
Expand Down Expand Up @@ -85,17 +85,23 @@ ensure_rule inet leash out_route "leash:drop-quic" udp dport 443 drop
# Uses inet family to cover both IPv4 and IPv6.
# SECURITY: This is a REQUIRED security control - failure is fatal.
# Requires --cgroupns=host on the container to see host cgroup paths.
CGROUP_ISOLATION=${LEASH_CGROUP_ISOLATION:-required}

if [ -n "$TARGET_CGROUP" ] && [ -n "$LEASH_PORT" ]; then
ensure_chain inet leash out_filter { type filter hook output priority 0\; }
# Check if rule already exists
if nft_cmd list chain inet leash out_filter 2>/dev/null | grep -F "leash:block-control-plane" >/dev/null; then
: # Rule already exists, nothing to do
elif nft_cmd add rule inet leash out_filter socket cgroupv2 level 1 "$TARGET_CGROUP" tcp dport $LEASH_PORT reject with tcp reset comment "leash:block-control-plane" 2>&1; then
elif nft_cmd add rule inet leash out_filter socket cgroupv2 level 1 "\"$TARGET_CGROUP\"" tcp dport $LEASH_PORT reject with tcp reset comment "\"leash:block-control-plane\"" 2>&1; then
echo "leash: blocked target cgroup $TARGET_CGROUP from reaching control plane port $LEASH_PORT (nftables)"
else
elif [ "$CGROUP_ISOLATION" = "required" ]; then
echo "leash: FATAL: could not apply cgroup-based control plane isolation (nftables)" >&2
echo "leash: This security control is required to prevent target container from accessing leashd API" >&2
echo "leash: Set LEASH_CGROUP_ISOLATION=optional to run without cgroup isolation" >&2
exit 1
else
echo "leash: WARNING: cgroup-based control plane isolation unavailable (nftables); continuing without it" >&2
RULE_ERRORS=$((RULE_ERRORS + 1))
fi
fi

Expand Down
Loading