Skip to content

Add upstream proxy #104

Open
eraow wants to merge 6 commits into
coder:mainfrom
eraow:feature/upstream-proxy
Open

Add upstream proxy #104
eraow wants to merge 6 commits into
coder:mainfrom
eraow:feature/upstream-proxy

Conversation

@eraow

@eraow eraow commented Jul 13, 2026

Copy link
Copy Markdown

Note: This PR was generated with AI assistance.

Summary

Adds an --upstream-proxy option so httpjail can forward its own outbound
requests through an HTTP proxy. This makes httpjail usable in environments
that only allow internet access via a corporate proxy.

Motivation

I want to run httpjail behind a corporate proxy. Without this option,
httpjail connects directly to upstream hosts, which fails when direct
egress is blocked and only a proxy is permitted.

What this does

  • Adds --upstream-proxy <URL> (e.g. http://proxy.example.com:8080).
  • When set, httpjail routes its upstream HTTP/HTTPS requests through the
    given proxy instead of connecting directly.
  • Behavior is unchanged when the flag is not provided.

Usage

httpjail --upstream-proxy http://proxy.example.com:8080 --js-file rules.js -- curl https://github.com

Manual verification

$ cat rules.js
const DOMAINS = [
  "github.com",
];

(function () {
  const h = (r.host || "").toLowerCase();
  for (const d of DOMAINS) {
    if (d[0] === ".") {
      if (h === d.slice(1) || h.endsWith(d)) return true;
    } else if (h === d) {
      return true;
    }
  }
  return false;
})();


## PASS Test
$ sudo env -u SUDO_UID -u SUDO_GID target/debug/httpjail -v  --upstream-proxy http://${proxy}:8080 --js-file rules.js --request-log jail.log curl -s -o /dev/null -w "%{http_code}\n" https://github.com
22:02:58.774  INFO httpjail: Using V8 JavaScript rule evaluation from file: rules.js
22:02:58.776  INFO httpjail::rules::v8_js: File watching enabled for JS rules - will check for changes on each request
22:02:58.776  INFO httpjail::rules::v8_js: V8 JavaScript rule engine initialized
22:02:58.776  INFO httpjail: Routing httpjail upstream requests through the configured upstream proxy
22:02:58.776  INFO httpjail::tls: Loaded cached CA certificate from /root/.config/httpjail/ca-cert.pem
22:02:58.776  INFO httpjail::tls: Certificate manager initialized
22:02:58.776  INFO httpjail::proxy: Upstream client initialized to route through the upstream proxy
22:02:58.776  INFO httpjail::proxy: Starting HTTP proxy on port 33769
22:02:58.776  INFO httpjail::proxy: Starting HTTPS proxy on port 34343
22:02:58.777  INFO httpjail::jail::linux::resources: Created network namespace: httpjail_er7tzu31
22:02:58.777  INFO httpjail::jail::linux: Created network namespace: httpjail_er7tzu31
22:02:58.918  INFO httpjail::jail::linux: Routes in namespace httpjail_er7tzu31 after configuration:
default via 10.99.184.253 dev vn_er7tzu31 
10.99.184.252/30 dev vn_er7tzu31 proto kernel scope link src 10.99.184.254 

22:02:58.918  INFO httpjail::jail::linux: Creating /etc/netns resolv.conf with nameserver 10.99.184.253
22:02:58.918  INFO httpjail::jail::linux::resources: Created /etc/netns/httpjail_er7tzu31/resolv.conf with nameserver 10.99.184.253
22:02:58.918  INFO httpjail::jail::linux: Starting host DNS server on 10.99.184.253
22:02:58.918  INFO httpjail::jail::linux::dns: Starting dummy DNS server on 10.99.184.253:53
22:02:58.918  INFO httpjail::jail::linux: Started host DNS server on 10.99.184.253:53
22:02:58.923  INFO httpjail::jail::linux::nftables: Created nftables table httpjail_er7tzu31 with NAT rules for subnet 10.99.184.252/30
22:02:58.923  INFO httpjail::jail::linux: Set up NAT rules for namespace httpjail_er7tzu31 with subnet 10.99.184.252/30
22:02:58.949  INFO httpjail::jail::linux::nftables: Created nftables rules in namespace httpjail_er7tzu31 for HTTP:33769 HTTPS:34343
22:02:58.949  INFO httpjail::jail::linux: Linux jail setup complete using namespace httpjail_er7tzu31 with HTTP proxy on port 33769 and HTTPS proxy on port 34343
22:02:58.949  INFO httpjail::jail::managed: Started lifecycle heartbeat for jail 'er7tzu31'
22:02:58.961  INFO httpjail::proxy_tls: Extracted SNI hostname: github.com
22:02:58.961  INFO httpjail::tls: Certificate generation: hostname=github.com, key_type=ECDSA-P256
200
22:02:59.067  INFO httpjail::jail::linux: Triggering jail cleanup for er7tzu31

## BLOCK Test
$ sudo env -u SUDO_UID -u SUDO_GID target/debug/httpjail -v  --upstream-proxy http://${proxy}:8080 --js-file rules.js --request-log jail.log curl -s -o /dev/null -w "%{http_code}\n" https://example.com
22:03:10.078  INFO httpjail: Using V8 JavaScript rule evaluation from file: rules.js
22:03:10.080  INFO httpjail::rules::v8_js: File watching enabled for JS rules - will check for changes on each request
22:03:10.080  INFO httpjail::rules::v8_js: V8 JavaScript rule engine initialized
22:03:10.080  INFO httpjail: Routing httpjail upstream requests through the configured upstream proxy
22:03:10.080  INFO httpjail::tls: Loaded cached CA certificate from /root/.config/httpjail/ca-cert.pem
22:03:10.080  INFO httpjail::tls: Certificate manager initialized
22:03:10.080  INFO httpjail::proxy: Upstream client initialized to route through the upstream proxy
22:03:10.080  INFO httpjail::proxy: Starting HTTP proxy on port 36481
22:03:10.080  INFO httpjail::proxy: Starting HTTPS proxy on port 36955
22:03:10.082  INFO httpjail::jail::linux::resources: Created network namespace: httpjail_ri1ch208
22:03:10.082  INFO httpjail::jail::linux: Created network namespace: httpjail_ri1ch208
22:03:10.240  INFO httpjail::jail::linux: Routes in namespace httpjail_ri1ch208 after configuration:
default via 10.99.247.149 dev vn_ri1ch208 
10.99.247.148/30 dev vn_ri1ch208 proto kernel scope link src 10.99.247.150 

22:03:10.240  INFO httpjail::jail::linux: Creating /etc/netns resolv.conf with nameserver 10.99.247.149
22:03:10.240  INFO httpjail::jail::linux::resources: Created /etc/netns/httpjail_ri1ch208/resolv.conf with nameserver 10.99.247.149
22:03:10.240  INFO httpjail::jail::linux: Starting host DNS server on 10.99.247.149
22:03:10.240  INFO httpjail::jail::linux::dns: Starting dummy DNS server on 10.99.247.149:53
22:03:10.240  INFO httpjail::jail::linux: Started host DNS server on 10.99.247.149:53
22:03:10.245  INFO httpjail::jail::linux::nftables: Created nftables table httpjail_ri1ch208 with NAT rules for subnet 10.99.247.148/30
22:03:10.245  INFO httpjail::jail::linux: Set up NAT rules for namespace httpjail_ri1ch208 with subnet 10.99.247.148/30
22:03:10.273  INFO httpjail::jail::linux::nftables: Created nftables rules in namespace httpjail_ri1ch208 for HTTP:36481 HTTPS:36955
22:03:10.273  INFO httpjail::jail::linux: Linux jail setup complete using namespace httpjail_ri1ch208 with HTTP proxy on port 36481 and HTTPS proxy on port 36955
22:03:10.273  INFO httpjail::jail::managed: Started lifecycle heartbeat for jail 'ri1ch208'
22:03:10.302  INFO httpjail::proxy_tls: Extracted SNI hostname: example.com
22:03:10.302  INFO httpjail::tls: Certificate generation: hostname=example.com, key_type=ECDSA-P256
403
22:03:10.353  INFO httpjail::jail::linux: Triggering jail cleanup for ri1ch208

@eraow eraow marked this pull request as ready for review July 13, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant