Разрешение корневого скрипта точки входа Docker

У меня есть Dockerfile с тремя ограничениями:

1.) Последний оператор USER в Dockerfile должен быть USER tomcat в целях безопасности (он построен на образе tomcat: 8.5.23-jre8-alpine)

2.) Он не может запустить chmod в каталоге /root/ или $JAVA_HOME

3.) Он должен иметь возможность изменять каталог $JAVA_HOME/lib/security в точке входа, а не в файле Docker (поскольку сертификаты передаются при запуске контейнера)

На данный момент у меня есть

FROM tomcat:8.5.23-jre8-alpine

#### OTHER IMAGE COMMANDS ####

COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh

RUN chown root:root /usr/local/bin/entrypoint.sh

RUN chmod 4755 /usr/local/bin/entrypoint.sh

USER tomcat

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["catalina.sh", "run"]

Я решил, что предоставление права собственности на файл root и chmod 4755 позволит пользователю tomcat выполнить точку входа, но при этом точка входа будет запущена как root, чтобы он мог изменять файловую систему по своему усмотрению. Однако, когда я запускаю эту строку в точке входа

$JAVA_HOME/bin/keytool -import -alias ca_local -keystore $JAVA_HOME/lib/security/cacerts -storepass XXXXX -noprompt -trustcacerts -file /usr/local/tomcat/certificates/ca-local.cer

Я получаю следующую ошибку:

keytool error: java.io.FileNotFoundException: /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts (Permission denied)

Похоже, что точка входа на самом деле не работает от имени пользователя root, как предполагал chown / chmod. Я знаю, что все мои файлы находятся в правильных местах, потому что, когда я удаляю USER tomcat из файла Docker, все работает нормально. Что мне не хватает в настройке разрешения точки входа?


person littlespice3    schedule 29.01.2018    source источник


Ответы (1)


В этих двух шагах:

RUN chown root:root /usr/local/bin/entrypoint.sh
RUN chmod 4755 /usr/local/bin/entrypoint.sh

Вы гарантируете, что ваш entrypoint.sh скрипт принадлежит root, а затем вы пытаетесь установить бит setuid. К сожалению, этот второй шаг не сработает: вы не можете пометить сценарий оболочки (или фактически любой интерпретируемый сценарий) как setuid; бит будет просто проигнорирован. См., Например, этот вопрос.

Но если это сработает, у вас возникнет другая проблема: ваш ENTRYPOINT скрипт отвечает за обработку любой команды, переданной в ваш контейнер, либо в командной строке docker run, либо через директиву CMD в Dockerfile. Если эта setuid попытка сработает, ваш ENTRYPOINT скрипт будет работать от имени пользователя root ... что означает, что вы в конечном итоге будете запускать catalina.sh run как root, а это значит, что ваша директива USER совершенно бессмысленна.

Вы можете добраться до того же места, просто отбросив директиву USER, разрешив запускать точку входа как root, а затем ваш сценарий ENTRYPOINT запускает CMD от имени пользователя tomcat (например, используя su или sudo):

FROM tomcat:8.5.23-jre8-alpine

#### OTHER IMAGE COMMANDS ####

COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["sh", "/usr/local/bin/entrypoint.sh"]
CMD ["catalina.sh", "run"]

И в entrypoint.sh:

#!/bin/sh

# Do stuff as root here.
$JAVA_HOME/bin/keytool -import -alias ca_local \
  -keystore $JAVA_HOME/lib/security/cacerts 
  -storepass XXXXX -noprompt -trustcacerts \
  -file /usr/local/tomcat/certificates/ca-local.cer

# Now run everything else as a non-root user
exec su - tomcat -c "$*"

Это очень распространенный механизм для обработки задач начальной настройки, которые должны выполняться от имени пользователя root, а все остальное - как пользователь без полномочий root.

Здесь все еще есть ряд проблем: базовый tomcat:8.5.23-jre8-alpine не имеет tomcat пользователя, а сценарии в /usr/local/tomcat/bin могут выполняться только root. Поэтому, если вы хотите, чтобы этот конкретный образ работал с пользователем без полномочий root, вам, вероятно, нужно сначала внести несколько изменений конфигурации.

person larsks    schedule 30.01.2018
comment
Во многих сборках образов используется gosu вместо su или sudo для большей совместимости с Docker. - person Matt; 30.01.2018
comment
runuser - отличный выбор, если ваш дистрибутив включает его в базовый образ. - person larsks; 30.01.2018
comment
Спасибо! Отличное объяснение, если бы я мог дать 2 голоса, я бы сделал это. Конфигурация пользователя Tomcat находится в разделе #### ДРУГИЕ КОМАНДЫ ИЗОБРАЖЕНИЯ ####, поэтому я просто запустил свой CMD как пользователь tomcat из точки входа. - person littlespice3; 30.01.2018