bootstrap.sh
1 #!/bin/sh 2 3 # Copyright 2025 Alibaba Group Holding Ltd. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 set -e 18 19 # Returns 0 if the value looks like a boolean "true" (1, true, yes, on). 20 is_truthy() { 21 case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in 22 1 | true | yes | on) return 0 ;; 23 *) return 1 ;; 24 esac 25 } 26 27 _sudo() { 28 if [ "$(id -u)" -eq 0 ]; then 29 "$@" 30 elif command -v sudo >/dev/null 2>&1; then 31 sudo -n "$@" 32 else 33 "$@" 34 fi 35 } 36 37 # Install mitm egress CA into the system trust store (no extra env vars). 38 # - Debian/Ubuntu/Alpine: update-ca-certificates + /usr/local/share/ca-certificates/ 39 # - RHEL/CentOS/Fedora/Alma/Rocky: update-ca-trust + /etc/pki/ca-trust/source/anchors/ 40 trust_mitm_ca() { 41 cert="$1" 42 if command -v update-ca-certificates >/dev/null 2>&1; then 43 _sudo mkdir -p /usr/local/share/ca-certificates 44 _sudo cp "$cert" /usr/local/share/ca-certificates/opensandbox-mitmproxy-ca.crt 45 _sudo update-ca-certificates 46 return 0 47 fi 48 if command -v update-ca-trust >/dev/null 2>&1; then 49 _sudo mkdir -p /etc/pki/ca-trust/source/anchors 50 _sudo cp "$cert" /etc/pki/ca-trust/source/anchors/opensandbox-mitmproxy-ca.pem 51 if ! _sudo update-ca-trust extract; then 52 _sudo update-ca-trust 53 fi 54 return 0 55 fi 56 57 echo "warning: cannot install mitm CA (need update-ca-certificates or update-ca-trust)" >&2 58 return 0 59 } 60 61 # Chromium/Chrome on Linux do not use only the system trust store: they also honor the per-user 62 # NSS database at $HOME/.pki/nssdb. Import the same mitm CA there so the browser trusts it. 63 # Requires certutil (e.g. Alpine: nss-tools, Debian/Ubuntu: libnss3-tools). 64 trust_mitm_ca_nss() { 65 cert="$1" 66 [ -f "$cert" ] || return 0 67 [ -n "${HOME:-}" ] && [ -d "$HOME" ] || return 0 68 if ! command -v certutil >/dev/null 2>&1; then 69 return 0 70 fi 71 pki="${HOME}/.pki/nssdb" 72 if ! mkdir -p "$pki" 2>/dev/null; then 73 return 0 74 fi 75 if [ -f "$pki/cert9.db" ]; then 76 nssdb="sql:$pki" 77 elif [ -f "$pki/cert8.db" ]; then 78 nssdb="dbm:$pki" 79 else 80 nssdb="sql:$pki" 81 if ! certutil -N -d "$nssdb" --empty-password 2>/dev/null; then 82 [ -f "$pki/cert9.db" ] || return 0 83 fi 84 fi 85 nick="opensandbox-mitmproxy" 86 certutil -D -d "$nssdb" -n "$nick" 2>/dev/null || true 87 if ! certutil -A -d "$nssdb" -n "$nick" -t "C,," -i "$cert"; then 88 echo "warning: failed to import mitm CA into NSS at $pki (Chrome may still distrust); need certutil" >&2 89 return 0 90 fi 91 return 0 92 } 93 94 MITM_CA="/opt/opensandbox/mitmproxy-ca-cert.pem" 95 if is_truthy "${OPENSANDBOX_EGRESS_MITMPROXY_TRANSPARENT:-}"; then 96 i=0 97 while [ "$i" -lt 30 ]; do 98 if [ -f "$MITM_CA" ] && [ -s "$MITM_CA" ]; then 99 break 100 fi 101 sleep 1 102 i=$((i + 1)) 103 done 104 if [ ! -f "$MITM_CA" ] || [ ! -s "$MITM_CA" ]; then 105 echo "warning: timed out after 30s waiting for $MITM_CA (egress mitm CA export); continuing without system CA trust" >&2 106 elif ! trust_mitm_ca "$MITM_CA"; then 107 echo "warning: failed to install mitm CA into system trust store; TLS interception may not work for system libraries" >&2 108 fi 109 110 if [ -f "$MITM_CA" ] && [ -s "$MITM_CA" ]; then 111 trust_mitm_ca_nss "$MITM_CA" || true 112 export NODE_EXTRA_CA_CERTS="$MITM_CA" 113 fi 114 fi 115 116 EXECD="${EXECD:=/opt/opensandbox/execd}" 117 118 if [ -z "${EXECD_ENVS:-}" ]; then 119 EXECD_ENVS="/opt/opensandbox/.env" 120 fi 121 if ! mkdir -p "$(dirname "$EXECD_ENVS")" 2>/dev/null; then 122 echo "warning: failed to create dir for EXECD_ENVS=$EXECD_ENVS" >&2 123 fi 124 if ! touch "$EXECD_ENVS" 2>/dev/null; then 125 echo "warning: failed to touch EXECD_ENVS=$EXECD_ENVS" >&2 126 fi 127 export EXECD_ENVS 128 129 echo "starting OpenSandbox Execd daemon at $EXECD." 130 $EXECD & 131 132 # Allow chained shell commands (e.g., /test1.sh && /test2.sh) 133 # Usage: 134 # bootstrap.sh -c "/test1.sh && /test2.sh" 135 # Or set BOOTSTRAP_CMD="/test1.sh && /test2.sh" 136 CMD="" 137 if [ "${BOOTSTRAP_CMD:-}" != "" ]; then 138 CMD="$BOOTSTRAP_CMD" 139 elif [ $# -ge 1 ] && [ "$1" = "-c" ]; then 140 shift 141 CMD="$*" 142 fi 143 144 SHELL_BIN="${BOOTSTRAP_SHELL:-}" 145 if [ -z "$SHELL_BIN" ]; then 146 if command -v bash >/dev/null 2>&1; then 147 SHELL_BIN="$(command -v bash)" 148 elif command -v sh >/dev/null 2>&1; then 149 SHELL_BIN="$(command -v sh)" 150 else 151 echo "error: neither bash nor sh found in PATH" >&2 152 exit 1 153 fi 154 fi 155 156 set -x 157 if [ "$CMD" != "" ]; then 158 exec "$SHELL_BIN" -c "$CMD" 159 fi 160 161 if [ $# -eq 0 ]; then 162 exec "$SHELL_BIN" 163 fi 164 165 exec "$@"