1つのコマンドでBを介してマシンAにSSHで接続するにはどうすればよいですか?


103

私の大学のネットワークにあるコンピューターAにアクセスしたいのです。ただし、このコンピューターには大学の内部ネットワーク経由でのみアクセスできるため、自宅から直接このコンピューターにSSHを使用することはできません。

私が今やっていることは次のとおりです。

  1. 別の大学のマシンにログインします(マシンBと言います)

    (このマシンBは、自宅のコンピューターからSSH経由でアクセスできます。)

  2. BでSSHを使用してAに接続します。

もっと速くする方法はありますか?1つのsshコマンドのみを使用します。


回答:


97

はい、ProxyCommandSSH config で使用します。

ホームディレクトリにSSH構成ファイルを作成します(これをシステム全体に適用する場合を除く)~/.ssh/config

Host unibroker          # Machine B definition (the broker)
Hostname 12.34.45.56    # Change this IP address to the address of the broker
User myusername         # Change this default user accordingly 
                        # (`user@unibroker` can overwrite it)

Host internalmachine    # Machine A definition (the target host)
ProxyCommand ssh -q unibroker nc -q0 hostname.or.IP.address.internal.machine 22

これで、マシンAに直接アクセスできます。

ssh user@internalmachine

また、単一のSSHホストターゲット名を使用できるようになったことに注意してください。これは他のアプリケーションでも使用できます。例えば:

  • ファイルをコピーするSCP。

    scp somefile user@internalmachine:~/
    
  • GUIアプリケーションで:

    sftp://user@internalmachine/マシンで参照する場所として使用します。

    KDEベース(Dolphin):使用 fish://user@internalmachine/

ノート

マシンから移動する場合と同じようにhostname.or.IP.address.internal.machine、ポートとポート(22)を変更しますunibroker

unibrokerホストのnetcatバージョンに応じて、-q0オプションを省略する必要があります。認証に関して 基本的に、ワークステーションから2つのSSH接続をセットアップしています。これは、unibrokerホストとinternalmachineホストの両方が次々に検証/認証されることを意味します(キーペア/パスワードとホストキー検証の両方)。

説明

ProxyCommand「netcat」を使用するこのアプローチは、そのための1つの方法にすぎません。SSHクライアントはターゲットマシンと直接通信するため、クライアントからホストキーを確認でき、ブローカー上の別のキーを使用せずに公開キー認証を使用できるため、これが気に入っています。

それぞれHostが新しいホストセクションの開始を定義します。Hostnameそのホストのターゲットホスト名またはIPアドレスです。Userでユーザー部分として提供するものですssh user@hostname

ProxyCommandターゲットマシンへのパイプとして使用されます。最初のマシンにSSHを使用し、ncそこからターゲットに単純な 'netcat'()を直接設定することにより、これは基本的に、それらの間のブローカーから内部マシンに転送されるプレーンテキストです。-qオプションは、任意の出力(単に個人的な好み)を沈黙させるです。

ブローカーにnetcatがインストールされていることを確認してください(通常はUbuntuでデフォルトで使用可能)-netcat-openbsdnetcat-openbsdをインストールするまたはnetcat-traditionalのnetcat-traditionalをインストールするいずれか。

ここでは、暗号化を使用してSSHを2回使用していることに注意してください。netcatチャネルはプレーンテキストですが、PC上のSSHクライアントは最終的なターゲットマシンで別の暗号化されたチャネルを設定します。


4
-q0オプションは、使用しているマシンでサポートされていなかったため、削除する必要がありました。それ以外は、すべてうまくいきました。これは素晴らしいヒントです。どうもありがとうございます。:)
ジェリー

私が問題に遭遇した、あなたの答えは、端末からの私のために正常に動作しますが、私は、GUI SFTPを使用してそれを行うことができません、それは言う:未処理のエラーメッセージは、ログインしながら、タイムアウトになりました。
Vikash B

@VikashBまあ、それは本当に動作するはずです。特定の状況に対処するために、新しい質問を作成することを検討してください。
gertvdijk

私はここでやった質問です:askubuntu.com/questions/688567/...
Vikash B

1
@gertvdijkの賢明な言葉を補完するために、sshプロキシとジャンプホストのトピックに関するすばらしいwikibookがあり、貴重なリファレンスとして役立ちます。
トラビスクラーク

