web-dev-qa-db-ja.com

ローカルポートまたはソケットファイルをリモートソケットファイルに転送します

簡単な質問-私は2つのLinuxボックスを実行しています。1つは自分のデスクトップ、もう1つは私のVPSです。 VPS側のセキュリティ上の理由から、MySQL(_/var/run/mysqld/mysql.sock_)へのソケット接続を選択しました。私は次のようにトンネリングできることを知っています:_ssh -L 3307:127.0.0.1:3306 [email protected]_いくつかのポートでリッスンするようにリモートSQLサーバーを設定した場合、知りたいのは次のようなことです:_ssh -L /path/to/myremotesqlserver.sock:/var/run/mysqld/mysql.sock_これにより2つのソケットをトンネリングし、 2つのポートとは対照的に?

完全に受け入れられる解決策は、ローカルポートをリモートソケットファイルに転送することですが、可能であれば、リモートボックスでtcpサーバーを実行しないようにしています。

(そしてはい、私はtcpがより簡単であることを知っています)。

25
user32616

当時は質問されたとき、それは本当に不可能でしたが、今日では可能です。

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以降で可能です。

36
Igor Chubin

オンデマンドでローカルソケットを転送する

  • 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ドメインソケットの転送 から盗まれた

35
ijk

私はこれをしていませんが、 socat で試します。おそらく次のようなもの:

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

繰り返しますが、私はこのようなことをしたことがありません。

11
Javier

Ssh 6.7以降、socatは必要ありません。 UNIXドメインソケットは次のように直接転送できます。

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

詳細: https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab16

5
CMCDragonkai

@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する必要はなく、sshの終了時にsocatを強制終了します
  3. 非公開のsshログインを許可します(ijkソリューションとは異なります)

特徴

  1. -fオプションが使用されていないため、公開鍵を使用して&経由でバックグラウンドで実行するか、インタラクティブにログインしてCtrl + Zを使用して同じ$!を使用できます。 pidを保存します。

短所

  1. -f sshオプションを簡単に使用することはできません。sshのpidがそのように失われるためです。このメソッドは、フォアグラウンドでの実行とCtrl + Cによる強制終了に依存しています。
  2. はるかに複雑

説明

  • socat ...&-リモートサーバーでバックグラウンドでsocatを実行します
  • pid=$!-pidを保存します
  • trap kill\ $pid 0-bashの終了時にkill $pidを実行します
  • while :; sleep...-無限ループに座ります
  • echo -ne \ \b-エコースペースの後にバックスペースが続きます。これは、sshが切断されるとすぐに失敗します。 sleep 5の場合、これはsocatがssh後最大5秒実行できることを意味します

注:実際にdocker、ポート2375/var/run/docker.sock、および環境変数DOCKER_Host='tcp://localhost:2375'を使用してテストされていますが、機能するはずです。 mysqlの場合はすべて同じ

更新

SSH Controls を使用すると、私の方法で-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は引き続き必要です)

2
Andy

はい、socatを使用できます。

最初にTCP SSHでトンネルを作成します。次にsocatを次のように使用します:

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

次に、新しく作成されたソケットにアクセス許可を与えます(chmod 777は可能性があります)

1
user190133

ハビエルの答えを詳しく説明すると、これは私にとってはうまくいきます:

ssh -f [email protected] -L 9999:localhost:9999 "socat TCP-LISTEN:9999,fork,bind=localhost UNIX-CONNECT:/var/run/mysqld/mysql.sock"

最初の接続を閉じるとsocatが停止することなく複数回接続できるようにするには、forkが必要です。また、socatがバインドするアドレスを指定する方法は、ポートの前のアドレスとしてではなく、bindオプションを使用することです。

この後、通常どおりlocalhost:9999に接続します。次に、トンネルを分解する:

ssh -f [email protected] "killall socat"

(または類似の何か、socatのPIDを維持することを含むより複雑なことを行うことができます)

1
mpontes