快速提问 - 我运行两个 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
=>TCP
和UNIX
=>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
答案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
'
优点
- 适用于 6.7 之前的 openssh(例如 CentOS 7)
- 在 ssh 终止时杀死 socat,而不必重新 ssh 到远程服务器
- 允许非公开 ssh 登录(与 ijk 解决方案不同)
特征
- 由于
-f
未使用该选项,您可以使用公钥并通过在后台运行,&
或者您可以以交互方式登录并使用 Ctrl+Z 并使用相同的方式$!
存储 pid。
缺点
- 无法轻松使用
-f
ssh 选项,因为这样您将丢失 ssh 的 pid。此方法依赖于在前台运行并按 Ctrl+C 终止。 - 更加复杂
解释
socat ...&
- 在远程服务器后台运行 socatpid=$!
- 存储 pidtrap 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
)