我们公司的产品是一个运行在容器中的应用程序。它监听 2222 端口以建立命令行界面。
一位客户遇到了 SSH 问题,我们以前从未见过这个问题,并且无法使用完全相同的操作系统(RHEL 7.8)、Docker 版本(RHEL 打包 1.13.1)+ 容器(我们的应用程序,相同版本)重现此问题。
当他们这样做时:
ssh -p 2222 <user>@<ip>
他们在客户端看到的错误是:
server refused to allocate pty
或者PTY allocation request failed on channel 0
我们的应用程序(服务器)中的错误日志是:
openpty: Operation not permitted
session_pty_req: session 0 alloc failed
pam_unix(sshd:session): session closed for user <>
谷歌搜索后发现,/dev/pts、/dev/pts/ptmx 或 /dev/ptmx 的权限可能不正确。但在这里它们是正确的。
另一种可能性是 devpts 的挂载缺少 gid=5。我检查了一下,主机和容器上的挂载看起来都是正确的。
# Host
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
# Container
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666 0 0
我已经将我的系统与客户的系统进行了交叉检查。一切看起来都一致,但显然有些地方不对劲。
另一个数据点:目前他们使用 user-id=1000001、group-id=0 或 root 运行容器docker run --user 100001:0 ...
。如果他们以 root 身份运行容器,docker run --user 0:0 ...
则不会发生此问题。这是某个地方的权限问题。
有人遇到过这种情况吗?
由于我没有主意,所以如果能提供任何提示我将非常感激。
答案1
我们发现问题在于客户的 NIS 将 tty 设置为第 7 组。
我们在容器内的 ssh 进程上设置了 strace。当他们尝试 ssh 时,openpty() 将尝试 chown 并失败,我们在 strace 日志中看到以下内容:
chown("/dev/pts/0", 1000001, 7) = -1 EPERM (Operation not permitted)
然后,当我们这样做时,getent group | grep tty
我们看到 NIS 将 tty 设置为第 7 组。
如果容器以 root 身份运行(docker run 中未指定 --user),或者 docker 容器未使用主机网络,则不会发生此失败。
为了解决这个问题,我们需要确保 NIS 设置不会泄露到容器中,因此请编辑容器内的 /etc/nsswitch.conf,并删除、和nis
条目。passwd
shadow
group
现在,当启动 ssh 会话时,容器中的 /dev/pts/<> 将与容器组(“正确”)一起创建,并且 chown 不会失败。