我需要在一些远程盒子上进行一些开发。幸运的是,我有 shell 访问权限,但我需要通过将 AllowTcpForwarding 设置为 false 的网关。
我在文档中看到了一个高峰,它说:
AllowTcpForwarding 指定是否允许 TCP 转发。默认值为“是”。请注意,禁用 TCP 转发不会提高安全性,除非用户也被拒绝 shell 访问,因为他们始终可以安装自己的转发器。
我将如何安装(或构建)我自己的转发器?我的目标是建立一个使用 Pycharm 的远程解释器通过 SSH 并将其绑定到某个本地端口,数据通过 ssh 馈送,通过网关,然后到实际运行代码的开发盒。我想我可以以某种方式利用 nc 或其他一些 unix 实用程序来帮助完成工作。
我知道我可以通过以下方式 ssh 到我的远程盒子:
ssh -t user1@gateway ssh user2@devbox
但显然这个选项在pycharm中不可用。我必须能够打开一些本地端口,以便
ssh -p 12345 localhost
(or variant)
会将我连接到 user2@devbox。这将允许我配置远程解释器以使用端口12345
连接localhost
到远程盒子。
答案1
只要能执行socat
本地 和 on gateway
(或者甚至只是bash
和cat
on gateway
,请参阅最后一个示例!)并且允许不是使用pty是8位干净的,可以通过ssh建立隧道。以下是 4 个示例,对之前的示例进行了改进:
基本示例工作一次
(让它分叉将需要每个隧道一个 ssh 连接,这不好)。必须转义:
socat 才能接受 exec 命令:
- 术语1:
$ socat tcp-listen:12345,reuseaddr exec:'ssh user1@gateway exec socat - tcp\:devbox\:22',nofork
- 术语2:
$ ssh -p 12345 user2@localhost
- 术语1:
user1@gateway's password:
- 术语2:
user2@localhost's password:
反转第一个和第二个地址使套接字立即可用
socat
必须保持负责,所以不nofork
:
- 术语1:
$ socat exec:'ssh user1@gateway exec socat - tcp\:devbox\:22' tcp-listen:12345,reuseaddr user1@gateway's password:
- 术语2:
$ ssh -p 12345 user2@localhost user2@localhost's password:
用一个ControlMaster
SSH
A 允许在仅使用到网关的单个 SSH 连接时进行分叉,从而提供类似于通常端口转发的行为:
- 术语1:
$ ssh -N -o ControlMaster=yes -o ControlPath=~/mysshcontrolsocket user1@gateway user1@gateway's password:
- 术语2:
$ socat tcp-listen:12345,reuseaddr,fork exec:'ssh -o ControlPath=~/mysshcontrolsocket user1@gateway exec socat - tcp\:devbox\:22'
- 第3项:
$ ssh -p 12345 user2@localhost user2@localhost's password:
仅bash
且cat
可用gateway
通过使用bash
内置tcp重定向,和两个半双工cat
命令(用于全双工结果),甚至不需要远程socat
或netcat
.处理多层嵌套和转义引号有点尴尬,也许可以做得更好,或者通过使用远程bash
脚本来简化。必须注意分叉cat
仅用于输出:
- 第 1 项(无变化):
$ ssh -N -o ControlMaster=yes -o ControlPath=~/mysshcontrolsocket user1@gateway user1@gateway's password:
- 术语2:
$ socat tcp-listen:12345,reuseaddr,fork 'exec:ssh -T -o ControlPath=~/mysshcontrolsocket user1@gateway '\''exec bash -c \'\''"exec 2>/dev/null 8<>/dev/tcp/devbox/22; cat <&8 & cat >&8"\'\'\'
- 第3项:
$ ssh -p 12345 user2@localhost user2@localhost's password:
答案2
用 Bash 替换 ProxyJump
楼上的想法不错!这是我的通用 ssh_config 版本代理跳转不管用因为允许Tcp转发设置为 no,我的默认 shell 是 BASH:
ProxyCommand=ssh -T user1@gateway "exec 3<>/dev/tcp/%h/%p 2<&- ; cat <&3 & cat >&3 ; kill $!"
- -T禁用伪终端分配
- 执行不会创建新进程(bash)
- 3<>只是重定向到可用的文件描述符
- /dev/tcp/...会要求 bash 打开相应的 TCP 套接字。
- %H和%p将由您的 OpenSSH 客户端评估为开发盒和22 号
- 2<&-将关闭 STDERR (您也可以将其重定向到 /dev/null)
- 猫<&3&将在后台读取选定的文件描述符3
- 猫 >&3将在前台写入我们的文件描述符
- 杀掉$!会扼杀“阅读”猫 <&3当您关闭/断开连接时,命令在后台运行。否则它会继续运行。
当 ProxyJump 在跳转服务器上被禁用时,它可以代替我,但我真的不想在那里转发我的私钥或在没有额外加密级别的情况下输入任何密码。使用其他 SSH_AUTH_SOCK 作为 root 或通过击键完全记录终端会话都是真实的事情。
但请始终确保您不违反任何适用于您的政策!
答案3
哦不,我们差点忘了 Netcat!
如果您的跳转主机上有 Netcat(任何版本),您可以在配置中使用它而不是 ProxyJump,通常如下所示:
ProxyCommand=ssh -T user1@gateway "exec nc %h %p"
或者从命令行:
ssh user2@devbox -oProxyCommand="ssh -T user1@gateway 'exec nc devbox 22'"
答案4
我只是设置另一个 sshd 在不同的端口上运行。
编辑设置以允许 tcpforwarding。
cp /etc/ssh/sshd{,-second}_config
编辑 sshd-second_config
Port 22220
cp /usr/lib/systemd/system/sshd.service /etc/systemd/system/sshd-second.service
按以下方式更改 /etc/systemd/system/sshd-second.service:
Description=OpenSSH server second instance daemon
ExecStart=/usr/sbin/sshd -D -f /etc/ssh/sshd-second_config $OPTIONS
ExecStart 行可能会有所不同,具体取决于版本。
systemctl daemon-reload
systemctl enable sshd-second.service --now
更多信息可以在这里找到:
https://access.redhat.com/solutions/1166283
现在您应该可以转发您想要的任何内容。