Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,16 @@
"containerEnv": {
"DEVCONTAINER": "1"
},
"runArgs": [
"--cap-drop=ALL",
"--cap-add=CHOWN",
"--cap-add=DAC_OVERRIDE",
"--cap-add=FOWNER",
"--cap-add=SETUID",
"--cap-add=SETGID",
"--cap-add=KILL",
"--cap-add=SYS_CHROOT",
"--pids-limit=4096"
],
"postCreateCommand": ["bash", "${containerWorkspaceFolder}/scripts/devcontainer-postcreate.sh"]
}
9 changes: 9 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,15 @@ does not contain that server. The upstream Feature enables root login in its
SSHD configuration, but Squarebox publishes no SSH host port or password, and
restricts remote-forwarded listeners to loopback.

The Dev Container applies the same `runArgs` hardening as the installers and
Compose: `--cap-drop=ALL`, re-adding only `CHOWN`, `DAC_OVERRIDE`, `FOWNER`,
`SETUID`, `SETGID`, and `KILL`, plus `--pids-limit=4096`. It adds exactly one
extra capability, `SYS_CHROOT`, because the SSH server Feature's OpenSSH uses
privilege separation: the pre-authentication child `chroot`s into `/run/sshd`,
and without `SYS_CHROOT` every connection is reset during key exchange. The
Feature listens on port 2222, so `NET_BIND_SERVICE` is not needed, and logins
were verified to succeed without `AUDIT_WRITE`.

Linux capabilities are reduced, and the Box is bounded to 4096 PIDs so a
runaway process cannot exhaust the host's process table. The Box has network
access and the host resources explicitly mounted by its Install identity.
Expand Down
30 changes: 30 additions & 0 deletions tests/test-repository-consistency.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,36 @@ test "$(jq '[.mounts[]? | select(
)] | length' .devcontainer/devcontainer.json)" = 1 \
|| fail "Dev Container Managed home is not a rebuild-stable, per-Box volume"

# The Dev Container must keep the installers' capability reduction and PID
# bound. Its only documented extra is SYS_CHROOT, which the SSH server Feature
# needs for OpenSSH privilege separation (see SECURITY.md).
DEVCONTAINER_SSHD_EXTRA_CAPS=SYS_CHROOT
installer_caps=$(grep -oE -- '--cap-add=[A-Z_]+' install.sh | sed 's/^--cap-add=//' | sort -u)
test -n "$installer_caps" || fail "install.sh capability set could not be read"
ps_caps=$(grep -oE -- "--cap-add=[A-Z_]+" install.ps1 | sed 's/^--cap-add=//' | sort -u)
test "$ps_caps" = "$installer_caps" \
|| fail "install.ps1 and install.sh capability sets differ"
grep -Fq -- '--cap-drop=ALL' install.sh || fail "install.sh no longer drops all capabilities"
test "$(jq -r '[.runArgs[]? | select(. == "--cap-drop=ALL")] | length' \
.devcontainer/devcontainer.json)" = 1 \
|| fail "Dev Container does not drop all capabilities"
test "$(jq -r '[.runArgs[]? | select(. == "--pids-limit=4096")] | length' \
.devcontainer/devcontainer.json)" = 1 \
|| fail "Dev Container is not bounded to 4096 PIDs"
test "$(jq -r '[.runArgs[]? | select(test("^--(privileged|cap-add=ALL|security-opt|pids-limit=(-1|0)$)"))] | length' \
.devcontainer/devcontainer.json)" = 0 \
|| fail "Dev Container runArgs weaken the hardened Box"
test "$(jq -r '[.capAdd[]?, .privileged // empty, .securityOpt[]?] | length' \
.devcontainer/devcontainer.json)" = 0 \
|| fail "Dev Container must not widen authority through capAdd/privileged/securityOpt"
devcontainer_caps=$(jq -r '.runArgs[]? | select(startswith("--cap-add=")) | ltrimstr("--cap-add=")' \
.devcontainer/devcontainer.json | sort -u)
expected_devcontainer_caps=$(printf '%s\n' $installer_caps $DEVCONTAINER_SSHD_EXTRA_CAPS | sort -u)
test "$devcontainer_caps" = "$expected_devcontainer_caps" \
|| fail "Dev Container capability set must equal the installers' set plus SYS_CHROOT"
grep -Fq 'SYS_CHROOT' SECURITY.md \
|| fail "SECURITY.md does not justify the Dev Container SYS_CHROOT capability"

if grep -E '(USER_HOME|\$HOME|USERPROFILE).*[.]config/git' \
install.sh install.ps1 docker-compose.yml >/dev/null; then
fail "host real Git config is still referenced"
Expand Down
Loading