wurstmeister / kafka-docker

Dockerfile for Apache Kafka
http://wurstmeister.github.io/kafka-docker/
Apache License 2.0
6.92k stars 2.73k forks source link

[Feature Request] Run process as non-root. #403

Open PAStheLoD opened 6 years ago

PAStheLoD commented 6 years ago

edit: (original title) Ability to set/map externally visible uid?

Hello,

I'd like to ask for some advice, help or maybe even file this as a request for enhancement. Currently the docker container creates files and runs as root. We'd like to run it as a non-privileged user, if it's possible.

Thank you!

barrer commented 5 years ago

Try this configuration file, it does not require the /var/run/docker.sock file, which means no high permissions are required, but docker itself requires root.

https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface

I think the following knowledge needs to be reserved before using this image: docker, docker network, docker compose, zookeeper, kafka, network operating system.

version: '2'
services:
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
  kafka1:
    image: wurstmeister/kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT
      KAFKA_LISTENERS: INSIDE://:9092
      KAFKA_ADVERTISED_LISTENERS: INSIDE://192.168.47.131:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
    depends_on:
      - zookeeper
  kafka2:
    image: wurstmeister/kafka
    ports:
      - "9096:9096"
    environment:
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT
      KAFKA_LISTENERS: INSIDE://:9096
      KAFKA_ADVERTISED_LISTENERS: INSIDE://192.168.47.131:9096
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
    depends_on:
      - zookeeper
  kafka3:
    image: wurstmeister/kafka
    ports:
      - "9010:9010"
    environment:
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT
      KAFKA_LISTENERS: INSIDE://:9010
      KAFKA_ADVERTISED_LISTENERS: INSIDE://192.168.47.131:9010
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
    depends_on:
      - zookeeper
sscaling commented 5 years ago

My interpretation of the question is that this is regarding the Kafka process inside the container, not the privileges of the docker command.

barrer commented 5 years ago

@PAStheLoD @sscaling

This is not necessary unless there is a vulnerability in the Linux Kernel namespaces that causes the program inside the container to control the external program. If you are concerned, please check it out: https://docs.docker.com/engine/security/security/

But not allowing the /var/run/docker.sock file to be accessed inside the container is still a very important security measure. I hope the author can remove this default configuration.

sscaling commented 5 years ago

@barrer thanks for the input. As i'm sure you are aware, Kafka is a non-trivial piece of infrastructure to run in a production environment - it is expected that the operator understands the environment, the configuration mechanisms and risks associated with them. As documented in the FAQ, mounting the socket is not required. This image purely provides a wrapper around the Kafka binary, it is the responsibility of the operator to configure it in an appropriate way for their use-case and environment.

The reason this has not been actioned, is that the operator can use the --user (docker run) or user: (docker-compose) options to specify a user to run the process as. So arguably there is no action to take here - I just haven't investigated further / validated this with this image.

chrisjs commented 5 years ago

@sscaling in kubernetes for example when setting the runAsUser value, when the container starts you get the following error:

/usr/bin/start-kafka.sh: line 100: /opt/kafka/config/server.properties: Permission denied

which is:

echo "" >> "$KAFKA_HOME/config/server.properties"

with the perms of:

-rw-r--r-- 1 root root 6954 Jun 22 2018 /opt/kafka/config/server.properties

sdressler commented 5 years ago

If I may chime in here, I think it is in general a good practice to have a fixed non-root user inside the container and always run with that, and also to set permissions accordingly. The only difficulty is then to also use this with persistent data, i.e. the permissions have to be right. Would a PR be welcome?

Asgoret commented 5 years ago

@sdressler you saw this theme? https://github.com/confluentinc/cp-helm-charts/issues/173 And bitnami version of kafka?

sdressler commented 5 years ago

@Asgoret I did, but I don't get the point, I'm afraid.

I wanted to use Kafka on Rancher and they actually have the bitnami version but it does not spin up completely, hence I looked for alternatives and came here. Don't mind running as root much, but wanted to offer help.

Asgoret commented 5 years ago

@sdressler Oh) I tried to help with non-root start. If you already do this it's great)

sdressler commented 5 years ago

@Asgoret please go ahead, I won't have time in near future ;-)

Lukkie commented 5 years ago

I managed to do accomplish this as follows. First, add an additional entrypoint script, e.g. nonroot-entrypoint.sh

#!/bin/bash
adduser -S -D -H kafka
chown -R kafka /kafka
chown -hLR kafka $KAFKA_HOME
chown -R kafka /usr/bin/*.sh

# Run as kafka user
exec su-exec kafka /bin/bash -c /usr/bin/start-kafka.sh

Next, I extended the dockerfile like this:

FROM wurstmeister/kafka:2.11-1.1.1

RUN apk add --no-cache su-exec
COPY nonroot-entrypoint.sh /usr/bin/
RUN chmod a+x /usr/bin/nonroot-entrypoint.sh

CMD ["nonroot-entrypoint.sh"]

Kafka now runs as PID 1 under the kafka user.

Chrislevi commented 4 years ago

Is there any news with this? I've hit the same wall. using --user changes the running user but the image itself is built as root with all the files inside. I really wan't to avoid building 3rd party images with our own dockerfiles since it kinda defeats the purpose.

OneCricketeer commented 4 years ago

@Chrislevi with our own dockerfiles since it kinda defeats the purpose.

I would argue that it allows you to share the same base images, thus saving on storage costs of the servers running Docker.

@Lukkie That is a nice extension, but that entrypoint is going to run at every start of the container, so why not chown and adduser within the Dockerfile?

zhangguanzhang commented 11 months ago

same issue