◆ すでに ssh 接続してるときに 接続元 PC とファイルやりとりしたい
◆ 接続後に接続元へポートフォワードできる
◆ でも結局 scp で接続元と通信することになる
◆ Windows のクライアントだと Windows に sshd ないから接続できない
◆ 多段で ssh 接続してると一番の接続元へのポートフォワードになってる 

ssh で接続中に接続先の PC にあるファイルを接続元コピーしたいことってありますよね

ssh で接続してるんだからお手軽に接続元と接続先でファイル共有できてもいいと思うのですけど そんな機能はないみたい

コピーするには

(1) 接続元から別の接続で scp する
(2) 接続先から接続元に scp する

このどちらかになります

接続してる状態でファイルを確認したり作成したりして その流れでコピーしたいのに別の接続はあまり作りたくないです
タブやウィンドウを使って 今の接続を維持できたとしても気が進みません

なので 接続先から接続元に scp が一番の妥協策 になるのですが これにも問題があります
接続元の IP がわからなかったり ルータの挟んでて接続元の PC へ直接アクセスできないこともあります

ポートフォワード

いい方法ないかとググってみると 同じことをしたいっていう質問がありました
回答ではポートフォワードを使っていました

IP わからなくても ssh 接続先のポートを ssh 接続元のポートに転送することができるようです

これを使って 「接続先 2222 --> 接続元 22」ポートフォワードすれば  接続先で localhost:2222 に scp でコピーしたら 接続元にコピー出来ます

ssh エスケープシーケンス

ポートフォワードの設定ですが 回答には 「~C」 で ssh コマンドラインに入れると書いてるのですが さっぱり意味がわかりませんでした

「~C」 コマンドを実行してももちろんそんなコマンドないよ ってエラー
「ssh ~C」 なんてコマンドうってみても同じく

聞いたことのない機能だったのでぐぐるとこんなページがありました
https://lonesysadmin.net/2011/11/08/ssh-escape-sequences-aka-kill-dead-ssh-sessions/

C 以外にもいろいろあるみたい
だけどやっぱり使い方が


そのあと適当に入力してるとなんとか ssh コマンドラインに入れました

使い方は

「~C を押すだけ」

本当にこれでした
それ以外に言いようがないです

C のあとにエンターキーも押さないのでシェルに入力するコマンドとも別物です

「~」 を打っても画面に何も出ない状態だとちゃんと入力できています
一度何か入力してバックスペースしていたりするとダメで Enter でリセットしてから入力すると入力できるはずです


~ から始めると特殊な意味だと
~/bin/xxxxx

みたいにホームディレクトリのファイルを実行するときに気づいたりしそうなのに と思ってやってみると

「~/」 と入力したら 「~/」 と入力されていました
認識されないものだと通常入力になるようです
m.saki@fedora ~> ~?
Supported escape sequences:
~.   - terminate connection (and any multiplexed sessions)
~B   - send a BREAK to the remote system
~C   - open a command line
~R   - request rekey
~V/v - decrease/increase verbosity (LogLevel)
~^Z  - suspend ssh
~#   - list forwarded connections
~&   - background ssh (when waiting for connections to terminate)
~?   - this message
~~   - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)

ポートフォワード設定はこんなコマンドです
m.saki@fedora ~>
ssh> ?
Commands:
      -L[bind_address:]port:host:hostport    Request local forward
      -R[bind_address:]port:host:hostport    Request remote forward
      -D[bind_address:]port                  Request dynamic forward
      -KL[bind_address:]port                 Cancel local forward
      -KR[bind_address:]port                 Cancel remote forward
      -KD[bind_address:]port                 Cancel dynamic forward

コピーしてみる

korora の user から cent の root にログインして fish shell の設定ファイルをコピーしてみます

