我可以使用 ssh 密钥来验证 HTTP 请求吗?

问题描述 投票:0回答:1

我正在编写一个需要与 Web 服务交互的命令行工具,并且我希望能够使用用户的 ssh 密钥对其进行身份验证。我想知道我是否可以做这样的事情:

  1. 用户使用用户的用户 ID 向 url 发出请求(比如
    /auth/login
    )。
  2. 服务器知道用户的 ssh 公钥,并使用该密钥加密会话 ID。
  3. 用户使用其私钥解密服务器的响应,并在每个后续请求中提供该会话 ID。

我想我的主要问题是:我刚刚重新发明了一个众所周知的安全机制吗?这听起来有点像 oauth,但我不太确定它是否或如何映射到任何现有的 oauth 工作流程中。

authentication oauth ssh rsa
1个回答
0
投票

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
  1. 用户访问https://auths.sh,服务器生成随机UUID并告诉用户运行命令
    ssh auths.sh 28c21335-6ba1-4d3a-8835-e737811297d5
  2. 使用给定的UUID执行ssh命令,服务器将用户的公钥写入文件
    /tmp/28c21335-6ba1-4d3a-8835-e737811297d5
  3. 浏览器已通过身份验证(UUID 存储在 cookie 中
    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(),
        ),

可以修改代码,添加会话加密和解密。

© www.soinside.com 2019 - 2024. All rights reserved.