在PHP中创建永久的SSH隧道

时间:2018-12-14 19:07:41

标签: php ssh-tunnel

我有一个函数需要通过PHP中的SSH隧道将PDO对象返回到远程主机。

我目前以一种方式工作,即当请求PDO对象时,它会创建SSH隧道,连接PDO并返回PDO对象。

我希望能够一次创建SSH隧道并将其保留在其中,因此当我有100个请求到特定远程服务器的PDO对象时,我只会创建一次SSH隧道。

目前,脚本完成运行后,SSH隧道将被破坏。

我该如何设置以实现这一目标?

目前我已经尝试过:

exec('ssh -fNg -L 13306:127.0.0.1:3306 user@host > /dev/null 2>/dev/null &');

exec('autossh -f -M 13308 -fNg -L 13306:127.0.0.1:3306 user@host > /dev/null 2>/dev/null &');

在两种情况下,脚本退出时都会破坏隧道。

谢谢!

1 个答案:

答案 0 :(得分:2)

这是一个奇怪的用例,不是我特别建议通过派生Web请求来完成的事情。 [或什至完全没有],但是您也许可以利用ssh的ControlMaster自行处理持久连接和多路复用连接。

添加以下选项:

  1. -o ControlMaster auto
    • 允许通过单个网络连接共享多个会话。
  2. -o ControlPersist 30
    • 指定在关闭初始客户端连接后,主连接应在后台保持打开状态。
  3. -o ControlPath /path/to/socket/dir/%r@%h-%p [可选,但推荐]
    • 指定用于连接共享的控制套接字的路径。

参考:https://linux.die.net/man/5/ssh_config

重要的是要注意,一旦建立了ControlMaster套接字,任何允许访问它的用户都可以在不进行身份验证的情况下进行访问。您可能希望根据应用程序的身份验证/授权将套接字路径彼此隔离。

通过上述方法,ssh二进制文件本身就可以处理持久连接,等待超时到期并正常关闭连接所需的必要的删除操作。尽管要注意的一件事是,如果ssh进程被杀死,则套接字仍然存在,需要在再次连接之前进行手动清理。

此外,此代码还取决于对用户的IMMENSE信任级别,不会执行任何愚蠢和/或恶意的操作。至少要确保您在任何和所有用户输入中自由使用escapeshellarg()escapeshellcmd(),这些输入可能会变成执行的命令。