1. 序章

システムへのリモートアクセスはこれまで以上に一般的です。 ただし、プロトコルと環境の制限が異なるため、一般的なデータ共有とクリップボードのデータ共有は、クライアントマシンとサーバーマシンの間ですぐに利用できるとは限りません。

このチュートリアルでは、LinuxのリモートSSHセッションからローカルにデータを転送する方法について説明します。 まず、SSHとは何かとその使用方法を簡単に説明します。 次に、インタラクティブセッションと非インタラクティブセッションの出力をリダイレクトする方法について説明します。 最後に、クリップボードにリダイレクトする特定のケースで締めくくります。

このチュートリアルのコードは、GNU Bash5.1.4を使用したDebian11(Bullseye)でテストしました。 これはPOSIXに準拠しており、そのような環境で機能するはずです。

2. SSHプロトコル

Secure Shell (SSH)は、安全な情報転送のための暗号化ネットワークプロトコルです。

ここでは、SSHキーがすでに次のようになっていると想定します。

これは、デフォルトのキーアクセスがすぐに利用できることを意味し、ssh(Secure Shell)クライアントコマンドでの認証をスキップします。

認証が主要なハードルであり、キーアクセスが構成されているため、sshの使用は簡単になります。

3. SSHリモート実行モード

大まかに言えば、 ssh を使用して、1つ以上のコマンドを実行し、対話型セッションを終了または開始して、入力を待つことができます。 私たちのニーズでは、後者のシナリオはより複雑です。 両方について簡単に説明しましょう。

3.1. 相互の作用

インタラクティブSSHセッションモードでは、プロンプトでコマンドを入力しますが、それらはすべてリモートマシンで実行されます

$ hostname
personal.local
$ ssh x@baeldung.com
$ hostname
baeldung.com

ここでは、 hostname を使用して、現在のマシンのホスト名を出力します。 その後、サーバーbaeldung.comでユーザーxとのリモートインタラクティブSSHセッションに入ります。ここで、同じコマンドによって返されるホスト名がリモートシステムのホスト名であることを示します。

SSHプロトコルは、リモートマシンでデフォルトのシェルを実行するだけでこれを実現します。これにより、SSHセッション全体が引き継がれます。 この対話型セッションを終了すると、シェルと ssh クライアントプロセスが終了し、開始したターミナルに制御が戻ります。

3.2. 脚本

SSHプロトコルの多くの機能の1つは、リモートコマンドの実行です。

$ hostname
personal.local
$ ssh x@baeldung.com 'hostname'
baeldung.com

基本的に、 sshのインタラクティブ機能をスキップし、提供された1つまたは複数のコマンドを実行して、出力を返します。 コマンドが引数としてどのように提供されるかに注意してください。

両方の実行モードについて詳しく説明します。 非対話型スクリプトモードを続行しましょう。

4. 非対話型SSH出力リダイレクト

ssh は、入力と出力の点で他のLinuxコマンドと同じように動作するため、ストリームの1つをキャプチャすると、好きなように処理できます。

4.1. パイプSSH出力

他のストリームと同様に、ssh出力をパイプできます。

$ ssh x@baeldung.com 'ip address' | grep global
inet 10.0.6.66/24 brd 10.0.6.255 scope global eth0

ここでは、ipを介してリモートマシンのネットワーク情報を取得します。 続いて、これを grep (グローバル正規表現印刷)にパイプして、グローバルIPのみをフィルターで除外します。

もちろん、直接パイプなしでこの効果を達成することができます。

4.2. サブシェルでのSSH

実際、サブシェルを使用してSSHから返されるデータを取得できます。

$ REMOTE_HOSTNAME="$(ssh x@baeldung.com 'hostname')"
$ ping "${REMOTE_HOSTNAME}"
PING baeldung.com (203.0.113.66) 56(84) bytes of data.
64 bytes from 203.0.113.66 (203.0.113.66): icmp_seq=1 ttl=666 time=66.6 ms

まず、リモートホスト名をREMOTE_HOSTNAME変数に格納します。 その後、ホスト名を引数としてpingコマンドを使用します。

もちろん、これらのソリューションは、インタラクティブなssh環境で分離されたデータに対してをフィルタリングせずに役立つことはめったにありません。

5. インタラクティブSSH出力リダイレクト

SSHセッションからの完全な出力は、 ssh クライアントが終了した後にのみパイプに使用できるため、対話型セッションから現在のデータをすぐに取得するためのソリューションを考え出す必要があります。

5.1. ストリームの複製

完全なリダイレクトなしでstdoutからデータを取得する1つの方法は、teeコマンドです。

$ echo '-----' > stdout.txt
$ ssh x@baeldung.com | tee stdout.txt
$ hostname
baeldung.com
$ exit
$ cat stdout.txt
-----
$ hostname
baeldung.com
$ exit

まず、ファイル stdout.txt を作成し、5つのダッシュを入力します。 その後、SSHセッションを開始し、teeにパイプします。 teeがSSHセッション内のすべての情報を同時にstdoutとstdout.txtにリダイレクトする方法に注意してください。

もちろん、ここでの問題は、冗長性とフィルターの欠如です。 次に、いくつかのより詳細なアプローチを確認します。

5.2. Netcat

ライブSSHセッションから情報を抽出する別の方法は、それを送信することです。 セッションからクライアントに情報を転送するためにnc(Netcat)を使用できます。 このためには、最初にクライアント自体で別のサーバーを起動する必要があります。

