10 分で入門する SSH(中級編)
こんにちわ、krkettleです
この記事では多段 SSH、ポートフォワードなどの SSH の中級者向けの内容について紹介します
前提条件
- macOS 、OpenSSH(8.1p1)で稼働確認をしています
- キーペアは ECDSA を利用して作成しています(鍵のパスを適宜読み変えてください)
- SSH で使われている技術(公開鍵認証・電子署名など)は説明しません
- こちらについては以下の記事をご参照下さい krkettle.hatenablog.com
- キーペア作成やワンライナーでの SSH 接続は説明しません
- こちらについては以下の記事をご参照下さい krkettle.hatenablog.com
プロキシを経由する
社内ルール等でプロキシを経由する必要がある場合は以下のように設定します
※Linux や Windows では設定が異なる場合があります
認証がない場合
Host remote (中略) ProxyCommand nc -X connect -x [proxy-ip]:[proxy-port] %h %p
- proxy-ip: プロキシの IP アドレス
- proxy-port: プロキシのポート番号
認証がある場合
Host remote (中略) ProxyCommand env CONNECT_USER=[proxy-user] CONNECT_PASSWORD=[proxy-pass] connect -H [proxy-ip]:[proxy-port] %h %p
- proxy-user: プロキシ認証のユーザ名
- proxy-pass: プロキシ認証のパスワード
多段 SSH
SSH 接続先で直接対象のサーバに接続するのではなく
踏み台サーバを経由することがあると思います
ローカル → 踏み台 → 目的のサーバで 2 回 SSH コマンドを打つことなく
1 回の ssh コマンドでローカルから目的のサーバに接続する設定をします
Host bastion (略) Host remote (中略) ProxyCommand ssh -CW %h:%p bastion
# 一回のコマンドでOK
ssh remote
言われてみれば当然ですが、踏み台サーバに秘密鍵をおく必要があります
ただ、踏み台サーバに重要なデータ(秘密鍵など)を置いておくのは好ましくないです
これはssh-agentを利用することで回避可能です
ssh-agent
ssh-agent を使うと以下のメリットがあります
ssh-agent 実行の流れ
ssh-agent を起動する
eval `ssh-agent`
ssh-add -K ~/.ssh/id_ecdsa Enter passphrase for ~/.ssh/id_ecdsa: # パスワードを入力してください
# remote-user: アクセス先のユーザ名 # server-ip: アクセス先の(グローバル)IPアドレス # -A: 認証情報の転送機能を有効化 ssh -A [remote-user]@[remote-ip]
ssh-agent を終了する
# ※SSH接続が終わった後に実行 eval `ssh-agent -k`
~/.ssh/config で 転送機能を有効化
~/.ssh/config でForwardAgent
を設定しておけば
転送機能の引数(-A
)を省略できます
Host remote (中略) FowardAgent yes
ssh remote
ssh-agent を自動終了する
ssh-agent を利用した後に毎回明示的に終了するのは面倒ですが
~/.zlogout に記述しておくことで、これを回避することができます
echo "$(which ssh-agent) -k" >> ~/.zlogout
ssh ポートフォワーディング
SSH 接続先で開いているポートをローカルで開きたい場合があります
Juypter Notebookを簡単な例にとってみましょう
Jupyter Notebook の具体例
Jupyter Notebook はブラウザで Python などのプログラムを実行したり、
分析結果を可視化できるツールで、以下のような手順で利用します
- Jupyter Notebook を起動する
- ブラウザを起動し、localhost の指定のポート番号にアクセスする
しかし、SSH 接続先で Jupyter Notebook を起動した場合はどうでしょうか
こんな時に役立つ機能が ssh ポートフォワーディングです
ssh ポートフォワーディングとは
今回はローカルフォワードについてのみ設定方法を紹介します
ローカルフォワード
ローカルフォワードの流れは以下の通りです
# local-port: ローカルからアクセスするポート番号 # target-ip: 目的サーバのIPアドレス or ドメイン名 # target-port: 目的サーバのポート番号 ssh -L [local-port]:[target-ip]:[target-port] [remote-user]@[remote-ip]
ローカルのポートにアクセスする
(Chrome などのブラウザからでも、ターミナルから curl でも OK)
ここで注意事項があります
リモートマシン(remote)と目的のサーバ(target)は必ずしも別である必要はありません
(remote と target が同じ場合はtarget-ip
の部分にlocalhost
を設定すれば OK です)
~/.ssh/config で ローカルフォワードを有効化
~/.ssh/config でLocalForward
を設定しておけば
ローカルフォワードの引数(-L
)を省略できます
※LocalForward は複数設定できるため、複数組のポートに対して設定可能です
Host remote (中略) LocalForward 8080 localhost:8888
ssh remote
上記の例では、ローカルの 8080 番ポートにアクセスすることで、 リモートマシン(remote)の 8888 番ポートにアクセスできます
具体例
これまでの内容を元に~/.ssh/config の具体例を紹介します
構成図と各種設定は以下の通りです
ServerAliveInterval 60 Host bastion HostName bastion-ip User sample-user Port 50022 ProxyCommand env CONNECT_USER=sample-user CONNECT_PASSWORD=password connect -H proxy-ip:proxy-port %h %p ForwardAgent yes Host remote HostName remote-ip User sample-user Port 50022 ProxyCommand ssh -CW %h:%p bastion LocalForwad 8080 localhost:8888
※今回の例では踏み台 - リモートマシン間が SSH 接続の必要があるため、 LocalForawrd では remote 内で localhost を利用しました
echo "$(which ssh-agent) -k" >> ~/.zlogout eval `ssh-agent` ssh-add -K ~/.ssh/id_ecdsa ssh remote