feat: refuse to start as root
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 2m5s
Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 2m5s
The image runs as its own unprivileged user, and everything in run.sh now assumes it: keys.dat is worked on by its owner, no privilege is dropped anywhere, and what confines the container is whatever the caller passed. Started as root by a `user:` override, none of that holds and the container looks identical from outside -- a silent loss of every property this image was changed to have. Four lines at the top of run.sh, and the reason is then the first line of `docker logs`. It is the same bargain as the build-time checks: a wrong posture should fail loudly rather than pass for a right one.
This commit is contained in:
@@ -167,7 +167,8 @@ Container images are configured using parameters passed at runtime.
|
|||||||
it creates in its own home. Nothing is dropped at run time because nothing
|
it creates in its own home. Nothing is dropped at run time because nothing
|
||||||
privileged is held in the first place. No file in the image carries a setuid
|
privileged is held in the first place. No file in the image carries a setuid
|
||||||
or setgid bit either, so a daemon that has been taken over has nothing left to
|
or setgid bit either, so a daemon that has been taken over has nothing left to
|
||||||
climb.
|
climb. A caller that puts the user back to root gets a refusal on the first
|
||||||
|
line of the log, not a container that looks the same and confines nothing.
|
||||||
|
|
||||||
The price is a bind mount. `/home/bitmessage` mounted from the host has to be
|
The price is a bind mount. `/home/bitmessage` mounted from the host has to be
|
||||||
owned by uid 2000, because the container can no longer chown it on the way in;
|
owned by uid 2000, because the container can no longer chown it on the way in;
|
||||||
|
|||||||
+3
-1
@@ -165,7 +165,9 @@ docker run -d \
|
|||||||
которые заводит сам демон — `knownnodes.dat` и `messages.dat`, — он заводит в
|
которые заводит сам демон — `knownnodes.dat` и `messages.dat`, — он заводит в
|
||||||
своём домашнем каталоге. Ничего не понижается на старте, потому что повышенных
|
своём домашнем каталоге. Ничего не понижается на старте, потому что повышенных
|
||||||
прав изначально нет. Ни на одном файле образа нет бита setuid или setgid, так
|
прав изначально нет. Ни на одном файле образа нет бита setuid или setgid, так
|
||||||
что захваченному демону не по чему подниматься.
|
что захваченному демону не по чему подниматься. Вызывающая сторона, вернувшая
|
||||||
|
пользователя в root, получит отказ первой строкой журнала, а не контейнер,
|
||||||
|
который выглядит так же и не ограничивает ничего.
|
||||||
|
|
||||||
Плата за это — bind-монтирование. Каталог `/home/bitmessage`, приехавший с
|
Плата за это — bind-монтирование. Каталог `/home/bitmessage`, приехавший с
|
||||||
хоста, должен принадлежать uid 2000: сменить владельца на входе контейнер
|
хоста, должен принадлежать uid 2000: сменить владельца на входе контейнер
|
||||||
|
|||||||
@@ -2,6 +2,19 @@
|
|||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
|
# The image runs as its own unprivileged user and everything here assumes it:
|
||||||
|
# keys.dat is worked on by its owner, nothing drops a privilege anywhere, and
|
||||||
|
# what confines the container is whatever the caller passed -- cap_drop,
|
||||||
|
# no-new-privileges, read_only. Started as root instead, by a `user:` override
|
||||||
|
# or a `docker run -u 0`, none of that is true any more and the container looks
|
||||||
|
# exactly the same from outside. Refuse, where the reason is the first line of
|
||||||
|
# `docker logs`, rather than run on quietly with the wrong properties.
|
||||||
|
if [ "$(id -u)" = 0 ]
|
||||||
|
then
|
||||||
|
echo "run.sh: this image must not be run as root; drop the user override" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
export BITMESSAGE_API_USER="${BITMESSAGE_API_USER:-bitmessage_api_user}"
|
export BITMESSAGE_API_USER="${BITMESSAGE_API_USER:-bitmessage_api_user}"
|
||||||
export BITMESSAGE_API_PASSWORD="${BITMESSAGE_API_PASSWORD:-bitmessage_api_password}"
|
export BITMESSAGE_API_PASSWORD="${BITMESSAGE_API_PASSWORD:-bitmessage_api_password}"
|
||||||
export BITMESSAGE_SEED_ADDRESSES="${BITMESSAGE_SEED_ADDRESSES:-0}"
|
export BITMESSAGE_SEED_ADDRESSES="${BITMESSAGE_SEED_ADDRESSES:-0}"
|
||||||
|
|||||||
Reference in New Issue
Block a user