質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
公開鍵認証

公開鍵認証とは、公開鍵と秘密鍵の2つの鍵の組を利用する、SSHで利用される認証方式です。

SSH

SSH(Secure Shell)は、セキュアチャネルを通してデータを交換するためのネットワークプロトコルです。リモートサーバーへのコマンド実行やファイル転送を行う時に一般的に使用されます。

Q&A

解決済

2回答

7875閲覧

多段SSHでの公開鍵認証でのログインについて

ako

総合スコア15

公開鍵認証

公開鍵認証とは、公開鍵と秘密鍵の2つの鍵の組を利用する、SSHで利用される認証方式です。

SSH

SSH(Secure Shell)は、セキュアチャネルを通してデータを交換するためのネットワークプロトコルです。リモートサーバーへのコマンド実行やファイル転送を行う時に一般的に使用されます。

0グッド

1クリップ

投稿2016/09/02 09:02

###前提・実現したいこと
サーバBへのSSHログインを行う際に、必ずサーバAを踏み台にしてログインをするようなルールの基、設定を行っています。
ログインに使う鍵は、自端末で生成した公開鍵をサーバAに登録、サーバAで生成した公開鍵をサーバBに登録という状態になっています。
なので、多段SSHログインの際、サーバAへログインするための鍵は自端末に、サーバBへログインするための鍵はサーバAにあり、それぞれ利用したいです。
~/.ssh/configへの記述方法をご教授頂ければと思います。
###発生している問題・エラーメッセージ
サーバAへのログインまでは可能ですが、サーバA→サーバBの際に、ローカルの鍵を参照してしまいログインすることが出来ません。

ssh_exchange_identification: Connection closed by remote host

###試したこと
~/.ssh/configへの記述

Host hostA HostName xxx.xxx.xxx.x1 User myuser Identityfile ~/.ssh/keyA Host hostB HostName xxx.xxx.xxx.x2 User myuser Identityfile ~/.ssh/keyB ProxyCommand ssh hostA nc %h %p

さらに追記したものの、目的とは違う結果

Host hostA HostName xxx.xxx.xxx.x1 User myuser Identityfile ~/.ssh/keyA Host hostB HostName xxx.xxx.xxx.x2 User myuser Identityfile ~/.ssh/keyB ProxyCommand ssh -o 'ForwardAgent yes' HostA 'ssh-add && nc %h %p'

###補足情報(言語/FW/ツール等のバージョンなど)
自端末:OSX 10.11.6
サーバ:Amazon Linux 2016.03.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

クライアント:ssh → サーバB:sshd の場合、ssh コマンドが参照できる秘密鍵はクライアントに存在するもののみです。
サーバA をプロキシにしても同じです。

ForwardAgent は、クライアントの秘密鍵をサーバA (の ssh コマンド)で参照するためのもので、逆向きにはできないと思います。

一旦、サーバA にログインし、サーバA の ssh コマンドでサーバB にログインするしかないと思います。
サーバA の .bashrc や .ssh/authorized_keys の command="" を工夫すれば(例えばプロンプトを出してサーバB にログインするか、サーバA のシェルを起動するか選択)、少ない手間でサーバB にログインすることができると思います。

サーバB のインタラクティブシェルではなく、サーバB でリモートコマンドを実行したいということでしょうか?

(2016/09/03 23:51 追記)

「踏み台となるサーバAを意識せずに」とは言えないかもしれませんが、
サーバA の .ssh/authorized_keyscommand="ssh hostB" を設定することで、クライアントからサーバA に SSH でログインすると、サーバA で自動的に command が実行され、サーバB にログインできます。

ユーザが増えた場合、サーバA の .ssh/authorized_keys に公開鍵を登録します。

(サーバA: ~myuser/.ssh/authorized_keys に command="ssh hostB" を付けて公開鍵を登録) command="ssh hostB" ssh-rsa (ユーザ1 の公開鍵) command="ssh hostB" ssh-rsa (ユーザ2 の公開鍵) :

