将本地端口或者套接字文件转发到远程套接字文件

分享于 

7分钟阅读

互联网

  繁體 雙語

问题:

快速问题- 我运行两个linux框架,一个我自己的桌面和另一个我的fram 。 出于安全方面的原因,我选择了套接字连接到 MySQL ( /var/run/mysqld/mysql.sock ) 。 我知道我可以这样隧道: ssh -L 3307:127.0.0.1:3306 user@site.com 如果我设置远程 SQL Server 来侦听某个端口,但我想知道的是,我可以执行以下操作: ssh -L/path/to/myremotesqlserver.sock:/var/run/mysqld/mysql.sock 因此,隧道两个插座,而不是两个端口?

一个完美可以接受的解决方案也是将本地端口转发到远程套接字文件,但是我不能在远程框中运行tcp服务器。

( 当然,我知道tcp会更容易) 。


回答 1:

按需转发本地套接字
  • 设置 SSH public 密钥身份验证
  • 在两端安装 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域套接字。


回答 2:

当时的Altough,当问题被问到时,它真的不可以能,但是现在是可以能的。

你可以同时使用 UNIX=> TCP和 UNIX=> UNIX转发。

例如:


ssh 


 -R/var/run/mysql.sock:/var/run/mysql.sock 


 -R127.0.0.1:3306:/var/run/mysql.sock 


 somehost



这是可能的,因为 OpenSSH 6.7.


回答 3:

我没有这么做,但我会尝试使用 socat 。 可能是这样的:


ssh xxx@yyy.zzz -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:

不需要更多 socat,因为 ssh 6.7. 你可以直接转发unix域套接字,如下所示:


ssh -nNT -L $(pwd)/docker.sock:/var/run/docker.sock user@someremote



更多信息:https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab160


回答 5:

对javier的回答,这适用于我:

ssh -f xxx@yyy.zzz -L 9999:localhost:9999"socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock"

你需要 fork 以便能够在关闭第一个连接的情况下连接多次而不使用 socat 。 另外,socat允许你指定一个地址绑定到 bind 选项,而不是端口之前的地址。

之后,你就可以正常地连接到 localhost:9999 。 然后拆除隧道:

ssh -f xxx@yyy.zzz"killall socat"

( 或者类似的,你可以做更详细的事情,涉及保持socat的PID )


回答 6:

是,你可以使用 socat 。

首先使用SSH进行TCP隧道。 然后使用 socat:

socat unix-listen:/var/run/mysqld/mysqld.sock,fork,unlink-early tcp: 127.0.0.1: 3306

然后给新创建的套接字授予权限( chmod 777可能)


回答 7:

对 @mpontes'/@javier's 回答的另一


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


'



优点

  • 比 6.7早于 openssh ( 像 CentOS 7 )
  • 在ssh终止时杀死 socat,而不是将 Having 终止到远程服务器
  • 允许非公共ssh登录( 与ijk解决方案不同)
  • 功能

  • 由于没有使用 -f 选项,可以使用 public 键并在后台运行,或者使用 & 登录,使用Ctrl+Z交互并使用相同的$ 存储 pid 。!
  • 缺点

  • 由于你将丢失ssh的pid,因此无法轻松使用 -f ssh选项。 这里方法依赖于在前景中运行和Ctrl+C终止。
  • 复杂得多
  • 说明

    • socat.. .& - 在远程服务器的后台运行 socat
    • pid=$ - 存储 pid!
    • trap kill $pid 0 - 在bash终止时运行 kill $pid
    • while :; sleep... - 坐在无限循环中
    • echo -ne b - echo 空格后跟退格符。 ssh断开连接后就会失败。 使用 sleep 5,这意味着 socat 在ssh之后可以运行 5秒

    注意:实际上是使用 Docker 。端口 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
    
    
    
    

    你可以在 .ssh/config 文件中保存 -o 选项,也可以使用 -S ( 但是你仍然需要 -o ControlMaster )



文件  for  LOC  soc  Local  socket