-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathentrypoint.sh
More file actions
executable file
·104 lines (95 loc) · 4.31 KB
/
entrypoint.sh
File metadata and controls
executable file
·104 lines (95 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env bash
# Agent container entrypoint.
#
# Two-phase startup:
# Phase 1 (root): firewall + CA certificate — requires NET_ADMIN and system paths.
# Phase 2 (devbox): user-setup.sh — git identity, config overlay, hold open.
#
# Capabilities: cap_drop ALL + cap_add NET_ADMIN, SETUID, SETGID, SETPCAP.
# NET_ADMIN for iptables. SETUID/SETGID for gosu. SETPCAP for bounding set drop.
set -euo pipefail
# =========================================================================
# Phase 1: Root — firewall and CA certificate (requires elevated privileges)
# =========================================================================
# --- Detect bridge subnet ---
if [ -z "${DEVBOX_BRIDGE_SUBNET:-}" ]; then
DEVBOX_BRIDGE_SUBNET="$(ip route | awk '!/default/ && /dev/ && /src/ {print $1; exit}')" || true
if [ -z "$DEVBOX_BRIDGE_SUBNET" ]; then
DEVBOX_BRIDGE_SUBNET="$(ip route | awk '/default/ {print $3}' | head -1 | sed 's/\.[0-9]*$/\.0\/16/')" || true
fi
if [ -z "$DEVBOX_BRIDGE_SUBNET" ]; then
DEVBOX_BRIDGE_SUBNET="172.17.0.0/16"
echo "[entrypoint] Could not detect bridge subnet, using fallback: $DEVBOX_BRIDGE_SUBNET"
else
echo "[entrypoint] Detected bridge subnet: $DEVBOX_BRIDGE_SUBNET"
fi
export DEVBOX_BRIDGE_SUBNET
else
echo "[entrypoint] Using configured bridge subnet: $DEVBOX_BRIDGE_SUBNET"
fi
# Source firewall module (defines CIDR_PATTERN and firewall_init).
if [ ! -f /usr/local/lib/devbox/firewall.sh ]; then
echo "[entrypoint] FATAL: firewall.sh not found at /usr/local/lib/devbox/firewall.sh"
exit 1
fi
source /usr/local/lib/devbox/firewall.sh
if [[ ! "$DEVBOX_BRIDGE_SUBNET" =~ $CIDR_PATTERN ]]; then
echo "[entrypoint] FATAL: Invalid bridge subnet: '$DEVBOX_BRIDGE_SUBNET'"
exit 1
fi
# Initialize iptables firewall — mandatory for container safety.
if command -v iptables &>/dev/null; then
if ! firewall_init; then
echo "[entrypoint] Firewall init failed, retrying in 2s..."
sleep 2
if ! firewall_init; then
echo "[entrypoint] FATAL: Firewall initialization failed. Refusing to start."
exit 1
fi
fi
else
echo "[entrypoint] FATAL: iptables not available. Cannot enforce network policy."
exit 1
fi
# --- Proxy CA Certificate ---
# The proxy CA cert is on a shared volume mounted read-only at /run/proxy-ca.
# Copy it into the system CA directory so update-ca-certificates can process it.
CA_STAGING="/run/proxy-ca/mitmproxy-ca-cert.pem"
CA_CERT="/usr/local/share/ca-certificates/mitmproxy-ca.crt"
CA_TIMEOUT=60
CA_ELAPSED=0
while [ ! -f "$CA_STAGING" ] && [ "$CA_ELAPSED" -lt "$CA_TIMEOUT" ]; do
if [ "$CA_ELAPSED" -eq 0 ]; then
echo "[entrypoint] Waiting for proxy CA certificate..."
elif [ "$((CA_ELAPSED % 5))" -eq 0 ]; then
echo "[entrypoint] Still waiting for CA certificate... (${CA_ELAPSED}s/${CA_TIMEOUT}s)"
fi
sleep 1
CA_ELAPSED=$((CA_ELAPSED + 1))
done
if [ ! -f "$CA_STAGING" ]; then
echo "[entrypoint] FATAL: Proxy CA cert not found at $CA_STAGING after ${CA_TIMEOUT}s"
exit 1
fi
echo "[entrypoint] Installing proxy CA certificate..."
cp "$CA_STAGING" "$CA_CERT"
if ! ca_output="$(update-ca-certificates --fresh 2>&1)"; then
echo "[entrypoint] FATAL: update-ca-certificates failed"
echo "$ca_output"
exit 1
fi
# Append mitmproxy cert to the system bundle (update-ca-certificates symlinks
# local certs but doesn't always append them to the PEM bundle on Ubuntu).
cat "$CA_CERT" >> /etc/ssl/certs/ca-certificates.crt
[ -n "$ca_output" ] && echo "$ca_output" | tail -1
export NODE_EXTRA_CA_CERTS="$CA_CERT"
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
# =========================================================================
# Phase 2: Drop to unprivileged user — config overlay and hold container open
# =========================================================================
# Irrevocably drop NET_ADMIN from the bounding set, then drop to unprivileged user.
# After this, no process in the container — not even root — can regain NET_ADMIN.
# The iptables rules become immutable for the lifetime of the container.
exec setpriv --no-new-privs --bounding-set -net_admin,-setpcap --inh-caps -net_admin,-setpcap \
-- gosu devbox /usr/local/bin/user-setup.sh "$@"