まずはログイン
[user@korora testdir]$ ssh root@cent
The authenticity of host 'cent (192.168.1.106)' can't be established.
ECDSA key fingerprint is SHA256:~~~.
ECDSA key fingerprint is MD5:~~~.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'cent,192.168.1.106' (ECDSA) to the list of known hosts.
root@cent's password:
Last login: Fri Apr 21 11:32:17 2017 from 192.168.1.109
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
ファイルを探します
root@cent ~# ls /etc/fish
conf.d/  config.fish
root@cent ~# ls /etc/fish/conf.d/
root@cent ~# cat /etc/fish/config.fish
# Put system-wide fish configuration entries here
# or in .fish files in conf.d/
# Files in conf.d can be overridden by the user
# by files with the same name in $XDG_CONFIG_HOME/fish/conf.d

# This file is run by all fish instances.
# To include configuration only for login shells, use
# if status --is-login
#    ...
# end
# To include configuration only for interactive shells, use
# if status --is-interactiv
#   ...
# end
コピーするファイルが決まったのでポートフォワードの設定
root@cent ~#
root@cent ~#
ssh> -R 2222:localhost:22
Forwarding port.
localhost:2222 にコピーします
root@cent ~# scp -P2222 /etc/fish/config.fish user@localhost:
The authenticity of host '[localhost]:2222 ([::1]:2222)' can't be established.
ECDSA key fingerprint is ~~~.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:2222' (ECDSA) to the list of known hosts.
user@localhost's password:
config.fish                                                  100%  428     0.4KB/s   00:00
接続を終了してファイルを確認します
root@cent ~# exit

Connection to cent closed.
[user@korora testdir]$ cat ~/config.fish
# Put system-wide fish configuration entries here
# or in .fish files in conf.d/
# Files in conf.d can be overridden by the user
# by files with the same name in $XDG_CONFIG_HOME/fish/conf.d

# This file is run by all fish instances.
# To include configuration only for login shells, use
# if status --is-login
#    ...
# end
# To include configuration only for interactive shells, use
# if status --is-interactiv
#   ...
# end

ちゃんとコピーできてますね


-R 2222:localhost:22

とコマンド入力してましたが
「2222」 が接続先の PC のポートです
「localhost」 がどこにフォワードするかで localhost と自分自身を指定すれば接続元からみた自分自身 つまり接続元になります
「22」 が 「localhost」 で指定した PC のどのポートにフォワードするかです

これで 接続先で 2222 ポートに通信すると接続元の 22 と通信してることになります

注意

接続元に sshd が必要

今回いつもの fedora じゃなくて korora と centos 使いました
というのもこの PC では fedora は サーバ用のインストールで Windows の msys2 から ssh で使う用なんです

この方法は接続先から直接接続元にコピーできるわけではなく 接続元の ssh を通して scp でコピーします
msys2 だと接続元は Windows なので sshd がありません

Windows で sshd サービスを使うことも出来るようですが このためにわざわざ準備したくはないです
なので Linux から Linux の接続のときに使うものということになります(Mac なんて知らない

多段 ssh だと両端がフォワード対象

Windows へのコピーは諦めて fedora から centos に接続して centos のファイルを fedora にコピーしようとしました

ですが 変わらずうまくいきません
エラーも Windows に繋ごうとしてるときと同じです

そのときの ssh は msys2 --> fedora --> centos です

centos にいるときに接続元へのフォワードなら fedora:22 になると思ったのですが 多段で ssh してると一番最初の接続元の msys2 (Windows) にフォワードされてるようです

ssh_exchange_identification

なので GUI 付きでインストールしてる korora から fedora に接続したのですがポートフォワード経由で fedora から korora に接続すると

ssh_exchange_identification: Connection closed by remote host

とエラーでした

allow も deny も空なので いまいち原因がわかってないのですが 直接 fedora --> korora で接続したことあるのに fedora:2222 でも同じ korora への接続になるので known_hosts でおかしいと判断されたのかな……?

そういうわけで初接続になる korora --> centos でやると無事コピーできました

まとめ

便利   なはずだけどけっこう制限あるし多段接続で途中のものにコピーできないしで あんまり頻繁には使わないかも