CI から SSH を許可するために、秘密のデータを置く専用の場所に置いたり鍵を暗号化して置いたりするわけですが、破られた場合の次の策として rbash を設定しようとしていました。 rbash を使用すると、実行可能なコマンドに制限のかかったユーザを作成することができますが、うっかり不十分な制限になってしまうことがあります。
.bash_profile だけではダメ(かも)
CentOS 7 で作られる .bashrc が
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
としているおかげで、 .bash_profile で設定した PATH が上書きされてしまいます。
.bashrc で設定するようにしましょう。
ビルトインコマンドが使える
$ ssh user@host 'test -f /etc/passwd && echo test'
test
もっと厳しくするには、enable -n COMMAND を .bashrc に追記して不要なビルトインコマンドを無効化します。
scp で .bashrc を上書きできる
chown で root に所有させたりして、該当ユーザは読み込みだけにします。
その他 .profile, .bash_profile, .bash_logout あたりも注意。
任意のコマンドを実行できるコマンドを許可してしまう
awk, find など。 EDITOR を使うやつも注意。
一旦、自前のシェルスクリプトで引数を制限してしまうのも良いかもしれません。
scp, rsync で任意のコマンドを実行できる
表からはわからないので注意。
scp -S /bin/echo . example@localhost:/
とすると、実行したマシン上で任意のコマンドが実行できる。
これが困るのは rbash で制限している時。 scp は、上記の echo で示した通り、手元とリモートの両方の scp で動作するので、リモートマシンにも scp の PATH を通す必要がある。しかし、 rbash は直接起動したコマンドしか面倒を見れないので、 rbash による制約を回避できてしまう。
# !/bin/bash
if [[ " $@" = *" -S"* ]]; then
echo "Command failed: $@" >&2
exit 1
fi
/bin/scp $@
代わりに上記のようなシェルスクリプトを制限するユーザの PATH 上に置いておく。
rsync も似たようなことが出来てしまうので、
# !/bin/bash
if [[ " $@" = *" -rsh"* || " $@" = *" -e"* ]]; then
echo "Command failed: $@" >&2
exit 1
fi
/bin/rsync $@
まだ抜けがありそうな気がする。