我正在尝试将一些脚本作为Alpine Docker镜像中的不同用户运行。以devuser
身份登录后,我希望将setup.sh
设为root
,将app.sh
设为appuser
。由于我已经读过你不能在脚本文件上使用SUID,我有几个C程序setup
和app
,它们调用脚本。我可以setup
作为root
运行,但无法app
作为appuser
运行。
这是目录的内容。请注意,app和setup在程序上设置了SUID位。我尝试在脚本上设置SUID,但这不起作用。
/opt/app $ ls -l
total 24552
-r-sr-xr-x 1 appuser appgroup 10632 Jun 27 12:59 app
-r-------- 1 appuser appgroup 25101769 Jun 27 12:59 app.jar
-r-xr-xr-- 1 appuser appgroup 327 Jun 27 12:59 app.sh
-r-------- 1 appuser appgroup 316 Jun 27 12:59 application.yml
-r-sr-xr-x 1 root root 10632 Jun 27 12:59 setup
-r-xr-xr-- 1 root root 152 Jun 27 12:59 setup.sh
我的运行时间为devuser
。
/opt/app $ whoami
devuser
我可以成功运行setup
。它由root
拥有,并以root
运行。
/opt/app $ ./setup
Running As: root:appgroup
我尝试运行app
并且不会更改为所有者。
/opt/app $ ./app
Running As: devuser:appgroup
Error: Unable to access jarfile app.jar
以下是setup.sh
的来源。
/opt/app $ cat setup.sh
#!/bin/ash
echo "Running As: $(whoami):$(id -gn)"
以下是app.sh
的来源。
/opt/app $ cat app.sh
#!/bin/ash
echo "Running As: $(whoami):$(id -gn)"
java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar $SPRING_OPTS
以下是两位用户。
/opt/app $ id devuser
uid=701(devuser) gid=700(appgroup) groups=700(appgroup),700(appgroup)
/opt/app $ id appuser
uid=700(appuser) gid=700(appgroup) groups=700(appgroup),700(appgroup)
以下是setup.c
的来源。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
setuid(0);
system("./setup.sh");
return 0;
}
以下是app.c
的来源。我也试过了setuid(0)
但是没有用。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
setuid(700);
system("./app.sh");
return 0;
}
最后我脏衣服; Docker构建。我尝试将adduser
设置为系统用户和非系统用户。
RUN addgroup -g 700 appgroup \
&& adduser -G appgroup -D -u 700 -S -H -s /bin/sh appuser \
&& adduser -G appgroup -D -u 701 -s /bin/sh devuser
RUN sh -c 'touch app.jar' \
&& chown appuser:appgroup *.jar \
&& chown appuser:appgroup *.yml \
&& chown appuser:appgroup app.sh \
&& chown appuser:appgroup app \
# && chmod -R 750 . \
&& chmod u+x,g+x,o-x *.sh \
&& chmod 4555 setup \
&& chmod 4555 app \
&& chmod 400 *.yml \
&& chmod 400 *.jar \
&& chmod -R -w .
USER devuser
# USER appuser
感谢您的帮助, 韦斯。
答案 0 :(得分:1)
如果您在setuid()
中将setreuid()
更改为app.c
,它将起作用。
查看此答案和评论的原因:https://stackoverflow.com/a/20687988
但是,您的描述方式是非标准的。拥有可调用Shell脚本的SUID二进制文件听起来很hack。
这是一种使用Alpine标准su-exec的方法:
app.sh
#!/bin/sh
echo "Running As: $(whoami):$(id -gn)"
java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar $SPRING_OPTS
setup.sh
#!/bin/sh
echo "Running As: $(whoami):$(id -gn)"
exec su-exec appuser:appgroup ./app.sh
Dockerfile
FROM alpine
WORKDIR /app
RUN apk add --no-cache su-exec
RUN addgroup -g 700 appgroup \
&& adduser -G appgroup -D -u 700 -S -H -s /bin/sh appuser
COPY * ./
RUN chmod 0755 *.sh
ENTRYPOINT ["./setup.sh"]
简单得多,也可能更安全。