docs: add MITM interception research and redirect scripts

This commit is contained in:
Nikketryhard
2026-02-14 04:03:22 -06:00
parent 4fa8775b61
commit 9cf7bb75d2
4 changed files with 647 additions and 0 deletions

View File

@@ -0,0 +1,242 @@
# MITM Traffic Interception — Research & Status
## Goal
Capture the LS's LLM API traffic (requests + responses, including system prompts
and token usage) by routing it through our MITM proxy.
## Key Discovery: How the LS Makes LLM API Calls
The LS does **NOT** use gRPC for LLM API calls. It uses:
- **Protocol**: Standard HTTPS POST with Server-Sent Events (SSE)
- **Endpoint**: `https://daily-cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse`
- **HTTP client**: `ApiServerClientV2` — a Go HTTP client that creates its own `tls.Config`
and transport, **ignoring `HTTPS_PROXY` by default**
The Go HTTP client for LLM API calls is separate from the one used for Unleash
(feature flags) and other auxiliary traffic. The Unleash client respects proxy
settings, but the LLM client does not.
## What We Tried
### 1. Extension Patch — `detectAndUseProxy` ✅ Partial
**Status**: Applied and still active. Harmless.
The extension sends a protobuf field `detect_and_use_proxy` (field 34) to the LS
during initialization. By default, it's set to `UNSPECIFIED` (0), meaning the LS
ignores proxy env vars.
**Patch applied:**
```bash
sudo sed -i 's/detectAndUseProxy=pe.UNSPECIFIED/detectAndUseProxy=1/' \
/usr/share/antigravity/resources/app/extensions/antigravity/dist/extension.js
```
**Enum values:**
- 0 = `DETECT_AND_USE_PROXY_UNSPECIFIED` (default, ignore proxy)
- 1 = `DETECT_AND_USE_PROXY_ENABLED`
- 2 = `DETECT_AND_USE_PROXY_DISABLED`
**Result:** Unleash/aux traffic now routes through `HTTPS_PROXY`. But the LLM API
client (`ApiServerClientV2`) has its own transport that ignores this flag. LLM
calls still go direct to Google.
**Verify:** `grep -o 'detectAndUseProxy=[^;]*' /usr/share/antigravity/resources/app/extensions/antigravity/dist/extension.js`
→ should show `detectAndUseProxy=1`
**Re-apply after updates:** Yes, must re-apply after every Antigravity update.
### 2. MITM Wrapper (`mitm-wrapper.sh`) ✅ Works for Env Vars
Sets `HTTPS_PROXY` and `SSL_CERT_FILE` on the LS process by wrapping the binary.
**How it works:**
1. Renames real binary to `.real`
2. Places a shell script wrapper at the original path
3. Wrapper sets env vars and execs the real binary with all original args
**Result:** The wrapper correctly sets env vars on the LS process (verified via
`/proc/<PID>/environ`). Combined with the extension patch, Unleash traffic routes
through the proxy. But LLM API calls still bypass — the `ApiServerClientV2` Go
HTTP client doesn't honor `HTTPS_PROXY`.
### 3. iptables REDIRECT — ALL Port 443 ❌ Failed
Redirected all outbound port 443 traffic from the user's UID to the MITM proxy.
**Problems encountered:**
1. **Redirect loop** — proxy's own upstream connections got caught by iptables,
creating infinite loops → fd exhaustion → crash
2. **Fixed loop with GID bypass** — running proxy with `sg mitm-bypass` and
excluding GID in iptables. This fixed the loop.
3. **Broke Antigravity** — ALL HTTPS traffic (telegram, discord, microsoft
telemetry, extension marketplace, etc.) went through the proxy. The TLS
passthrough worked technically but was too disruptive.
4. **TLS trust failure** — even with the MITM wrapper setting `SSL_CERT_FILE`,
the LS's Go LLM client likely uses a custom `tls.Config` with its own root
CAs, not the system pool. So it rejected our MITM CA cert.
**Abandoned.** Too disruptive, and the fundamental TLS trust issue remained.
### 4. DNS Redirect (`/etc/hosts`) ❌ Failed
Redirected only `daily-cloudcode-pa.googleapis.com` to 127.0.0.1 via `/etc/hosts`,
then used a targeted iptables rule for `127.0.0.1:443` only.
**Problems:**
- Same TLS trust issue — the Go LLM client rejected our MITM CA
- Needed `dig @8.8.8.8` bypass for upstream resolution (implemented but untested)
**Abandoned.** TLS trust is the blocker.
## The Core Blocker
**The LS's Go LLM HTTP client (`ApiServerClientV2`) uses a custom `tls.Config`
that does NOT read from `SSL_CERT_FILE` or the system CA store.** It likely has
its own hardcoded/embedded root CAs.
This means:
- Even if we redirect traffic to our MITM proxy ✅
- Even if the MITM generates valid certs for the domain ✅
- The LS rejects the cert because it doesn't trust our CA ❌
## Potential Solutions (Untried)
### A. Binary Patching
Patch the Go binary to accept our CA or disable cert verification.
- Find the `tls.Config` setup in the binary
- Modify `InsecureSkipVerify` to `true`, or inject our CA cert DER bytes
- Very fragile, breaks on updates
### B. LD_PRELOAD Hook
Hook `connect()` syscall to redirect traffic.
- **Won't work** for Go — Go uses raw syscalls, not libc wrappers
### C. Network Namespace
Run the LS in an isolated network namespace with custom routing.
- Complex setup, but clean isolation
- The standalone LS work would feed into this
### D. Standalone LS with Full Control
Get standalone LS cascades working (see `docs/standalone-ls-todo.md`), then
have full control over the process environment, including:
- Custom CA trust
- Custom DNS resolution
- Custom proxy settings
- Network namespace isolation
**This is probably the best long-term approach.**
### E. Kernel-level TLS Interception (eBPF)
Use eBPF to intercept TLS records pre-encryption.
- Very powerful, can read plaintext before encryption
- Complex, requires kernel support (>= 4.18)
- Tools: `bpftrace`, custom eBPF programs, `ecapture`
### F. `SSLKEYLOGFILE` + Passive Capture
- Go doesn't support `SSLKEYLOGFILE` (confirmed by testing)
- Could patch the binary to enable it, but same fragility as option A
### G. ptrace-based Interception
Use `ptrace` to intercept `write()`/`sendmsg()` syscalls on TLS sockets.
- Can read plaintext data being written to TLS connections
- Tools: `strace -e trace=write -p <PID>` (but output is messy)
- Better: custom ptrace tool that filters for TLS socket FDs
## Technical Details
### Model IDs
| Placeholder | Model |
| ------------------------- | ------------------- |
| `MODEL_PLACEHOLDER_M18` | Gemini 3 Flash |
| `MODEL_PLACEHOLDER_M8` | Gemini 3 Pro (High) |
| `MODEL_PLACEHOLDER_M7` | Gemini 3 Pro (Low) |
| `MODEL_PLACEHOLDER_M26` | Claude Opus 4.6 |
| `MODEL_PLACEHOLDER_M12` | Claude Opus 4.5 |
| `MODEL_CLAUDE_4_5_SONNET` | Claude Sonnet 4.5 |
### LS Binary Location
`/usr/share/antigravity/resources/app/extensions/antigravity/bin/language_server_linux_x64`
### API Endpoint
`https://daily-cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse`
### Protobuf Field 34 — `detect_and_use_proxy`
- Part of the init metadata sent from extension to LS via stdin
- Enum: `DetectAndUseProxy` (0=UNSPECIFIED, 1=ENABLED, 2=DISABLED)
- Controls whether auxiliary HTTP clients honor `HTTPS_PROXY`
- Does NOT control the LLM API client
### Unleash Feature Flags
- Authorization: `*:production.e44558998bfc35ea9584dc65858e4485fdaa5d7ef46903e0c67712d1`
- Endpoint: `antigravity-unleash.goog`
- App name: `codeium-language-server`
### Files Modified (Current State)
- `extension.js``detectAndUseProxy=1` (harmless, keeps working)
- Everything else — clean/reverted
## Code Changes Made (in the proxy)
1. **Transparent proxy mode** (`src/mitm/proxy.rs`) — supports iptables REDIRECT
by detecting raw TLS ClientHello and extracting SNI
2. **CryptoProvider init** (`src/main.rs`) — prevents rustls panic under load
3. **PID detection fix** (`src/backend.rs`) — prefers `.real` binary PID over
wrapper shell script PID
4. **SS fallback** (`src/backend.rs`) — discovers LS port via `ss` when log file
doesn't have it
5. **DNS bypass** (`src/mitm/proxy.rs`) — `connect_upstream` resolves via
`dig @8.8.8.8` to bypass `/etc/hosts`
6. **Scripts**`dns-redirect.sh`, `iptables-redirect.sh` (both functional)
## Cleanup Checklist
If things are broken, undo in this order:
```bash
# 1. Remove iptables rules
sudo ./scripts/iptables-redirect.sh uninstall
sudo ./scripts/dns-redirect.sh uninstall
# 2. Remove /etc/hosts entries (verify manually)
sudo grep -v "antigravity-mitm" /etc/hosts | sudo tee /etc/hosts.tmp && sudo mv /etc/hosts.tmp /etc/hosts
# 3. Uninstall wrapper
sudo ./scripts/mitm-wrapper.sh uninstall
# 4. Remove system CA
sudo rm -f /usr/local/share/ca-certificates/antigravity-mitm.crt
sudo update-ca-certificates
# 5. Restart Antigravity
```
## Next Steps
→ See `docs/standalone-ls-todo.md` for standalone LS isolation work

