概要
リモートから外部のサーバに対してコマンドを発行する方法をいろいろと考えてみました
要するにわざわざリモートサーバにログインしてコマンドを発行しなくて済むような方法を考えてみます
環境
- macOS 10.15.5 (client)
- Ubuntu 16.04 (server)
- golang 1.14.4
ノンパス ssh を使う方法
一番オーソドックスな方法かなと思います
ログインする側で公開鍵を作成します
作成のパスワードは空にします
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub
生成された pub ファイルをログイン対象のサーバの authorized_keys
に登録します
vim ~/.ssh/authorized_keys
これで ssh 経由でコマンドを発行できます
ssh vagrant@192.168.100.10 sudo gitlab-ctl status
また対象のサーバに対してダイレクトに実行するのが嫌だという場合は途中にプロキシなどを挟んで netcat 越しに実行しても良いと思います
メリット/デメリット
メリットは ssh なので暗号化はされています
また ssh 自体かなり使われている技術なので導入障壁は低いかなと思います
デメリットしてはサーバの ssh ポートを外部から LISTEN しておく必要があります
IP でアクセス制御したり ssh するユーザをある程度絞る必要があります
shell2http を使う
shell2http は登録したコマンドを http 経由で発行することができる Golang 製のツールです
Ubuntu へのインストールは以下のように行います
snap install shell2http
ただ一部権限がなく動作しないコマンドがあるようなので github にあるバイナリファイルを使いましょう (参考)
go get -u github.com/msoap/shell2http
例えば gitlab-ctl status
というコマンドを /status
のパスでコールするには以下のようにします
shell2http /status "gitlab-ctl status"
curl 192.168.100.10:8080/status
こんな感じで :8080/status
にリクエストするとコマンドの実行結果が返ってきます
LISTEN させるポートや動作させるシェルなどオプションで様々な指定が可能です
--add-exit
を指定すると /exit
にアクセスした際に shell2http のプロセス自体を kill してくれます
shell2http --shell bash --port 8888 --add-exit /status "gitlab-ctl status"
--form
オプションを使えばパラメータを受け取ることもできます
コマンド部分はシングルクォートで囲う必要があるので注意してください
shell2http--form /status 'gitlab-ctl $v_cmd'
curl "192.168.100.10:8080/status?cmd=status"
こんな感じでサブコマンドを変数にすると便利です
メリット/デメリット
メリットは ssh/22 をオープンしなくて良い点です
代わりに 8080 ポートをオープンしましょう
あとは curl なり HTTP プロトコルを使ってコマンドを実行できます
ssh 同様コマンドの結果はそのまま返ってくるのでパースなどは自分でやる必要があります
デメリットは shell2http のプロセス管理をする必要がある点です
また golang のインストールも必要になるので作業手順も若干増えます
暗号化に関してはオプションで証明書を指定可能なので https を使うことで通信を暗号化できます
Tips: No such file or directory や Cannot access などのエラーが出る場合
おそらく snap などでインストールしているのが原因です
go get を使って github から最新版を入手してください
その他案
その他使えそうな技術をピックアップしてみました
chef や ansible のプロビジョニングツールを使う
というのがモダンで良いとは思うのですが結局プロビジョニング対象のサーバに対して ssh できる必要があります
管理的なコストを考えるとソースに落とせるのでそれだけでメリットはありますが学習コストなどは増えてしまいます
クラウドサービスを使う
例えば GCP には gcloud コマンドという CLI が付属しておりこれをつかうことで簡単にリモートからコマンドを発行することができます
内部的には ssh を使っているのでプロトコル的には同じなのですがファイアウォールの設定やインスタンスの設定をしないで済むのは嬉しい点かなと思います
また AWS には AWS System Manager というサービスがありこれは画面からコマンドを実行することもできるのでかなり理想に近い感じはします
ちなみに SSM エージェントと呼ばれるエージェントをインストール必要がありこれはソースも公開されています
自作する
あとは気に入ったものがなかったり要件を満たさない場合には自作するしかないと思います
自作であればプロトコルやインタフェースは自由に選べるしエージェントを使って pull 側の仕組みを作ったりすることもできます
ですが当然開発コストやノウハウがそれなりに必要にはなるので障壁は一番高いかなと思います
最後に
リモートのサーバに対してログインせずにコマンドを実行する方法を考えてみました
over HTTP でコマンドを実行する方法は他にもいろいろとありそうだったので興味があれば調べてみてください
AWS のようにエージェント形式で気軽に使えるツールはあまりないようでやはりエージェント形式の場合はサーバも必須になるので構成も複雑になるかなと思います
0 件のコメント:
コメントを投稿