ただし、command を設定すると、サーバA のシェルにはアクセスできなくなるので、サーバA にログインするための別の鍵ペアを用意するか、サーバA に別のユーザを作成するといいと思います。

投稿2016/09/02 12:19

編集2016/09/03 14:51
TaichiYanagiya

総合スコア12141

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ako

2016/09/03 11:04

返事が遅くなり申し訳ありません。 >サーバB のインタラクティブシェルではなく、サーバB でリモートコマンドを実行したいということでしょうか? ごめんなさい、私の知識ではちょっとこの質問はよくわかりません。 やりたいことは、サーバAに置いてある鍵を使ってサーバBへsshログインしたい、ということです。 この時に、ログインするユーザは踏み台となるサーバAを意識せずに使えるようにしたかったのです。 .ssh/configの記述だけでは無理なのでしょうか。
TaichiYanagiya

2016/09/03 14:54

.ssh/authorized_keys の設定例を回答に追記しました。 「サーバB でリモートコマンドを実行」とは、クライアントから「ssh hostB ps aux」などとして、サーバB でコマンドを実行して終了する(サーバB にログインしない)ことです。
ako

2016/09/04 09:22

追記拝見いたしました。 ご丁寧にありがとうございます。 このcommandを用いる場合に、サーバBへのログインに使われるのはどの鍵になるのでしょうか? サーバAの.ssh/configへ予め記述しておくような方法になりますか? >サーバB のインタラクティブシェルではなく、サーバB でリモートコマンドを実行したいということでしょうか? こちらの説明もありがとうございました。 とても良くわかりました。
TaichiYanagiya

2016/09/04 12:15

> このcommandを用いる場合に、サーバBへのログインに使われるのはどの鍵になるのでしょうか? サーバA の .ssh/id_rsa (または id_dsa など)です。 秘密鍵ファイルを指定したい場合、command="ssh -i 秘密鍵ファイル hostB" とするか、.ssh/config で指定します。
ako

2016/09/05 06:26

なるほどですね、この方法も目的がわかりやすくていいですね。 こちらも試してみようと思います。 ご教授ありがとうございました。
guest

0

ベストアンサー

ssh を2段ログインしてから hostB で localhost からしかアクセスを許されない鍵(これはクライアントが持っている必要がある)で localhost に ssh ログインしてはどうでしょう?

  • 前提としてクライアント→hostA, および hostA→hostB はそれぞれ別の鍵で認証できている状態とします
  • hostB に nc をインストール
  • hostB の authorized_keys にクライアントが持っている鍵(hostA にログインしているものと同じでOK)の公開鍵を localhost からのアクセスのみに制限して追加(authorized_keys に from="localhost" ssh-rsa XXX...を追加)
  • .ssh/config の設定で2段ログインしてから nc を起動(config の hostB の設定にProxyCommand ssh hostA ssh hostB nc localhost 22を追加。このときの鍵は前項の鍵)

これでクライアントが持っている鍵だけで hostB にログインできてはいけないという要件を満たしていると思います。
一応、私の環境では成功しましたが、ログアウト時にKilled by signal 1.というメッセージが出てしまいます。使えなくはないと思いますが、いかがでしょうか?

投稿2016/09/02 10:40

編集2016/09/02 11:15
mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ako

2016/09/02 10:59

解答ありがとうございます。 方法の提案をしていただけたということは、私がやろうとしている、踏み台のサーバAには端末で作ったkeyAでログイン、目的のサーバBにはサーバAで作り置いてあるkeyBを使ってのログイン、という方法は不可能なのでしょうか? また、ご指示頂いた方法の場合、2段ログインしてからということは、サーバBにログイン後再度サーバBにログインする、のような挙動になりますでしょうか?
mit0223

2016/09/02 11:10

わかりにくくて、すみません。「踏み台のサーバAには端末で作ったkeyAでログイン、目的のサーバBにはサーバAで作り置いてあるkeyBを使ってのログイン」はできていると思います。ProxyCommand で Client->hostA, hostA->hostB, hostB->hostB の3回 sshでログインしてます。最後のhostB->hostB のログインは nc でその入出力がクライアントに転送されてきますので、実際には Clinet->hostB のログインとなります。hostB の sshd からみると、localhost からログインしているように見えるので、認証が通るということです。
mit0223

