feat: enhance networking capabilities with improved egress handling and automatic host sharing rules
This commit is contained in:
+38
-18
@@ -373,8 +373,10 @@ not needed. It never recopies the rootfs, reprovisions credentials, or
|
||||
regenerates guest SSH host keys. Name/IP/MAC, ports, and guest disk changes
|
||||
survive stop/start; guest RAM does not.
|
||||
|
||||
Start on a healthy running VM synchronizes policy without spawning another
|
||||
VMM. An ambiguous process or interrupted live boot/stop is not adopted as a
|
||||
Start on a healthy running VM validates its retained network, synchronizes
|
||||
policy, then restores shared bridge/NAT/forwarding rules without spawning another
|
||||
VMM. A shared-network setup failure retains the running VM for retry. An ambiguous
|
||||
process or interrupted live boot/stop is not adopted as a
|
||||
successful start. Failed resume retains the private disk for retry. Restart
|
||||
performs stop and start under one operation lock, not two independent public
|
||||
calls with a race between them.
|
||||
@@ -605,7 +607,7 @@ Linux bridge: uvm0 (10.42.0.1/24 by default)
|
||||
|
|
||||
iptables forwarding + MASQUERADE
|
||||
|
|
||||
host default uplink
|
||||
host IPv4 route for the destination (current uplink)
|
||||
|
|
||||
internet
|
||||
```
|
||||
@@ -620,7 +622,7 @@ internet
|
||||
- Bridge creation or validation that an existing interface is actually a
|
||||
Linux bridge.
|
||||
- Gateway address setup and IPv4 forwarding.
|
||||
- One egress NAT rule and forward/return rules for the default uplink.
|
||||
- Egress NAT and forward/return rules scoped to the guest subnet/bridge.
|
||||
- TAP ownership aliases (`uvm:<id>`), preparation while down, activation,
|
||||
deactivation, cleanup, and error reporting.
|
||||
|
||||
@@ -629,6 +631,23 @@ it may belong to another VM. A create-time name collision is an error. Cleanup
|
||||
checks the TAP kind and ownership alias, with a narrow unaliased-TAP allowance
|
||||
for legacy records; it does not treat an arbitrary interface name as ownership.
|
||||
|
||||
Internet sharing is configured even with no host default route. Rules never
|
||||
pin an uplink interface: Linux routing selects it, and MASQUERADE uses that
|
||||
interface's address. Offline-to-online transitions, reconnects and route changes
|
||||
therefore work without another UVM command or a monitoring daemon. Existing
|
||||
connections may need to reconnect after the upstream address changes. Guest
|
||||
DNS in the Ubuntu template uses the public resolvers documented in README.
|
||||
|
||||
`uvm-egress`-commented iptables rules are checked before insertion, with a bounded
|
||||
xtables-lock wait. Scoped exceptions are inserted at the start of the host chains
|
||||
so pre-existing terminal drops cannot shadow them. Outbound forwarding requires
|
||||
the UVM bridge and source subnet; routed replies require the destination bridge,
|
||||
subnet and established/related conntrack state. Native bridge policy still checks
|
||||
identity, service ports and permitted protocols. Outbound forwarding also covers
|
||||
peer traffic if the host already uses `br_netfilter`, while MASQUERADE excludes
|
||||
the UVM bridge to retain private peer source addresses. Global chain policies
|
||||
and unrelated rules remain administrator-owned.
|
||||
|
||||
### Native Bridge Policy
|
||||
|
||||
The supported path is a **software Linux bridge** with STP disabled. Each
|
||||
@@ -685,16 +704,16 @@ including on conntrack-tools 1.4.8, where `--list` is not a supported option.
|
||||
|
||||
### Coexistence and Recovery
|
||||
|
||||
Existing `iptables` egress MASQUERADE/forwarding remains unchanged. The new
|
||||
policy adds no DNAT, public listener, or host-port mapping and does not replace
|
||||
the host firewall manager. Public connectivity, DNS, guest reverse proxies/TLS,
|
||||
Shared `iptables` egress MASQUERADE/forwarding is separate from private bridge
|
||||
policy. The policy adds no DNAT, public listener, or host-port mapping and does not replace
|
||||
the host firewall manager. Public inbound connectivity, DNS publication, guest reverse proxies/TLS,
|
||||
and integration with UFW/firewalld/Docker/libvirt remain out of scope. An
|
||||
administrator's external routing/NAT can still affect reachability; do not
|
||||
infer source-CIDR restrictions or complete public-exposure protection from the
|
||||
use of private addresses. Operators must choose a non-conflicting topology.
|
||||
|
||||
If an external actor loses or changes UVM rules, recovery is explicit
|
||||
`ports sync`, not a promised daemon repair. An `enforced` snapshot cannot
|
||||
If an external actor loses or changes private policy, recovery is explicit
|
||||
`ports sync`; `start` also restores shared networking for a running VM. An `enforced` snapshot cannot
|
||||
prevent later root-level changes or prove that other rules allow traffic.
|
||||
[FIREWALL.md](FIREWALL.md) retains the original proposal/backend evaluation;
|
||||
do not import its unimplemented topology checks into current documentation.
|
||||
@@ -950,17 +969,18 @@ The opt-in packet harness must run **only in disposable isolated user/network
|
||||
namespaces**. It verifies namespace separation before creating links or
|
||||
changing rules, and never falls back to the parent host namespace. It may
|
||||
require privileges (or enabled unprivileged user namespaces) plus `unshare`,
|
||||
`ip`, `bridge`, `nft`, `conntrack`, and `sysctl`:
|
||||
`ip`, `bridge`, `nft`, `iptables`, `conntrack`, and `sysctl`:
|
||||
|
||||
```sh
|
||||
UVM_FIREWALL_INTEGRATION=1 python3 -B -m unittest discover -s tests/integration -v
|
||||
```
|
||||
|
||||
The harness uses bridge-connected veths in place of guest TAPs and routed
|
||||
egress without NAT. It exercises host/peer service traffic, both-direction
|
||||
close of existing streams while preserving conntrack/egress, IPv6/spoof
|
||||
blocking, quarantine, and offline cleanup. It does not boot a microVM or
|
||||
validate real TAP/NAT deployment.
|
||||
The harness uses bridge-connected veths in place of guest TAPs and two simulated
|
||||
uplinks. It exercises NAT with a pre-existing terminal FORWARD drop, offline
|
||||
startup, uplink changes and reconnects for host/guest TCP and guest UDP/53.
|
||||
It also checks host/peer service traffic, both-direction close of existing
|
||||
streams while preserving conntrack/egress, IPv6/spoof blocking, quarantine,
|
||||
and offline cleanup. It does not boot a microVM or validate a real TAP deployment.
|
||||
|
||||
The packet test skipped in this workspace because namespace creation was
|
||||
denied (`Operation not permitted`). Document that permission limitation, not
|
||||
@@ -1011,7 +1031,7 @@ on an isolated Linux host:
|
||||
| Firecracker exits early | VM `firecracker.log`, VM config, `/dev/kvm` access |
|
||||
| VM is `dead` in `list` | PID/start token in state, `/proc/<pid>`, VM log |
|
||||
| Cannot stop legacy VM | Missing start/boot identity or failed protected binary/socket match; never guess a PID |
|
||||
| Guest has no egress | `ip route show default`, bridge address, TAP state, iptables rules |
|
||||
| Guest has no egress | Host connectivity/routes, bridge/TAP state, `uvm-egress` iptables rules; `start` refreshes networking on a running VM |
|
||||
| Policy missing/drift/unknown | Actual nft JSON and ownership, STP/group mask, permissions; explicit sync after fixing cause |
|
||||
| Retained-disk start fails | `disk_ready`, safe private path, kernel/VMM integrity, process identity, retained network, pending operation |
|
||||
| API server refuses to start | `UVM_API_TOKEN`, requested host, TLS cert/key files |
|
||||
@@ -1035,9 +1055,9 @@ The code is intentionally honest about current limits:
|
||||
- Guest health is inferred from VMM process state, not application readiness.
|
||||
- No quotas, DHCP, host-port mapping, UDP/IPv6 services, or network tenancy.
|
||||
- No guest snapshots, extra disks, production image builder, or SSH-key injection.
|
||||
- Per-VM private TCP ingress policy exists, but public connectivity, DNS,
|
||||
- Per-VM private TCP ingress policy exists, but public inbound connectivity, DNS publication,
|
||||
guest reverse proxy/TLS, and external firewall integration remain out of scope.
|
||||
- Existing egress `iptables` rules are incremental and unchanged; only the
|
||||
- Shared egress `iptables` rules are incremental and idempotent; only the
|
||||
private bridge policy is atomically rendered per VM.
|
||||
- No autostart, background reconciliation, or guest-coordinated shutdown.
|
||||
- The JSON inventory is suitable for one host, not distributed coordination.
|
||||
|
||||
Reference in New Issue
Block a user