- Dave McKay
@TheGurkha
- February 26, 2020, 8:00am EDT

SUID, SGID, Sticky BitsはLinuxで実行ファイルとディレクトリに設定できる強力な特別なパーミッションです。 8207>
They’re Already in Use
Building security into a multiuser operating system presents some quandaries.では、これらを使用する利点と潜在的な落とし穴を共有します。 たとえば、パスワードの (一見) 基本的な概念を見てみましょう。 誰かがログインするたびに、その人が入力したパスワードと保存されているコピーを比較できるように、パスワードはすべて保存されなければなりません。 明らかに、パスワードは王国への鍵であるため、保護されなければなりません。
Linux では、保存されたパスワードは 2 つの方法で保護されています。 もし root 権限を持つ人だけが保存されたパスワードにアクセスできるなら、その権限を持っていない人はどのようにパスワードを変更するのでしょうか。
Elevating Your Status
通常、Linux コマンドやプログラムはプログラムを起動した人と同じ権限セットで実行します。 rootがパスワードを変更するためにpasswdコマンドを実行すると、rootのパーミッションで実行されます。 つまり、passwd コマンドは /etc/shadow ファイルに保存されたパスワードに自由にアクセスできるのです。
理想的なのは、システム上の誰もが passwd プログラムを起動でき、passwd プログラムが root の昇格した権限を維持できる仕組みでしょう。
上記のシナリオはまさに Set User ID ビット (SUID) が行うことです。 プログラムを起動した人の権限ではなく、ファイルの所有者の権限でプログラムやコマンドを実行します。
You’re Elevating the Program’s Status
しかしながら、もう 1 つの難問があります。 その人が他の誰かのパスワードに干渉するのを防がなければならないのです。 Linux には SUID スキームが組み込まれており、一時的に借用した一連の権限でアプリケーションを実行することができますが、これはセキュリティの話の半分に過ぎません。
誰かが他人のパスワードで作業するのを防ぐ制御メカニズムは、OS や SUID スキームではなく、passwd プログラム内に含まれているのです。 つまり、セキュリティは最初に考慮すべきことであり、その上で構築するのです。 8207>
オープン ソース ソフトウェアの最大の利点は、ソース コードを自分で見ることができ、また、信頼できるピア レビューを参照することができることです。 passwd プログラムのソースコードにはチェックが入っていて、プログラムを動かしている人が root かどうかがわかります。 誰かが root である場合 (または sudo を使っている人)、異なる能力が許可されます。
誰かが root であるかを検出するコードです。

それが考慮された例が次のものです。 rootはどんなパスワードでも変更できるので、プログラムは通常行う、その人がどのパスワードの変更を許可しているかのチェックをわざわざ行う必要がない。

Linux のコアコマンドとユーティリティは、セキュリティが組み込まれていて、コードが何度も見直されていると確信できる。 もちろん、まだ知られていないエクスプロイトの脅威は常に存在します。
サードパーティのソフトウェア、特にオープンソースでないものは、SUIDを使用することに非常に注意する必要があります。 私たちはそれをするなとは言いませんが、もしするのであれば、それがあなたのシステムを危険にさらすことがないようにしたいものです。 正しく自己管理しないプログラムとそれを実行している人の権限を昇格させたくないのです。
Linux Commands That Use SUID
Linux コマンドのうち、SUID ビットを使用して、一般ユーザーによる実行時にコマンドに昇格した特権を与えるものを以下に示します:
ls -l /bin/su
ls -l /bin/ping
ls -l /bin/mount
ls -l /bin/umount
ls -l /usr/bin/passwd

Note the filename are highlighted in red, which shows the SUID bit is set.
ファイルやディレクトリのパーミッションは、通常3つの文字からなるグループ: rwx で表されます。 これらは read、write、execute の頭文字をとったものです。 文字があれば、その権限は与えられている。
これらのパーミッションには、左から右の順に、ファイルの所有者のためのもの、ファイルのグループのメンバーのためのもの、その他の人のためのものの 3 つのグループがある。
ファイルに SUID ビットが設定されている場合、「s」は所有者の実行権限を表す。
実行可能な機能を持たないファイルに SUID ビットが設定されている場合、大文字の「S」はこれを表す。
例を見てみる。 一般ユーザdaveはpasswdコマンドを入力する:
passwd

passwdコマンドはdaveに新しいパスワードを要求している。 8207>
別のターミナルウィンドウでpsとgrepを使用し、passwdプロセスを探します。
次のコマンドを入力する:
ps -e -f | grep passwd

2 行が報告され、そのうちの 2 行目は grep プロセスが “passwd” という文字を含むコマンドを検索しているというものである。
passwdプロセスは、rootが起動した場合と同じように動作していることがわかる。
Setting the SUID Bit
SUIDビットをchmodで簡単に変更することが可能である。 u+sシンボルモードはSUIDビットを設定し、u-sシンボルモードはSUIDビットをクリアします。
SUIDビットの概念のいくつかを説明するために、htgという小さなプログラムを作りました。 これは dave ユーザのルートディレクトリにあり、 SUID ビットは設定されていない。 実行すると、実ユーザIDと実効ユーザID (UID) が表示される。
実UIDはプログラムを起動した人のものである。
実IDはプログラムを起動した人に属する。実効IDは、プログラムが起動したように動作するアカウントである。
ls -lh htg
./htg

