ものすごくひさしぶりにRLoginの話。
RLoginで踏み台の先にログインしたいときはポートフォワードを使うと便利です。
でも場合によってはポートフォワードが禁止されていることがあって。。。
大量のサーバーに繋ぐのが辛い。。。
ので、ポートフォワードを使わずに接続を自動化できるようにしました。
目次
おさらい
この辺の話の応用的な。
-
RLoginでエックスサーバーにSSHする方法
みなさん、SSHしてますか(意味不明) WordPressは、ブラウザだけでサーバーのファイルを修正できるようになってます。 でも、1行追加するだけなのにダウンロード→編集→アップロードとかめんどくさ ...
続きを見る
-
RLoginで踏み台経由でログインする
お気に入りのWindwos用ターミナルRLogin そんなこと猫でもできる 2 PocketsRLoginでエックスサーバーにSSHする方法https://nekodeki.com/rlo ...
続きを見る
-
コマンドプロンプトでRLoginを起動してログインする
以前書いた、RLoginでサーバーにログインする方法 この方法は、RLoginの一番スタンダードな使い方だと思います。 接続設定を手動で作成する方式です。 ただ、この方法だと非常にまずい場合がありまし ...
続きを見る
自動化の手段を探る
自動化するにあたり、まずはどうやってアプローチするかを検討します。
とりあえずRLoginの仕様書を漁ってみるとチャットスクリプトとスクリプトが使えそうです。
なおこの2つは全くの別物なので注意。
チャットスクリプト
プログラミングできなくても使えそう。
ただ、外部から変数の値を書き換えたりはできなさそうです。
スクリプト
チャットスクリプトよりプログラミングチック。
コマンドプロンプトから起動するときに外部読み込みするスクリプトのファイルを指定できます。
今回は外部からIPを渡して接続先を変えていきたいので、使うとしたらスクリプトになりそうです。
スクリプトに外部から値を渡せるか?
スクリプトサンプルの1つ目が自動ログインに使えそう。
引数を渡せれば動的にIPを変えられるけど
スクリプト仕様書を見ても引数渡す方法が書いてない。。。
コマンドラインからも渡す方法がなさそう。。。
これは困った。
このままだと接続したいIPの数だけスクリプトファイルを作らなければならず、自動化のメリットが薄れます。
スクリプトファイルを書き換えて増産しよう
まぁできないものは仕方ない。
スクリプトファイルを必要な数だけ作るのが避けられないとして、手で作るのは面倒すぎるのでここも自動でやることにします。
最終的にRLoginの起動コマンドを打てればPowerShellだろうがPythonだろうがなんでもいいのですが、私は基本的に人に配布する予定があるツールについては
- 極力環境構築を不要にする
- コピってすぐ使えるのが理想
というのを目標にしているので、今回は全部batchでやることにします。
だってWindowsPCなら絶対使えるから!
PowerShellはポリシーでエラー吐いたりするから嫌い!
batchもわけわかんなくて嫌いだけど!!
自動化全体図
こんな感じ。
実装
踏み台とその先のサーバーが同じユーザー名・パスワードでログインできる前提です。
RLoginには踏み台に入れるEntryを作成しておきます。
上の設定をもとにすると最終的にCMDで実行するコマンドはこんな感じ。
1 |
RLogin_login.bat [ユーザー名(ec2-user)] [パスワード] [RLoginのEntry名(AWS_踏み台)] [scriptTemplate.txtのパス] [ipList.csvのパス] |
ipList.csv
踏み台から接続したいIPと起動する台数をCSV形式で書きます。
例えばこんな感じにすると、最終的にRLoginで5つのウィンドウが起動します。
1 2 |
192.0.2.1,3 192.0.2.20,2 |
scriptTemplate.txt
RLoginで踏み台に入った後に実行するScriptのTemplateを用意します。
ポイントは2つ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
ip = "ipStr"; // 接続先IP password = "passStr"; // パスワード Document.Open(); wait(CONNECT); sopen(OPEN_LOOK); // batchで読み込むと!が消えるので^でエスケープしておく while ( sgets(100) ^!= "" ); sputs("ssh " . $ip . "\r"); while ( sgets(100) ^!= "" ); sputs($password . "\r"); sclose(); |
置換用のIPとパスワード
batchで「ipStr」「passStr」という文字列を探して置換します。
!を^でエスケープ
batchで読み込んだときに!が消えてしまうので^でエスケープしておきます。
※RLoginに直接スクリプトを設定する場合は不要
RLogin_login.bat
全体の処理を行うbatch。
ポイントは3つですかね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
@echo off @REM コマンドライン引数 set user=%1 set pass=%2 set entry=%3 set scriptPath=%4 set ipListPath=%5 @REM Script置換の目印 set markStrIp=ipStr set markStrPass=passStr @REM IPリストを1行ずつ読み込んで処理 @REM forするときのおまじない setlocal enabledelayedexpansion for /f "delims=, tokens=1,2" %%t in (%ipListPath%) do ( @REM わかりやすく名前を付けたいけど都合が悪いのでそのまま @REM ip=%%t @REM count=%%u @REM Scriptファイルの名前が被らないようにしてtmpに作成 set tmpScriptPath=%USERPROFILE%\AppData\Local\Temp\rlogin_loginScript_!random!.txt @REM Scriptファイル内のIPとパスワードを書き換えたファイルをtmpに作成 for /f "delims=" %%a in (%scriptPath%) do ( set line=%%a @REM for内でsetした変数は%%ではなく!!で囲まないと最新の値が使えない @REM 置換するために!を使うので!ip!という表記が使えない set line=!line:%markStrIp%=%%t! set line=!line:%markStrPass%=%pass%! echo !line!>>!tmpScriptPath! ) @REM IPリスト2列目の数字の分だけループしてRloginを起動 for /l %%i in (1,1,%%u) do ( @REM Rlogin.exeはパスを通しておくこと start /b Rlogin /inuse /user %user% /pass %pass% /entry %entry% /script !tmpScriptPath! @REM ウィンドウが開くまで3秒スリープ ping 127.0.0.1 -n 3 > nul ) ) |
変数使用時の%%と!!の使い分け
通常batchで変数を使用するときは%%で囲みます。
ただ、これだとfor … do ()の中で変数をsetしても最新の値を使えない遅延環境変数という仕様が。。。
詳しくはQiitaなんかを読んでいただくとして。
forの中で変数をsetしたいときは
- setlocal enabledelayedexpansionを書く
- 変数の呼び出しは%%ではなく!!で囲む
としましょう。
文字列を置換
batchはreplaceのような関数がなく
!検索対象の文字列:置換対象の文字列=置換する文字列!
という書き方をするのですけど。
先に書いたように、遅延環境変数も!!で囲むわけで。。。
1 2 3 4 |
@REM for内でsetした変数は%%ではなく!!で囲まないと最新の値が使えない @REM 置換するために!を使うので!ip!という表記が使えない set line=!line:%markStrIp%=%%t! |
いやもう、遅延環境変数って誰得なんですかね。。。
動くことは動くけどさ。。。
RLoginはパスを通しておく
batch…というかコマンドラインでRLoginを実行するとき、RLogin.exeのパスを書いてもいいのですが。
どうせならコマンドっぽくRLoginだけで呼び出せるようにパスを通しておきましょう。
パスを通すの意味がわからない人はこれ。
実行
RLoginの準備と各ファイルが準備できたら以下コマンドをコマンドプロンプトで実行します。
1 |
RLogin_login.bat [ユーザー名(ec2-user)] [パスワード] [RLoginのEntry名(AWS_踏み台)] [scriptTemplate.txtのパス] [ipList.csvのパス] |
RLoginの起動コマンドに/inuseオプションを付けているので、すでに起動中のRLoginがあればそのウインドウのタブとしてオープンします。
コマンドラインオプションは公式サイトで確認できます。
これでIPの種類や接続数がどれだけあっても、ipList.csvさえ作れば自動で対象サーバーにログインできるようになりました。
batch嫌いはちょっとだけ改善した、かも
今まで
batchってマジ意味不明。。。
全然思った通りに動かない。。。
嫌い。。。
って苦悩しながら書いてたんですが、今回ようやく遅延環境変数やforの結果で代入される変数の意味が理解できました。
tokensが複数、変数は%%aなどアルファベット1文字で指定
⇒ 2つ目以降値は%%b、%%cと指定した変数のアルファベットの連番?になる
って仕様考えたの誰なんですかね。。。
tokensが27個必要な場合はどうするんだ。。。
など文句はいっぱいありますがw
自由に書けるようになったらやれることの幅は広がりそうなので、機会があればまた使ってみようと思います。