mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-12 23:29:16 +03:00
fix(docker): prevent privilege regain after bootstrap
Co-authored-by: yu-xin-c <175149126+yu-xin-c@users.noreply.github.com>
This commit is contained in:
@@ -189,10 +189,47 @@ jobs:
|
|||||||
- name: Build image with default channel dependencies
|
- name: Build image with default channel dependencies
|
||||||
run: docker build -t nanobot:test .
|
run: docker build -t nanobot:test .
|
||||||
|
|
||||||
- name: Verify Docker Compose startup
|
- name: Verify Docker Compose startup and privilege boundary
|
||||||
env:
|
env:
|
||||||
HOME: ${{ runner.temp }}
|
HOME: ${{ runner.temp }}
|
||||||
run: docker compose run --rm --no-deps --build -T nanobot-cli status
|
run: |
|
||||||
|
docker compose run --rm --no-deps --build -T nanobot-cli status
|
||||||
|
docker compose run --rm --no-deps -T --entrypoint sh nanobot-cli -s <<'OUTER'
|
||||||
|
set -eu
|
||||||
|
field() {
|
||||||
|
awk -v key="$1:" '$1 == key { print $2 }' /proc/self/status
|
||||||
|
}
|
||||||
|
test "$(id -u)" = "0"
|
||||||
|
test "$(field NoNewPrivs)" = "1"
|
||||||
|
setpriv --reuid=nanobot --regid=nanobot --init-groups sh -s <<'INNER'
|
||||||
|
set -eu
|
||||||
|
field() {
|
||||||
|
awk -v key="$1:" '$1 == key { print $2 }' /proc/self/status
|
||||||
|
}
|
||||||
|
test "$(id -u)" = "1000"
|
||||||
|
test "$(field NoNewPrivs)" = "1"
|
||||||
|
for capability_set in CapInh CapPrm CapEff CapAmb; do
|
||||||
|
test "$(field "$capability_set")" = "0000000000000000"
|
||||||
|
done
|
||||||
|
INNER
|
||||||
|
OUTER
|
||||||
|
docker compose -f docker-compose.yml -f docker-compose.bwrap.yml \
|
||||||
|
run --rm --no-deps -T --entrypoint sh nanobot-cli -s <<'BWRAP'
|
||||||
|
set -eu
|
||||||
|
mkdir -p /home/nanobot/.nanobot/workspace
|
||||||
|
chown -R nanobot:nanobot /home/nanobot/.nanobot
|
||||||
|
setpriv --reuid=nanobot --regid=nanobot --init-groups \
|
||||||
|
bwrap --new-session --die-with-parent \
|
||||||
|
--ro-bind /usr /usr \
|
||||||
|
--ro-bind-try /bin /bin \
|
||||||
|
--ro-bind-try /lib /lib \
|
||||||
|
--ro-bind-try /lib64 /lib64 \
|
||||||
|
--proc /proc --dev /dev --tmpfs /tmp \
|
||||||
|
--bind /home/nanobot/.nanobot/workspace /home/nanobot/.nanobot/workspace \
|
||||||
|
--chdir /home/nanobot/.nanobot/workspace \
|
||||||
|
-- sh -c 'test "$(id -u)" = 1000; touch sandbox-ok'
|
||||||
|
test -f /home/nanobot/.nanobot/workspace/sandbox-ok
|
||||||
|
BWRAP
|
||||||
|
|
||||||
- name: Verify default WhatsApp dependencies
|
- name: Verify default WhatsApp dependencies
|
||||||
run: docker run --rm --entrypoint python nanobot:test -c "import neonize, segno"
|
run: docker run --rm --entrypoint python nanobot:test -c "import neonize, segno"
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ x-common-config: &common-config
|
|||||||
- CHOWN
|
- CHOWN
|
||||||
- SETGID
|
- SETGID
|
||||||
- SETUID
|
- SETUID
|
||||||
|
# Prevent the non-root process from regaining capabilities through setuid
|
||||||
|
# binaries or file capabilities left inside the container image.
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
nanobot-gateway:
|
nanobot-gateway:
|
||||||
|
|||||||
+13
-6
@@ -160,8 +160,11 @@ docker compose logs -f nanobot-gateway # view logs
|
|||||||
docker compose down # stop
|
docker compose down # stop
|
||||||
```
|
```
|
||||||
|
|
||||||
The default Compose file drops all Linux capabilities and keeps Docker's default
|
The default Compose file drops all Linux capabilities except `CHOWN`, `SETUID`, and
|
||||||
AppArmor/seccomp profiles enabled. If you explicitly set
|
`SETGID`, which the root entrypoint needs to fix bind-mount ownership and become UID
|
||||||
|
1000. It also enables `no-new-privileges`, so the non-root process cannot regain those
|
||||||
|
bootstrap capabilities through setuid binaries or file capabilities. Docker's default
|
||||||
|
AppArmor/seccomp profiles remain enabled. If you explicitly set
|
||||||
`"tools.exec.sandbox": "bwrap"` in `~/.nanobot/config.json`, add the bwrap
|
`"tools.exec.sandbox": "bwrap"` in `~/.nanobot/config.json`, add the bwrap
|
||||||
override file when starting containers:
|
override file when starting containers:
|
||||||
|
|
||||||
@@ -170,9 +173,9 @@ docker compose -f docker-compose.yml -f docker-compose.bwrap.yml up -d nanobot-g
|
|||||||
docker compose -f docker-compose.yml -f docker-compose.bwrap.yml run --rm nanobot-cli agent -m "Hello!"
|
docker compose -f docker-compose.yml -f docker-compose.bwrap.yml run --rm nanobot-cli agent -m "Hello!"
|
||||||
```
|
```
|
||||||
|
|
||||||
The override grants `CAP_SYS_ADMIN` and disables AppArmor/seccomp confinement for
|
The override adds `CAP_SYS_ADMIN` and disables AppArmor/seccomp confinement for the
|
||||||
the container so bubblewrap can create its nested namespaces. Use it only when the
|
container so bubblewrap can create its nested namespaces. It preserves
|
||||||
bwrap sandbox is enabled.
|
`no-new-privileges`. Use it only when the bwrap sandbox is enabled.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
@@ -197,6 +200,8 @@ vim ~/.nanobot/config.json
|
|||||||
# health endpoint on 18790.
|
# health endpoint on 18790.
|
||||||
docker run \
|
docker run \
|
||||||
--cap-drop ALL \
|
--cap-drop ALL \
|
||||||
|
--cap-add CHOWN --cap-add SETGID --cap-add SETUID \
|
||||||
|
--security-opt no-new-privileges:true \
|
||||||
-v ~/.nanobot:/home/nanobot/.nanobot \
|
-v ~/.nanobot:/home/nanobot/.nanobot \
|
||||||
-p 18790:18790 -p 8765:8765 \
|
-p 18790:18790 -p 8765:8765 \
|
||||||
nanobot gateway
|
nanobot gateway
|
||||||
@@ -205,7 +210,9 @@ docker run \
|
|||||||
# bubblewrap needs for nested namespaces. Without them, `bwrap` may exit with
|
# bubblewrap needs for nested namespaces. Without them, `bwrap` may exit with
|
||||||
# `clone3: Operation not permitted`.
|
# `clone3: Operation not permitted`.
|
||||||
docker run \
|
docker run \
|
||||||
--cap-drop ALL --cap-add SYS_ADMIN \
|
--cap-drop ALL \
|
||||||
|
--cap-add CHOWN --cap-add SETGID --cap-add SETUID --cap-add SYS_ADMIN \
|
||||||
|
--security-opt no-new-privileges:true \
|
||||||
--security-opt apparmor=unconfined \
|
--security-opt apparmor=unconfined \
|
||||||
--security-opt seccomp=unconfined \
|
--security-opt seccomp=unconfined \
|
||||||
-v ~/.nanobot:/home/nanobot/.nanobot \
|
-v ~/.nanobot:/home/nanobot/.nanobot \
|
||||||
|
|||||||
Reference in New Issue
Block a user