2段の踏み台Linuxサーバがあるネットワークで、手元の作業PCから目的のWindowsへRDP接続します。
- NW構成:Win1(作業PC) → Linux2 → Linux3 → Win4
- 手段:SSH ローカルポートフォワーディング(-L) を 多段 に重ねる
- 仕上げ:Tera Termマクロで トンネル作成〜mstsc起動までワンクリック化
※ SSHトンネルは便利な一方、攻撃にも悪用されうる技術なので、最後に「運用上の注意」もまとめます。
1. NW構成(今回のゴール)
添付図の構成です。
- Win1(作業PC):
- Linux2(SSH踏み台1):192.168.2.2:22
- Linux3(SSH踏み台2):192.168.3.3:22
- Win4(RDP先):192.168.4.4:3389
※Linux2とLinux3はIPフォワード(ルーティング)無効でWin1から直接Linux3やWin4へアクセスできない環境
ゴール:Win1から 127.0.0.1:53389 にRDPすると、Win4へ到達する
(ローカルに見せかけて、裏で多段SSHトンネルが張られている状態)
2. まずは仕組みを分解(手動だとこうなる)
今回のキモは「53389番を“同じ番号のまま”バケツリレーする」ことです。
2.1 Win1 → Linux2(1段目)
Win1上で、ローカル53389を Linux2のlocalhost:53389 へ転送します。
Win1(手元)で実行するイメージ
ssh linux2@192.168.2.2 -p 22 -L 53389:127.0.0.1:53389
これで Win1 の 127.0.0.1:53389 に投げた通信は、Linux2 の 127.0.0.1:53389 に届くようになります。
2.2 Linux2 → Linux3 → Win4(2段目)
次に Linux2上で、ローカル53389を Win4:3389 へ転送します(経路はLinux3経由)。
Linux2(踏み台1)上で実行するイメージ
ssh linux3@192.168.3.3 -p 22 -L 53389:192.168.4.4:3389
これで Linux2 の 127.0.0.1:53389 に来た通信は、SSHトンネル経由で Win4:3389 に届きます。
2.3 最後にRDPクライアント(mstsc)
Win1からローカルへRDPするだけ
mstsc → 接続先:127.0.0.1:53389
3. Tera Termマクロでワンクリック化
ここからが本題です。
上の「分解した手順」を、Tera Termマクロで一気通貫にします。
- Tera Termで Linux2 へSSH接続しつつ、1段目の -L を設定
- Linux2に入ったら、Linux3へ ssh して2段目の -L を設定
- 一時ファイルとして .rdp を生成して mstsc.exe を起動
Tera Termのポート転送(SSH Forwarding)は公式マニュアルでも案内されている機能です。
4. Teratermマクロ(使ったマクロを記載)
; -- Linux2情報 --
LINUX2_IP = '192.168.2.2'
LINUX2_PORT = '22'
LINUX2_USER = 'linux2'
; -- Linux3情報 --
LINUX3_IP = '192.168.3.3'
LINUX3_PORT = '22'
LINUX3_USER = 'linux3'
; -- Win4情報 --
WIN4_IP = '192.168.4.4'
WIN4_PORT = '3389'
WIN4_USER = 'win4'
; -- ポートフォワード設定 --
PORTFOWRD = '53389'
; -- 設定ファイル名 --
PASSWORD_FILE = 'multihop_passwords.dat'
RDP_FILE_NAME = 'autogen_rdp_config.rdp'
; ================================================
; 1. 接続前処理(パスワード取得)
; ================================================
getdir MACRO_DIR
sprintf2 PASSWORD_FILE_PATH '%s\%s' MACRO_DIR PASSWORD_FILE
getpassword PASSWORD_FILE_PATH 'Linux2のパスワード' LINUX2_PASSWORD
getpassword PASSWORD_FILE_PATH 'Linux3のパスワード' LINUX3_PASSWORD
; ================================================
; 2. Linux2への接続
; ================================================
CONNECT_COMMAND = LINUX2_IP
strconcat CONNECT_COMMAND ':'
strconcat CONNECT_COMMAND LINUX2_PORT
strconcat CONNECT_COMMAND ' /ssh /2 /auth=password /user='
strconcat CONNECT_COMMAND LINUX2_USER
strconcat CONNECT_COMMAND ' /passwd='
strconcat CONNECT_COMMAND LINUX2_PASSWORD
strconcat CONNECT_COMMAND ' /ssh-L'
strconcat CONNECT_COMMAND PORTFOWRD
strconcat CONNECT_COMMAND ':127.0.0.1:'
strconcat CONNECT_COMMAND PORTFOWRD
connect CONNECT_COMMAND
wait '# ' '$ '
; ================================================
; 3. Linux3への接続
; ================================================
; -- Linux3のパスワード再取得
getdir MACRO_DIR
PASSWORD_FILE = 'multihop_passwords.dat'
sprintf2 PASSWORD_FILE_PATH '%s\%s' MACRO_DIR PASSWORD_FILE
getpassword PASSWORD_FILE_PATH 'Linux3のパスワード' LINUX3_PASSWORD
; -- Linux3へのSSHコマンド生成
SSH_COMMAND = 'ssh -o StrictHostKeyChecking=no -L '
strconcat SSH_COMMAND PORTFOWRD
strconcat SSH_COMMAND ':'
strconcat SSH_COMMAND WIN4_IP
strconcat SSH_COMMAND ':'
strconcat SSH_COMMAND WIN4_PORT
strconcat SSH_COMMAND ' '
strconcat SSH_COMMAND LINUX3_USER
strconcat SSH_COMMAND '@'
strconcat SSH_COMMAND LINUX3_IP
strconcat SSH_COMMAND ':'
strconcat SSH_COMMAND LINUX3_PORT
sendln SSH_COMMAND
wait "password:"
sendln LINUX3_PASSWORD
wait '# ' '$ '
; ================================================
; 4. RDPクライアント起動
; ================================================
getenv 'TEMP' TEMP_DIR
sprintf2 RDP_FILE_PATH '%s\%s' TEMP_DIR RDP_FILE_NAME
fileopen FHANDLE RDP_FILE_PATH 1
if FHANDLE = -1 then
messagebox 'RDP設定ファイルの作成に失敗しました。 ' 'エラー'
end
endif
filewriteln FHANDLE 'prompt for credentials:i:1'
sprintf2 LINE 'full address:s:127.0.0.1:%s' PORTFOWRD
filewriteln FHANDLE LINE
sprintf2 LINE 'username:s:%s' WIN4_USER
filewriteln FHANDLE LINE
fileclose FHANDLE
sprintf2 EXEC_COMMAND 'mstsc.exe "%s"' RDP_FILE_PATH
exec EXEC_COMMAND
5. 詰まりポイント(チェックリスト)
5.1 そもそもLinuxサーバでSSH転送が許可されているか
sshd側で転送が無効だと、channel open failed などで転送が張れません。
AllowTcpForwarding の設定が関係します。
5.2 Win4のRDP(3389)がLinux3から到達できるか
Win4側Windowsファイアウォールで Linux3 → Win4:3389 が許可されているか
5.3 ローカルポート(53389)が競合してないか
既にWin1、Linux2、Linux3で53389を使っているとトンネルが作れません。その場合は別ポートに変えてOKです。
6. 運用上の注意(大事)
- 3389をインターネットに直出ししない(可能ならVPNや踏み台・GWで制御)
- トンネルは便利ですが、攻撃でも“内部到達”に使われます(検知・制御の観点も意識)
- 可能ならSSHは 鍵認証、踏み台は 接続元制限、ログ監視…など「いつもの堅実運用」を
7. おわり(使いどころ)
踏み台が増えるほど「毎回コマンド打つ」のが地味にストレスなので、
“理解は分解して、運用はワンクリック” に寄せるのはかなりアリでした。
同じ考え方はDB接続(SSHトンネル)でもよく使うので、踏み台越し接続の引き出しとして持っておくと便利です。