rbashでのコマンド制限時の注意点
概要
sshでログインする、あるユーザに対して、rbashを利用しcdやechoなどのコマンドを一部しか使えなくしたかったのですが、設定が不適切な場合はrbashは予想通りに機能せず、下記のやり方でssh接続時にrbashで制限したいコマンドも実行できることが分かりました。
$ ssh foo@bar [制限したいコマンド]
原因としては~/.bashrcにコマンド制限のための下記のようなPATHの変更する記述を忘れたためです。
~/.bash_profileでは、sshログイン後の制限はできますが、ssh接続時の制限はできません。
foo@bar:~$ cat ~/.bash_profile
PATH="$HOME/bin"
foo@bar:~$ cat ~/.bashrc
PATH="$HOME/bin"
bashは起動方法によって読み込まれる設定ファイルが違います。
詳細についてはbashのman pageのINVOCATION(起動)節を読んでみて下さい。
なお、設定ファイルおよびPATHを通すディレクトリ(上記例では$HOME/bin/)は書き込み禁止にする必要が有ります。
環境
下記の通り$HOME/bin以下のcat, date, echo, lsしか実行できないように設定したつもりでした。
なお、rbashの設定方法は検索してもらえれば日本語の記事が複数見つかります。
- OS: Ubuntu 20.04.3 LTS
foo@bar:~$ uname -a
Linux ubuntu 5.4.0-1055-raspi #62-Ubuntu SMP PREEMPT Wed Mar 2 14:43:34 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
- シェル: rbash
# ログイン後のシェルはrbash
foo@bar:~$ echo $SHELL
/bin/rbash
# ssh接続時のシェルはrbash
$ ssh foo@bar 'echo $SHELL'
/bin/rbash
- rbash環境
foo@bar:~$ cat .bash_profile
PATH="$HOME/bin"
# 下記ではbin/のオーナーがfooで書き込み可能になっています。
# 本来はオーナーをrootにしfooからの書き込みは禁止にする必要が有ります。
foo@bar:~$ ls -al bin/
total 8
drwxrwxr-x 2 foo foo 4096 Mar 13 13:27 .
drwxr-xr-x 6 foo foo 4096 Mar 13 13:25 ..
lrwxrwxrwx 1 foo foo 8 Mar 13 13:17 cat -> /bin/cat
lrwxrwxrwx 1 foo foo 9 Mar 13 13:27 date -> /bin/date
lrwxrwxrwx 1 foo foo 9 Mar 13 11:53 echo -> /bin/echo
lrwxrwxrwx 1 foo foo 7 Mar 13 13:05 ls -> /bin/ls
実施内容
sshログイン後はtouchコマンドが使えません。
foo@bar:~$ touch tmp.txt
-rbash: /usr/lib/command-not-found: restricted: cannot specify `/' in command names
ssh接続時に以下の通りtouchコマンドのシンボリックリンクを$PATHに配置できます。
lnはrbashでは使えないようにしています。
ssh foo@bar ln -s /bin/touch /home/foo/bin/
下記の通り$PATHに配置されています。
foo@bar:~$ ls -al bin/
total 8
drwxrwxr-x 2 foo foo 4096 Mar 13 14:04 .
drwxr-xr-x 6 foo foo 4096 Mar 13 13:25 ..
lrwxrwxrwx 1 foo foo 8 Mar 13 13:17 cat -> /bin/cat
lrwxrwxrwx 1 foo foo 9 Mar 13 13:27 date -> /bin/date
lrwxrwxrwx 1 foo foo 9 Mar 13 11:53 echo -> /bin/echo
lrwxrwxrwx 1 foo foo 7 Mar 13 13:05 ls -> /bin/ls
lrwxrwxrwx 1 foo foo 10 Mar 13 14:04 touch -> /bin/touch
その後は問題なくtouchが使えます。
foo@bar:~$ ls
bin
foo@bar:~$ touch tmp.txt
foo@bar:~$ ls
bin tmp.txt
他の方法
ログインユーザに使わせたいコマンドは一つのみで、ssh接続のみの場合、sshdのForceCommandという設定でも類似のことができます。
これは、「クライアントが指定したコマンドを無視し、ここで指定されたコマンドを強制的に実行する」ことができる設定です。
~/.bashrcの設定を忘れて ssh foo@bar [制限したいコマンド]
を使われた場合でも、ForceCommandのみが実行され、制限したいコマンドは実行できませんでした。
まとめ
rbashの設定の際に私が間違えた点を記述しました。
他にも類似のミスを人がいるかもしれないと思い、備忘録も兼ねて記事にしました。
(IWAMOTO Kouichiさん、ご指摘ありがとうございました。)
Discussion
おそらく設定の問題かと。
同じ設定を
~/.bashrc
に設定してみるとどうでしょうか?~/.bash_profile
は、bashが対話的なログインシェルとして起動された時に実行されます。ssh user@host command
のようにssh
でコマンドを指定した場合は対話的シェルでもログインシェルでもない為、~/.bash_profile
は実行されません。その為、PATH
の設定が行われずデフォルトの状態となるので、ln
等のデフォルトのPATH
に有るコマンドが実行出来てしまいます。~/.bashrc
は対話的な非ログインシェルの時に実行されます。これだけだとssh
でコマンド指定した時には実行されない事になりますが、他の条件として「標準入力がネットワークに接続されている時」というのが有り、これに当てはまるので~/.bashrc
は実行されます。bashの起動時の動作は他にも色々と条件が有って複雑怪奇なので、詳細についてはbashのman pageのINVOCATION(起動)節を読んでみて下さい。
これだと
$SHELL
の展開はローカル側で行われるので、リモート側で実際に実行されるのはecho /bin/bash
となります。リモートでの
$SHELL
を確認したい場合は、ssh foo@bar 'echo $SHELL'
のようにクオートする必要が有ります。何か違和感が有るなと思っていたのですが、そもそも
ln
が使えたとしてもbin
にリンクが作れるのがおかしいです。これを見ると、
bin
の所有者がfooで書き込み権が有ります。書き込み権が有るという事は、何らかの方法でファイルを作れれば新しいコマンドが追加出来る事になります。
使えるコマンドを制限したいのですから
chmod 555 bin
を実行してbin
への書き込み権を落とすchown root bin
を実行してbin
の所有者をrootにするの二つを行うべきです。
他にも、
~/.bash_profile
,~/.bashrc
の所有者をrootにする~/.bash_profile
,~/.bashrc
の書き込み権を落とすも行う方がいいでしょう。(前二つは必須、後ろ二つはファイルが作れなくなるので可能ならば)
IWAMOTO Kouichiさん
非常に参考になるご指摘ありがとうございました。
記事も頂いた情報をもとに修正しました。