\r\n\r\n
SUID、SGID、Stickyビットは、Linux上の実行ファイルやディレクトリに設定できる強力な特殊権限です。それらを使用するメリットと潜在的な落とし穴をお伝えします。
マルチユーザーオペレーションシステムにセキュリティを組み込むことは、いくつかの困難があります。パスワードの基本概念(のように見えるもの)を例にとります。誰かがログインするたびに、その人が入力したパスワードと保存されているパスワードを比較できるように、パスワードはすべて保存されていなければならない。明らかに、パスワードは王国への鍵であり、保護されなければならない。
Linuxでは、保存されたパスワードは暗号化され、root権限を持つ人だけがパスワードを含むファイルにアクセスできる、という2つの方法で保護されています。ルートアクセス権を持つ人だけが保存されたパスワードにアクセスできる場合、そのアクセス権を持たない人はどうやってパスワードを変更すればよいのでしょうか?
通常、Linuxのコマンドやプログラムは、そのプログラムを起動した人と同じ権限セットで実行されます。rootがパスワードを変更するためにpasswdコマンドを実行すると、rootの権限で実行されます。つまり、passwdコマンドは、/etc/shadowファイルに保存されているパスワードに自由にアクセスできるのです。
理想的な解決策は、システム上の誰もがpasswdプログラムを起動できるが、passwdプログラムはrootの昇格した特権を保持することである。こうすることで、誰でもパスワードを変更することができます。
上記のシナリオは、まさにSUID(Set User ID)ビットが行うことです。プログラムやコマンドの実行に、プログラムを起動した人ではなく、ファイルの所有者のパーミッションを使用するのです。
しかし、もう一つの混乱がある。他人のパスワードに干渉できないようにする必要がある。 LinuxはSUID方式を採用しており、一時的に権限を借りたアプリケーション群を実行できるようになっているが、これではセキュリティが半分しか確保できない。
他人のパスワードが使われないようにする制御機構は、OSやSUID方式ではなく、passwdプログラムに含まれています。
セキュリティ・バイ・デザイン」を念頭に置いて作成されていない場合、昇格した特権でプログラムを実行することは、セキュリティ・リスクをもたらす可能性があります。つまり、セキュリティを一番に考え、その土台の上に構築していくのです。プログラムを書いてから、セキュリティのうわべを取り繕うようなことはしないでください。
オープンソースソフトウェアの大きな利点は、自分でソースコードを見ることも、信頼できるピアレビューを参照することもできることです。passwdプログラムのソースコードには、プログラムを実行している人がrootかどうかを確認するためのチェックがあります。誰かがrootユーザー(またはsudoを使っている人)であれば、異なる機能が許可されます。
これは、誰かがルートユーザーであるかどうかを検出するコードです。
これを考慮した例を紹介します。rootはどんなパスワードでも変更できるため、プログラムが通常行う、ユーザーが変更する権利があるパスワードを確認するためのチェックをわざわざ行う必要がないのです。したがって、rootの場合は、これらのチェックをスキップしてチェック機能を終了します。
Linuxのコアとなるコマンドやユーティリティであれば、セキュリティを実装していることはもちろん、何度もコードのレビューが行われていることが確認できます。もちろん、未知のエクスプロイトの脅威は常に存在します。ただし、確認された脆弱性**に対処するためのパッチやアップデートは近日中に提供される予定です。
特にオープンソースでないものはサードパーティーのソフトウェアであり、SUIDを使用する場合は特に注意が必要です。しかし、もしやるのであれば、システムを危険にさらすことがないようにしたいものです。自分自身とそれを動かす人々を適切に自律化しないプログラムの権限を昇格させたくはないでしょう。
以下に、SUIDビットを利用して、一般ユーザーで実行した場合にコマンドに昇格特権を付与するLinuxコマンドを紹介します。
ls -l /bin/su ls -l /bin/ping ls -l /bin/mount ls -l /bin/umount ls -l /usr/bin/passwdSUIDビットが設定されていることを示すために、ファイル名が赤くハイライトされていることに注意してください。
ファイルやディレクトリのパーミッションは,通常3つの文字で表されます.レターがある場合は、許可されたことになります。ただし、文字ではなくハイフン(-)が表示されている場合は、許可が下りていないことを意味します。
これらの権限には、左から順に、ファイル所有者の権限、ファイルグループのメンバーの権限、その他の権限の3つのグループがあります。ファイルにSUIDビットを設定する場合、"s "は所有者の実行権限を示す。
実行機能を持たないファイルにSUIDビットが設定されている場合、大文字の "S "がそのことを示す。
例として、一般ユーザのdaveがpasswdコマンドを入力した場合を見てみましょう。
passwdpasswdコマンドはdaveに新しいパスワードを要求し、psコマンドは実行中のプロセスの詳細を表示することができます。
別の端末ウィンドウでpsとgrepを使い、passwdの処理を探します。また、psの-e(プロセス毎)、-f(フルフォーマット)オプションも使用することにします。
次のようなコマンドを入力します。
ps -e -f | grep passwd2行が報告され、そのうちの2行目はgrep処理で、"passwd "という文字列のコマンドを探します。しかし、この行はdaveが開始したpasswd処理の最初の行であるため、我々が関心を持つのはこの行である。
rootが起動したときと同じようにpasswdのプロセスが実行されていることがわかります。
SUIDビットはchmodで簡単に変更できます。u+s符号モードはSUIDビットをセットし、u-s符号モードはそれをクリアします。
SUIDビットの概念の一部を説明するために、htgというアプレットを作成しました。daveユーザのルートディレクトリにあり、SUIDビットはありません。実行すると、実在する有効なユーザーID(UID)が表示されます。
本当のUIDは、プログラムを起動した人のものです。有効なIDは、プログラムを起動するのに使われたアカウントと同じように、プログラムを実行するのに使われたアカウントです。
以下のように入力します。
ls -lh htg ./htgこのプログラムのローカルコピーを実行すると、実IDと有効IDの両方がdaveに設定されていることがわかります。したがって、通常のプログラムのように動作します。
他の人が使えるように、/usr/local/binディレクトリにコピーしておきましょう。
SUIDビットを設定するためにchmodを使って以下のコマンドを入力し、設定されていることを確認します。
sudo cp htg /usr/local/bin sudo chmod u+s /usr/local/bin/htg ls -hl /usr/local/bin/htgそこで、プログラムをコピーして、SUIDビットを設定します。もう一度実行しますが、今度は /usr/local/bin フォルダにあるコピーを
htgdaveがプログラムを起動しても、有効なIDはrootユーザーに設定されています。したがって、maryがプログラムを起動しても、次のように同じことが起こります。
htg本当のIDはMaryで、有効なIDはrootです。プログラムはrootユーザーの権限で実行されます。
関連:Linuxでのchmodコマンドの使い方
SGID(Set Group ID)ビットはSUIDビットと非常によく似ています。実行ファイルにSGIDビットが設定されている場合、そのファイルのグループが有効グループに設定されます。このプロセスは、起動した人の権限ではなく、ファイルグループのメンバーの権限で実行されます。
有効なグループも表示されるように、htgプログラムを調整しました。htgのプログラムグループをユーザーmaryのデフォルトグループmaryに変更します。また、USをchownとg+s symbol modeで使用し、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 を表示します。 その後、dave として htg プログラムを実行します。
次のようなコマンドを入力します。
id -G dave id -G mary htgmaryのデフォルトのグループIDは1001で、htgプログラムの有効なグループは1001です。したがって、このプログラムはdaveによって開始されたものの、maryのグループのメンバーの権限で実行されたことになります。まるでデイブがメアリーのグループに参加したかのようです。
SGIDビットをディレクトリに適用してみましょう。まず、「work」というディレクトリを作成し、そのグループを「geek」に変更し、そのディレクトリにSGIDビットを設定することにします。
lsを使ってディレクトリの設定を確認する場合、ディレクトリの内容ではなく、ディレクトリの詳細を確認するために、-d(ディレクトリ)オプションも使用することにしています。
次のようなコマンドを入力します。
sudo mkdir work sudo chown dave:geek work sudo chmod g+s work ls -lh -d workSGIDビットと "geek "グループを設定します。これらは、作業ディレクトリに作成されるすべてのアイテムに影響します。
以下のように入力して、作業ディレクトリにアクセスし、"demo "というディレクトリを作成し、そのプロパティを確認します。
cd work mkdir demo ls -lh -d demoSGIDビットと "geek "グループは、"demo "ディレクトリに自動的に適用されます。
次のように入力して、ファイルを作成し、touchコマンドでそのプロパティを確認してみましょう。
touch useful.sh ls -lh useful.sh新規ファイルのグループは自動的に "geek "に設定されます。
関連:Linuxにおけるchownコマンドの使用方法
スティッキービットの名前の由来は、その歴史的な用途からきています。実行ファイルに設定すると、実行ファイルのテキスト部分をスワップに保持するようオペレーティングシステムにマークし、再利用を高速化します。Linuxでは、スティッキービットはディレクトリにのみ作用し、ファイルに設定しても意味がありません。
ディレクトリにスティッキービットを設定すると、ユーザーはそのディレクトリ内の自分の所有するファイルのみを削除することができます。他人が所有するファイルは、そのファイルにどのようなパーミッションの組み合わせが設定されていても、削除することはできません。
これにより、各人や起動したプロセスが共有ファイルストレージとして使用できるディレクトリを作成することができます。これらのファイルは、やはり誰も他人のファイルを削除することはできないので、保護されています。
shared」というディレクトリを作成し、そのディレクトリに対して、chmodのo+tシンボリックモードでスティッキービットを設定することにしましょう。次に、そのディレクトリと、/tmpおよび/var/tmpディレクトリのパーミッションを確認します。
次のようなコマンドを入力します。
mkdir shared sudo chmod o+t shared ls -lh -d shared ls -lh -d /tmp ls -lh -d /var/tmpスティッキービットが設定されている場合、「その他」のファイルパーミッションセットの実行可能ビットは「t」に設定され、ファイル名も青色でハイライト表示されます。
tmpと/var/tmpフォルダは、所有者、グループ、その他のすべてのファイルパーミッションが設定されているディレクトリの例です(そのため、緑色で強調表示されています)。一時ファイルの共有場所として使用されます。
このパーミッションがあれば、理論的には誰でも何でもできるはずです。しかし、スティッキービットはそれらを上書きし、誰も自分のものでないファイルを削除することはできません。
今後の参考のため、上記で説明した内容を簡単に列挙します。