Join -r/--run containers to networks: veth creation, IPs, routes
Commit 4/6 of the network isolation feature (docs/networking-design.md).
network_join.{h,cpp}: join_networks() waits (bounded, polling) for the
session's own isolated net namespace to exist -- bwrap's outer pid
never enters it, and the on_bwrap_pid_known callback fires before
bwrap has even started its own setup -- then per network: ensures it's
provisioned, creates a veth pair where the bridge lives, attaches the
bridge side, moves the container side into the session's namespace as
eth<N>, assigns it a free address, brings it up, and (extern only)
replaces the default route.
sandbox_process.{h,cpp}: generalized pid_namespace_isolated() into
namespace_isolated(outer_pid, ns_pid, ns_type) so this can reuse it for
"net" instead of "pid".
network_subnet.{h,cpp}: gateway-address logic generalized into
host_address(af, cidr, n) shared by the existing gateway functions
(n=1) and new ipv4/ipv6_host_address() (n=2, 3, ... for containers).
network_bridge.{h,cpp}: bridge_name()/wrap_for_network() exported so
network_join.cpp can attach to the exact bridge/namespace
network_bridge.cpp provisioned.
commands.cpp: run_container() validates network namespace isolation is
actually available before ever starting bwrap (can't be degraded the
way --hostname is), then joins networks from on_bwrap_pid_known,
before the -D/--daemonize report is sent.
Real bug caught by testing, fixed before landing: address allocation
first tried to detect in-use IPs via `ip addr show master <bridge>`,
but a container's address lives on its own interface inside its own
private namespace, invisible from the bridge's namespace -- two
concurrent containers on the same network both got 10.168.0.2. Fixed
with a flock-based per-address lease file (same technique pid_file.h's
SessionLock already uses), verified with two containers running
simultaneously getting distinct addresses.
Known, documented limitation: a very short-lived sandboxed command can
exit before the namespace-wait polling catches up (bwrap execs
straight into the target with no hook point in between namespace
creation and exec); real long-running networked services are
unaffected.
Verified end-to-end as root (via a scoped doas rule): two containers
on the same intern network got distinct addresses and could ping each
other; an intern-joined container could not reach the outside; an
extern-joined container reached the real internet through NAT; a
container joining both simultaneously got two working interfaces.
This commit is contained in:
+2
-1
@@ -22,7 +22,8 @@ slocker_lite = executable('slocker-lite',
|
||||
'src/bwrap.cpp', 'src/user_spec.cpp', 'src/config_file.cpp', 'src/volume_mount.cpp',
|
||||
'src/pid_file.cpp', 'src/exec_session.cpp', 'src/env_spec.cpp', 'src/daemonize.cpp',
|
||||
'src/sandbox_process.cpp', 'src/session_cgroup.cpp', 'src/kill_session.cpp',
|
||||
'src/network_subnet.cpp', 'src/persistent_netns.cpp', 'src/network_bridge.cpp'],
|
||||
'src/network_subnet.cpp', 'src/persistent_netns.cpp', 'src/network_bridge.cpp',
|
||||
'src/network_join.cpp'],
|
||||
include_directories : include_directories('.'),
|
||||
dependencies : [fmt_dep, catch2_dep, yaml_dep, archive_dep, json_dep, spdlog_dep],
|
||||
install : true)
|
||||
|
||||
Reference in New Issue
Block a user