Fixes for coderabbit.

This commit is contained in:
Adam Outler
2026-01-09 01:34:31 +00:00
parent 739f17474f
commit 51e31d8854
3 changed files with 39 additions and 29 deletions

View File

@@ -26,8 +26,11 @@ The container is designed to inspect the runtime environment at startup (`/root-
### Warning Log ### Warning Log
When AUFS is detected without root privileges, the system emits the following warning during startup: When AUFS is detected without root privileges, the system emits the following warning during startup:
> ⚠️ **WARNING:** Legacy AUFS storage driver detected. AUFS strips file capabilities (setcap). Layer-2 scanners will fail. > ⚠️ WARNING: Reduced functionality (AUFS + non-root user).
> **Action:** Set PUID=0 in your config or migrate off AUFS. >
> AUFS strips Linux file capabilities, so tools like arp-scan, nmap, and nbtscan fail when NetAlertX runs as a non-root PUID.
>
> **Action:** Set PUID=0 on AUFS hosts for full functionality.
## Security Ramifications ## Security Ramifications
@@ -144,12 +147,15 @@ docker exec netalertx getcap /usr/sbin/arp-scan
``` ```
**3. Simulating AUFS (Dev/Test)** **3. Simulating AUFS (Dev/Test)**
Developers can force the AUFS logic path on a modern machine by mocking the mounts file: Developers can force the AUFS logic path on a modern machine by mocking the mounts file. Note: Docker often restricts direct bind-mounts of host `/proc` paths, so the test suite uses an environment-variable injection instead (see `test_puid_pgid.py`).
```bash ```bash
echo "none / aufs rw,relatime 0 0" > /tmp/mock_mounts # Create mock mounts content and encode it as base64
docker run --rm -v /tmp/mock_mounts:/proc/mounts:ro netalertx/netalertx echo "none / aufs rw,relatime 0 0" | base64
# Run the container passing the encoded mounts via NETALERTX_PROC_MOUNTS_B64
# (the entrypoint decodes this and uses it instead of reading /proc/mounts directly)
docker run --rm -e NETALERTX_PROC_MOUNTS_B64="bm9uZSAvIGF1ZnMgcncs..." netalertx/netalertx
``` ```
## Additional Resources ## Additional Resources

View File

@@ -665,7 +665,7 @@ def _run_container(
stdout=subprocess.PIPE, # MUST capture stdout for test assertions and debugging stdout=subprocess.PIPE, # MUST capture stdout for test assertions and debugging
stderr=subprocess.PIPE, # MUST capture stderr for test assertions and debugging stderr=subprocess.PIPE, # MUST capture stderr for test assertions and debugging
text=True, text=True,
timeout=max(SUBPROCESS_TIMEOUT_SECONDS, sleep_seconds), # Coderabbit - please stop trying to increase the length of timeout. timeout=max(SUBPROCESS_TIMEOUT_SECONDS, sleep_seconds), # Coderabbit - please stop trying to increase the length of timeout.
check=False, check=False,
) )

View File

@@ -248,20 +248,22 @@ def test_aufs_explicit_root_no_warning() -> None:
mock_file_path = f"/tmp/mock_mounts_{uuid.uuid4().hex[:8]}" mock_file_path = f"/tmp/mock_mounts_{uuid.uuid4().hex[:8]}"
with open(mock_file_path, "w") as f: with open(mock_file_path, "w") as f:
f.write(mock_mounts_content) f.write(mock_mounts_content)
# Run with explicit PUID=0 - should not warn about non-root try:
result = _run_root_entrypoint( # Run with explicit PUID=0 - should not warn about non-root
env={"PUID": "0", "PGID": "0", "SKIP_TESTS": "1"}, result = _run_root_entrypoint(
volumes=[f"{volume}:/data", f"{mock_file_path}:/proc/mounts:ro"], env={"PUID": "0", "PGID": "0", "SKIP_TESTS": "1"},
) volumes=[f"{volume}:/data", f"{mock_file_path}:/proc/mounts:ro"],
)
combined = (result.stdout or "") + (result.stderr or "") combined = (result.stdout or "") + (result.stderr or "")
assert result.returncode == 0, f"Container should start: {combined}" assert result.returncode == 0, f"Container should start: {combined}"
assert "Running as root (PUID=0)" in combined, f"Should confirm running as root: {combined}" assert "Running as root (PUID=0)" in combined, f"Should confirm running as root: {combined}"
# Should NOT have the AUFS reduced functionality warning when running as root # Should NOT have the AUFS reduced functionality warning when running as root
assert "Reduced functionality (AUFS + non-root user)" not in combined, f"Should not warn when explicitly using root: {combined}" assert "Reduced functionality (AUFS + non-root user)" not in combined, f"Should not warn when explicitly using root: {combined}"
finally:
# Clean up mock file # Clean up mock file
os.unlink(mock_file_path) if os.path.exists(mock_file_path):
os.unlink(mock_file_path)
finally: finally:
subprocess.run(["docker", "volume", "rm", "-f", volume], check=False, capture_output=True, text=True, timeout=15) subprocess.run(["docker", "volume", "rm", "-f", volume], check=False, capture_output=True, text=True, timeout=15)
@@ -281,17 +283,19 @@ def test_aufs_non_root_warns() -> None:
with open(mock_file_path, "w") as f: with open(mock_file_path, "w") as f:
f.write(mock_mounts_content) f.write(mock_mounts_content)
result = _run_root_entrypoint( try:
env={"PUID": "20211", "PGID": "20211"}, result = _run_root_entrypoint(
volumes=[f"{volume}:/data", f"{mock_file_path}:/proc/mounts:ro"], env={"PUID": "20211", "PGID": "20211"},
) volumes=[f"{volume}:/data", f"{mock_file_path}:/proc/mounts:ro"],
)
combined = (result.stdout or "") + (result.stderr or "") combined = (result.stdout or "") + (result.stderr or "")
assert result.returncode == 0, f"Container should continue with warnings: {combined}" assert result.returncode == 0, f"Container should continue with warnings: {combined}"
assert "Reduced functionality (AUFS + non-root user)" in combined, f"AUFS warning missing: {combined}" assert "Reduced functionality (AUFS + non-root user)" in combined, f"AUFS warning missing: {combined}"
assert "aufs-capabilities" in combined, "Warning should link to troubleshooting guide" assert "aufs-capabilities" in combined, "Warning should link to troubleshooting guide"
finally:
os.unlink(mock_file_path) if os.path.exists(mock_file_path):
os.unlink(mock_file_path)
finally: finally:
subprocess.run(["docker", "volume", "rm", "-f", volume], check=False, capture_output=True, text=True, timeout=15) subprocess.run(["docker", "volume", "rm", "-f", volume], check=False, capture_output=True, text=True, timeout=15)