Running the latest Ironclaw isolation profile on my analysis sandbox. My custom tool, a memory forensics scraper written in Rust, needs to HTTP POST its findings to our internal logging server at `log-collector.internal.corp:8080`. The agent's network namespace is correctly isolated, but now the egress filtering is blocking the outbound connection. I get "Connection refused" which, in this context, means the packet never left the sandbox's virtual interface.
The default `egress_filter.bpf` program attached to the cgroup only allows outbound DNS to the hardened resolver and HTTPS to a few known update servers. Plain HTTP on a non-standard port is obviously denied. I need to add a rule, but I want to be specific and not just punch a hole for all HTTP.
Here's the current relevant snippet of the BPF program's deny/allow logic for TCP egress. I've anonymized the IPs.
```c
// ... checks for DNS port 53 first ...
// Allow-list for HTTPS egress
if (dport == 443) {
// Allowed destination IPs: 203.0.113.1 (update server), 198.51.100.42 (telemetry)
if (daddr == 0x010113CB || daddr == 0x2A6333C6) {
bpf_printk("DEBUG: Allowing HTTPS egress to allowed host");
return TC_ACT_OK;
}
return TC_ACT_SHOT;
}
// Default deny for all other TCP
return TC_ACT_SHOT;
```
I need to extend this to permit TCP port 8080 to `log-collector.internal.corp`. I've resolved it to `10.42.7.11`. My proposed addition is below the HTTPS block, before the final deny:
```c
// Allow HTTP POST to internal log collector on port 8080
if (dport == 8080) {
// Only to the specific log collector IP
if (daddr == 0x0B072A0A) { // 10.42.7.11 in hex
bpf_printk("DEBUG: Allowing egress to log collector");
return TC_ACT_OK;
}
return TC_ACT_SHOT;
}
```
My questions:
1. Is this the right layer? Should I be doing this in the cgroup egress filter, or would a netfilter rule in the agent's network namespace be more appropriate? I want the rule to be part of the Ironclaw profile, so BPF seems correct.
2. Should I add a source port restriction? My tool uses a random high port, which is fine.
3. Is there a more elegant way to manage this allow-list, or are we stuck hand-rolling these `if` statements for every new internal service? A map lookup would be dynamic but also more complex.
The goal is to keep the principle of least privilege: one tool, one destination, one port.
cat /proc/self/status