chore: remove legacy proxyctl and mitm-redirect.sh scripts
Both are superseded by the zg binary and setup-linux.sh. Updated docs/mitm.md to reflect current setup flow.
This commit is contained in:
14
docs/mitm.md
14
docs/mitm.md
@@ -129,20 +129,16 @@ Events dispatched through `tokio::sync::mpsc` channels from MITM → API handler
|
|||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
### UID-Scoped iptables (Classic Mode)
|
### UID-Scoped iptables (Linux)
|
||||||
|
|
||||||
|
The `zerogravity-ls` user and iptables rules are created automatically by `setup-linux.sh`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# One-time setup — creates zerogravity-ls user + iptables rule
|
./scripts/setup-linux.sh
|
||||||
sudo ./scripts/mitm-redirect.sh install
|
zg start
|
||||||
|
|
||||||
# Run proxy (standalone LS + MITM both enabled by default)
|
|
||||||
RUST_LOG=info ./target/release/zerogravity
|
|
||||||
|
|
||||||
# Check intercepted usage
|
# Check intercepted usage
|
||||||
curl -s http://localhost:8741/v1/usage | jq .
|
curl -s http://localhost:8741/v1/usage | jq .
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
sudo ./scripts/mitm-redirect.sh uninstall
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Headless Mode
|
### Headless Mode
|
||||||
|
|||||||
@@ -1,183 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# mitm-redirect.sh — UID-scoped iptables redirect for MITM interception
|
|
||||||
#
|
|
||||||
# Creates a dedicated system user for the standalone LS and adds an iptables
|
|
||||||
# rule that ONLY redirects traffic from that user's UID. No /etc/hosts
|
|
||||||
# modification, no system-wide changes.
|
|
||||||
#
|
|
||||||
# Flow:
|
|
||||||
# 1. Standalone LS runs as 'zerogravity-ls' user (via sudo -u)
|
|
||||||
# 2. iptables catches :443 traffic from that UID only → REDIRECT to MITM port
|
|
||||||
# 3. MITM terminates TLS (Go client trusts our CA via SSL_CERT_FILE)
|
|
||||||
# 4. MITM forwards upstream, captures usage
|
|
||||||
#
|
|
||||||
# What this does NOT affect:
|
|
||||||
# - Your real Antigravity session (different UID)
|
|
||||||
# - Any other software on your PC (different UID)
|
|
||||||
# - DNS resolution (no /etc/hosts changes)
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# sudo ./scripts/mitm-redirect.sh install [mitm_port]
|
|
||||||
# sudo ./scripts/mitm-redirect.sh uninstall [mitm_port]
|
|
||||||
# sudo ./scripts/mitm-redirect.sh status
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
MITM_PORT="${2:-8742}"
|
|
||||||
LS_USER="zerogravity-ls"
|
|
||||||
DATA_DIR="/tmp/zerogravity-standalone"
|
|
||||||
LS_BINARY="/usr/share/antigravity/resources/app/extensions/antigravity/bin/language_server_linux_x64"
|
|
||||||
SUDOERS_FILE="/etc/sudoers.d/zerogravity-ls"
|
|
||||||
|
|
||||||
install() {
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
|
||||||
echo "Error: must run as root (sudo)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[mitm-redirect] Installing UID-scoped iptables redirect → :$MITM_PORT"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# ── 1. Create system user ───────────────────────────────────────────
|
|
||||||
if id "$LS_USER" &>/dev/null; then
|
|
||||||
echo " ✓ user '$LS_USER' already exists (uid=$(id -u "$LS_USER"))"
|
|
||||||
else
|
|
||||||
useradd -r -s /usr/sbin/nologin -d "$DATA_DIR" "$LS_USER"
|
|
||||||
echo " + created user '$LS_USER' (uid=$(id -u "$LS_USER"))"
|
|
||||||
fi
|
|
||||||
local LS_UID
|
|
||||||
LS_UID=$(id -u "$LS_USER")
|
|
||||||
|
|
||||||
# ── 2. Create data directory (writable by both users) ────────────────
|
|
||||||
mkdir -p "$DATA_DIR/.gemini"
|
|
||||||
chmod 1777 "$DATA_DIR" "$DATA_DIR/.gemini"
|
|
||||||
echo " + data dir: $DATA_DIR (mode 1777, writable by all)"
|
|
||||||
|
|
||||||
# ── 3. Sudoers entry ────────────────────────────────────────────────
|
|
||||||
# Allow the invoking user (SUDO_USER) to run ANY command as zerogravity-ls.
|
|
||||||
# This is needed for the proxy to spawn the LS binary.
|
|
||||||
local REAL_USER="${SUDO_USER:-$(logname 2>/dev/null || whoami)}"
|
|
||||||
cat > "$SUDOERS_FILE" <<EOF
|
|
||||||
# Allow $REAL_USER to run commands as $LS_USER (for zerogravity)
|
|
||||||
$REAL_USER ALL=($LS_USER) NOPASSWD: ALL
|
|
||||||
# Allow $REAL_USER to kill $LS_USER's processes (for clean shutdown)
|
|
||||||
$REAL_USER ALL=(root) NOPASSWD: /usr/bin/kill -TERM *, /usr/bin/kill -KILL *, /usr/bin/pkill -TERM -u $LS_USER *, /usr/bin/pkill -KILL -u $LS_USER *
|
|
||||||
EOF
|
|
||||||
chmod 440 "$SUDOERS_FILE"
|
|
||||||
echo " + sudoers: $REAL_USER can run as $LS_USER + kill $LS_USER processes"
|
|
||||||
|
|
||||||
# ── 4. iptables REDIRECT (scoped to UID) ────────────────────────────
|
|
||||||
# Remove existing rule first (idempotent)
|
|
||||||
iptables -t nat -D OUTPUT -m owner --uid-owner "$LS_UID" \
|
|
||||||
-p tcp --dport 443 -j REDIRECT --to-port "$MITM_PORT" 2>/dev/null || true
|
|
||||||
|
|
||||||
iptables -t nat -A OUTPUT -m owner --uid-owner "$LS_UID" \
|
|
||||||
-p tcp --dport 443 -j REDIRECT --to-port "$MITM_PORT"
|
|
||||||
echo " + iptables: uid=$LS_UID :443 → :$MITM_PORT"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "[mitm-redirect] ✓ Installed (only affects uid=$LS_UID)"
|
|
||||||
echo " Restart the proxy to take effect:"
|
|
||||||
echo " RUST_LOG=info ./target/release/zerogravity --standalone"
|
|
||||||
}
|
|
||||||
|
|
||||||
uninstall() {
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
|
||||||
echo "Error: must run as root (sudo)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[mitm-redirect] Removing UID-scoped iptables redirect"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Remove iptables rule
|
|
||||||
if id "$LS_USER" &>/dev/null; then
|
|
||||||
local LS_UID
|
|
||||||
LS_UID=$(id -u "$LS_USER")
|
|
||||||
iptables -t nat -D OUTPUT -m owner --uid-owner "$LS_UID" \
|
|
||||||
-p tcp --dport 443 -j REDIRECT --to-port "$MITM_PORT" 2>/dev/null || true
|
|
||||||
echo " - iptables: removed REDIRECT rule for uid=$LS_UID"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove sudoers entry
|
|
||||||
rm -f "$SUDOERS_FILE"
|
|
||||||
echo " - sudoers: removed $SUDOERS_FILE"
|
|
||||||
|
|
||||||
# Clean data dir
|
|
||||||
rm -rf "$DATA_DIR"
|
|
||||||
echo " - data dir: removed $DATA_DIR"
|
|
||||||
|
|
||||||
# Optionally remove user (commented out — user might want to keep it)
|
|
||||||
# userdel "$LS_USER" 2>/dev/null || true
|
|
||||||
echo " ℹ user '$LS_USER' kept (run 'sudo userdel $LS_USER' to remove)"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "[mitm-redirect] ✓ Uninstalled."
|
|
||||||
}
|
|
||||||
|
|
||||||
status() {
|
|
||||||
echo "[mitm-redirect] Status"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Check user
|
|
||||||
if id "$LS_USER" &>/dev/null; then
|
|
||||||
local LS_UID
|
|
||||||
LS_UID=$(id -u "$LS_USER")
|
|
||||||
echo " user: $LS_USER (uid=$LS_UID) ✓"
|
|
||||||
else
|
|
||||||
echo " user: $LS_USER (not found) ✗"
|
|
||||||
echo
|
|
||||||
echo " Run: sudo $0 install"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check sudoers
|
|
||||||
if [[ -f "$SUDOERS_FILE" ]]; then
|
|
||||||
echo " sudoers: $SUDOERS_FILE ✓"
|
|
||||||
else
|
|
||||||
echo " sudoers: $SUDOERS_FILE (not found) ✗"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check iptables
|
|
||||||
echo " iptables:"
|
|
||||||
if iptables -t nat -L OUTPUT -n 2>/dev/null | grep -q "owner UID match.*$LS_UID"; then
|
|
||||||
iptables -t nat -L OUTPUT -n -v 2>/dev/null | grep "owner UID" | sed 's/^/ /'
|
|
||||||
else
|
|
||||||
echo " (no rules for uid=$LS_UID)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check data dir
|
|
||||||
echo " data dir: $(ls -ld "$DATA_DIR" 2>/dev/null || echo '(not found)')"
|
|
||||||
|
|
||||||
# Test sudo
|
|
||||||
echo
|
|
||||||
echo " sudo test:"
|
|
||||||
if sudo -n -u "$LS_USER" true 2>/dev/null; then
|
|
||||||
echo " ✓ can run as $LS_USER without password"
|
|
||||||
else
|
|
||||||
echo " ✗ cannot run as $LS_USER (check sudoers)"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
case "${1:-help}" in
|
|
||||||
install) install ;;
|
|
||||||
uninstall) uninstall ;;
|
|
||||||
status) status ;;
|
|
||||||
*)
|
|
||||||
echo "Usage: sudo $0 {install|uninstall|status} [mitm_port]"
|
|
||||||
echo
|
|
||||||
echo "Redirects ONLY the standalone LS's outgoing :443 traffic through"
|
|
||||||
echo "the MITM proxy using UID-scoped iptables rules."
|
|
||||||
echo
|
|
||||||
echo "This does NOT affect:"
|
|
||||||
echo " - Your real Antigravity coding session"
|
|
||||||
echo " - Any other software on your PC"
|
|
||||||
echo " - DNS resolution (/etc/hosts is untouched)"
|
|
||||||
echo
|
|
||||||
echo " install [port] Create user + iptables REDIRECT for that UID"
|
|
||||||
echo " uninstall [port] Remove iptables rule + sudoers"
|
|
||||||
echo " status Show current state"
|
|
||||||
echo
|
|
||||||
echo "Default MITM port: 8742"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
138
scripts/proxyctl
138
scripts/proxyctl
@@ -1,138 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# proxyctl — manage the antigravity proxy daemon
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SERVICE="antigravity-proxy"
|
|
||||||
SCRIPT_PATH="$(readlink -f "$0")"
|
|
||||||
PROJECT_DIR="$(cd "$(dirname "$SCRIPT_PATH")/.." && pwd)"
|
|
||||||
PORT="${PROXY_PORT:-8741}"
|
|
||||||
BASE_URL="http://localhost:${PORT}"
|
|
||||||
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
CYAN='\033[0;36m'
|
|
||||||
DIM='\033[2m'
|
|
||||||
BOLD='\033[1m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo -e "${BOLD}proxyctl${NC} — antigravity proxy daemon manager"
|
|
||||||
echo ""
|
|
||||||
echo -e " ${CYAN}start${NC} Start the proxy daemon"
|
|
||||||
echo -e " ${CYAN}stop${NC} Stop the proxy daemon"
|
|
||||||
echo -e " ${CYAN}restart${NC} Rebuild + restart"
|
|
||||||
echo -e " ${CYAN}rebuild${NC} Build release binary only"
|
|
||||||
echo -e " ${CYAN}status${NC} Service status + quota + usage"
|
|
||||||
echo -e " ${CYAN}logs${NC} [N] Show last N lines (default 30)"
|
|
||||||
echo -e " ${CYAN}logs-follow${NC} [N] Tail last N lines + follow"
|
|
||||||
echo -e " ${CYAN}logs-all${NC} Full log dump"
|
|
||||||
echo -e " ${CYAN}test${NC} [msg] Quick test request (gemini-3-flash)"
|
|
||||||
echo -e " ${CYAN}health${NC} Health check"
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
do_build() {
|
|
||||||
echo -e "${YELLOW}Building release binary...${NC}"
|
|
||||||
cd "$PROJECT_DIR"
|
|
||||||
cargo build --release 2>&1
|
|
||||||
echo -e "${GREEN}Build complete.${NC}"
|
|
||||||
}
|
|
||||||
|
|
||||||
do_start() {
|
|
||||||
systemctl --user daemon-reload
|
|
||||||
systemctl --user start "$SERVICE"
|
|
||||||
echo -e "${GREEN}Started.${NC} Waiting for ready..."
|
|
||||||
# Wait up to 10s for health
|
|
||||||
for i in $(seq 1 20); do
|
|
||||||
if curl -sf "${BASE_URL}/health" >/dev/null 2>&1; then
|
|
||||||
echo -e "${GREEN}Proxy is up on port ${PORT}.${NC}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
sleep 0.5
|
|
||||||
done
|
|
||||||
echo -e "${RED}Proxy didn't become healthy in 10s. Check logs:${NC}"
|
|
||||||
journalctl --user -u "$SERVICE" --no-pager -n 20
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
do_stop() {
|
|
||||||
systemctl --user stop "$SERVICE" 2>/dev/null || true
|
|
||||||
echo -e "${YELLOW}Stopped.${NC}"
|
|
||||||
}
|
|
||||||
|
|
||||||
do_restart() {
|
|
||||||
echo -e "${YELLOW}Stopping...${NC}"
|
|
||||||
do_stop
|
|
||||||
do_build
|
|
||||||
do_start
|
|
||||||
}
|
|
||||||
|
|
||||||
do_status() {
|
|
||||||
echo -e "${BOLD}── Service ──${NC}"
|
|
||||||
systemctl --user status "$SERVICE" --no-pager 2>/dev/null | head -6 || echo -e "${RED}Not running${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Health check
|
|
||||||
if ! curl -sf "${BASE_URL}/health" >/dev/null 2>&1; then
|
|
||||||
echo -e "${RED}Proxy is not responding on port ${PORT}.${NC}"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${BOLD}── Quota ──${NC}"
|
|
||||||
curl -sf "${BASE_URL}/v1/quota" 2>/dev/null | jq '.' 2>/dev/null || echo -e "${DIM}(no quota data)${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo -e "${BOLD}── Usage ──${NC}"
|
|
||||||
curl -sf "${BASE_URL}/v1/usage" 2>/dev/null | jq '.' 2>/dev/null || echo -e "${DIM}(no usage data)${NC}"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo -e "${BOLD}── Sessions ──${NC}"
|
|
||||||
curl -sf "${BASE_URL}/v1/sessions" 2>/dev/null | jq '.' 2>/dev/null || echo -e "${DIM}(no sessions)${NC}"
|
|
||||||
}
|
|
||||||
|
|
||||||
do_logs() {
|
|
||||||
local lines="${1:-30}"
|
|
||||||
journalctl --user -u "$SERVICE" --no-pager -n "$lines"
|
|
||||||
}
|
|
||||||
|
|
||||||
do_logs_follow() {
|
|
||||||
local lines="${1:-30}"
|
|
||||||
journalctl --user -u "$SERVICE" --no-pager -n "$lines" -f
|
|
||||||
}
|
|
||||||
|
|
||||||
do_logs_all() {
|
|
||||||
journalctl --user -u "$SERVICE" --no-pager
|
|
||||||
}
|
|
||||||
|
|
||||||
do_test() {
|
|
||||||
local msg="${1:-Say hello in exactly 3 words}"
|
|
||||||
echo -e "${CYAN}Testing:${NC} ${msg}"
|
|
||||||
curl -sf "${BASE_URL}/v1/responses" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{
|
|
||||||
\"model\": \"gemini-3-flash\",
|
|
||||||
\"input\": \"${msg}\",
|
|
||||||
\"stream\": false,
|
|
||||||
\"timeout\": 30
|
|
||||||
}" | jq '.'
|
|
||||||
}
|
|
||||||
|
|
||||||
do_health() {
|
|
||||||
curl -sf "${BASE_URL}/health" | jq '.' 2>/dev/null && echo -e "${GREEN}Healthy${NC}" || echo -e "${RED}Not responding${NC}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ── Main ──
|
|
||||||
case "${1:-}" in
|
|
||||||
start) do_start ;;
|
|
||||||
stop) do_stop ;;
|
|
||||||
restart) do_restart ;;
|
|
||||||
rebuild) do_build ;;
|
|
||||||
status) do_status ;;
|
|
||||||
logs) do_logs "${2:-30}" ;;
|
|
||||||
logs-follow) do_logs_follow "${2:-30}" ;;
|
|
||||||
logs-all) do_logs_all ;;
|
|
||||||
test) do_test "${2:-}" ;;
|
|
||||||
health) do_health ;;
|
|
||||||
*) usage ;;
|
|
||||||
esac
|
|
||||||
Reference in New Issue
Block a user