chgrpが「setuidビット」をクリアしないようにする方法


8

RHベースのLinuxイメージがあります。私たちの製品の最新の開発バージョンにアップグレードするために、いくつかの「特別なアーカイブ」を「適用」する必要があります。

アーカイブを作成した人は、ベースイメージ内で一部の権限が間違っていることに気付きました。私たちは走るように言われました

sudo chgrp -R nobody /whatever

私たちはそれをしました。その後、アプリケーションの実行中に、あいまいな問題が発生しました。

後で見つけたもの:chgrpを呼び出すと、/ whatever内のバイナリのsetuidビット情報がクリアされます。

そして実際の問題は次のとおりです。一部のバイナリは、正しく機能するためにそのsetuidビットが設定されている必要あります。

短い話:私のsetuidビット殺さずに "chgrp"コマンドを実行する方法はありますか?

私はローカルUbuntuで以下を実行しました。同じ結果につながる:

mkdir sticky
cd sticky/
touch blub
chmod 4755 blub 
ls -al blub 

->背景が赤のファイル名が表示されます->そう、そうです、setuid

chgrp -R myuser .
ls -al blub 

->赤い背景なしでファイル名を表示します-> setuidがなくなっています


1
この4XXXビットはスティッキーではなく、setuidビット(s)と呼ばれます。スティッキーはtビットであり、その目的は少し異なります:en.wikipedia.org/wiki/Sticky_bit
zuazo

2
(1)setuidビットではなくビットを設定しているsticky。(2)setuid行うとき、chgrpまたはchownセキュリティ上の問題になるときにビットをクリアしない。
佐藤桂2016

1
この動作はディストリビューション間で異なります。ただし、ここで説明するように、setuidビットの変更は、基になるsyscallの動作によって異なります。
zuazo 2016

みんなありがとう。あなたは正しいです、これはsetuidビットについてです!ご協力いただきありがとうございます。また、これは「設計どおりに機能する」ことを認めます。今、私はそれらのビットを殺すことなく行う必要があることを行うための最も健全な方法を見つける必要があります。私はgefaclを使用してテキストダンプを作成し、テキスト構成を修正してから適用することを検討しています。これで、何が起こるかを完全に制御できるはずです。
GhostCat

回答:


7

chgrp -R nobody /whateversetuidビットを保持したまま実装したい場合は、次の2つのfindコマンドを使用できます

find /whatever ! -type l -perm -04000 -exec chgrp nobody {} + \
                                      -exec chmod u+s {} +
find /whatever ! -type l ! -perm -04000 -exec chgrp nobody {} +

このfind ... -perm 04000オプションは、setuidビットが設定されたファイルを取得します。最初のコマンドは次にを適用しchgrp、次にa chmodを適用して、ノックオフされたsetuidビットを復元します。2番目の方法chgrpは、setuidビットを持たないすべてのファイルに適用されます。

いずれの場合も、シンボリックリンクを呼び出しchgrpたりchmod、ターゲットに影響を与えるため、シンボリックリンクを使用しないでください! -type l


chgrpまた、復元する必要があるsetgidビット(およびLinuxの機能)もクリアすることに注意してください。
ステファンChazelas

@StéphaneChazelas正解ですが、誰もsetgidについて言及していないので、その解決策を提供することについては心配していませんでした。ただし、このソリューションは自明な拡張性がありますが、3分の1find
roaima

さて、それは3番目の発見ではありえません、あなたはケースu + g、uだけ、gだけをカバーしなければなりません。いずれの場合も、1回のfind呼び出しで実行できるはずです。テキストをスクロールする必要がある場合、SEの長い行は好きではありません。私の追加!-type lは、それがエッジの上に行かせた
ステファンChazelas

さて、/ を複数の呼び出しに分割してしまうfindと、1つのアプローチを-exec +確実に実行するのが難しい場合があります。chmodchgrp
ステファンChazelas

1
実はfind . ! -type l -exec chgrp nobody {} + \( -perms -6000 -exec chmod gu+s {} + -o -perms -4000 -exec chmod u+s {} + -o -perms -2000 -exec chmod g+s {} + \)大丈夫だと思います。chgrpより多くのファイルと一致するため、すべてのファイルについて、sのに行う必要がありますchmod
ステファンChazelas

5

