Retain Caddy file capability at ingress boundary
This commit is contained in:
@@ -185,6 +185,11 @@ The dispatch-only `Runtime Ingress Drill` workflow exposes the same bounded
|
|||||||
check independently so ingress changes can be diagnosed before an immutable
|
check independently so ingress changes can be diagnosed before an immutable
|
||||||
runtime publication; it accepts only digest-pinned Caddy, HAProxy, and API
|
runtime publication; it accepts only digest-pinned Caddy, HAProxy, and API
|
||||||
images and has no push trigger.
|
images and has no push trigger.
|
||||||
|
The official Caddy binary carries the `NET_BIND_SERVICE` file capability. The
|
||||||
|
managed-ingress container therefore drops every capability and adds back only
|
||||||
|
`NET_BIND_SERVICE`; otherwise Linux rejects the binary at `execve` before its
|
||||||
|
high-port configuration can start. `no-new-privileges`, a read-only root
|
||||||
|
filesystem, and non-privileged container ports remain enforced.
|
||||||
The bounded setup helper writes only generated public configuration as root so
|
The bounded setup helper writes only generated public configuration as root so
|
||||||
it can initialize a new volume; the actual HAProxy process retains the image's
|
it can initialize a new volume; the actual HAProxy process retains the image's
|
||||||
non-root identity and runs read-only with all capabilities dropped.
|
non-root identity and runs read-only with all capabilities dropped.
|
||||||
|
|||||||
@@ -551,6 +551,9 @@ class DeploymentInstallerTests(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
self.assertIn("caddy-data:/data", ingress["volumes"])
|
self.assertIn("caddy-data:/data", ingress["volumes"])
|
||||||
self.assertIn("caddy-config:/config", ingress["volumes"])
|
self.assertIn("caddy-config:/config", ingress["volumes"])
|
||||||
|
self.assertEqual(["ALL"], ingress["cap_drop"])
|
||||||
|
self.assertEqual(["NET_BIND_SERVICE"], ingress["cap_add"])
|
||||||
|
self.assertEqual(["no-new-privileges:true"], ingress["security_opt"])
|
||||||
self.assertIn("reverse_proxy load-balancer:8080", render_caddy_config(spec))
|
self.assertIn("reverse_proxy load-balancer:8080", render_caddy_config(spec))
|
||||||
self.assertNotIn("operator@example.test", json.dumps(compose))
|
self.assertNotIn("operator@example.test", json.dumps(compose))
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ class ManagedIngressDrillTests(unittest.TestCase):
|
|||||||
self.assertNotIn('"127.0.0.1::8080"', source)
|
self.assertNotIn('"127.0.0.1::8080"', source)
|
||||||
self.assertIn("requested_http_port", source)
|
self.assertIn("requested_http_port", source)
|
||||||
self.assertIn("requested_https_port", source)
|
self.assertIn("requested_https_port", source)
|
||||||
|
self.assertIn('"--cap-add",\n "NET_BIND_SERVICE"', source)
|
||||||
|
|
||||||
def test_published_port_reads_the_docker_mapping(self) -> None:
|
def test_published_port_reads_the_docker_mapping(self) -> None:
|
||||||
completed = subprocess.CompletedProcess(
|
completed = subprocess.CompletedProcess(
|
||||||
|
|||||||
@@ -388,6 +388,8 @@ def main() -> int:
|
|||||||
"no-new-privileges",
|
"no-new-privileges",
|
||||||
"--cap-drop",
|
"--cap-drop",
|
||||||
"ALL",
|
"ALL",
|
||||||
|
"--cap-add",
|
||||||
|
"NET_BIND_SERVICE",
|
||||||
"--publish",
|
"--publish",
|
||||||
f"127.0.0.1:{requested_http_port}:8080/tcp",
|
f"127.0.0.1:{requested_http_port}:8080/tcp",
|
||||||
"--publish",
|
"--publish",
|
||||||
|
|||||||
@@ -627,6 +627,7 @@ def render_compose(spec: InstallationSpec) -> dict[str, object]:
|
|||||||
"tmpfs": ["/tmp:rw,noexec,nosuid,size=64m"],
|
"tmpfs": ["/tmp:rw,noexec,nosuid,size=64m"],
|
||||||
"security_opt": ["no-new-privileges:true"],
|
"security_opt": ["no-new-privileges:true"],
|
||||||
"cap_drop": ["ALL"],
|
"cap_drop": ["ALL"],
|
||||||
|
"cap_add": ["NET_BIND_SERVICE"],
|
||||||
"volumes": [
|
"volumes": [
|
||||||
f"./{CADDY_CONFIG_FILENAME}:/etc/caddy/Caddyfile:ro",
|
f"./{CADDY_CONFIG_FILENAME}:/etc/caddy/Caddyfile:ro",
|
||||||
"caddy-data:/data",
|
"caddy-data:/data",
|
||||||
|
|||||||
Reference in New Issue
Block a user