按需求转发本地套接字

按需求转发本地套接字

快速提问 - 我运行两个 Linux 机器,一个是我自己的台式机,另一个是我的 VPS。出于 VPS 端的安全原因,我选择了套接字连接到 MySQL ( /var/run/mysqld/mysql.sock)。我知道我可以像这样建立隧道:如果我设置远程 SQL 服务器来监听某个端口,但我想知道的是,我是否可以这样做:从而建立两个套接字的隧道,而不是两个端口?ssh -L 3307:127.0.0.1:3306 [email protected]ssh -L /path/to/myremotesqlserver.sock:/var/run/mysqld/mysql.sock

一个完全可以接受的解决方案是将本地端口转发到远程套接字文件,但在可能的情况下,我尝试不在远程设备上运行 tcp 服务器。

(是的,我知道 tcp 会更容易)。

答案1

尽管在提出这个问题的时候,这确实是不可能的,但现在已经有可能了。

您可以同时使用:UNIX=>TCPUNIX=>UNIX转发。

例如(LOCAL PORT TO REMOTE)

ssh \
  -R /var/run/mysql.sock:/var/run/mysql.sock \
  -R 127.0.0.1:3306:/var/run/mysql.sock \
  somehost

例如(REMOTE PORT TO LOCAL)

ssh \
  -L /var/run/mysql.sock:/var/run/mysql.sock \
  -L 127.0.0.1:3306:/var/run/mysql.sock \
  somehost

注意-R-L

从 OpenSSH 6.7 开始这是可能的。

答案2

按需求转发本地套接字

  • 设置 SSH 公钥认证
  • socat两端安装
  • 为您的套接字在本地创建一个目录,其他用户无法访问。
export SOCKET_DIR=~/.remote-sockets
mkdir -p $SOCKET_DIR
socat "UNIX-LISTEN:$SOCKET_DIR/mysqld.sock,reuseaddr,fork" \
EXEC:'ssh user@server socat STDIO UNIX-CONNECT\:/var/run/mysqld/mysqld.sock'

然后

mysql -S $SOCKET_DIR/mysqld.sock -u mysqluser -p

被盗使用 ssh 和 socat 转发 unix 域套接字

答案3

我还没有这样做过,但我会尝试索卡特. 也许是这样的:

ssh [email protected] -L 9999:localhost:9999 "socat TCP-LISTEN:localhost:9999 UNIX-CONNECT:/var/run/mysqld/mysql.sock"
socat UNIX-LISTEN:/path/to/local/socket TCP:localhost:9999

再说一遍,我从来没有做过这样的事。

答案4

@mpontes'/@javier 的答案的另一个修改是

ssh user@remoteserver -L 9999:localhost:9999 'socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock& pid=$!; trap "kill $pid" 0; while echo -ne " \b"; do sleep 5; done'

清洁工

ssh user@remoteserver -L 9999:localhost:9999 '
  socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock&
  pid=$!
  trap "kill $pid" 0
  while echo -ne " \b"; do
    sleep 5
  done
'

优点

  1. 适用于 6.7 之前的 openssh(例如 CentOS 7)
  2. 在 ssh 终止时杀死 socat,而不必重新 ssh 到远程服务器
  3. 允许非公开 ssh 登录(与 ijk 解决方案不同)

特征

  1. 由于-f未使用该选项,您可以使用公钥并通过在后台运行,&或者您可以以交互方式登录并使用 Ctrl+Z 并使用相同的方式$!存储 pid。

缺点

  1. 无法轻松使用-fssh 选项,因为这样您将丢失 ssh 的 pid。此方法依赖于在前台运行并按 Ctrl+C 终止。
  2. 更加复杂

解释

  • socat ...&- 在远程服务器后台运行 socat
  • pid=$!- 存储 pid
  • trap kill\ $pid 0-kill $pid在 bash 终止时运行
  • while :; sleep...- 陷入无限循环
  • echo -ne \ \b- 回显空格,然后回显退格键。一旦 ssh 断开连接,此操作就会失败。使用sleep 5,这意味着socat可以在 ssh 之后运行最多 5 秒

笔记:实际上已经使用 docker、port 2375/var/run/docker.sock和环境变量进行了测试DOCKER_HOST='tcp://localhost:2375',但对于 mysql 应该同样有效

更新

使用SSH 控制,你可以-f按照我的方式使用该标志,只需添加以下标志

-f -o ControlPath=~/.ssh/%C -o ControlMaster=auto

你会得到

ssh -f -o ControlPath=~/.ssh/%C -o ControlMaster=auto user@remoteserver -L 9999:localhost:9999 'set -m; socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock& pid=$!; trap "kill $pid" 0; while echo -ne " \b"; do sleep 5; done'

现在你可以使用以下命令终止所有受控会话

ssh -o ControlPath=~/.ssh/%C -O exit remoteserver

这些-o选项可以保存在你的.ssh/config文件中,或者你可以使用 -S (但你仍然需要-o ControlMaster

相关内容