SUIDおよびSGIDビットをchgrp(またはchown)クリアすることは完全に合理的です。セキュリティ上の問題を防ぐための安全対策です。SGIDの場合(実行可能ファイルでは、私は推測する)は、グループ所有者の有効なグループでこのプログラムを実行することを意味します

グループの所有者を変更すると、セキュリティとアクセス制御の点でこれはまったく異なるものになります。つまり、実効グループで実行する代わりにuvw、プログラムは実効グループで実行されるようになりxyzます。

したがって、所有権の変更時に明示的にSUIDまたはSGIDビットを復元する必要があります。

補遺:chgrp(またはchown)はSGID(またはSUID、それぞれ)のみをクリアする必要があるという主張について

chownINGのかchgrpINGのあなたは、実行可能ファイルのセキュリティ設定を変更し、この属性を上昇させる任意の特権をクリアするのに十分な理由です。Unixの威力は概念の単純さに由来し、Unixのセキュリティはすでにかなりトリッキーです。この目的のために、所有権の変更時にSUIDとSGIDを削除することは、単なる安全策です。結局のところ、Unix / Linuxの歴史には、SUIDまたはSGID設定の誤解によるかなりの脆弱性がありました。

したがって、Unixがこのように動作する深い理由はありません。これは、保守的な設計上の決定にすぎません。


1
これは、所有者の変更がSUIDビットをクリアし、グループの変更がSGIDビットをクリアする理由を完全に説明しています。しかし、問題は、SUIDを実行するユーザーに影響を与えない、グループ変更操作中のSUIDビットについてです。したがって、別の説明が必要です。
Ben Voigt 2016

1
@BenVoigt:それはかなり良いことを説明しています。chownとchgrpはどちらもchown()syscallを呼び出します。これにより、通常のファイルのsuidとsgidがクリアされます。
ジョシュア

1
@ジョシュア:それは説明です。説明は「効果的なグループで実行する代わりにuvw、プログラムが効果的なグループで実行されるケースを回避するためxyz」ですが、これは議論中のケースには当てはまりません。
Ben Voigt 2016

します。chowningまたはchgrping によってセキュリティ設定を変更します。これは、特権昇格属性をクリアする十分な理由です。さもなければこれが不注意を打つ可能性は高いです。
カウンター

4

非ディレクトリのsetuidsetgidビット(少なくともLinuxでは)のクリアは、それ自体ではなく、によってchown()行われるシステムコール時にカーネルによって行わchgrpchgrpます。したがって、後でそれを復元するのが唯一の方法です。

また、セキュリティ機能もクリアされます。

したがって、GNU Linuxでは:

chown_preserve_sec() (
  newowner=${1?}; shift
  for file do
    perms=$(stat -Lc %a -- "$file") || continue
    cap=$(getfattr -m '^security\.capability$' --dump -- "$file") || continue
    chown -- "$newowner" "$file" || continue
    [ -z "$cap" ] || printf '%s\n' "$cap" | setfattr --restore=-
    chmod -- "$perms" "$file"
  done
)

そして(としてroot):

chown_preseve_sec :newgroup file1 file2...

権限を保持しようとしながらグループを変更します。

再帰的に、次のことができます:

# save permissions (and ACLs). Remove the "# owner" and "# group" lines
# to prevent them being restored!
perms=$(getfacl -RPn . | grep -vE '^# (owner|group): ')
# save capabilities
cap=$(getfattr -Rhm '^security\.capability$' --dump .)

chgrp -RP nobody .

# restore permissions, ACLs and capabilities
printf '%s\n' "$perms" | setfacl --restore=-
[ -z  "$cap" ] || printf '%s\n' "$cap" | setfattr -h --restore=-

(それ以外に何も同時にファイルをめちゃくちゃにしていないことを前提としています)。


1

いつものように管理することには多くの方法があります。

私が配置したソリューションは次のようになります:

cd /home/me
getfacl -R /whatever > whatever-permissions.org 2> /dev/null

# A) change lines starting with      # group: root
# to                                 # group: whatineed
sed 's/^# group: root/# group: whatineed/g' whatever-permissions.org > whatever-permissions.new

# B) change lines with               group::x.y
# to                                 group::xwy
# (where x, y mean: whatever was there before)
sed 's/^group::\(.\).\(.\)/group::\1w\2/g' whatever-permissions.new > whatever-permissions.new

cd /
setfacl --restore /home/me/whatever-permissions.new
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.