なんとなく以前作ったものをGoで書き直したので供養します。リモートのサーバを操作できます。
GitHub - ebiiim/cmdproxy: Run any commands on remote hosts via HTTP(S).
使い方
- 事前に決めた共通のパスワードでサーバ
cmdprx
を起動しておき、
|
|
- クライアント
cmdprx-cli
から実行したいコマンドを送ると、
|
|
- 実行結果が返ってきます。
|
|
プログラムから呼び出す場合はこんな感じです。
クリックで展開
|
|
何をしているの?
特にすごいことはしてなくて、JSONをリクエストボディに入れてやりとりするだけです。
これだけだとただの踏み台なので、クライアントはハッシュしたパスワードをリクエストボディに含めて、サーバはそれを検証します。(リクエストヘッダに入れたほうがキレイですね……)
URLのパスも同様です。(これはリクエストボディなどに入れるのと本質的に変わらないので、なくてもいいかもしれません)
通信路を暗号化しないとtcpdumpされちゃうのでHTTPSに対応します。
FAQ
Q. リモートのサーバでコマンドを実行したい
A. 次からお選びください
- SSH
- IPsecなどVPNを使う
- stunnelをいい感じに使う
- 専用線接続
- ちゃんとしたAPIを生やす
Q. では、なぜこんなものを?
A. いろいろあった
クリックで展開
「異世界の時刻を知ること」が現実世界でお金になるとします。あなたは、異世界にサーバを設置し、リモートでdate
コマンドを実行できるようにする仕事をしています。あなたが上司の魔法で異世界に転生し、サーバを設置してSSHの動作を確認しようとしたそのとき、上司からテレパシーでメッセージが届きました。
「そういえばうちはHTTP(S)しか使えないよ」
「異世界はヤバいから1回の通信は数秒しか維持できないよ」
「あと30分で帰れなくなるから急いでね!」
そこで、あなたはテキストエディタを開き(以下略)
※フィクションです
Q. もうちょっと良くできない?
A. こんなのがあったらいいよね
- クライアント証明書認証
- 安心感がすごい
- Go 1.16から使えるらしい
go:embed
でいい感じにシングルバイナリにまとめられてカッコイイ
- 送信元ポート制限
- 送信元IPでフィルタできるのが理想ですが、送信元IPが一定じゃない環境ってよくあるので……
- 送信元ポートを制限したら変な通信あまり来ないのでは?(要検証)
- stdinとstdoutのストリーミング
- フィルタ処理とかで使う、stdinにデータを入力し続けて、完了したものが順次stdoutに出力されるやつ
- 自分で実装すると大変だけど、gRPC bidirectional streaming RPCでできそう
Q. 本番環境で使っていい?
A. ダメです、インターネットの治安維持に協力しましょう
1点付け加えると、443番ポートにbindするためにsudo cmdprx ...
で起動するとroot権限でコマンドを実行するので大変ヤバいです。setcap
でwell-known portsにbindできるようにしましょう。
|
|
おわりに
HTTP越しになんか呼び出さなきゃいけなくて、しかも納期は30分後!ってときにこのページを思い出していただければと思います。そんな場面に遭遇しないのが一番ですが。