我试图强制通过 SSH 登录的用户在 IP 命名空间内拥有一个 shell。
我试过用/etc/passwd
类似的东西替换外壳,ip netns exec sshns /bin/bash
但它没有用。
还有其他想法吗?有可能吗?它会安全还是根本不安全?
通过更改登录 shell 来处理这个问题,如 OP 的示例,是当用户连接到sshd
主网络命名空间时,即使你让他们的 shell 在另一个命名空间内运行,但他们的端口转发无论如何都会在默认网络命名空间中运行.
我提出的解决方案还解决了包含端口转发到命名空间以及 shell 的问题。它可能仅限于使用本地帐户,因为通过网络(NIS、SMB 等)对远程系统进行身份验证可能不起作用,因为身份验证阶段将从网络命名空间内执行。
我需要 shell 和端口转发在目标命名空间中运行,而无需在默认命名空间和包含的命名空间之间创建网络/路由。
以下是实现此目的的一些方法/工具:
xinetd
- 感谢 Stéphane Chazelas 指出这一点。对于单个或静态数量的命名空间并转发给它们xinetd
似乎是更好的选择。例如文件/etc/xinetd.d/sshd-netns-foo
service sshdnetns
{
type = UNLISTED
socket_type = stream
protocol = tcp
port = 222
wait = no
user = root
server = /sbin/ip
server_args = netns exec NameSpaceName /usr/sbin/sshd -i
}
Run Code Online (Sandbox Code Playgroud)
socat
- 对于需要独立启动/停止转发给它们的多个命名空间socat
是一个很好的选择。在默认命名空间中运行:
socat tcp-listen:222,fork,reuseaddr \
exec:'ip netns exec NameSpaceName /usr/sbin/sshd -i',nofork
Run Code Online (Sandbox Code Playgroud)
ncat
- 如果socat
不可用,那么ncat
(在我的 RHEL 盒子上nc
)可以完成这项工作。缺点ncat
是通过管道sshd
连接ncat
而不是直接连接到套接字,因此sshd
无法看到客户端 IP,因此日志不太有用。您最终还会运行一个额外的中间ncat
过程。
ncat --keep-open --sh-exec "exec ip netns exec NameSpaceName /usr/sbin/sshd -i" -l 222
Run Code Online (Sandbox Code Playgroud)
可能还有其他工具。
这在自定义端口 222 上的默认命名空间中接受 SSH 连接,并且对于每个连接sshd -i
在目标命名空间内启动一次。
这为我解决了这个问题,但是您还需要限制可以登录到每个命名空间的用户。创建命名空间特定的 sshd 配置:
mkdir -pv /etc/netns/NameSpaceName/
cp -Rp /etc/ssh /etc/netns/NameSpaceName/
Run Code Online (Sandbox Code Playgroud)
为每个sshd_config
文件添加访问控制,例如在默认情况下/etc/ssh/sshd_config
:
AllowUsers user1 user2
Run Code Online (Sandbox Code Playgroud)
...并在 /etc/netns/NameSpaceName/ssh/sshd_config
AllowUsers restrictedUser1 restrictedUser2
Run Code Online (Sandbox Code Playgroud)
... 也看看AllowGroups
指令
现在重新创建目录绑定的命名空间以生效
我的简短测试显示用户访问控制按预期工作,但我并没有真正使用它,因此您可以验证它。
我尝试将单独的/etc/passwd
,/etc/shadow
和/etc/group
文件放入/etc/netns/NameSpaceName/
单独的用户列表中,但在我的快速测试中不起作用:useradd test
命名空间内部失败。
笔记:
如果您不喜欢自定义端口,您可以双重归属,例如 macvlan,或者只是添加另一个 IP 地址并侦听专用 IP 上的默认端口。
所有身份验证、外壳、子系统、端口转发等都由 处理,sshd
所以我不必破解其他任何东西。
它确实有sshd -i
这样运行的缺点,请阅读man sshd
查找-i
选项。您可以通过sshd
在命名空间内全时运行并将转发守护程序更改为以下内容来轻松解决它:
nc --keep-open --sh-exec "exec ip netns exec NameSpaceName nc localhost 22" -l 222
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以使用 mount 和/或用户命名空间(除了网络命名空间)更巧妙地解决它。我没有这些经验。
可能有更好的方法来实现这一点,我会对其他人提出的内容非常感兴趣。