我正在编写一个需要与 Web 服务交互的命令行工具,并且我希望能够使用用户的 ssh 密钥对其进行身份验证。我想知道我是否可以做这样的事情:
/auth/login
)。我想我的主要问题是:我刚刚重新发明了一个众所周知的安全机制吗?这听起来有点像 oauth,但我不太确定它是否或如何映射到任何现有的 oauth 工作流程中。
SSH 和 HTTP 显然是不同的协议。您将需要对不同服务(使用共享会话存储)发出多个请求。穷人的解决方案可以利用
ssh
隧道。在命令行工具中,您将启动一个进程来保持与服务器的连接
/---- a local port (entry to the tunnel)
/
ssh -L 8080:localhost:8081 remote.server.com
\ \-------------------- remote port (publicly not accessible)
\
\--- address resolve at the other end of tunnel (on server)
一旦隧道建立并且用户通过他的公共 ssh 密钥进行身份验证。 CLI 工具可以向本地 http 端口
8080
发出请求,该端口将通过安全隧道路由到服务器。该请求将被加密,但服务器不知道有关用户及其 ssh 密钥的任何信息。我们要么必须保持隧道打开,要么为每个到 HTTP 服务器的请求建立新的连接(例如 VPN)。
为了正确实现这一点,您必须实现/修改 ssh 服务器。 这基本上就是您想要的,通过 ssh 进行 HTTP 身份验证的 POC 和 这里的源代码。
代码使用了一个不错的项目charmbracelet/wish,它实现了ssh服务器。
/--- port 8080 - HTTP sever
./auths.sh -
\--- port 4202 - SSH server
ssh auths.sh 28c21335-6ba1-4d3a-8835-e737811297d5
/tmp/28c21335-6ba1-4d3a-8835-e737811297d5
SESSION_ID
),HTTP 服务器知道用户的公共 ssh 密钥。使用
wish
包,您可以轻松实现自定义身份验证:
s, err := wish.NewServer(
wish.WithAddress(fmt.Sprintf("%s:%d", host, port)),
wish.WithHostKeyPEM(pem),
wish.WithPublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool {
// <- validate public key against e.g. authorized_keys
return true
}),
wish.WithMiddleware(
sshHandler,
logging.Middleware(),
),
可以修改代码,添加会话加密和解密。