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


24

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

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

(そして、はい、tcpの方が簡単だとわかっています)。


mySQLボックスでTCPを使用したくない理由がセキュリティの懸念(リモート攻撃など)である場合はもちろんファイアウォールを使用できます。それでも十分でない場合は、mySQLに127.0.0.1のみをリッスンさせますTCP接続の場合、SSHを簡単にトンネリングできます。そうでない場合は、以下のsocatソリューションをサポートします。
マティアスアンバーグ

lwn.net/Articles/609321 OpenSSH 6.7はソケット転送をもたらします
Hubbitus

@Hubbitusは現在、この機能を利用できますが、利用可能な場合、回答例を提供できますか?
CMCDragonkai

そのコメントは回答形式でしたが、誰かによってコメントに変換されました。そして今、あなたはすでに以下の答えを提案しています。
ハビタス

回答:


35

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

  • 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

UNIXドメインソケットをsshとsocatで転送することから盗まれた


これは素晴らしいことであり、受け入れられた答えであるはずです。
ジョンスミスオプション

32

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

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


1
上記を使用してローカルソケットをリモートサーバーソケットに転送し、リモートでdocker clientを実行しました(sshで直接実行できますが、その面白さはどこにありますか)ssh -L /home/user/docker.sock:/var/run/docker.sock dockerhost -N
-sdkks

11

私はこれをやっていませんが、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

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


私はそれを試してみて、それがどうなるかをお知らせします。私はtcpベースの実装を使用しています。

現時点では機能させることはできませんが、とにかく+1するため、私は気に入っています。修正したらお知らせします。

+1は便利なユーティリティのようです。
ワーナー

5

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-e6567cfab160


また、これは別のユーザーとしてローカルソケットに接続するのにも役立ちます。これにより、特定のユーザーID(独自のジョブランナーからの接続)を切断するサーバープロセスに対してクライアントプログラムを実行できます。
ウォーボ

sshdを使用してアクセスを認証する同じマシンにソケットを別のユーザーによって制御されている別のディレクトリに転送しますか?あなたのユースケースは何ですか?
CMCDragonkai

ディレクトリのアクセス許可/アクセスは問題ありません。むしろ、特定のデーモンは、特定のグループのユーザーによって行われた接続試行をドロップします(初心者が混乱しないようにするため)。sshを使用すると、それらのユーザーは、そのグループに属していないユーザーのように(トンネルソケットを介して)接続できるため、切断されません。
ウォーボ

面白い、おかしい、nix-daemonの意味、私はそれに関する問題も扱っています。なぜnix-daemonが特定のグループのユーザーへの接続をドロップしているのだろうか?これはセキュリティ設定の問題ですか?または関連:nixos.org/nix/manual/#idm140737318362784
CMCDragonkai

コミットメッセージによると「偶発的な」使用を防ぐためです。私はそれを育て、ここで
Warbo

2

@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. -fsshのpidを失うと、sshオプションを簡単に使用できません。このメソッドは、フォアグラウンドで実行し、Ctrl + Cで強制終了します。
  2. はるかに複雑

説明

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

注:実際にドッキングウィンドウ、ポート使用してテスト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


Dockerコンテナー内のスクリプトを使用して、コードを他のホストにデプロイしています。接続ロジックは素晴らしいですが、bashセッションが終了すると終了します。これにより、docker run ... connect.shトンネルのセットアップを呼び出すためにmyが呼び出されなくなりますdocker run ... deploy.sh。私が試したnohup&disown彼らは壊れているように見えるsocat閉じることstdoutとトリガkill。このケースをサポートするための微調整のアイデアはありますか(つまり、SSHが非難を乗り越えても生き残る)。
クレイトン

OK。これは実際には端末で(w / -fおよび& disown)正常に動作します。どうやら、問題はスクリプト「ラッパー」によって作成されているようです。入力を歓迎しますが、現在、より適切なQ&Aを検討しています。
クレイトン

@claytondあなたが何をしているのか正確にはわかりませんが、はい、コンテナのpid 1が終了すると、他のすべてのコマンドが終了します。 「if $ 1(コマンド)== deploay then」と表示される画像は、sshコマンドを実行し、deployコマンドを実行してから終了し、ssh接続を閉じます。またdocker run ... connect.sh、およびdocker exec {container name/id} deploy.shを使用して、一緒に遊ぶこともできます。
アンディ

あなたが正しい。私は実際にexec既にrunコンテナで使用していますが、exec終了後にSSHパイプが持続しませんでした。スクリプトの実行方法に問題があることが原因であることを明確にしました。呼び出しを独自のスクリプトに移動して呼び出した場合nohup <script.sh> & disown、の完了後も存続しexecます。
クレイトンド

1

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

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を保持することを含むより精巧なことをすることができます)


1

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

最初にSSHでTCPトンネルを実行します。次に、次のようにsocatを使用します。

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

次に、新しく作成されたソケットに許可を与えます(chmod 777の場合があります)


これはOpenSSH 6.6以降で可能です。
ysdx

3
chmod 777: いやいやいやいやいや!決して実行しませんchmod 777。それは実際には必要ありません!「テスト目的」でもありません。ファイルが読み取り可能な場合、読み取り可能です。userまたは書き込みgroupが必要なユーザーによって書き込み可能な場合は、書き込み可能です。すべての人に書き込み許可を与える必要は絶対にありchmodません。正気なものに戻すのを忘れることは、まさに多国籍企業がハッキングされる方法です。しないでください。今まで。Unixの許可の概要を書きまし。読んでください!
マーティントゥルノイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.