# shellcheck shell=bash # Netlock: direct egress (ping, curl by IP, ssh, anything not via the egress filter) is # rejected for processes running with the netlock group as their primary group. OpenCode # is started through `sg `, so the agent and everything it spawns are covered. OCSB_NETLOCK_UNIT=opencode-sandbox-netlock.service OCSB_NETLOCK_PROBE=${OCSB_NETLOCK_PROBE:-1.1.1.1/443} ocsb_netlock_active() { systemctl is-active --quiet "${OCSB_NETLOCK_UNIT}"; } ocsb_netlock_member() { local members getent group "${OCSB_NETLOCK_GROUP}" >/dev/null || return 1 members=$(getent group "${OCSB_NETLOCK_GROUP}" | cut -d: -f4) [[ ",${members}," == *",${USER},"* ]] } ocsb_netlock_setup() { sudo "${OCSB_HOME}/lib/netlock-root.sh" setup "${OCSB_NETLOCK_GROUP}" "${USER}" } # Fails unless direct TCP from the group is rejected (not merely timing out) ocsb_netlock_check() { local rc=0 ocsb_netlock_member || ocsb_die "${USER} is not in group ${OCSB_NETLOCK_GROUP} (opencode-sandbox netlock setup)" sg "${OCSB_NETLOCK_GROUP}" -c "timeout 10 bash -c 'exec 3<>/dev/tcp/${OCSB_NETLOCK_PROBE}'" 2>/dev/null || rc=$? case ${rc} in 0) ocsb_die "netlock is NOT working: direct TCP to ${OCSB_NETLOCK_PROBE/\//:} from ${OCSB_NETLOCK_GROUP} succeeded" ;; 124) ocsb_die "netlock check inconclusive: direct TCP to ${OCSB_NETLOCK_PROBE/\//:} hung instead of being rejected" ;; esac } ocsb_netlock_verify() { local code echo "Netlock self-test (group ${OCSB_NETLOCK_GROUP}):" if sg "${OCSB_NETLOCK_GROUP}" -c 'curl --noproxy "*" -s -o /dev/null --max-time 5 https://example.com/' 2>/dev/null; then echo " ✗ direct HTTPS bypassing the filter went through"; return 1 fi echo " ✓ direct HTTPS bypassing the filter is blocked" if sg "${OCSB_NETLOCK_GROUP}" -c 'ping -c1 -W1 1.1.1.1' >/dev/null 2>&1; then echo " ✗ ping went through"; return 1 fi echo " ✓ ping is blocked" if [[ -n ${OCSB_PROJECT_DIR} ]]; then # What is checked is that the group reaches the proxy and the proxy opens the tunnel # (CONNECT 200), not that a particular remote site answers in time code=$(sg "${OCSB_NETLOCK_GROUP}" -c "curl -sx http://127.0.0.1:${OCSB_EGRESS_PORT} -o /dev/null -w '%{http_connect} %{http_code}' --max-time 20 https://example.com/" || true) case "${code}" in 200\ * | *\ [23]??) echo " ✓ HTTPS through the filter → tunnel open (connect/http: ${code})" ;; *) echo " ✗ HTTPS through the filter → connect/http: ${code:-none} (is the egress filter up?)"; return 1 ;; esac fi } ocsb_netlock() { local sub=${1:-status} case "${sub}" in setup) ocsb_netlock_setup ;; teardown) sudo "${OCSB_HOME}/lib/netlock-root.sh" teardown ;; status) if getent group "${OCSB_NETLOCK_GROUP}" >/dev/null; then echo " group ${OCSB_NETLOCK_GROUP}: exists$(ocsb_netlock_member && echo ", ${USER} is a member")" else echo " group ${OCSB_NETLOCK_GROUP}: missing (opencode-sandbox netlock setup)" fi if systemctl is-enabled --quiet "${OCSB_NETLOCK_UNIT}" 2>/dev/null; then echo " unit ${OCSB_NETLOCK_UNIT}: $(systemctl is-active "${OCSB_NETLOCK_UNIT}")" else echo " unit ${OCSB_NETLOCK_UNIT}: not installed (opencode-sandbox netlock setup)" fi ;; verify) ocsb_netlock_verify ;; *) ocsb_die "netlock: unknown subcommand ${sub} (setup|teardown|status|verify)" ;; esac }