2016/09/02 11:31

ひょっとして、hostB にログインする鍵をクライアントから送らない理由が私が思ってるのと、違うのでしょうか?セキュリティ上の理由で hostB にログインする鍵をクライアントに保存することがNGだという要件だと思ったのですが。
ako

2016/09/02 11:40

今回ご提示頂いた方法なのですが、残念ながら2段目でkeyBが見つけられずにログインできない、という状態なので、「Client->hostA->hostB->hostB」この流れのhostA->hostBこの部分が実現できません。 単体でのhostA->hostBのログインは可能なのですが… リモートであるhostAに置いてあるkeyBを認証に使うのは不可能なのでしょうか?
ako

2016/09/02 11:42

>セキュリティ上の理由で hostB にログインする鍵をクライアントに保存することがNGだという要件だと思ったのですが。 こちらはおっしゃっている理由で合っております。
mit0223

2016/09/02 12:21

ProxyCommand ssh hostA ssh hostB nc localhost 22 なので、単体でログインできていれば、これも実行できるはずです。 ssh hostA の部分で hostA にログインしており、その hostA のシェルの中で ssh hostB を実行します。このとき、ログインに使用される鍵は hostA に保存されている鍵 keyB です。ako さんの試されたものは hostA のシェルの中で nc を起動しているので、ここのログインの鍵をクライアントから送る必要がありましたが、 nc ではなく ssh を起動しているので、hostA->hostB に hostA の ssh クライアントでログインしているわけです。 ここから、ちょっとしたトリックを使います。ProxyCommand は、実行したコマンドの標準入出力に対して、ssh クライアントとしてアクセスするというものですから、とにかく ssh にログインしないと気がすまないわけです。なので、nc を起動して、hostB の sshd への通信をクライアントに転送して、 ssh ログインを実行させています。で、その時の秘密鍵はクライアント側に保持している必要はありますが、hostB 側で localhost からしか使えないように制限しているので、安全というロジックです。
ako

2016/09/02 13:36

ご丁寧にありがとうございます。 遅い時間になってしまったので、取り急ぎ返信だけさせていただきます。 明日試してみてからまた改めて返事をさせて頂きます。
ako

2016/09/03 11:09

返事が遅くなりまして申し訳ありません。 今試してみたところ、hostAに置いてある鍵を利用してhostBへログインできたことが確認できました。 ちょっと質問がズレてしまうのですが、ログインできるユーザを増やす場合、authorized_keysの編集はhostAだけでなく、hostBの方も必要になりますか? hostAに置いてある鍵を使うのであれば、hostBの編集は必要無さそうですが >で、その時の秘密鍵はクライアント側に保持している必要はありますが、 この部分で引っかかるような気がしております。 ちょっと試してみようと思います。
mit0223

2016/09/03 12:45

ずれたほうの質問について、hostBへのログインに用いる keyB は複数のユーザで共有しているという前提でよろしいでしょうか? そうであれば、最後の鍵について、回答では「hostA にログインしているものと同じでOK」と書きましたが、この鍵の管理についてちゃんと考えないといけません。ログインできるユーザを増やす場合にユーザごとに鍵を増やす必要があるかというと、その必要はありません。そもそも hostB->hostB へのログインにしか利用できないようにする運用ポリシーですので、単なる乱数と捉えても良いと思います。つまり、この鍵自身は秘密にする必要はなく、トリックに用いる鍵であると捉えるほうが良いと思います。 ですので、おすすめは hostA のログインに用いる鍵とは別にトリック用の鍵として用意し、複数ユーザに配布してもよいという運用ポリシーにすれば良いと思います。
ako

2016/09/04 09:28

結論としては、hostA、hostBにログインするための鍵自体、クライアント側に置いてある必要があるということですね。 mit0223さんにご提案いただいた方法でまずは進めてみようと思います。 非常に勉強になりました。どうもありがとうございました。 またよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問