📝

rbashでのコマンド制限時の注意点

2022/03/14に公開
3

概要

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(起動)節を読んでみて下さい。
http://manpages.ubuntu.com/manpages/bionic/ja/man1/bash.1.html#起動

なお、設定ファイルおよび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さん、ご指摘ありがとうございました。)

GitHubで編集を提案

Discussion

ピン留めされたアイテム
IWAMOTO KouichiIWAMOTO Kouichi

おそらく設定の問題かと。

foo@bar:~$ cat .bash_profile
PATH="$HOME/bin"

同じ設定を~/.bashrcに設定してみるとどうでしょうか?

~/.bash_profileは、bashが対話的なログインシェルとして起動された時に実行されます。
ssh user@host commandのようにsshでコマンドを指定した場合は対話的シェルでもログインシェルでもない為、~/.bash_profileは実行されません。その為、PATHの設定が行われずデフォルトの状態となるので、ln等のデフォルトのPATHに有るコマンドが実行出来てしまいます。

~/.bashrcは対話的な非ログインシェルの時に実行されます。これだけだとsshでコマンド指定した時には実行されない事になりますが、他の条件として「標準入力がネットワークに接続されている時」というのが有り、これに当てはまるので~/.bashrcは実行されます。

bashの起動時の動作は他にも色々と条件が有って複雑怪奇なので、詳細についてはbashのman pageのINVOCATION(起動)節を読んでみて下さい。
http://manpages.ubuntu.com/manpages/bionic/ja/man1/bash.1.html#起動

# 接続時のシェルはbashのまま
$ ssh foo@bar echo $SHELL
/bin/bash

これだと$SHELLの展開はローカル側で行われるので、リモート側で実際に実行されるのは echo /bin/bashとなります。
リモートでの$SHELLを確認したい場合は、ssh foo@bar 'echo $SHELL'のようにクオートする必要が有ります。

ピン留めされたアイテム
IWAMOTO KouichiIWAMOTO Kouichi

何か違和感が有るなと思っていたのですが、そもそもlnが使えたとしてもbinにリンクが作れるのがおかしいです。

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

これを見ると、binの所有者がfooで書き込み権が有ります。
書き込み権が有るという事は、何らかの方法でファイルを作れれば新しいコマンドが追加出来る事になります。
使えるコマンドを制限したいのですから

  • chmod 555 binを実行してbinへの書き込み権を落とす
  • chown root binを実行してbinの所有者をrootにする

の二つを行うべきです。
他にも、

  • ~/.bash_profile, ~/.bashrcの所有者をrootにする
  • ~/.bash_profile, ~/.bashrcの書き込み権を落とす
  • (可能ならば)ホームディレクトリの所有者をrootにする
  • (可能ならば)ホームディレクトリの書き込み権を落とす

も行う方がいいでしょう。(前二つは必須、後ろ二つはファイルが作れなくなるので可能ならば)

teasyteasy

IWAMOTO Kouichiさん
非常に参考になるご指摘ありがとうございました。
記事も頂いた情報をもとに修正しました。