51

一度にホップ

私が他の回答で提供したProxyCommandアプローチの明らかな代替案は、ターゲットマシンに直接「ホッピング」することです。

ssh -t user@machineB ssh user@machineA

-t最初のsshコマンドに注意してください。それなしでは失敗します:

Pseudo-terminal will not be allocated because stdin is not a terminal.
ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
Permission denied, please try again.
[...]

実際のTTYを強制的に割り当てます

この欠点は、すべての構成、検証、および認証がマシンBで行われるようになったことです。これは、セキュリティ上の理由で私の状況では本当に好きではありません。私は自分のPC上のキーペアが好きで、自分のPCから最終的なターゲットマシンを認証および検証します。さらに、SSHにはインタラクティブシェルしか使用できないため、SCPやGUIファイルマネージャーのような他のツールを使用することはできません。

前述のすべての理由から、ProxyCommandアプローチを強くお勧めしますが、簡単に接続するにはこれで問題ありません


「ワンオフ」と永続的なソリューションの両方で1つの答えがありませんか?
おとなしそうな

5
@demureこれがStackExchangeサイトの仕組みです...参照:質問に2回答える際の公式のエチケットは何ですか?「2つの異なる回答を投稿する方が、1つの回答にするよりも良い」と述べています。。そして、私はこれが同じ解決策だとは思わない。私の意見では、このアプローチが永続的/一時的に異なることはありません。
gertvdijk

他のガイドでは、さらに-Aスイッチを使用するように言われていますが、これはセキュリティに影響があることを示しています。認証エージェント接続を転送すること、または転送しないことの意味を知っていますか?
ダイアゴン

@gertvdijkスーパー忍者はこちら!上位2つのソリューションがあります。私はそれを見たことがありません。超クール。N個のソリューションで1メガの長いソリューションを作成するよりもずっと良い方法です(これは通常私が見ているものです)。
トレバーボイドスミス

これは、他のsshを妨げる設定をセットアップするよりもはるかに便利です。
ニキルサフ

37

-Jコマンドラインオプションを使用できます:

ssh -J user@machineB user@machineA

からman ssh

-J [user@]host[:port]
     Connect to the target host by first making a ssh connection to
     the jump host and then establishing a TCP forwarding to the
     ultimate destination from there.  Multiple jump hops may be
     specified separated by comma characters.  This is a shortcut to
     specify a ProxyJump configuration directive.

OpenSSHバージョン7.3(2016年8月にリリース)で導入されました。Ubuntu 16.10以降で使用できます。


3
machineAのキーファイルを指定する必要がある場合でも機能するため、+ 1
悲嘆

1
+1、これはすべてのホストが十分に最近のOpenSSHバージョンを実行している場合、ProxyCommandの回答と比較してより良いバージョンです。
gertvdijk

この場合、OpenSSHサーバーはAマシンとBマシンの両方にインストールする必要がありますか?私は正しく理解していますか?
ミハイル

17

使用してみてください

Host <visible hostname alias>
        Controlmaster auto
        User <user>
        hostname <visible hostname>
        port <port>
        IdentityFile ~/.ssh/<id file>

Host <private LAN hostname alias>
     ProxyCommand ssh -q -W <private LAN hostname>:<private LAN port> <visible hostname alias>

〜/ .ssh / configで、コンピューターにあるキーのみを使用してすべてを一発で実行します。


1
これは、netcatをミックスに導入するよりもクリーンです。また、プライベートSSHキーもBマシン上に存在する必要はありません。
-danemacmillan

1

これは非常に役立つ提案です。何時間もぐちゃぐちゃにした後、私はこのメモを見つけ、文書化されたとおりにこれが機能することを確認しました。MachineAからMachineBにリモートmachineCから接続するには:

例:[xuser @ machineC〜] ssh -t MachineA ssh MachineB