View File

@@ -0,0 +1,74 @@
# Standalone LS for Proxy Isolation
## Goal
Route ALL proxy traffic through a standalone LS instance instead of the real one,
so development/testing/proxying never interferes with active coding sessions.
## Current State
The proxy currently talks to the **real** LS spawned by Antigravity.
This is risky — a bad cascade or proxy bug can disrupt the coding conversation.
## What Works
- Standalone LS starts fine with custom init metadata via stdin protobuf
- Connects to the main extension server (`-extension_server_port`)
- Accepts cascade requests (returns cascadeId)
- With `detect_and_use_proxy = ENABLED` (field 34 = 2), honors `HTTPS_PROXY`
## What Doesn't Work
- **Cascades silently fail** — the LS accepts the request but never processes it
- No planner invocation, no upstream API call, no logs beyond startup
- 9 lines of log after 40s wait
- Main LS logs show zero trace of the standalone's cascade
## Suspected Blockers (investigate in order)
1. **Auth context** — standalone may not receive OAuth token from extension server
- Check: does the standalone's `GetUserStatus` return valid auth?
- The extension server might only share tokens with the "primary" LS
2. **Unleash feature flags** — cascade processing gated by flags the standalone doesn't fetch
- The standalone connects to Unleash via the proxy, but might not get the right flags
- Check: compare Unleash responses between main and standalone
3. **Workspace indexing** — planner might require indexed workspace state
- The standalone's workspace (`/tmp/antigravity-standalone`) is empty
- Try: point it at a real workspace with actual files
4. **Extension server coupling** — cascade might need the extension to "drive" it
- The chat panel in the extension might send additional RPCs to progress the cascade
- Check: trace what RPCs the extension sends after StartCascade
## Investigation Plan
```bash
# 1. Launch with max verbosity
echo "$METADATA" | base64 -d | \
timeout 90 "$LS_BIN" \
-v 5 \
-server_port 42200 \
... > /tmp/standalone-verbose.log 2>&1 &
# 2. Check auth status
curl -sk "https://127.0.0.1:42200/exa.language_server_pb.LanguageServerService/GetUserStatus" \
-H "Content-Type: application/json" \
-H "x-codeium-csrf-token: $CSRF" \
-d '{}'
# 3. Send cascade and watch logs in real-time
tail -f /tmp/standalone-verbose.log &
curl -sk "https://127.0.0.1:42200/.../StartCascade" ...
# 4. Compare Unleash flags
# Main LS unleash vs standalone unleash
```
## Key Technical Details
- Init metadata protobuf field 34 = `detect_and_use_proxy` (enum: 0=UNSPECIFIED, 1=ENABLED, 2=DISABLED)
- Model IDs: M18=Flash, M8=Pro-High, M7=Pro-Low, M26=Opus4.6, M12=Opus4.5
- LS binary: `/usr/share/antigravity/resources/app/extensions/antigravity/bin/language_server_linux_x64`
- API endpoint: `daily-cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse`

