1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

authorized_keysのオプションとForceCommand的なサンプルとSSH_ORIGINAL_COMMANDに空白が含まれてもいい感じに扱う

Last updated at Posted at 2019-10-29

タイトル詰め込みすぎ。

SSH公開鍵を登録するときにしばしばauthorized_keysを設定します。
最近知ったのですが結構色々オプションが指定できます。詳しくはドキュメントをお読みください。

今回は特定の公開鍵でログインしたときに実行するコマンドを指定するオプションを紹介します。

例えば、サーバの再起動だけ行えるようにしておいて、ある運用者にその秘密鍵を共有することで、再起動以外の余計な操作をできないようにすることができ、気持ちセキュアに運用を組めます。

たとえばログインしたらlsを実行して終了するようにしてみます。
ただ、lsだけではかわいそうなので、引数を指定できるようにします。

あらかじめ秘密鍵と公開鍵を用意しておき、リモートのauthorized_keysに公開鍵を以下のように書きます。

~/.ssh/authorized_keys
command="ls $SSH_ORIGINAL_COMMAND" ssh-rsa AAAAB3...

SSH_ORIGINAL_COMMANDはsshコマンドの引数の情報が入った環境変数です。

試してみましょう。
あくまでsshコマンドなので、--を入れないと、-lがsshのオプションとして処理されてしまいます。

ssh USER@HOST -- -l /tmp

ここまでは簡単ですね。

(ちなみに、sshd_configForceCommandが設定されていればそちらが優先されます。)

引数の扱いが難しい問題

引数を処理してましたが、上記のとおり、$@ではなく、環境変数 SSH_ORIGINAL_COMMANDを使う必要があります。これは普通の環境変数なので文字列です。

なので、空白の扱いに困ることになります。

例えば以下の場合、引数は2つとして処理してほしいものですが、うまくいきません。

$ ssh USER@HOST a "b c"
ls: cannot access a: No such file or directory
ls: cannot access b: No such file or directory
ls: cannot access c: No such file or directory

というわけで、今回はこれをどうにかします。(本題)

authorized_keysは以下のようにします。ログイン時のシェルがbashならこんな感じにかけます。

~/.ssh/authorized_keys
command="read -a ssh_args <<< \"$SSH_ORIGINAL_COMMAND\" && ls \"${ssh_args[@]}\"" ssh-rsa AAAAB3...

使うときはこうします。

$ ssh USER@HOST "$(printf "%q " a "b c")"
ls: cannot access a: No such file or directory
ls: cannot access b c: No such file or directory

printf "%q " でいい感じにエスケープがかかるので、それをリモート側のbashのread -a aname 入力として使い、いい感じに処理できます。

おまけ:醜さ軽減

authorized_keysがエスケープだらけで醜い場合はスクリプト化するとよいでしょう。

~/.ssh/authorized_keys
command="/path/to/script.sh" ssh-rsa AAAAB3...
/path/to/script.sh
# !/bin/bash
read -a ssh_args <<< "$SSH_ORIGINAL_COMMAND"
ls "${ssh_args[@]}"

また、実行側のsshコマンドもつらいですね。
ホスト決め打ち、sshのオプションとSSH_ORIGINAL_COMMANDを厳密に区別しなくて良いのであれば、functionなりシェルスクリプトなりにしておくと良いでしょう。

function ssh_1(){
  ssh USER@HOST -- "$(printf "%q " "$@")"
}
$ ssh_1 a "b c"
ls: cannot access a: No such file or directory
ls: cannot access b c: No such file or directory
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?