Linuxでユーザー権限がどのように機能するかを知りたいです。カーネルがinit
起動し、root で始まります。そうですか?その後、Initは起動スクリプトを実行し、再びrootとして実行されますgetty
(agetty
)。login
私はAgettyが単にユーザー名を読んで実行され、まだrootとして実行されていると思います。まだ興味深い内容はありません。しかし、何が役に立ちますか?ログインする? 「ログインしようとしました」より優れているものが見つかりませんでした。ログインが一致するパスワードを見つけたとし(一般ユーザーとしてログインしようとした場合)、ユーザーIDはどのように変更されますか?システムコールが必要なようですが、見つかりません。 (おそらく私は目が遠いのでしょうか?)
また、su
「su
setuid」ビットが設定されているため、実行時に常にrootとして実行されます。ただし、通常のユーザーとしてログインするように求められた場合は、ユーザーIDを再度変更する必要があります。ユーザーを変更する必要があるときに同じ「魔法」が発生することを正しく理解していますかsu
?login
それでは、なぜ2つの異なるプログラムがありますか?ログインを実行すると、他の種類の深刻なビジネスが発生しますか?
答え1
ログインプログラムの機能はいくつかの部分に分かれています。ログインプログラムは、ログインしようとしているユーザーとは異なる方法で対話します。ここにいくつかの例があります。
login
:テキスト端末の入力を読み込みます。su
:ログインしたユーザーが呼び出して、コマンドライン引数からほとんどのデータと端末から認証データ(パスワード)を取得します。gksu
:と似ていますsu
が、Xから認証データを読み込みます。rlogind
: TCP 接続で入力を受け取るログイン規約sshd
: TCP 接続で入力を受け取るSSH規約- Xディスプレイマネージャ(xdm、gdm、kdm、...):同様です
login
が、Xディスプレイの入力を読みます。
これらのプログラムは同様の方法で動作します。
最初の部分は確認する:プログラムはユーザーからいくつかの入力を読み取り、ユーザーにログイン権限があることを確認します。従来のアプローチは、ユーザー名とパスワードを読み、そのユーザーがシステムのユーザーデータベースに記載されていること、ユーザーのパスワードが正しいことを確認することです。ユーザーが入力した内容はデータベースの内容です。しかし、他の可能性もたくさんあります(使い捨てパスワード、バイオメトリクス、権限転送など)。
ユーザーにどのアカウントでログインする権限があるかを確認したら、ログイン手順を使用して、このセッション中にユーザーが属するグループなどのユーザー権限を設定します。
ログインプロセスでは、アカウントの制限も確認できます。たとえば、ログイン時間または最大ログインユーザー数を適用したり、特定のユーザーへの特定の接続を拒否したりできます。
最後に、ログインプログラムはユーザセッションを確立する。いくつかのサブステップがあります:
- ユーザー、グループ、制限などの承認で決定されたプロセス権限を設定します。ここでは、このサブステップの簡単な例を見ることができます。(ユーザーとグループのみを処理します)。デフォルトのアイデアは、ログインプログラムがこの時点でまだrootとして実行されているため、最大の権限を持つことです。まず、root ユーザーを除くすべての権限を削除し、最後に
setuid
最も重要な権限の削除を呼び出します。 - ユーザーのホームディレクトリがマウントされ、「メールがあります」というメッセージが表示されることがあります。
- ユーザーとしてプログラム、通常はユーザーのシェルを呼び出します(コマンドが
login
指定されていないsu
場合sshd
、XディスプレイマネージャはXセッションマネージャまたはウィンドウマネージャを呼び出します)。
- ユーザー、グループ、制限などの承認で決定されたプロセス権限を設定します。ここでは、このサブステップの簡単な例を見ることができます。(ユーザーとグループのみを処理します)。デフォルトのアイデアは、ログインプログラムがこの時点でまだrootとして実行されているため、最大の権限を持つことです。まず、root ユーザーを除くすべての権限を削除し、最後に
現在、ほとんどのユニPAM(プラグ型認証モジュール)ログインサービスを管理する統合された方法を提供します。 PAMはその機能を次のように分割します。4部品:「auth」には認証(上記1)と承認(上記2)が含まれています。上記の3と4のような「アカウント」と「パスワード」はログインには使用されませんが、認証トークンの更新には使用されます(パスワードなど)。
答え2
探しているシステムコールはsetuid
と同じと呼ばれます。seteuid
しかし、実際には、変更したいユーザーIDのバリエーションに応じて、完全なヘムシリーズがあります。
setgid
プロセスが実行されるグループを変更するなど、いくつかの並列呼び出しもあります。
答え3
login
必要に応じてroot権限が放棄されます。最初にroot権限のみを必要とする多くのプログラムはrootで始まり、必要な操作を実行してから通常のユーザーアカウントにドロップダウンするので、誰かがrootにアクセスするためにバイナリのバグを使用することを心配する必要はありません。シェル。login
当然、特権はより長く維持されますが、原則は同じです。
実際、root権限を放棄するのはとても簡単です。ユーザーIDとグループIDをそれぞれ変更するPOSIX定義setuid()
と関数(ルートで始まる場合はtrueで有効)。これら2つのグループを呼び出して追加のグループを設定します。 (これはデフォルトグループIDの設定にのみ使用されます。)setgid()
login
initgroups()
setgid
もちろん、実際にプロセスUID / GID変更を処理するのはカーネルです。Linuxカーネルシステムコールの実装を見つける方法は?私のカーネルソースコードには、システムコールの多くの説明があります。
#define __NR_setgid 144
__SYSCALL(__NR_setgid, sys_setgid)
#define __NR_setuid 146
__SYSCALL(__NR_setuid, sys_setuid)
したがって、144と146は、マイコンピュータのこれらの機能のシステムコール番号です。
su
ソースコードが何であるかを確認しませんでしたが、exec()
同じ方法でシェルを実行する前にroot権限を削除することが疑われます。