ブラウザからデバイスの管理画面にアクセスできる程度にsshの-Lオプションを理解する

SSHは基本的にはCLIベースですが、人類はCLIだけでなくGUIで設定したいもの。

あらゆるデバイスが多機能化してきた現代では、GUIのデバイス管理画面がないとやってられません。
そこで、はるか遠くの端末側から見えているネットワーク上においてアクセス可能なWEBページを、手元にある端末のブラウザで開くことができたら便利です。 

**ブラウザを開くためだけにオフィスに行くのは、ラーメンを作るためにメンマ用の竹を探しに行くようなものです[^1]**


はるか昔、SSHの`-L`オプションを使えば、それが実現できると聞きましたが、難しそうなので避けていました。
しかし、避けられない時が来た場合、なるべく効率よく脳にインストールする必要があります。
**今回は手を動かしながら`-L`オプションを最低限理解することにしました。**

# 教訓まとめ

```:パラメータ
ssh -L port:host:hostport user@ip
```

- `port`は8888など指定すれば`localhost:8888`の形式でブラウザからアクセスできる
- `host`はリモートから見て接続したいホストを入れる
- `hostport`はリモートから見て接続したいホストが決めているポート番号を入れる
    - 接続したいホストの製造元が公表しているポート番号を事前に調べること
    - 安直にウェルノウンポートを入れても接続できるとは限らない！



# manページから方針を立てる

とりあえず、困った時の伝家の宝刀`man`を開きましょう。

```:terminal
man ssh
```
## パラメータから使い方を類推する

`-L`オプションに渡すべきargを眺めてみましょう。

```:Args
     -L [bind_address:]port:host:hostport
     -L [bind_address:]port:remote_socket
     -L local_socket:host:hostport
     -L local_socket:remote_socket
```


うん、**なんか多くてよくわからない**ということがわかりました。（＝無知の知）
選択肢が多い場合、頭がオーバーフローするので、一旦優先順位をつけていきましょう。

## 優先順位をつけて仮説を立てる

- `port`,`host`,`hostport`は何となく意味がわかります。
- `bind_address`は`[]`で囲まれているのでOptionalなことがわかるので、とりあえず無視しましょう。

- 私はソケットのことは詳しくないので、`local_socket`,`remote_socket`はよくわかりませんが、３、４番目なので優先順位は低いということで、一旦無視します。

ということで、当面は以下の形式で所望の動作が実現できるだろうと仮説を立てました。
これを後ほど検証していきましょう。

```
-L port:host:hostport
```


ネットで`-L`オプションの具体的な例を調べて、観察することとしましょう。

ここで、名前はその存在意義を表すので、助けになるかもしれません。
どうやら、`-L`というのはLocal Forwardingという概念を指すようです。


https://qiita.com/mechamogera/items/b1bb9130273deb9426f5

**今までポートフォワーディングについて学ぶことは避けていましたが、`-L`オプションのためには必須であることがわかりました。** その中でも、Local Forwardingということを行うということがわかりました。

# いざ、試行錯誤

安直な試行錯誤から学びはあるものです。

```:とりあえず実験
-L port:host:hostport user@ip
```

試しに`localhost:port`にブラウザからアクセスしてみると、`ERR_CONNECTION_RESET`となりひらけません。

まあ、安直な試行だから当たり前だよね、と思いつつ、
sshのターミナルを見てみると、お、なんかエラーを吐いています。やった！

```
channel 3: open failed: connect failed: Temporary failure in name resolution
```

ホスト名`host`を変えていなかったことに気付いたので、ここを適切なホスト名を指定してみる。
具体的には、リモートからアクセスしたいホストのIPを入れるとブラウザから`localhost:port`にアクセス試行した時の、ターミナルのエラーは消えました。

これらからは以下が学べました：

- `port`には、ブラウザでは`localhost:{port}`と打ち込めばアクセスできうる

- ここでの`host`は、リモート側から名前が解決される


とはいうものの、ブラウザは「アクセスできません」と高らかに叫んできます。

## ポート番号に注意 - 正しいポート番号で「ホグワーツ特急に乗る」


`port`, `host`はおそらくこのままで大丈夫そうなので、次は`hostport`に注目してみました。
とりあえず、`HTTP:80`を試していたのですが、うまくいきませんでした。
ウェルノウンポートの`HTTPS:443`などを利用してみるが、依然うまくいきません。

これはもしかして、ポートが全然違うのか？頭をよぎりました。



ハリーポッターでホグワーツ特急に乗るのには、9と4分の3番線プラットフォームに入らないといけません。
具体的には、9番目と10番目の線の壁に突撃する必要があります。

しかし、何の当てもなく適当な番線の壁にカートで壁に突撃していたらどうなるでしょう？

**ホグワーツに向かう前に、病院送りになってしまします。。**
**それと同じようなことをTCPプロトコル上で私はやってしまっていたのです。。。**

そこで、管理画面にアクセスするデバイスのポート番号を公式サイトから調べたところ、やはり80でも443でもありませんでした。しっかり固有のポート番号が振られていました。

ここで教訓です：

- 管理画面にアクセスしたいデバイスのポート番号は、固有な場合があるので、ポート番号を公式サイトから調べる

# 教訓まとめ

```:パラメータ
ssh -L port:host:hostport user@ip
```

- `port`は8888など指定すれば`localhost:8888`の形式でブラウザからアクセスできる
- `host`はリモートから見て接続したいホストを入れる
- `hostport`はリモートから見て接続したいホストが決めているポート番号を入れる
    - 接続したいホストの製造元が公表しているポート番号を事前に調べること
    - 安直にウェルノウンポートを入れても接続できるとは限らない！


以上です。


# メタ教訓まとめ

情報量が多すぎてわからないときは、

- `man`ページなどを開いてみて方針を立てる
- 実際にコマンドを適当に実行してみる
- 何らかの仮説を立てて検証していく
- その都度、エラーに対処しながら必要な知識を身につける

というプロセスが効率が良いということは、今回も当てはまったようです。

それでは、素晴らしいリモートライフを！

[^1]: テレビ番組の鉄腕DASHでは、ラーメンを作るために、メンマを竹から作っています。これは、予算や時間が潤沢にある場合は問題ないですが、通常の場合は費用対効果の観点から、現実的ではないでしょう。 https://www.ntv.co.jp/dash/tetsuwan_new/past/2015/1018/02/