ssh ポート転送 備忘録
こんにちは、技術部の阿部です。
Yahoo も Google も Amazon も 2ch も無い時代からエンジニア(らしきこと)をやってます。
バブルが終焉を迎えようとしていた頃、見ていた夢にあっさり見切りをつけて
システムエンジニアの世界へ足を踏み入れてしまったわけです。
以来ン十年、携わったシステムの9割以上がUNIX系になりますが(MS製品は避けてきました)、
転々と流れて、ネットアシストに流れ着いた現在、やっぱりUNIX系サーバの運用管理業務に
勤しんでおります。
で、sshです。
運用管理という業務の性質上、毎日あちこちのサーバへsshログインしているわけですが、
sshには便利なポート転送という機能があります。
だが、しかし、いつも”ローカル?リモート?どっちだっけ?”となってググることになるので、
今回は備忘録も兼ねてポート転送について。
| ホストA | —> | ホストB | —> | ホストC |
x.x.x.x y.y.y.y z.z.z.z
ホストA から ホストC へ行きたい!
=========================================================
[hostA]$ ssh y.y.y.y
[hostB]$ ssh z.z.z.z
[hostC]$
=========================================================
至極フツーのアプローチです。私もいつもコレです。
ポート転送機能を使うと ホストA から ホストC へ、いきなりジャンプできます。
(ターミナルを2個開いたり、事前の仕込みが必要ではありますが・・・。)
=========================================================
1. ターミナルを2個開いてホストAにログインしときます
=========================================================
2. ターミナル1 [hostA]$ ssh -L 10022:z.z.z.z:22 y.y.y.y
または
[hostA]$ ssh -L 127.0.0.1:10022:z.z.z.z:22 y.y.y.y
=========================================================
3. ターミナル2 [hostA]$ ssh 127.0.0.1 -p 10022
[hostC]$
=========================================================
解説
=========================================================
[hostA]$ ssh -L 127.0.0.1:10022:z.z.z.z:22 y.y.y.y
書式:ssh -L [転送元IP]:[転送元ポート]:[転送先IP]:[転送先ポート] [踏み台IP]
転送元IPアドレスは省略可能で、省略したら<127.0.0.1>が補完される
=========================================================
この1行のコマンドを投げると次のようなことが起こります。
1. ホストAからホストBへssh接続する
2. ホストAとホストBの間に、ホストCのsshポートへワープするsshの道が作られる
3. ホストA上にはホストCへ通じるsshポート10022が開く
このときnetstatの出力はこんな感じになってます。
=========================================================
【ホストA】
tcp 0.0.0.0:22 0.0.0.0:* LISTEN 1150/sshd
tcp 127.0.0.1:10022 0.0.0.0:* LISTEN 17527/ssh <– ポート10022が開く
tcp x.x.x.x:37714 y.y.y.y:22 ESTABLISHED 17527/ssh <– AからBへssh接続
=========================================================
【ホストB】
tcp 0.0.0.0:22 0.0.0.0:* LISTEN 1280/sshd
tcp y.y.y.y:22 x.x.x.x:37714 ESTABLISHED 1596/sshd <– AからBへssh接続
=========================================================
この状態で、ターミナル2からローカルホストのポート10022にsshします。
=========================================================
[hostA]$ ssh 127.0.0.1 -p 10022
=========================================================
netstatの出力はこんな感じになってます。
=========================================================
【ホストA】
tcp 0.0.0.0:22 0.0.0.0:* LISTEN 1150/sshd
tcp 127.0.0.1:10022 0.0.0.0:* LISTEN 17527/ssh
tcp 127.0.0.1:10022 127.0.0.1:54502 ESTABLISHED 17527/ssh <– 10022へ接続
tcp x.x.x.x:37714 y.y.y.y:22 ESTABLISHED 17527/ssh <– AからBへssh接続
tcp 127.0.0.1:54502 127.0.0.1:10022 ESTABLISHED 17533/ssh <– 10022からCへ接続
=========================================================
【ホストB】
tcp 0.0.0.0:22 0.0.0.0:* LISTEN 1280/sshd
tcp y.y.y.y:22 x.x.x.x:37714 ESTABLISHED 1596/sshd <– AからBへssh接続
tcp y.y.y.y:49268 z.z.z.z:22 ESTABLISHED 1600/sshd <– BからCへssh接続
=========================================================
【ホストC】
tcp z.z.z.z:22 y.y.y.y:49268 ESTABLISHED 8078/sshd <– CからBへssh接続
=========================================================
目的地までコツコツsshするか、ひと手間(コマンド1行)かけて飛ぶか・・・
ケースbyケースですね、ハイ。
ホストAを、ホストCへの踏み台にしたいときはどーしましょ
=========================================================
[hostA]$ ssh -g -L 10022:z.z.z.z:22 y.y.y.y
または
[hostA]$ ssh -L 0.0.0.0:10022:z.z.z.z:22 y.y.y.y
=========================================================
-gオプションまたは転送元アドレスを<0.0.0.0>明示指定すればホストAが踏み台に変身します。
あと・・・もし、踏み台サーバ(上の例では、ホストB)にncコマンドが入っていれば
sshのProxyCommandオプションを使ってこんな芸当もできます。
=========================================================
[hostA]$ ssh z.z.z.z -o ‘ProxyCommand ssh y.y.y.y /usr/bin/nc %h %p’
[hostC]$
=========================================================
ncコマンド、別名netcatコマンドは、CentOSなら簡単にyumインストールできますが、
使い方次第で悪のツールにも化ける危険なコマンドです。
できることなら、特にお客様サーバ等への導入は避けたいところです。
興味のある方は下記サイトが詳しいのでどーぞ。
http://www.intellilink.co.jp/article/column/security-net01.html
sshバージョン5.4から、このnetcat機能が実装されています。
http://www.openssh.com/txt/release-5.4(抜粋)
=========================================================
* Added a ‘netcat mode’ to ssh(1): “ssh -W host:port …” This connects
stdio on the client to a single port forward on the server. This
allows, for example, using ssh as a ProxyCommand to route connections
via intermediate servers. bz#1618
=========================================================
-Wオプションでイケるみたいですね。
でも残念ながらCentOS6系の最新パッケージのバージョンは5.3です。
=========================================================
# ssh -V
OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013
# ssh –help
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
[-D [bind_address:]port] [-e escape_char] [-F configfile]
[-I pkcs11] [-i identity_file]
[-L [bind_address:]port:host:hostport]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-R [bind_address:]port:host:hostport] [-S ctl_path]
[-W host:port] [-w local_tun[:remote_tun]]
[user@]hostname [command]
=========================================================
バージョン5.3なのですが・・・ヘルプを見ると-Wオプションが・・・。
パッケージの変更履歴を見てみます。
=========================================================
# rpm -q openssh –changelog | grep -i netcat -B1
* Thu Dec 13 2012 Petr Lautrbach <plautrba@redhat.com> 5.3p1-84.1
– Add a ‘netcat mode’ (ssh -W) (#860809)
=========================================================
2012年12月にはパッケージに取り込まれていたようですね、はい。
いつもmanなんてインストールしないし見ないし、全く知りませんでした。
以上、常に情報のアンテナを張り巡らせて、マニュアルもチェックしましょう、というお話でした。