Replace built-in proxies with tun2socks transparent proxying

Remove the built-in HTTP/SOCKS5 proxy servers and domain allowlist/denylist
system. Instead, use tun2socks with a TUN device inside the network namespace
to transparently route all TCP/UDP traffic through an external SOCKS5 proxy.

This enables truly transparent proxying where any binary (Go, static, etc.)
has its traffic routed through the proxy without needing to respect
HTTP_PROXY/ALL_PROXY environment variables. The external proxy handles its
own filtering.

Key changes:
- NetworkConfig: remove AllowedDomains/DeniedDomains/proxy ports, add ProxyURL
- Delete internal/proxy/, internal/templates/, internal/importer/
- Embed tun2socks binary (downloaded at build time via Makefile)
- Replace LinuxBridge with ProxyBridge (single Unix socket to external proxy)
- Inner script sets up TUN device + tun2socks inside network namespace
- Falls back to env-var proxying when TUN is unavailable
- macOS: best-effort env-var proxying to external SOCKS5 proxy
- CLI: remove --template/import, add --proxy flag
- Feature detection: add ip/tun/tun2socks status to --linux-features
This commit is contained in:
2026-02-09 20:41:12 -06:00
parent da5f61e390
commit 9cb65151ee
38 changed files with 588 additions and 4155 deletions

View File

@@ -4,7 +4,6 @@ import (
"encoding/base64"
"os"
"path/filepath"
"strconv"
"strings"
)
@@ -49,13 +48,14 @@ func NormalizePath(pathPattern string) string {
}
// GenerateProxyEnvVars creates environment variables for proxy configuration.
func GenerateProxyEnvVars(httpPort, socksPort int) []string {
// Used on macOS where transparent proxying is not available.
func GenerateProxyEnvVars(proxyURL string) []string {
envVars := []string{
"FENCE_SANDBOX=1",
"TMPDIR=/tmp/fence",
}
if httpPort == 0 && socksPort == 0 {
if proxyURL == "" {
return envVars
}
@@ -75,32 +75,14 @@ func GenerateProxyEnvVars(httpPort, socksPort int) []string {
envVars = append(envVars,
"NO_PROXY="+noProxy,
"no_proxy="+noProxy,
"ALL_PROXY="+proxyURL,
"all_proxy="+proxyURL,
"HTTP_PROXY="+proxyURL,
"HTTPS_PROXY="+proxyURL,
"http_proxy="+proxyURL,
"https_proxy="+proxyURL,
)
if httpPort > 0 {
proxyURL := "http://localhost:" + itoa(httpPort)
envVars = append(envVars,
"HTTP_PROXY="+proxyURL,
"HTTPS_PROXY="+proxyURL,
"http_proxy="+proxyURL,
"https_proxy="+proxyURL,
)
}
if socksPort > 0 {
socksURL := "socks5h://localhost:" + itoa(socksPort)
envVars = append(envVars,
"ALL_PROXY="+socksURL,
"all_proxy="+socksURL,
"FTP_PROXY="+socksURL,
"ftp_proxy="+socksURL,
)
// Git SSH through SOCKS
envVars = append(envVars,
"GIT_SSH_COMMAND=ssh -o ProxyCommand='nc -X 5 -x localhost:"+itoa(socksPort)+" %h %p'",
)
}
return envVars
}
@@ -121,6 +103,3 @@ func DecodeSandboxedCommand(encoded string) (string, error) {
return string(data), nil
}
func itoa(n int) string {
return strconv.Itoa(n)
}