英文:
Can a Cloud Foundry app ssh to itself with key authentication?
问题
我有一个 CF 应用程序,需要访问一个 SFTP 服务器进行集成测试,我想利用本地容器的配置来使其充当一个。
我明白根据文档的说明,一个应用程序可以通过代理进行 SSH 到自身,但获取用于cf:<应用程序GUID>
用户名的密码是一个我想尽量避免的复杂问题。
如果我 SSH 到应用程序容器,我确实可以通过代理进行 SSH,但如果我尝试 SSH 到 localhost:2222
,我会收到一个“拒绝公钥”的错误消息,表明它支持密钥认证。
在应用程序容器中是否有一个私钥可供应用程序用于连接到自身的 SSH/SFTP?
英文:
I have a CF app that needs access to an sftp server for integration testing and I'd like to take advantage of the local container being configured to enable it to act as one.
I understand it's possible as explained in the docs for an app to ssh to itself through the proxy, but obtaining a password to use with the cf:<application-guid>
username is a complication that I'd like to avoid if possible.
If I ssh into the app container, I can indeed ssh through the proxy, but if I try to ssh to localhost:2222
, I get a "public key denied" error message, suggesting that it would support key authentication.
Is there a private key available in the app container that the app can use to connect to ssh/sftp to itself?
答案1
得分: 1
是的,在应用程序容器环境中存在一个私钥:运行在应用程序容器内的 diego-sshd
SSH 服务器进程在其环境中有其自己的私钥,存储在名为 SSHD_HOSTKEY
的环境变量中。
一旦你使用 cf ssh
进入应用程序容器获取一个 shell 会话,以下是一种快速提取该 PEM 编码私钥值到文件并使用它来进行身份验证到 diego-sshd
服务器的方法:
$ strings /proc/$(pidof diego-sshd)/environ | awk '/-----BEGIN/,/-----END/' | sed 's/SSHD_HOSTKEY=//g' > sshdkey
$ chmod 0600 sshdkey
$ ssh -i sshdkey -p 2222 localhost
你需要使用 chmod
命令来限制私钥文件的权限,只允许 vcap
用户在应用程序容器中访问,否则 SSH 客户端会报权限过于开放的错误。
一旦你开始了 SSH 会话,很难分辨你是否已经完成了任何操作,因为 shell 提示符看起来与现有的 CF SSH 会话相同,但你可以通过跟踪你的 shell 的 PID 通过进程树来进行检查:
$ pstree -pT $(pidof diego-sshd)
diego-sshd(8)───bash(259)───pstree(323)
$ echo $$
259
$ ssh -i sshdkey -p 2222 localhost
$ pstree -pT $(pidof diego-sshd)
diego-sshd(8)─┬─bash(259)───ssh(341)
└─bash(342)───pstree(353)
$ echo $$
342
在这种情况下,
259
是由初始的 CF SSH 会话启动的bash
进程的 PID,341
是启动嵌套 SSH 会话的ssh
进程的 PID,342
是由客户端会话启动的bash
进程的 PID。
关于 CF 内部发生了什么的一些背景信息:
- 当 Cloud Foundry 创建一个启用了 SSH 访问的新应用程序时,它会生成一个特定于应用程序的私有主机密钥 并将其存储在 CF 的 Diego 系统中应用程序的路由信息中](https://github.com/cloudfoundry/cloud_controller_ng/blob/1750fecda6f268ee4c9ecd826db5f5b8d565ab91/lib/cloud_controller/diego/app_recipe_builder.rb#L58-L62)。Diego SSH 代理组件使用此私钥来对应用程序实例的 diego-sshd SSH 服务器进行身份验证,以将应用程序开发人员的 CF SSH 会话 中的一个引导到其中一个应用程序实例中。
- Cloud Foundry 还会配置应用程序的 diego-sshd 附加服务器,使用
-hostKey
标志来匹配 SSH 代理将使用的密钥信息。 - 当然,这个密钥是敏感的,为了防止意外泄露,
diego-sshd
服务器在启动时将密钥值存储在SSHD_HOSTKEY
环境变量中,然后重新执行自己以清除命令行上的密钥值。但密钥值仍然存在于其环境中,因此我们可以从容器内部的proc
文件系统中提取其值。
英文:
Yes, there is a private key available in the app container environment: the diego-sshd
SSH server process running inside the app container has its own private key stored in its environment as the SSHD_HOSTKEY
environment variable.
Once you've used cf ssh
to get a shell session inside the app container, here's a quick way to extract that PEM-encoded private key value to a file and then to use it to authenticate to the diego-sshd
server:
$ strings /proc/$(pidof diego-sshd)/environ | awk '/-----BEGIN/,/-----END/' | sed 's/SSHD_HOSTKEY=//g' > sshdkey
$ chmod 0600 sshdkey
$ ssh -i sshdkey -p 2222 localhost
You need the chmod
command to restrict permissions on the private key file to only the vcap
user in the app container, as otherwise the SSH client will complain that permissions are too open.
It's hard to tell that you've done anything once you start that SSH session, as the shell prompt will look identical to the existing CF SSH session, but you can check by tracing your shell's PID through the process tree:
$ pstree -pT $(pidof diego-sshd)
diego-sshd(8)───bash(259)───pstree(323)
$ echo $$
259
$ ssh -i sshdkey -p 2222 localhost
$ pstree -pT $(pidof diego-sshd)
diego-sshd(8)─┬─bash(259)───ssh(341)
└─bash(342)───pstree(353)
$ echo $$
342
In this case,
259
is the PID of thebash
process started by the initial CF SSH session,341
is the PID of thessh
process starting the nested SSH session,342
is the PID of thebash
process started by that client's session.
Some background on what's going on with the CF internals:
- When Cloud Foundry creates a new app with SSH access enabled, it generates an app-specific private host key and stores it in the routing information for the app in CF's Diego system. The Diego SSH proxy component uses this private key to authenticate to the app instances' diego-sshd SSH servers when brokering an app developer's CF SSH session into one of the app instances.
- Cloud Foundry also configures the app's diego-sshd sidecar server with that private host key in the
-hostKey
flag so that it matches the key information that the SSH proxy will use. - That key is of course sensitive, so to prevent its accidental disclosure, on startup the
diego-sshd
server stashes the key value in thatSSHD_HOSTKEY
env var and then re-execs itself to clear the key value off the command line. But the key value is still in its environment, so we can extract its value from theproc
filesystem inside the container.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论