プログラムのローカルコピーを実行すると、実IDと実効IDが両方ともdaveに設定されていることがわかる。
他の人が使えるように、これを /usr/local/bin ディレクトリにコピーしてみましょう。
chmod を使って SUID ビットを設定し、設定されたことを確認します:
sudo cp htg /usr/local/bin
sudo chmod u+s /usr/local/bin/htg
ls -hl /usr/local/bin/htg

で、プログラムはコピーされ、SUID ビットは設定されています。 もう一度実行しますが、今度は/usr/local/binフォルダにコピーしたものを実行します:
htg

daveがプログラムを起動したにもかかわらず、実効IDはrootユーザに設定されています。 そこで、maryがプログラムを起動しても、以下のように同じことが起こります:
htg

実IDはmary、有効IDはrootです。 プログラムはrootユーザーの権限で実行されます。
RELATED: Linuxでのchmodコマンドの使い方
SGIDビット
セットグループID(SGID)ビットは、SUIDビットと非常によく似ています。 実行ファイルにSGIDビットが設定されると、有効なグループがそのファイルのグループに設定される。 プロセスは、それを起動した人の権限ではなく、ファイルのグループのメンバーの権限で実行されます。
私たちは htg プログラムを微調整して、有効なグループも表示するようにしました。 htg プログラムのグループを、ユーザー mary のデフォルトグループである mary に変更します。 また、chown で u-s と g+s のシンボリックモードを使用して、SUID ビットを削除し、SGID を設定します。
これを行うには、次のように入力します:
sudo chown root:mary /usr/local/bin/htg
sudo chmod u-s,g+s /usr/local/bin/htg
ls -lh /usr/local/bin/htg

グループの権限で “s” で示された SGID ビットが見えると思います。 また、グループがmaryに設定され、ファイル名が黄色でハイライトされていることに注意してください。
プログラムを実行する前に、daveとmaryがどのグループに属しているかを確定しておきましょう。 idコマンドに-G(groups)オプションを付けて、すべてのグループIDを表示させます。
id -G dave
id -G mary
htg

maryのデフォルトグループのIDは1001、htgプログラムの有効グループも1001であることがわかります。 つまり、daveで起動したものの、maryグループに所属するメンバーの権限で動作していることになります。 dave が mary グループに参加したのと同じです。
では、SGID のビットをディレクトリに適用してみましょう。 まず、”work” というディレクトリを作成し、そのグループを “geek” に変更します。
ディレクトリの設定を確認するためにlsを使用するとき、内容ではなくディレクトリの詳細を見るために-d (ディレクトリ) オプションも使用することにします。
sudo mkdir work
sudo chown dave:geek work
sudo chmod g+s work
ls -lh -d work

SGID bit と “geek” group が設定されました。
work ディレクトリに入り、”demo” というディレクトリを作成し、そのプロパティを確認するために次のように入力します:
cd work
mkdir demo
ls -lh -d demo

“demo” ディレクトリには自動的に SGID ビットと “geek” グループが適用されています。
次のように入力して、touchコマンドでファイルを作成し、そのプロパティを確認してみましょう:
touch useful.sh
ls -lh useful.sh

新しいファイルのグループは、自動的に「geek」になります。
関連情報。 Linux での chown コマンドの使い方
The Sticky Bit
The sticky bit の名前は、その歴史的な目的から付けられています。 実行ファイルに設定すると、実行ファイルのテキスト部分をスワップに保持するようオペレーティングシステムにフラグを立て、その再利用を高速化します。 Linux では、スティッキー・ビットはディレクトリにのみ影響し、ファイルに設定しても意味がありません。
ディレクトリにスティッキー・ビットを設定すると、そのディレクトリ内の自分に属するファイルのみを削除することができます。 ファイルに設定されたファイル権限の組み合わせに関係なく、他の誰かに属するファイルを削除することはできません。
これにより、すべての人と彼らが起動するプロセスが共有ファイル ストレージとして使用できるディレクトリを作成できます。 繰り返しになりますが、誰も他の人のファイルを削除できないため、ファイルは保護されます。
“shared” というディレクトリを作成しましょう。 そのディレクトリにスティッキービットを設定するために、chmodでo+tシンボリックモードを使用することにします。
次のコマンドを入力します:
mkdir shared
sudo chmod o+t shared
ls -lh -d shared
ls -lh -d /tmp
ls -lh -d /var/tmp

sticky bit が設定されると、ファイル権限の “other” セットで実行可能ビットは “t” に設定されます。 ファイル名も青で強調表示されます。
/tmp および /var/tmp フォルダーは、所有者、グループ、およびその他のすべてのファイル許可が設定されているディレクトリの例です (緑で強調表示されているのはそのためです)。 これらは一時ファイルの共有場所として使用されます。
これらのパーミッションがあれば、理論的には誰でも何でもできるはずです。
Reminders
今後の参考のために、上記で取り上げた内容を簡単にチェックリストにしておきます。
-
SUIDはファイルに対してのみ機能します。 -
SGIDはディレクトリとファイルに対して適用可能です。 - スティッキービットはディレクトリにしか適用できません。
- “
s“、”g“、”t” インジケータが大文字で表示された場合、実行ビット (x) は設定されていません。
Dave McKay が初めてコンピュータを使ったのはパンチテープが流行している時で、以来プログラミングを行っています。 IT業界で30年以上働いた後、現在はフルタイムのテクノロジー・ジャーナリストとして活躍しています。 フリーランスプログラマー、国際的なソフトウェア開発チームのマネージャー、ITサービスプロジェクトマネージャー、そして最近ではデータ保護責任者として活躍しています。 Linuxのエバンジェリストであり、オープンソースの提唱者でもある。