Docker中SSH无密码sudo正常,docker exec执行sudo需输密码的问题
用于8031端口SSH访问的Docker配置
Dockerfile
FROM alpine:latest RUN apk add --no-cache php8 \ php8-common \ php8-fpm \ php8-pdo \ php8-opcache \ php8-zip \ php8-phar \ php8-iconv \ php8-cli \ php8-curl \ php8-openssl \ php8-mbstring \ php8-tokenizer \ php8-fileinfo \ php8-json \ php8-xml \ php8-xmlwriter \ php8-xmlreader \ php8-simplexml \ php8-dom \ php8-pdo_mysql \ php8-pdo_sqlite \ php8-tokenizer \ php8-pecl-redis \ php8-pdo_pgsql \ php8-gd RUN apk add --update --no-cache openssh RUN apk add sudo RUN echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config RUN echo 'Port 8031' >> /etc/ssh/sshd_config RUN adduser -h /home/userdev -s /bin/sh -D userdev RUN echo '%wheel ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/wheel RUN adduser userdev wheel RUN echo -n 'userdev:mypassword' | chpasswd ENTRYPOINT ["/entrypoint.sh"] RUN apk --update --no-cache upgrade \ && apk add bash \ && apk add nano \ && apk add nodejs npm \ && apk add gmp gmp-dev \ && apk add git htop \ && apk add mc nano \ && apk add acl screen RUN mkdir -pv /var/www/html RUN setfacl -R -m u:userdev:rwX /var/www/html COPY .screenrc /home/userdev/ COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer EXPOSE 8031 COPY entrypoint.sh /
entrypoint.sh
#!/bin/bash ssh-keygen -A exec /usr/sbin/sshd -D -e "$@"
docker-compose.yml
name: docker-openssh-server services: openssh: image: alpine-sshd-final:latest ports: - "8031:8031" network_mode: "host" volumes: - /var/www/html:/var/www/html - ./sshd_config:/etc/ssh/sshd_config networks: default: name: docker-openssh-server_default
问题分析与解决
现象
- 通过SSH连接容器后,执行
sudo -i无需输入密码 - 使用
docker exec -it -u userdev:userdev container_name /bin/bash进入容器shell后,执行sudo要求输入密码
原因
核心问题是Docker exec指定用户组的方式未正确初始化用户的组环境:
- SSH登录时,sshd会为用户加载完整的会话环境,包括用户的所有附加组(如wheel)信息,sudo能正确识别用户属于wheel组,匹配
%wheel ALL=(ALL) NOPASSWD: ALL的规则 - 当用
-u userdev:userdev指定用户和用户组时,Docker会强制将用户的主组设为userdev,忽略了用户原本的附加组wheel,导致sudo无法识别用户的wheel组身份,从而触发密码验证
实现docker exec无密码sudo的方案
方案1:移除exec命令中的用户组指定
将exec命令改为只指定用户,Docker会自动加载用户的默认组(包括附加组wheel):
docker exec -it -u userdev container_name /bin/bash
方案2:直接给userdev配置无密码sudo(不依赖wheel组)
修改Dockerfile中的sudoers配置,替换原来的wheel组规则,直接针对userdev用户设置:
# 替换原有的RUN echo '%wheel ...'行 RUN echo 'userdev ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/userdev
这样无论用户环境如何加载,只要是userdev用户执行sudo,都无需输入密码。
方案3:以登录shell启动exec的bash
通过-l参数让bash以登录shell模式启动,加载完整的用户环境配置,包括组信息:
docker exec -it -u userdev:userdev container_name /bin/bash -l
内容的提问来源于stack exchange,提问作者Twissell
相关产品推荐
相关产品推荐

