問題ID:30502 (β版:9464) SSHポートフォワーディングについて
- フォーラムは新サイトへ移行しました。
- このフォーラムではゲスト投稿が禁止されています
cofffeeemilk
投稿数: 3
SSHポートフォワーディングのコマンド書式についてです。本問の解説では
ssh -L 転送対象ポート番号:SSHサーバから見た接続先アドレス:SSHサーバからの接続先ポート番号 [SSH接続ユーザー名@]SSHサーバアドレス
となっていますが、正しい書式は
ssh -L 転送対象ポート番号:SSHサーバアドレス:SSHサーバからの接続先ポート番号 [SSH接続ユーザー名@]SSHサーバアドレス
ではないでしょうか。Ping-tの書式はオプションが-Rのものと混ざっていると思われます。
あずき本およびRed Hat社(https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/s2-ssh-beyondshell-tcpip)で確認しました。もし私の指摘が間違っていたらどなたかご教授願います。
ssh -L 転送対象ポート番号:SSHサーバから見た接続先アドレス:SSHサーバからの接続先ポート番号 [SSH接続ユーザー名@]SSHサーバアドレス
となっていますが、正しい書式は
ssh -L 転送対象ポート番号:SSHサーバアドレス:SSHサーバからの接続先ポート番号 [SSH接続ユーザー名@]SSHサーバアドレス
ではないでしょうか。Ping-tの書式はオプションが-Rのものと混ざっていると思われます。
あずき本およびRed Hat社(https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/s2-ssh-beyondshell-tcpip)で確認しました。もし私の指摘が間違っていたらどなたかご教授願います。
quensan
投稿数: 119
引用:最初の「SSHサーバアドレス」には転送先のアドレスが入るのではないでしょうか。
なので、「SSHサーバから見た接続先アドレス(SSHサーバから見た転送先アドレス?)」
で間違いないと思います。
となっていますが、正しい書式は
ssh -L 転送対象ポート番号:SSHサーバアドレス:SSHサーバからの接続先ポート番号 [SSH接続ユーザー名@]SSHサーバアドレス
なので、「SSHサーバから見た接続先アドレス(SSHサーバから見た転送先アドレス?)」
で間違いないと思います。
arashi1977
居住地: 広島
投稿数: 1715
同じ問題番号でのスレッドがありましたが、こちらは参考になるでしょうか?
https://ping-t.com/modules/forum/index.php?topic_id=4406
https://ping-t.com/modules/forum/index.php?topic_id=4406
cofffeeemilk
投稿数: 3
>SSHサーバから見た接続先アドレス
多段式ポートフォワーディングだとそうなりますね。
しかしこの問題では【SSHサーバ(アドレス:ssh-server)内のデータベースサービス(ポート番号:3306)に接続する】ですので、ゴール地点はSSHサーバになるかと思われます。
参考にした外部サイト
https://www.netassist.ne.jp/blog/?p=354
書式:ssh -L [転送元IP]:[転送元ポート]:[転送先IP]:[転送先ポート] [踏み台IP]
転送元IPアドレスは省略可能で、省略したら<127.0.0.1>が補完される
転送先IPアドレスがつまりはゴールを指すのだとしたら、選択肢としてlocalhostになるのは元の場所に戻ってきてしまうのでトンネルにならないと思います。
転送先IPアドレスがローカルホストになる例は-Rでないと起こり得ないと思うのですが、どこか参考になるサイトなどございますかね?
多段式ポートフォワーディングだとそうなりますね。
しかしこの問題では【SSHサーバ(アドレス:ssh-server)内のデータベースサービス(ポート番号:3306)に接続する】ですので、ゴール地点はSSHサーバになるかと思われます。
参考にした外部サイト
https://www.netassist.ne.jp/blog/?p=354
書式:ssh -L [転送元IP]:[転送元ポート]:[転送先IP]:[転送先ポート] [踏み台IP]
転送元IPアドレスは省略可能で、省略したら<127.0.0.1>が補完される
転送先IPアドレスがつまりはゴールを指すのだとしたら、選択肢としてlocalhostになるのは元の場所に戻ってきてしまうのでトンネルにならないと思います。
転送先IPアドレスがローカルホストになる例は-Rでないと起こり得ないと思うのですが、どこか参考になるサイトなどございますかね?
cofffeeemilk
投稿数: 3
>arashi1977 さん
ここでの一番のポイントは
- ssh-serverはlocalhost(127.0.0.1)ではない
- localhostは127.0.0.1であって、外部からは接続できない
- ssh-serverから見たssh-serverがサーバ内を示すとは限らない
ということです。
ssh-serverから見たlocalhostだからといって、localhostがssh-serverだとは言えないということです。
ssh-serverからssh-serverを見たときサーバ内を示すとは限らない
この部分が引っかかります。自分自身のホスト名やIPアドレスがわかっているのに自分の中にトンネルを作れないことになりますよね。ssh-serverから見たlocalhostがssh-serverになるのなら、なおさらssh-serverから見たssh-serverが自分自身のことだとわかりそうなものですが…。
ここでの一番のポイントは
- ssh-serverはlocalhost(127.0.0.1)ではない
- localhostは127.0.0.1であって、外部からは接続できない
- ssh-serverから見たssh-serverがサーバ内を示すとは限らない
ということです。
ssh-serverから見たlocalhostだからといって、localhostがssh-serverだとは言えないということです。
ssh-serverからssh-serverを見たときサーバ内を示すとは限らない
この部分が引っかかります。自分自身のホスト名やIPアドレスがわかっているのに自分の中にトンネルを作れないことになりますよね。ssh-serverから見たlocalhostがssh-serverになるのなら、なおさらssh-serverから見たssh-serverが自分自身のことだとわかりそうなものですが…。
Re: 問題ID:30502 (β版:9464) SSHポートフォワーディングについて
msg# 1.4.1
arashi1977
居住地: 広島
投稿数: 1715
引用:実験してみたらわかりますよ。
細かい説明するのが大変なので、アドレス割当やマシン同士を疎通可能にするのは cofffeeemilk さんにおまかせしますが、こういうやり方をすれば確認できます。
1. お互いSSHを含む、疎通可能な環境を用意
2. サーバ側(ここでいう ssh-server に相当)にnc(netcat)をインストールして使えるようにする。
3. サーバ側の/etc/hostsを編集し、DNSによらず名前解決できるようにする。その際に以下のように設定する。
4. ping などで、名前解決の結果を確認する。以下は私の環境での例です。
5. サーバ側で以下のコマンドを実行し、「localhostの8888番ポート」で待ち受けるサーバを用意する。
6. クライアント(ポートフォワーディングの接続元)で、以下のようにして別々のトンネルを作成する。
7. (何でもいいですが、わかりやすいので)curl localhost:18888 として、ssh-server側のコンソールやcurlの結果になにか表示されるかを確認する。もしプロンプトが返ってこなければCtrl-Cなどで終了させる。
8. 同様に、curl localhost:28888 として、ssh-server側のコンソールやcurlの結果になにか表示されるかを確認する。もしプロンプトが返ってこなければCtrl-Cなどで終了させる。
長い…書くの疲れる…
ssh-serverからssh-serverを見たときサーバ内を示すとは限らない
この部分が引っかかります。自分自身のホスト名やIPアドレスがわかっているのに自分の中にトンネルを作れないことになりますよね。ssh-serverから見たlocalhostがssh-serverになるのなら、なおさらssh-serverから見たssh-serverが自分自身のことだとわかりそうなものですが…。
細かい説明するのが大変なので、アドレス割当やマシン同士を疎通可能にするのは cofffeeemilk さんにおまかせしますが、こういうやり方をすれば確認できます。
1. お互いSSHを含む、疎通可能な環境を用意
2. サーバ側(ここでいう ssh-server に相当)にnc(netcat)をインストールして使えるようにする。
3. サーバ側の/etc/hostsを編集し、DNSによらず名前解決できるようにする。その際に以下のように設定する。
127.0.0.1 localhost
{相手と疎通可能なIPアドレス} ssh-server
[staff@centos7 ~]$ ping -c 1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data. ← localhost は 127.0.0.1
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.026 ms
--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.026/0.026/0.026/0.000 ms
[staff@centos7 ~]$ ping -c 1 ssh-server
PING ssh-server (172.16.97.145) 56(84) bytes of data. ← ssh-server は localhost とは違うアドレス
64 bytes from ssh-server (172.16.97.145): icmp_seq=1 ttl=64 time=0.025 ms
--- ssh-server ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.025/0.025/0.025/0.000 ms
$ nc -4 -k -l localhost 8888 &
$ ssh -L 18888:localhost:8888 user@ssh-server
$ ssh -L 28888:ssh-server:8888 user@ssh-server
8. 同様に、curl localhost:28888 として、ssh-server側のコンソールやcurlの結果になにか表示されるかを確認する。もしプロンプトが返ってこなければCtrl-Cなどで終了させる。
長い…書くの疲れる…
hanajiro
投稿数: 49
"ssh -L 3306:ssh-server:3306 user@ssh-server"が誤答になっていますが、ssh-serverでホスト名"ssh-server"が名前解決できたらトンネル経由の通信になるのではないでしょうか?
<手順>
1. ssh-serverの/etc/hostsに以下のエントリを追記。
<ssh-serverのIPアドレス> ssh-server
2. クライアントで"ssh -L 3306:ssh-server:3306 user@ssh-server"を実行。
3. ssh-serverで"nc -l 3306"を実行。
4. 別の端末を使い、クライアントで"nc localhost 3306"を実行。(同じ端末でsshで戻ってきてもOKだけど、ウチではクソ重たかったので…)
5. クライアントで文字入力すると、ssh-serverで入力した文字が表示される。
tcpdumpを仕掛けながら文字入力を実行すると、<クライアント:任意のポート>⇔<ssh-server:22>の通信が成立している。
※"ssh -L 3306:localhost:3306 user@ssh-server"や"ssh -L 3306:<ssh-serverのIPアドレス>:3306 user@ssh-server"のでも上記各種結果が同じでした。
※そもそもその挙動がおかしいよ、ということでしたら、ツッコミお願いします(ncで文字が出力されたらいけない、など)。。。
<手順>
1. ssh-serverの/etc/hostsに以下のエントリを追記。
<ssh-serverのIPアドレス> ssh-server
2. クライアントで"ssh -L 3306:ssh-server:3306 user@ssh-server"を実行。
3. ssh-serverで"nc -l 3306"を実行。
4. 別の端末を使い、クライアントで"nc localhost 3306"を実行。(同じ端末でsshで戻ってきてもOKだけど、ウチではクソ重たかったので…)
5. クライアントで文字入力すると、ssh-serverで入力した文字が表示される。
tcpdumpを仕掛けながら文字入力を実行すると、<クライアント:任意のポート>⇔<ssh-server:22>の通信が成立している。
※"ssh -L 3306:localhost:3306 user@ssh-server"や"ssh -L 3306:<ssh-serverのIPアドレス>:3306 user@ssh-server"のでも上記各種結果が同じでした。
※そもそもその挙動がおかしいよ、ということでしたら、ツッコミお願いします(ncで文字が出力されたらいけない、など)。。。
arashi1977
居住地: 広島
投稿数: 1715
引用:設問の話として
引用:がありますよね。つまり、設問的には「トンネルを経由してssh-serverにssh接続し、localhost:3306で待ち受けるサービスに接続する」という状況です。
で、hanajiroさんの手順の
引用:って、どういうアドレスを入れて解決させる想定なのでしょうか?127.0.0.1ではなく、別のアドレスを使う想定でしょうか?
/etc/hostsに書くアドレス次第かもしれませんが、「ssh-server上でssh-server:3306で待ち受けるサービス」に接続するということは、「データベースサービスをポート3306で外部に公開している」という状況に、設問の環境を変えている(設問の意図を捻じ曲げている)ようにも見受けられます。
それと追加で、これは運用次第だと思いますが「自ホストの名前をhostsファイルに書いて名前解決の結果をいじる」のを許容するかどうかという点も気になります。
で、私の見解としてですが。
設問で「/etc/hostsを修正しても良い」のような記述が無いのであれば、「こうやればできるよね?」という環境の改変は禁じ手です。そういうのを前提に問題に向き合うのは避けたほうがいいです。
(自動車免許の実技試験でポールにあたってしまったときに、外に出て勝手にポールを移動させて「ボディに触れていないからセーフ」は通じないですよね )
※そもそもその挙動がおかしいよ、ということでしたら、ツッコミお願いします(ncで文字が出力されたらいけない、など)。。。
引用:
SSHサーバ(アドレス:ssh-server)内のデータベースサービス(ポート番号:3306)に接続するように
で、hanajiroさんの手順の
引用:
1. ssh-serverの/etc/hostsに以下のエントリを追記。
<ssh-serverのIPアドレス> ssh-server
/etc/hostsに書くアドレス次第かもしれませんが、「ssh-server上でssh-server:3306で待ち受けるサービス」に接続するということは、「データベースサービスをポート3306で外部に公開している」という状況に、設問の環境を変えている(設問の意図を捻じ曲げている)ようにも見受けられます。
それと追加で、これは運用次第だと思いますが「自ホストの名前をhostsファイルに書いて名前解決の結果をいじる」のを許容するかどうかという点も気になります。
で、私の見解としてですが。
設問で「/etc/hostsを修正しても良い」のような記述が無いのであれば、「こうやればできるよね?」という環境の改変は禁じ手です。そういうのを前提に問題に向き合うのは避けたほうがいいです。
(自動車免許の実技試験でポールにあたってしまったときに、外に出て勝手にポールを移動させて「ボディに触れていないからセーフ」は通じないですよね )
hanajiro
投稿数: 49
hostsは単にDNSの環境整えるのがめんどくさかっただけです。
「そもそもこのlocalhostのところって、どこから見てのどこで名前解決してるの?」という疑問から検証し結果を出したわけですし、問題文では判らない環境状況次第で正答が複数出てくるなら、問題の時点で制限をかけるか、複数解答にするか、単一解答なら明らかな誤答にするべきかと(問題ID:9792のように)思います。(まぁでも本番はこんな感じくらいでしか出題されないだろうなぁとは思う)。
「そもそもこのlocalhostのところって、どこから見てのどこで名前解決してるの?」という疑問から検証し結果を出したわけですし、問題文では判らない環境状況次第で正答が複数出てくるなら、問題の時点で制限をかけるか、複数解答にするか、単一解答なら明らかな誤答にするべきかと(問題ID:9792のように)思います。(まぁでも本番はこんな感じくらいでしか出題されないだろうなぁとは思う)。
hanajiro
投稿数: 49
制限というか条件が足りないという点の追記ですが:
>つまり、設問的には「トンネルを経由してssh-serverにssh接続し、localhost:3306で待ち受けるサービスに接続する」という状況です。
この問題文「SSHサーバ(アドレス:ssh-server)内のデータベースサービス(ポート番号:3306)…」だけでは、ssh-serverでlsofすると"localhost:3306 (LISTEN)"となっている状態だとはわかりませんが…むしろ
>「データベースサービスをポート3306で外部に公開している」という状況
にある(lsofすると"*:3306 (LISTEN)"となっている状態にある)と考える方が割と自然ではないでしょうか。サーバープログラムだし、外部に晒してナンボのものかと。
ただDB(ポート番号からするとMySQL?)運用では外部に晒すのは禁じ手でlocalhostでのみLISTENしろという常識みたいのがあれば問題文の状況下は推定できるのでしょうが、その認識の有無までは問われていないとは思います(仮にあったとしても試験の範囲外かと)。
名前解決のところ(と、localhostやホスト名の代わりにIPアドレスを書いたところ)は、あずき本や上記のRed Hatの解説ページが何故FQDNで書いているのかの裏付けを取ったものでもあります。
最大公約数的にlocalhostの方のみが正答というのもわからないわけでもないですが、条件を設けず可能性があるならホスト名の方も正答にしてもいいかと思います(それかホスト名の方を明らかな誤答になるよう内容を変えるとか)。
>つまり、設問的には「トンネルを経由してssh-serverにssh接続し、localhost:3306で待ち受けるサービスに接続する」という状況です。
この問題文「SSHサーバ(アドレス:ssh-server)内のデータベースサービス(ポート番号:3306)…」だけでは、ssh-serverでlsofすると"localhost:3306 (LISTEN)"となっている状態だとはわかりませんが…むしろ
>「データベースサービスをポート3306で外部に公開している」という状況
にある(lsofすると"*:3306 (LISTEN)"となっている状態にある)と考える方が割と自然ではないでしょうか。サーバープログラムだし、外部に晒してナンボのものかと。
ただDB(ポート番号からするとMySQL?)運用では外部に晒すのは禁じ手でlocalhostでのみLISTENしろという常識みたいのがあれば問題文の状況下は推定できるのでしょうが、その認識の有無までは問われていないとは思います(仮にあったとしても試験の範囲外かと)。
名前解決のところ(と、localhostやホスト名の代わりにIPアドレスを書いたところ)は、あずき本や上記のRed Hatの解説ページが何故FQDNで書いているのかの裏付けを取ったものでもあります。
最大公約数的にlocalhostの方のみが正答というのもわからないわけでもないですが、条件を設けず可能性があるならホスト名の方も正答にしてもいいかと思います(それかホスト名の方を明らかな誤答になるよう内容を変えるとか)。