Add comprehensive input validation and per-ipset tuning parameters - #41
Draft
struanb wants to merge 4 commits into
Conversation
…auth bypass Issue 1 (High) — strict input validation before iptables-restore: - Add validator functions (_val_identifier, _val_iface, _val_ip, _val_cidr, _val_mac, _val_proto, _val_port, _val_comment, _val_icmp_type, _val_host_entry) using allow-lists and stdlib ipaddress module. - Call validators in EgressRule, NatRule, and NetworkSpec constructors, and in Config.from_dicts() for ipset names and host entries. - Any invalid value raises ValueError before kernel mutation is attempted. Issue 2 (Medium/High) — management socket peer credential verification: - Read SO_PEERCRED on each accepted connection (pid, uid, gid). - Require UID 0 (root) for all mutating actions (apply, reload, set-network, remove-network, set-ipset, remove-ipset, reconcile). - Read-only actions (status, refresh) remain open to any group member. - Log peer pid/uid/gid and action for every request (audit trail). https://claude.ai/code/session_016QwTdAvrMgYdfJuycgobHc
…w-firewall-fixes-YgXxW
…ervals
Introduces IpsetDef to carry per-ipset tuning alongside the hostname list,
replacing the bare List[str] stored in Config.ipsets. Config format remains
fully backwards-compatible: plain-list ipset entries are unchanged; the
extended dict form is opt-in.
New fields (all optional, all env-var-defaulted):
dns_queries — getaddrinfo calls per hostname per refresh cycle.
Values > 1 accelerate discovery of CDN/anycast pools
that return a different IP on each query (e.g.
vscode.download.prss.microsoft.com).
Global default: IPSET_DNS_QUERIES env var (default 1).
stale_ttl — seconds a discovered IP stays in the live set after
it stops appearing in DNS. Longer values suit CDN
pools with large, slowly-rotating IP lists.
Global default: IPSET_STALE_TTL (300 s).
refresh_interval — seconds between refresh cycles for this ipset.
CDN sets can refresh every 5-10 s while stable
single-IP sets stay at 60 s, without forcing a
global speed-up that hammers DNS for all ipsets.
Global default: IPSET_REFRESH_INTERVAL (60 s).
Implementation:
- IpsetManager gains refresh_due() (refreshes only overdue ipsets) and
time_until_next_refresh() (precise sleep duration for the loop).
- _refresh_loop() replaced fixed-interval sleep with a precision-wake
approach: sleep = time_until_next_refresh(), wake = refresh_due().
- _refresh_one() calls _resolve_hostname_multi(host, dns_queries) and
uses ipset_def.stale_ttl for seen-set per-entry timeouts.
- All dict(old_cfg.ipsets) round-trips in socket handlers replaced with
{n: idef.to_dict() ...} to serialize IpsetDef back to JSON-ready form.
Example config for a CDN hostname:
"vscode-cdn": {
"hostnames": ["vscode.download.prss.microsoft.com"],
"dns_queries": 10,
"stale_ttl": 3600,
"refresh_interval": 10
}
https://claude.ai/code/session_016QwTdAvrMgYdfJuycgobHc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds comprehensive input validation to the firewall daemon and introduces per-ipset configuration tuning parameters (
dns_queries,stale_ttl,refresh_interval). It also implements per-ipset refresh scheduling and adds authorization checks to the management socket.Key Changes
Input Validation Framework
_val_identifier,_val_ip,_val_cidr,_val_mac,_val_proto,_val_port,_val_comment,_val_icmp_type,_val_host_entry) that validate all configuration inputs before any kernel mutationsValueErrorwith descriptive messages on invalid inputEgressRule,NatRule, andNetworkSpecconstructors to catch configuration errors earlyPer-Ipset Tuning Parameters
IpsetDefclass to encapsulate ipset configuration: hostnames plus optional tuning fieldsIPSET_DNS_QUERIESglobal constant (default: 1) to control DNS query repetition per hostname per refresh cyclehostnames+ optionaldns_queries,stale_ttl,refresh_intervalfields)IpsetDef.to_dict()intelligently serializes to compact form when all tuning fields match global defaults, keeping config files readablePer-Ipset Refresh Scheduling
refresh_all()withrefresh_due()that only refreshes ipsets whoserefresh_intervalhas elapsedtime_until_next_refresh()to calculate the precise sleep duration until the next ipset is due, enabling the refresh loop to wake exactly when needed rather than polling on a fixed tick_refresh_one()to call_resolve_hostname_multi()with per-ipsetdns_queriescount, allowing CDN ipsets (short interval, many queries) and stable ipsets (long interval, 1 query) to coexist_last_refreshtracking per ipset to implement independent refresh schedulesManagement Socket Authorization
SO_PEERCREDpeer credential reading to extract connecting process PID/UID/GID_MUTATING_ACTIONSfrozenset for actions that alter kernel state or persisted configstatus,refresh) are open to any peer in the socket's groupDNS Resolution Enhancement
_resolve_hostname_multi()function that queries DNSntimes for a hostname, returning all unique IPv4 addresses discovered across queriesGit Configuration Update
create_git_config()inlaunch.shto usegit config --replace-allinstead of overwriting the entire.gitconfigfile, preserving existing configuration while updating user name and emailNotable Implementation Details
IpsetDefserialization strategy maintains backward compatibility: existing configs with plain hostname lists continue to work, and only configs with non-default tuning parameters use the extended dict formtime.monotonic()) for scheduling to avoid issues with system clock adjustmentshttps://claude.ai/code/session_016QwTdAvrMgYdfJuycgobHc