163
scripts/dns-redirect.sh Executable file
View File

@@ -0,0 +1,163 @@
#!/usr/bin/env bash
# ╔═══════════════════════════════════════════════════════════════════════════╗
# ║ Antigravity MITM — DNS-based redirect for targeted interception ║
# ║ ║
# ║ Instead of redirecting ALL port 443 traffic (which breaks everything), ║
# ║ this uses /etc/hosts to redirect ONLY the LLM API domain to localhost, ║
# ║ then iptables redirects only localhost:443 → MITM port. ║
# ║ ║
# ║ Also adds the MITM CA to the system trust store so Go trusts it. ║
# ╚═══════════════════════════════════════════════════════════════════════════╝
set -euo pipefail
MITM_PORT="${ANTIGRAVITY_MITM_PORT:-8742}"
MITM_CA="${HOME}/.config/antigravity-proxy/mitm-ca.pem"
# If run with sudo, use SUDO_USER's home
if [[ -n "${SUDO_USER:-}" ]]; then
MITM_CA="$(eval echo "~${SUDO_USER}")/.config/antigravity-proxy/mitm-ca.pem"
fi
HOSTS_MARKER="# antigravity-mitm"
API_DOMAINS=(
"daily-cloudcode-pa.googleapis.com"
)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
cmd_install() {
echo -e "${BOLD}${CYAN}Antigravity MITM DNS Redirect Setup${NC}"
echo -e "────────────────────────────────────"
echo ""
# 1. Add MITM CA to system trust store
if [[ ! -f "$MITM_CA" ]]; then
echo -e " ${RED}${NC} MITM CA not found: ${MITM_CA}"
echo -e " Start the proxy once first to generate it."
exit 1
fi
local sys_cert="/usr/local/share/ca-certificates/antigravity-mitm.crt"
cp "$MITM_CA" "$sys_cert"
update-ca-certificates >/dev/null 2>&1
echo -e " ${GREEN}${NC} MITM CA added to system trust store"
# 2. Add /etc/hosts entries for API domains → 127.0.0.1
# First, cache the real IPs for the MITM to use later
local real_ips_file="/tmp/antigravity-mitm-real-ips"
> "$real_ips_file"
for domain in "${API_DOMAINS[@]}"; do
# Remove old entries
sed -i "/${domain}.*${HOSTS_MARKER}/d" /etc/hosts
# Resolve and cache the real IPs BEFORE redirecting
local real_ip
real_ip=$(dig +short "$domain" 2>/dev/null | grep -E '^[0-9]+\.' | head -1)
if [[ -n "$real_ip" ]]; then
echo "${domain}=${real_ip}" >> "$real_ips_file"
fi
# Add the /etc/hosts redirect
echo "127.0.0.1 ${domain} ${HOSTS_MARKER}" >> /etc/hosts
echo -e " ${GREEN}${NC} /etc/hosts: ${domain} → 127.0.0.1 (real: ${real_ip:-unknown})"
done
# 3. iptables: redirect ONLY 127.0.0.1:443 → MITM port
# This catches only the /etc/hosts redirected domains, nothing else!
iptables -t nat -D OUTPUT -d 127.0.0.1 -p tcp --dport 443 \
-j REDIRECT --to-port "$MITM_PORT" 2>/dev/null || true
iptables -t nat -A OUTPUT -d 127.0.0.1 -p tcp --dport 443 \
-j REDIRECT --to-port "$MITM_PORT"
echo -e " ${GREEN}${NC} iptables: 127.0.0.1:443 → localhost:${MITM_PORT}"
echo ""
echo -e " ${GREEN}Done!${NC}"
echo ""
echo -e " ${BOLD}How it works:${NC}"
echo -e " 1. LS resolves ${API_DOMAINS[0]} → 127.0.0.1 (via /etc/hosts)"
echo -e " 2. LS connects to 127.0.0.1:443"
echo -e " 3. iptables redirects to MITM proxy on :${MITM_PORT}"
echo -e " 4. MITM intercepts, decrypts (CA is trusted), proxies to real Google"
echo ""
echo -e " Real upstream IPs cached in: ${real_ips_file}"
echo -e " Restart Antigravity for changes to take effect."
echo -e " Undo: sudo $0 uninstall"
echo ""
}
cmd_uninstall() {
echo -e "${BOLD}${CYAN}Removing MITM DNS Redirect${NC}"
echo ""
# Remove /etc/hosts entries
sed -i "/${HOSTS_MARKER}/d" /etc/hosts
echo -e " ${GREEN}${NC} Removed /etc/hosts entries"
# Remove iptables rule
iptables -t nat -D OUTPUT -d 127.0.0.1 -p tcp --dport 443 \
-j REDIRECT --to-port "$MITM_PORT" 2>/dev/null || true
echo -e " ${GREEN}${NC} Removed iptables rule"
# Remove system CA (optional)
rm -f /usr/local/share/ca-certificates/antigravity-mitm.crt
update-ca-certificates >/dev/null 2>&1
echo -e " ${GREEN}${NC} Removed MITM CA from system trust store"
echo ""
}
cmd_status() {
echo -e "${BOLD}${CYAN}MITM DNS Redirect Status${NC}"
echo ""
# Check /etc/hosts
local hosts_count
hosts_count=$(grep -c "$HOSTS_MARKER" /etc/hosts 2>/dev/null || echo 0)
if [[ "$hosts_count" -gt 0 ]]; then
echo -e " ${GREEN}${NC} /etc/hosts: ${hosts_count} domain(s) redirected"
grep "$HOSTS_MARKER" /etc/hosts | sed 's/^/ /'
else
echo -e " ${YELLOW}${NC} /etc/hosts: no redirects"
fi
echo ""
# Check iptables
if iptables -t nat -L OUTPUT -n 2>/dev/null | grep -q "127.0.0.1.*REDIRECT.*${MITM_PORT}"; then
echo -e " ${GREEN}${NC} iptables: 127.0.0.1:443 → :${MITM_PORT}"
else
echo -e " ${YELLOW}${NC} iptables: no redirect"
fi
echo ""
# Check system CA
if [[ -f /usr/local/share/ca-certificates/antigravity-mitm.crt ]]; then
echo -e " ${GREEN}${NC} System CA: installed"
else
echo -e " ${YELLOW}${NC} System CA: not installed"
fi
echo ""
}
case "${1:-}" in
install)
cmd_install
;;
uninstall)
cmd_uninstall
;;
status)
cmd_status
;;
*)
echo "Usage: sudo $0 {install|uninstall|status}"
echo ""
echo "Redirects LLM API domain to localhost via /etc/hosts + iptables."
echo "Only intercepts API traffic, everything else is untouched."
exit 1
;;
esac

