ssh 活用

dynamic port forwarding

ssh -D 1080 remotehost とか,~/.ssh/config に

Host remotehost
DynamicForward 1080

と書いて ssh remotehost すると,1080番ポートで SOCKS プロキシサーバを立てられる.
firefox のような SOCKS プロキシに対応したソフトウェアなら,localhost:1080 を SOCKS プロキシとして設定すれば,remotehost からアクセスしているように振舞える.


活用方法としては例えば研究室内からしかアクセスできないページがあるとき,ssh -D 1080 研究室 してプロキシを通せばアクセスできるようになる.
あるいは普通は用意されたプロキシを通じないと外へアクセスできないけど ssh なら素通りできるような場合,ssh -D 1080 自宅 してこれを通してアクセスするようにすると幸せになれたりする.


SOCKS プロキシに対応したソフトウェアは少なく,wget なんかでも使えない.
そういうときは tsocks が使える.LD_PRELOAD で一部関数を上書きしていいかんじにやってくれる.
tsocks - Transparent SOCKS Proxying Library
tsocks の他に socksify というのもあるらしい.


DynamicForward の他に LocalForward や RemoteForward といった port forwarding がある.

ProxyCommand

hostA には外側からアクセスできるけど hostB には内側からしかアクセスできない状態で,外側から hostB にアクセスしたい場合.
ssh hostA の後に ssh hostB すれば可能だけど

  • わざわざ2回 ssh する必要がある
  • hostA と hostB の間にも鍵が必要

といった面倒さがある.


こういうときは ~/.ssh/config に

Host hostB
HostName hostB
ProxyCommand ssh hostA nc %h %p

と設定しておくと,ssh hostB で hostA を踏み台にして hostB に繋げるようになる.
ssh の他に nc が必要になるが,おそらくほとんどの環境で使えると思う*1
HostName に設定した hostB は hostA からでないと解決できないような名前でも問題ない.
鍵による認証は localhost <-> hostA 間と localhost <-> hostB 間で行われる.

セッションを共有

~/.ssh/config に

ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

とか設定しておくと,UNIX socket が作られて同一サーバへのセッションが共有されるようになる.
複数 ssh するときにログインが不要になるので早くなる.
また scp とかするときに zsh は引数を補完するたびにリモートにアクセスしてしまうので,一定時間内の ssh 要求をセキュリティ等の目的で制限しているとその制限にひっかかり悲しい思いをする,というようなことを防ぐ効果もあったりする.

切断

ssh 上で ~. と入力すると接続を切ることができる.
ネットワークの不調で ssh が止まったり,うっかり大量に端末に出力するコマンドを実行してしまったとき等に有効.
この ~ は escape character であり,設定で変えたり無効化したりもできる.

sftp

リモートとのファイルのやりとりは scp や rsync なんかも使えるが,インタラクティブにやるときは sftp が便利.
ftp と同じように cd とか ls とか get とか put とかできる.


他に sshfs で mount するという手もある.それなりに高速な回線環境ならシームレスにリモートのファイルを扱える.

現在の俺の ~/.ssh/config はだいたいこんなかんじになってる.
設定がうまく反映されないなーというときは ssh -v の出力を眺めたりする.
~/.ssh/config に書いた設定は ssh コマンドだけでなく,scp や sftp,git を ssh 経由で利用するとき等にも適用される.
その他様々な設定は man 5 ssh_config に.

# 自宅
Host srv1 srv1-proxy
HostName srv1.example.net
User eagletmt

# VirtualBox 内にある FreeBSD に ssh freebsd でも入れるようにしたりとか
Host freebsd
HostName 192.168.56.101
User eagletmt

# 外から見えるサーバ
Host srv3 srv3-proxy
HostName srv3.example.com
User eagletmt

# srv3 経由でしか入れないサーバ.srv2 という名前は srv3 で解決される.
Host srv2
HostName srv2
User eagletmt
ProxyCommand ssh srv3 nc %h %p

# ssh なんちゃら-proxy としたときには DynamicForward 1080 するように
Host *-proxy
DynamicForward 1080

# 一般的な設定
Host *
ServerAliveInterval 60
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

*1:Arch では gnu-netcat パッケージに入ってる