背景:
我的服务器上正在运行一个服务,该服务在域套接字上侦听/srv/socket
传入连接,然后与连接的用户交互。请注意,此服务是我编写的(使用 C++),因此我可以非常轻松地修改服务的行为。现在,此服务不执行任何身份验证或权限检查(您稍后会看到这一点必须更改)。与我合作的几个开发人员(大约五到十个)需要从互联网上其他位置的计算机访问此服务(并且只能访问此服务)。由于此服务赋予他们相当多的权限,因此我希望身份验证尽可能强,并且连接是加密的。我的主要问题(为了避免任何 XY 问题)是:我该如何设置它?
关于它的想法和问题:
我最初的想法是提供自己的身份验证,然后使用 TLS 进行加密(当然,在外部端口上公开服务)。但是,编写自己的身份验证可能会导致安全漏洞,并且设置通过 TLS 进行连接会很麻烦。
我的第二个想法是只使用 SSH。SSH 已经具有非常强大的身份验证和加密功能,基本上可以满足我的需要。不幸的是,我不太清楚如何设置它。首先,我当然不想让开发人员拥有完全的 shell 访问权限,因此我将更改他们的默认 shell /bin/false
(根据此网站和相关网站上的其他一些答案)。但我仍然需要他们能够连接到相关套接字。我研究了 ssh 隧道,但这似乎不是我需要的,其他类似于“ssh 作为代理”的搜索都揭示了相关但不完全相同的问题。这里正确的做法是什么?当然,我可以编写一个自定义可执行文件,它将充当“shell”,并简单地将这些用户连接到我的服务,但同样,此代码将具有安全性敏感性,在可能的情况下,我希望避免编写自己的代码。
最佳情况:
理想情况下,我希望发生以下情况:
- 用户在其客户端上运行一些命令。
- 创建到我的服务器上的代理服务的加密连接,并且用户向该服务进行身份验证(理想情况下,这是一个已知相当安全的完善的服务)。
- 代理服务打开与我的服务的连接,转发用户名(或某些用户标识符),然后连接客户端。
实现这一目标的最佳方法是什么?
答案1
我知道距离你提问已经有一段时间了,但如果你仍然感兴趣,可以看看我的邮政关于服务器故障。虽然那里的问题与您的要求无关,但我提出的解决方案可能直接相关。我希望从比我更了解安全影响的专家那里得到一些对该帖子的回应,但这并没有发生。
这篇文章有点长,不适合在这里重复,但简而言之,这个概念是:
- 设置 SSH 以要求您需要/可以容忍的尽可能多的身份验证机制,例如密码 + 密钥 + otp 等。
- 将用户 shell 设置为
/sbin/nologin
(/sbin/nologin
优先于/bin/false
) - 当用户通过 ssh 连接(验证)时,利用服务器上的 sshrc 调用脚本,该脚本可以执行您需要的任何操作,例如启动您的服务
在上述设置中,您的用户通过 SSH 进行身份验证,并且一旦通过身份验证,/etc/ssh/sshrc
就对您的服务执行必要的操作,并/sbin/nologin
在身份验证后正常断开 SSH 会话,因为不再需要它。
您可以随意使用 sshrc 中的脚本。例如,考虑从不为您的服务打开任何端口开始。一旦用户通过身份验证,sshrc 脚本就可以在您的防火墙中动态打开该用户 IP 的端口。
请注意:以上假设您确实非常清楚自己在 ssh 配置方面做了什么。虽然目前有几种经过良好测试的 SSH 实现,但其中许多很容易配置错误,从而带来重大安全隐患。此外,对于 SSH 身份验证,我强烈建议始终使用密钥 +(至少用户知道一件事,例如密码或 otp,最好两者兼有)。