$ nc -l -p 36661

-l フラグは、-pに続くポートでリスニングサーバーを起動します。 その後、別の端末で逆SSHトンネルセッションを確立します

$ ssh x@baeldung.com -R localhost:36660:localhost:36661

-R (リバーストンネル)フラグ引数を次のように読み取ります。リモートホストのポート 36660 へのデータを、ポート36661の現在のクライアントマシンにリダイレクトします。 。 これにより、SSHサーバー上の nc を介して、クライアントで開いたncサーバーにデータを送信できます。

$ echo "$(date)" | nc localhost 36660

ここでは、現在のdateをSSHサーバーであるlocalhostのポート36660に送信します。 ただし、この情報は、リバーストンネルのため、実際にはクライアントのポート36661に送信されます。

実際、 nc サーバーを使用してクライアント端末に戻ると、Netcatコマンドのすぐ下に現在の日付が表示されます。 大まかに言えば、このプロセスは、サーバーがデータを提供するために使用するクライアントへの逆接続を確立するだけです

同じことを達成するためのncの代替手段があります。 さらに、これから説明する他のオプションは、クリップボードへのアクセスという貴重なボーナス機能を提供します。

6. SSHクリップボード

SSHプロトコル標準はクリップボードメカニズムを指定していません。 ただし、ローカルで利用可能なのコピーと貼り付けには、利用可能なすべてのオプションを使用できることがよくあります。

たとえば、SSHセッションが開始されたGUIターミナルウィンドウからテキストを選択してコピーして貼り付けることができます。 または、以下のいずれかの方法を採用することもできます。

6.1. Xセレクション

コマンドラインからクリップボードに送信する場合は、xselまたはxclipコマンドを使用できます。

$ ssh x@baeldung.com 'hostname' | xsel --input
$ xsel --output
baeldung.com

基本的に、ssh出力をxselコマンドにパイプします。 重要なのは、Xサーバーがローカルで実行されていないとxselxclipなどのツールを使用できないことです。

一方、リモートX11の使用は、次の場合にのみxclipを介して可能です。

  • XServerをローカルマシンにインストールして実行します
  • X11Forwardingyes/etc / ssh /sshd_configに追加またはコメント解除します

xclip を使用するには、sshクライアントを-X(X11転送)フラグで起動します。

$ ssh -X x@baeldung.com
$ echo "$(date)" | xclip -i

xclip を使用してリモートマシンでデータ入力を取得した後、ローカルマシンで出力を使用できます。

$ xclip -o
Sun 10 Oct 2021 10:00:00 AM EST

重要なのは、このデータはSSHセッション中にのみ利用可能であり、の後では利用できないことです。

6.2. Netcatクリップボード

もちろん、上からNetcatソリューションを使用することもできますが、はxselにパイプします。

$ nc -l -p 36661 | xsel --input

ncサーバーで受信したデータはすべてクリップボードに直接送信され、クライアントのxselを介して復元できます。 ただし、このすべての機能を専用のパッケージに組み合わせたオプションは他にもあります。

6.3. レモネード

そのような代替手段の1つは、レモネードコマンドです。これは、次のことを可能にする単一のツールです。

  • クライアントでリスナーを開始します
  • SSHセッションからクライアントにデータを送信する
  • サーバーで事前定義されたアクションを実行する

実際、このツールはncとほとんど同じように使用します。 まず、ターミナルでレモネードサーバーを起動します。

$ lemonade start

この後、別の端末で、以前と同じようにサーバーにsshします。 唯一の変更点はリバーストンネルポートです。どちらも2489で、レモネードのデフォルトです。

$ ssh x@baeldung.com -R localhost:2489:localhost:2489

最後に、サーバーで lemonade を使用して、データをクライアントに送り返します。

$ echo "$(date)" | lemonade copy

重要なのは、 copyコマンドを使用してレモネードを作成し、SSHセッションデータをローカルのクリップボードに直接移動することです。 次に、このデータをグラフィカルインターフェイスだけでなく、クライアントのコマンドラインからも貼り付けることができます。

$ lemonade paste
Sun 10 Oct 2021 10:00:00 AM EST

ツールは、他のツールと同様に、サーバーとクライアントの両方にインストールする必要があることに注意してください。 さらに、レモネードには、クライアントでブラウザを開いたり、特定のURLにリダイレクトしたりするなど、他の便利な機能があります。

6.4. Clippy

clippyで上記のすべてを達成できます。 さらに、Clippyは、より多くのセキュリティと、ツールを使用してSSHセッションを直接開始する機能を実装しています。 これにより、リバーストンネル構成が容易になります。

$ clippy ssh x@baeldung.com
$ echo "$(date)" | clippy set

他の方法と同様に、クライアントの同じツールを介してデータを取得します。

$ clippy get
Sun 10 Oct 2021 10:10:00 AM EST

Clippyは、SSHのようにコマンドラインだけでなく、デスクトップでの任意のコマンドの実行もサポートしています。

7. 概要

このチュートリアルでは、サーバーへのSSHセッション後およびその間にデータをクライアントに戻す方法について説明しました。 インタラクティブおよび非インタラクティブのシナリオを検討しました。 最後に、ローカルクリップボードにデータを直接送信するオプションについても検討しました。

結論として、クライアントのクリップボードの場合でも、サーバーからクライアントにデータを送信する方法は複数ありますが、他の方法よりも簡単な方法もあります。