fix: standalone MITM — remove HTTPS_PROXY with iptables, fix is_agent detection

- Only set HTTPS_PROXY/HTTP_PROXY when iptables UID isolation is NOT
  available. With iptables, double-proxying caused profile picture
  fetches to fail with 'lookup http' DNS errors.
- Fix is_agent detection: handle JSON with spaces after colons
  ("requestType": "agent" vs "requestType":"agent")
- Suppress wrapper-not-installed warning in standalone mode
- Show 'iptables (standalone)' in banner instead of 'not installed'
This commit is contained in:
Nikketryhard
2026-02-14 18:47:38 -06:00
parent f0c2574c88
commit e678ec655b
3 changed files with 19 additions and 8 deletions

View File

@@ -247,7 +247,7 @@ async fn main() {
// ── Step 5: Start serving ─────────────────────────────────────────────────
let app = api::router(state.clone());
print_banner(cli.port, &pid, &https_port, &csrf, &token, &mitm_port_actual);
print_banner(cli.port, &pid, &https_port, &csrf, &token, &mitm_port_actual, is_standalone);
info!("Listening on http://{addr}");
axum::serve(listener, app)
@@ -295,7 +295,7 @@ async fn shutdown_signal() {
}
}
fn print_banner(port: u16, pid: &str, https_port: &str, csrf: &str, token: &str, mitm: &Option<(u16, String)>) {
fn print_banner(port: u16, pid: &str, https_port: &str, csrf: &str, token: &str, mitm: &Option<(u16, String)>, is_standalone: bool) {
let chrome_major = &*constants::CHROME_MAJOR;
let ver = crate::constants::antigravity_version();
@@ -319,8 +319,9 @@ fn print_banner(port: u16, pid: &str, https_port: &str, csrf: &str, token: &str,
println!(" \x1b[36m ca cert\x1b[0m {ca_path}");
// Check if wrapper is installed
let wrapper_installed = check_wrapper_installed();
if wrapper_installed {
if is_standalone {
println!(" \x1b[36m wrapper\x1b[0m \x1b[32miptables (standalone)\x1b[0m");
} else if check_wrapper_installed() {
println!(" \x1b[36m wrapper\x1b[0m \x1b[32minstalled\x1b[0m");
} else {
println!(" \x1b[36m wrapper\x1b[0m \x1b[33mnot installed\x1b[0m");
@@ -351,7 +352,9 @@ fn print_banner(port: u16, pid: &str, https_port: &str, csrf: &str, token: &str,
// Setup hints
if let Some((mitm_port, ca_path)) = mitm {
if !check_wrapper_installed() {
if is_standalone {
// Standalone mode uses iptables UID isolation — no wrapper needed
} else if !check_wrapper_installed() {
println!(" \x1b[1;33m[!]\x1b[0m mitm wrapper not installed");
println!(" \x1b[2mrun:\x1b[0m ./scripts/mitm-wrapper.sh install");
println!(" \x1b[2mor:\x1b[0m HTTPS_PROXY=http://127.0.0.1:{mitm_port}");

View File

@@ -551,9 +551,9 @@ async fn handle_http_over_tls(
let raw_body = super::modify::dechunk(body_slice);
// Only modify "agent" requests, not "checkpoint" (LS internal)
let is_agent = raw_body
.windows(20)
.any(|w| w == b"\"requestType\":\"agent" || w == b"requestType\":\"agent\"");
let body_str = String::from_utf8_lossy(&raw_body);
let is_agent = body_str.contains("\"requestType\":\"agent\"")
|| body_str.contains("\"requestType\": \"agent\"");
if is_agent {
if let Some(modified_body) = super::modify::modify_request(&raw_body) {

View File

@@ -143,6 +143,14 @@ impl StandaloneLS {
env_vars.push(("SSL_CERT_FILE".into(), combined_ca_path));
env_vars.push(("SSL_CERT_DIR".into(), "/dev/null".into()));
env_vars.push(("NODE_EXTRA_CA_CERTS".into(), mitm.ca_cert_path.clone()));
// Only set HTTPS_PROXY when iptables UID isolation is NOT available.
// With iptables, all outbound traffic is transparently redirected at the
// kernel level — setting HTTPS_PROXY on top causes double-proxying
// (profile picture fetches, etc. break with "lookup http" errors).
if !has_ls_user() {
env_vars.push(("HTTPS_PROXY".into(), format!("http://{}", mitm.proxy_addr)));
env_vars.push(("HTTP_PROXY".into(), format!("http://{}", mitm.proxy_addr)));
}
}
// Check if 'antigravity-ls' user exists for UID-scoped iptables isolation