より広い文脈では、私はQEMU + KVMを使用して次のようにUbuntuマシンを仮想化します。
qemu-system-x86_64 \
-enable-kvm \
-m 2048 \
-nic none \
-vnc :5 \
-hda test-vm.raw \
-device vfio-pci,host=01:00.0 \
-serial unix:/tmp/console.sock,server,nowait
/tmp/console.sock
「シリアル」を介してVMにログインするために使用するもの:
socat stdin,raw,echo=0,escape=0x11 "unix-connect:/tmp/console.sock"
これは大きな問題なしでうまく機能します。
ただし、パスワードを入力すると、プロセスが開始さsudo su
れたagetty
端末(シリアルコンソールではない)にパスワードの入力を求められます。
agetty
端末から起動するのが一般的な起動方法ではないことを知っています。
agetty
ところで、どのようにこのようなことが起こるのか、ターミナルなしでターミナルから始める方法が気になります。どの接続(sudo
起動した端末でパスワードを要求すると、パスワードがあるとagetty
信じられます。はい一部の接続)を起動した端末に接続します。
私は努力しました:
$ nohup agetty ttyS0 9600 &
$ disown <pid>
成功しませんでした。
ここで動作する基本的なメカニズムとこの問題をどのように解決できるかを知りたいです*。
agetty
*前述のように、一般端末から始めるのは、このプログラムを使用する方法ではないことがわかっています。私はこれがどのように起こるのか、そしてagetty
これらの行動を防ぐ方法にまだ興味があります。
答え1
端末で実行すると、agetty
新しいセッションのセッションリーダーになり、それを呼び出した制御端末を継承します。したがって、仮想マシンで実行されるすべてのコマンドは制御端末を継承し、sudoなどのユーティリティの動作に影響します。 agetty が起動する端末は制御端末として使用されるため、sudo でパスワードの入力を求められます。
ターミナルセッションは通常、セッションで実行されている各プロセスが属するセッションID(SID)に関連付けられます。 SIDを設定するプロセスをセッションリーダーと呼びます。 agettyが起動すると、新しいセッションのセッションリーダーになり、制御端末を継承します。したがって、sudo
仮想マシンで実行すると、agettyプロセスが開始される端末でパスワードを入力するように求められます。
agettyと端末間の接続を切断するには、setidコマンドを使用できます。
setsid agetty ttyS0 9600
このsetsid
コマンドは新しいセッションを作成し、呼び出されたコマンドを新しいセッションのセッションリーダーに設定します。また、この操作はコマンドに制御端末がないように設定し、新しいセッション(たとえばsudo
)で生成されたプロセスが元の制御端末を継承しないようにします。 ~からPOSIX仕様setsid
:
呼び出しプロセスがプロセスグループリーダーではない場合、setid()関数は新しいセッションを作成します。返されると、呼び出しプロセスはこの新しいセッションのセッションリーダーでなければならず、新しいプロセスグループのプロセスグループリーダーでなければならず、制御端末があってはなりません。呼び出しプロセスのプロセスグループIDは、呼び出しプロセスのプロセスIDと同じに設定する必要があります。呼び出しプロセスは新しいプロセスグループの唯一のプロセスであり、新しいセッションの唯一のプロセスである必要があります。
sudo
最初にこの制御端末に興味があるのはなぜですか?このsudo
コマンドは、stdout または stderr に書き込むのとは異なり、仲介者を介さずに呼び出すユーザーと直接対話するために最善を尽くします。 stdoutまたはstderrに記録すると、機密情報が公開される危険性があるか、他のプロセスがこのデータを盗聴する可能性があります。
制御端末はユーザーの直通回線に近いと見なされ、パスワード入力などのユーザーに敏感な作業のためのより安全なチャンネルになります。 sudo が呼び出されると、通常は stdout または stderr をバイパスし、パスワードプロンプトを端末に直接書き込みます。これは、パスワードプロンプトがユーザーに表示され、誤ってリダイレクト、記録、キャプチャされないようにするためです。