168
scripts/iptables-redirect.sh Executable file
View File

@@ -0,0 +1,168 @@
#!/usr/bin/env bash
# ╔═══════════════════════════════════════════════════════════════════════════╗
# ║ Antigravity MITM — iptables redirect for transparent interception ║
# ║ ║
# ║ Redirects outbound port 443 traffic to the MITM proxy. ║
# ║ Uses a dedicated GID to exclude the proxy's own upstream traffic, ║
# ║ preventing redirect loops. ║
# ║ ║
# ║ Usage: sudo ./iptables-redirect.sh install ║
# ║ sudo ./iptables-redirect.sh uninstall ║
# ║ sudo ./iptables-redirect.sh status ║
# ╚═══════════════════════════════════════════════════════════════════════════╝
set -euo pipefail
MITM_PORT="${ANTIGRAVITY_MITM_PORT:-8742}"
CHAIN="ANTIGRAVITY_MITM"
BYPASS_GROUP="mitm-bypass"
# Resolve target user (the one whose traffic we redirect)
TARGET_USER="${SUDO_USER:-$(whoami)}"
TARGET_UID=$(id -u "$TARGET_USER" 2>/dev/null || echo "")
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
cmd_install() {
echo -e "${BOLD}${CYAN}Antigravity MITM iptables Setup${NC}"
echo -e "────────────────────────────────"
echo ""
if [[ -z "$TARGET_UID" ]]; then
echo -e " ${RED}${NC} Cannot resolve UID for user '${TARGET_USER}'"
exit 1
fi
# Create bypass group (proxy runs with this GID to avoid redirect loop)
if ! getent group "$BYPASS_GROUP" >/dev/null 2>&1; then
groupadd "$BYPASS_GROUP"
echo -e " ${GREEN}${NC} Created group: ${BYPASS_GROUP}"
else
echo -e " ${GREEN}${NC} Group exists: ${BYPASS_GROUP}"
fi
# Add user to bypass group (so they can use 'sg' to run proxy)
if ! id -nG "$TARGET_USER" 2>/dev/null | grep -qw "$BYPASS_GROUP"; then
usermod -aG "$BYPASS_GROUP" "$TARGET_USER"
echo -e " ${GREEN}${NC} Added ${TARGET_USER} to ${BYPASS_GROUP}"
fi
local bypass_gid
bypass_gid=$(getent group "$BYPASS_GROUP" | cut -d: -f3)
# Check MITM proxy is running
if ! ss -tlnp 2>/dev/null | grep -q ":${MITM_PORT}"; then
echo -e " ${YELLOW}!${NC} MITM proxy not running on :${MITM_PORT} (will work once started)"
else
echo -e " ${GREEN}${NC} MITM proxy listening on :${MITM_PORT}"
fi
# Create our chain
iptables -t nat -N "$CHAIN" 2>/dev/null || true
iptables -t nat -F "$CHAIN"
# THE KEY RULE: redirect port 443 traffic UNLESS it's from the bypass group.
# This prevents redirect loops — the proxy runs with GID=mitm-bypass,
# so its upstream connections to Google are NOT redirected back to itself.
iptables -t nat -A "$CHAIN" \
-m owner ! --gid-owner "$bypass_gid" \
-p tcp --dport 443 \
-j REDIRECT --to-port "$MITM_PORT"
echo -e " ${GREEN}${NC} Redirect rule: tcp/443 → :${MITM_PORT} (skip GID ${bypass_gid})"
# Hook into OUTPUT for target user only
iptables -t nat -D OUTPUT -m owner --uid-owner "$TARGET_UID" \
-p tcp --dport 443 -j "$CHAIN" 2>/dev/null || true
iptables -t nat -A OUTPUT -m owner --uid-owner "$TARGET_UID" \
-p tcp --dport 443 -j "$CHAIN"
echo -e " ${GREEN}${NC} OUTPUT hook: UID ${TARGET_UID} (${TARGET_USER})"
echo ""
echo -e " ${GREEN}Done!${NC}"
echo ""
echo -e " ${BOLD}IMPORTANT:${NC} Run the proxy with the bypass group to avoid loops:"
echo -e " ${CYAN}sg ${BYPASS_GROUP} -c 'RUST_LOG=info ./target/release/antigravity-proxy'${NC}"
echo ""
echo -e " Then restart Antigravity to re-establish connections."
echo -e " Undo: sudo $0 uninstall"
echo ""
}
cmd_uninstall() {
echo -e "${BOLD}${CYAN}Removing iptables MITM redirect${NC}"
echo ""
local target_uid
target_uid=$(id -u "$TARGET_USER" 2>/dev/null || echo "1000")
# Remove jump from OUTPUT
iptables -t nat -D OUTPUT -m owner --uid-owner "$target_uid" \
-p tcp --dport 443 -j "$CHAIN" 2>/dev/null || true
echo -e " ${GREEN}${NC} Removed OUTPUT jump"
# Flush and delete our chain
iptables -t nat -F "$CHAIN" 2>/dev/null || true
iptables -t nat -X "$CHAIN" 2>/dev/null || true
echo -e " ${GREEN}${NC} Removed ${CHAIN} chain"
echo ""
echo -e " ${YELLOW}Note:${NC} Group '${BYPASS_GROUP}' left intact (harmless)."
echo -e " Remove with: sudo groupdel ${BYPASS_GROUP}"
echo ""
}
cmd_status() {
echo -e "${BOLD}${CYAN}iptables MITM Status${NC}"
echo ""
if iptables -t nat -L "$CHAIN" -n 2>/dev/null | grep -q "REDIRECT"; then
echo -e " ${GREEN}${NC} Chain ${CHAIN}: active"
iptables -t nat -L "$CHAIN" -nv --line-numbers 2>/dev/null | \
sed 's/^/ /'
else
echo -e " ${YELLOW}${NC} Chain ${CHAIN}: not installed"
fi
echo ""
if iptables -t nat -L OUTPUT -n 2>/dev/null | grep -q "$CHAIN"; then
echo -e " ${GREEN}${NC} OUTPUT hook: installed"
iptables -t nat -L OUTPUT -n 2>/dev/null | grep "$CHAIN" | sed 's/^/ /'
else
echo -e " ${YELLOW}${NC} OUTPUT hook: not installed"
fi
echo ""
if getent group "$BYPASS_GROUP" >/dev/null 2>&1; then
local gid
gid=$(getent group "$BYPASS_GROUP" | cut -d: -f3)
echo -e " ${GREEN}${NC} Bypass group: ${BYPASS_GROUP} (GID ${gid})"
else
echo -e " ${YELLOW}${NC} Bypass group: not created"
fi
echo ""
}
case "${1:-}" in
install)
cmd_install
;;
uninstall)
cmd_uninstall
;;
status)
cmd_status
;;
*)
echo "Usage: sudo $0 {install|uninstall|status}"
echo ""
echo "Redirects outbound port 443 traffic to the MITM proxy."
echo "The proxy must be run with 'sg mitm-bypass' to avoid redirect loops."
exit 1
;;
esac