简体   繁体   English

Docker 与登录断开连接时容器未退出 shell

[英]Docker container not exiting when disconnected from a login shell

I have a docker container running on the server side as a user's login shell so that anyone can ssh into the server and get access to some resource inside.我有一个 docker 容器在服务器端运行,作为用户登录 shell 以便任何人都可以 ssh 进入服务器并访问其中的一些资源。

Say, I have a user called test and I want people to be able to SSH into test 's account using some publicly available password.说,我有一个名为test的用户,我希望人们能够使用一些公开可用的密码将 SSH 进入test的帐户。 Here's what I have in /etc/passwd这是我在/etc/passwd中的内容

test:1000:1000::/:/bin/test-shell

and in /bin/test-shell并在/bin/test-shell

#!/bin/bash
docker run -it --rm --network none python:3.10-alpine /bin/sh

Now, whenever someone ssh into my machine using ssh test@example.com , they are immediately dropped into a disposable docker container.现在,每当有人 ssh 使用ssh test@example.com test@example.com 进入我的机器时,它们会立即放入一个一次性 Z045AFE6 容器中。 So far so good.到目前为止,一切都很好。

The problem I have is, if the user doesn't exit the shell by either calling exit or pressing Ctrl-D but just closes their terminal window instead, the container is left running indefinitely and taking up limited server resources.我遇到的问题是,如果用户没有通过调用exit或按Ctrl-D退出 shell 而只是关闭了他们的终端 window,则容器将无限期地运行并占用有限的服务器资源。 I'm wondering if it is possible (and if so, how) to make sure the container is properly stopped (and therefore deleted) when a user disconnects.我想知道当用户断开连接时是否有可能(如果可以,如何)确保容器正确停止(并因此被删除)。

I have seen Why does SIGHUP not work on busybox sh in an Alpine Docker container?我已经看到为什么 SIGHUP 在 Alpine Docker 容器中的busybox sh 上不起作用? and tried the approach of trapping both SIGHUP and SIGPIPE (running trap exit SIGHUP SIGPIPE inside the container), unfortunately nothing happens.并尝试了捕获 SIGHUP 和 SIGPIPE 的方法(在容器内运行trap exit SIGHUP SIGPIPE ),不幸的是没有任何反应。 I'm suspecting maybe the signals are received by the host shell instead of inside the shell inside the container, but I'm not sure how I can leverage that (if that's really what happens) considering I have no way to get the dynamically generated container name, and I can't name the container because I want every single ssh attempt to spawn a different container.我怀疑信号可能是由主机 shell 而不是在容器内的 shell 内接收的,但我不确定如何利用它(如果真的发生这种情况)考虑到我无法获得动态生成的容器名称,我无法命名容器,因为我希望每个 ssh 都尝试生成不同的容器。

Maybe setting up a connection timout with ClientAliveInterval and ClientAliveCountMax from /etc/ssh/sshd_config will help.也许使用/etc/ssh/sshd_config中的ClientAliveIntervalClientAliveCountMax设置连接超时会有所帮助。 By default it is not active.默认情况下它是不活动的。

https://linux.die.net/man/5/sshd_config https://linux.die.net/man/5/sshd_config

I think this answer may help you: https://unix.stackexchange.com/a/85429我认为这个答案可能会对您有所帮助: https://unix.stackexchange.com/a/85429
For example you can try something like this:例如,您可以尝试这样的事情:

#!/bin/bash
[[ "$PAM_USER" -ne "test" ]] && exit 0

SESSION_COUNT="$(w -h "$PAM_USER" | wc -l)"

if (( SESSION_COUNT == 0 )) && [[ "$PAM_TYPE" == "close_session" ]]; then
  docker kill <containerId>
fi

You should use some unique tag for containerId maybe you can associate id of the container with the session id您应该为 containerId 使用一些唯一标签,也许您可以将容器的 id 与 session id 相关联

You could add this in your /bin/test-shell script:您可以在/bin/test-shell脚本中添加它:

#!/bin/bash
# Generate a random name for container
CONTAINER_NAME=${RANDOM}

# Register script to stop container with name
trap '/bin/stop-container "$CONTAINER_NAME"' EXIT

# Run container with name
docker run --name $CONTAINER_NAME -it --rm --network none python:3.10-alpine /bin/sh

# Unregister trap if normal exit
trap - EXIT

At the moment, I can't test it, but it could works, because as described in trap manual:目前,我无法对其进行测试,但它可以工作,因为如陷阱手册中所述:

The environment in which the shell executes a trap on EXIT shall be identical to the environment immediately after the last command executed before the trap on EXIT was taken. shell 执行 EXIT 陷阱的环境应与执行 EXIT 陷阱之前执行的最后一个命令之后的环境相同。

Hope this help you to find the right direction.希望这可以帮助您找到正确的方向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM