#!/bin/bash # lib/steps/singbox.sh — instalar/verificar sing-box step_singbox() { print_section "sing-box" log_step "Checking sing-box binary" 4 $TOTAL_STEPS local found="" for candidate in /usr/bin/sing-box /usr/local/bin/sing-box /bin/sing-box; do [ -x "$candidate" ] && found="$candidate" && break done [ -z "$found" ] && found=$(command -v sing-box 2>/dev/null || true) if [ -n "$found" ]; then local ver ver=$("$found" version 2>/dev/null | head -1 || echo "unknown") log_ok "Encontrado: ${found} (${ver})" if [ "$found" != "$SINGBOX_BIN" ]; then sudo ln -sf "$found" "$SINGBOX_BIN" log_ok "Symlink → ${SINGBOX_BIN}" fi else _install_singbox fi # setcap — sing-box crea TUN sin necesitar root completo if command -v setcap &>/dev/null; then sudo setcap cap_net_admin,cap_net_raw+ep "$SINGBOX_BIN" log_ok "setcap cap_net_admin,cap_net_raw+ep → ${SINGBOX_BIN}" else log_warn "setcap no disponible — sing-box necesitará sudo para TUN" fi log_ok "sing-box listo → ${SINGBOX_BIN}" } _install_singbox() { log_info "sing-box no encontrado — instalando v${SINGBOX_VERSION}..." local arch arch=$(uname -m) case "$arch" in x86_64) arch="amd64" ;; aarch64) arch="arm64" ;; *) log_error "Arquitectura no soportada: ${arch}" exit 1 ;; esac local url="https://github.com/SagerNet/sing-box/releases/download/v${SINGBOX_VERSION}/sing-box-${SINGBOX_VERSION}-linux-${arch}.tar.gz" local tmp_tar="/tmp/sing-box-$$.tar.gz" local tmp_dir="/tmp/sing-box-$$" start_spinner "Descargando sing-box v${SINGBOX_VERSION}..." if wget -q --timeout=60 "$url" -O "$tmp_tar"; then stop_spinner "Descarga completa" else stop_spinner rm -f "$tmp_tar" log_error "Descarga falló: ${url}" exit 1 fi start_spinner "Extrayendo..." mkdir -p "$tmp_dir" tar -xzf "$tmp_tar" -C "$tmp_dir" --strip-components=1 stop_spinner "Extraído" sudo cp "$tmp_dir/sing-box" "$SINGBOX_BIN" sudo chmod 755 "$SINGBOX_BIN" rm -rf "$tmp_tar" "$tmp_dir" log_ok "sing-box instalado: $($SINGBOX_BIN version | head -1)" }