「-t」は重要です。sshが存在しないと失敗します。最初にMachineAでパスワードを入力し、次にMachineBで2回入力するように求められます。また、3つのマシンすべてでユーザー「xuser」が定義されていることを前提としていることに注意してください。そうでない場合は、ssh構文「yuser @ MachineA ...」を使用します。また、必要に応じて、ドット付きクワッドraw IP#を使用できることに注意してください。これは、世界に公開されていないIPを使用しているプラ​​イベートローカルネットを介してリンクしている場合に役立ちます。ローカルホストファイルやDNSにはありません。MachineBからリモートmachineCにファイルを取得するには、MachineBからMachineAにscpし、次にMachineAからリモートmachineCにscpできます。(たとえば、リモートmachineCはMachineAをpingできますが、MachineBはできません。)警告:FedoraとWindowsXPでテストしました。MachineAはICS(インターネット接続共有)を実行するXP-boxです。MachineBとリモートmachineCはFedora-Linuxボックスです。この提案は私にとって重要な問題を解決しました-すなわち。リモートサイトLANへの制限され、監視されたリモートアクセス。また、MachineBから「ログアウト」すると、「xxx.xxx.xxx.xxxへの接続が閉じられました」という2つのメッセージが表示されます。メッセージ。


公開鍵認証を設定および構成する場合、パスワードの入力について心配する必要はありません。しかし-t、まだ必要です。
フェリペアルバレス

@FelipeAlvarezマシンBがAにパスワードなしでログインすることを信用していない場合、2番目のパスワードの入力を心配する必要があります。
マイケル

1

ProxyCommandは、両方のシステムでシェルアクセスを許可する場合のクリーンなソリューションです。リモートユーザーにブローカー(B)を介して内部マシン(A)にアクセスできるようにしたかったのですが、セキュリティを向上させるためにユーザーにBへのシェルアクセスを許可しませんでした。これはうまくいきました:

ログインシェルを交換する

ブローカーのログインシェル(を使用chsh)をextuser次のスクリプト(ファイルに保存)に置き換えます。

#!/bin/sh   # this is essential to avoid Exec format error
ssh internaluser@A

リモートユーザーの場合はextuser @ Bに、extuser @ Bの場合はinternaluser @ Aにパスワードログインが設定されていない場合、次のコマンドを実行すると、リモートユーザーが直接Aに移動します。

ssh extuser@B

ヒント:カスタムログインシェルに変更する前に、extuser @ Bに必要なパスワードなしのログインauthorized_keysセットアップを作成します。変更後、このアカウントはシェルを介してだれもアクセスできないため、sudoer @ Bのみがファイルを直接編集してauthorized_keysファイルを変更できます。

sudo vi ~extuser/.ssh/authorized_keys
sudo touch ~extuser/.hushlogin

最後の行は、Bからのログインバナーの表示を抑制することです。そのため、リモートユーザーはAに透過的にアクセスできます。


非常に興味深いアプローチ。ただし、これの主な欠点は次のとおりです。1)使用は標準のSSH使用に制限されます(SFTP / SCPサポートなし)。2)ユーザーは単一のもの以外の別のターゲットホストを選択できません(ログインシェルにハードコードされているため)3)ワークステーションから最終ターゲットホストへのホストキー検証は行えません(ブローカーSSHバイナリを使用しているため) 。4)ユーザーが最終ターゲットホストにアクセスするための秘密鍵は、ユーザーではなくブローカーにあります。これにより、管理者によるユーザーのなりすましが可能になります(通常は不可能です)。
gertvdijk

すべてのポイントが真実です。詳しく説明してくれてありがとう。ただし、主な目的は、信頼できるユーザーにBへのログインなしでAへのsshアクセスを提供することです。Bに信頼できるユーザーの公開鍵を追加できるのは(sudo、ログインなしで)管理者だけなので、これはユーザーが(管理者)extuser @ B(外部の信頼できるユーザーではない)の秘密キーへのアクセス、およびそもそもセットアップしました!
サンター

1

複数のジャンパーが必要だということです:)

最近、私はジャンパー1ジャンパー2と私の最終的なマシンでこの問題に遭遇しました、私のソル

ローカルスクリプト:

#!/bin/bash
sshpass -p jumper1Passwd ssh -t jumper1@jumper1IP ./Y00.sh

次に、最初のジャンパー(ルーター)に、Y00.shという名前のスクリプトを配置しました。

ssh -tt jumper2@jumper2 -i ~/.ssh/id_rsa sshpass -p finalPassWord ssh -tt final@final

これらをIPとパスワードに置き換えることができます。幸運を祈ります!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.