![如何实现类似于 GitHub 的动态、基于密钥的 SSH?](https://linux22.com/image/613914/%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E7%B1%BB%E4%BC%BC%E4%BA%8E%20GitHub%20%E7%9A%84%E5%8A%A8%E6%80%81%E3%80%81%E5%9F%BA%E4%BA%8E%E5%AF%86%E9%92%A5%E7%9A%84%20SSH%EF%BC%9F.png)
我想要为我的应用用户提供类似 SSH/RSYNC 的功能。我希望他们能够将 SSH 密钥粘贴/保存到我的应用中类似于 GitHub 的做法:
所以,我的问题是,一旦我让用户保存他们的密钥(最好在数据库中):
有没有什么方法可以在不实际创建 Linux 用户帐户的情况下提供/模仿 SSH/RSYNC 功能?我希望能够根据他们存储在数据库中的公钥进行授权,并让他们 RSYNC 进入/退出特定文件夹(例如,基于他们在应用程序中的用户名)。
(如果重要的话,它将是一个部署到 Ubuntu 服务器的 Rails 应用程序)
答案1
查看command
SSH 的 authorized_keys-file 的 -option。这样,您可以根据用户的 SSH 密钥强制特定用户访问您的计算机并执行命令。
假设您的服务器上有一个名为“git”的用户。此用户具有以下 authorized_keys 文件作为示例:
command="/path/to/script user1",no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa [public key of user1]
command="/path/to/script user2",no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa [public key of user2]
因此,当 user1 运行 时,会被调用(以 git 用户身份)。此脚本可以访问环境变量 $SSH_ORIGINAL_COMMAND 中的原始命令()(有关更多详细信息,请参阅 SSH 文档)。ssh [email protected] "/execute/command --with --parameter"
/path/to/script
/execute/command --with --parameter
这样,只需将正确的行放入authorized_keys文件即可(您可以从存储在数据库中的密钥动态构建文件)。
从那里您可以编写自己的 shell 或使用原始命令执行任何您想做的事情。
这基本上就是 gitolite 和 gitosis 管理 git 存储库权限的方式(我认为 Github 使用其中之一)。
希望这能有所帮助——亲切的问候!
答案2
OP 明确表示他希望将密钥分配给多个用户,并且他希望将用户存储在数据库中,而不是作为实际的 Linux 用户。在上面提到的 Github 样式设置中,只有一个 git 用户。
为了使答案完整,OP 还需要使用 AuthorizedKeyCommand 指令,该指令在此处解释得很清楚 -OpenSSH 使用数据库中的公钥
因此,您可以结合使用两者。存储在数据库中的 x 个用户的服务器身份验证由 完成。基于自定义身份验证脚本(您在 Web 应用程序中调用某个脚本的 bash 脚本)
当您的自定义脚本将公钥返回给 OpenSSH 进行身份验证(代替 authorized_keys 文件)时,您可以按照 Michael Trojanek 的回答中描述的格式提供它。这样,您就可以为动态用户可以访问的特定功能提供授权。
答案3
Linux 用户可能不仅来自 /etc/passwd 和 shadow,还可能来自其他 NSS 模块。比如说,除了其他模块外,还有 MySQL NSS 模块和 LDAP NSS 模块。但是,将它们的主目录配置为来自与 /home 不同的地方,原因很快就会显现出来。
您可以使用手写的 FUSE 模块合成它们的主目录。这样的模块很容易编写;作为示例,我建议查看 MySQL FUSE 文件系统源代码(您要做的事情一定更容易)。您应该从数据库密钥记录合成一个 ~/.ssh/authorized_keys 文件,以使基于密钥的身份验证生效,您还可以在其中限制用户使用该密钥连接时可以执行的操作。您的 FUSE 模块可能会将一些请求代理到实际文件系统,而不是将文件存储在数据库中;有关示例实现,请参阅 encfs 源代码,您基本上会执行相同的操作,但不加密。
因此,您将这样的文件系统安装在某处,这将成为您所有合成用户主页。
瞧,一切都使用数据库中的数据,详细信息也已合成。请注意,您在此处创建的仍然是实际的用户帐户,但其所有详细信息都存储在数据库中,并且这些用户受到任意限制。