web-dev-qa-db-ja.com

tmux経由でSSHログインした後、新しいグループがアクティブにならないのはなぜですか?

これは私の状況です:

  • ユーザーに新しいグループを追加しました。
  • /etc/groupが正しく設定されていることを確認しました。
  • su - myuserを実行すると、グループはid -aで表示されます。
  • ただし、ログイン(ssh経由)で再度ログインしても、グループは再読み込みされません。id -aしません新しいグループを表示します

これは、SSH接続が古いグループ設定で一部のプロセスを再利用していたためです。

これは何でしょうか?

追加情報:

  • tmuxを使用していますが、クライアント上にあります。私がsshしている(そしてグループを変更している)サーバーでは、tmuxが実行されていません。
  • これは、ssh接続の共有に関連している可能性があります。
2
dangonfast

ssh接続が古いグループ設定で一部のプロセスを再利用していたため

SSH接続の共有について言及した後、これが原因であることは明らかです。問題を理解するために、Linuxのプロセスがその所有者に関する情報をどのように伝達するかを見てみましょう。


新しいプロセスを生み出す

すべてのプロセスは、ユーザーinitに属するPID1(upstartまたはsystemdまたはrootなど)を持つプロセスから発生します。プロセスはそれ自体を複製できます。_man 2 fork_を参照してください。または、独自の画像を別の画像に置き換えることもできます。_man 3 exec_を参照してください。プログラム[〜#〜] a [〜#〜]がプログラム[〜#〜を生成する一般的な方法] b [〜#〜]はフォークするため、一時的に[〜#〜] a [〜#〜]、次にexec to[〜#〜] b [〜#〜](新しい[〜#〜] a [〜#〜][〜#〜] b [〜#〜])。 [〜#〜] a [〜#〜](親プロセス)と[〜# 〜] b [〜#〜](子プロセス)。

各プロセスは、その所有者とグループに関する情報を伝達します。_man 2 getuid_、_man 2 getgid_、_man 2 getgroups_を参照してください。子プロセスが生成されると、通常、この情報を継承します。

root以外のユーザーに属するプロセスを作成するには、ある時点で、特権プロセスがその所有者を変更する必要があります。これを実現するために、setuid(2)setgid(2)setgroups(2)などを使用します。通常、目的のUIDが指定され、グループ(補足グループを含む)がそれから派生します。これは、新しいグループがアクティブになる瞬間です。

非特権プロセスが生成された後、その子(存在する場合)は、ユーザーが属するグループのcurrentセットをOSに照会せずに、情報を継承します。に。現時点では、新しいグループをアクティブにすることはできません。例外があります。setuidフラグがあり、suが所有するsgSudoまたはrootのようなプログラムは、特権として起動します。ユーザーがアクションの実行を許可されていることを確認した後、状況はすでに説明した状況と同じになり、新しいグループがアクティブになります。

したがって、_su - myuser_は、舞台裏でユーザーを変更するため、新しいグループに気づきます。ユーザーが属するグループのcurrentセットを取得することは、このプロセスの一部です。

一方、idは、シェルから継承したものを示します。この情報は古いものです。特権のある祖先がユーザーIDを操作したときからです。

_id myuser_は新しいグループに気付くでしょう。唯一のidはそれ自体に関連付けられた情報を(getgroups(2)などで)取得し、_id myuser_はOSにcurrent選択したユーザーに関する情報。

結論は次のとおりです。シェル(およびその子)は、特権プロセスの子孫である場合に新しいグループに気付くため、グループが追加された後にrootとユーザーの間の移行が発生しました。 (正式な注意:rootからrootへの移行も同じです。重要なのは所有権を新たに設定する行為です)。


実際には

_/dev/tty2_かそこら(SSHなし)

標準のテキストコンソール(_/dev/tty2_など)からログインできます。プロセスツリーの関連部分は次のとおりです。

_systemd───login───bash───pstree
^^^^^^^^^^^^^^^                 these are owned by root
                  ^^^^^^^^^^^^^ these are owned by my user
_

ユーザーを新しいグループに追加し、別のttyにログインした後:

_systemd─┬─login───bash
        └─login───bash───pstree
^^^^^^^^^^^^^^^                 these are owned by root
                  ^^^^^^^^^^^^^ these are owned by my user
_

2番目のbashは、変更を加えた後に特権loginから生成されたため、新しいグループを認識します。この基本的なケースでは、「ログアウトして再度ログインする」アプローチが機能します。

GUI(まだSSHなし)

プロセスツリーの一部の例を考えてみましょう。

_systemd───plasmashell───konsole───bash
^^^^^^^                                this is owned by root
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ these are owned by my user
_

ユーザーを新しいグループに追加した後、konsoleの新しいシェル(新しいタブ)には変更が表示されません。また、KDE ​​Plasma(xterm)からスポーンした場合、plasmashellも発生しません。しかし、_/dev/tty2_経由でログインし、DISPLAY変数を適切に設定してエクスポートし、そこからxtermを生成すると、シェルはxtermwill変更を確認します。どちらの場合も、xtermは同じKDEデスクトップに表示されますが、最初の1つは、変更前にユーザーを切り替えた特権プロセスから(間接的に)発生します。後者は、変更後1分前にユーザーを切り替えた特権プロセスから(間接的に)発生します。

SSH

私のDebiansshd(SSHデーモン)フォークとフォークでは、プロセスツリーの関連部分は次のようになっています。

_systemd───sshd───sshd───sshd───bash
^^^^^^^^^^^^^^^^^^^^^               these are owned by root
                        ^^^^^^^^^^^ these are owned by my user
_

接続を共有せずに2回目に接続した後:

_systemd───sshd─┬─sshd───sshd───bash
               └─sshd===sshd───bash───pstree
^^^^^^^^^^^^^^^^^^^^^                        these are owned by root
                        ^^^^^^^^^^^^^^^^^^^^ these are owned by my user
_

その間にユーザーを新しいグループに追加したとします。私が_===_と示した「リンク」は、変更後に特権のあるsshdが非特権のリンクを生成したことを意味します。後者とその子孫は新しいグループを認識しています。

接続共有では、これは異なります。

_systemd───sshd───sshd───sshd─┬─bash
                             └─bash───pstree
^^^^^^^^^^^^^^^^^^^^^                        these are owned by root
                        ^^^^^^^^^^^^^^^^^^^^ these are owned by my user
_

この場合、新しいbashは、ユーザーが所有するoldsshdから生成されました。このsshdは私のグループに関する古い情報を運び、新しいbashはそれを継承しました。

あなたの場合も同じことが起こると思います。

tmux

問題はsshdに限定されません。 tmuxを取ります。 tmuxを使用する一般的なケースでは、ユーザーがログインした後、tmuxをログインシェルとして直接開始することも、(非tmux)ログインシェルから間接的に(手動で)開始することもできます。または_.bashrc_からのように; execの有無にかかわらず)。このツールは、クライアントとして、ユーザーが所有するtmuxサーバーに接続します。この特定のユーザーのサーバーがまだない場合は、サーバーが起動されます。 「最終的な」シェルを開始するのはサーバーです。プロセスツリーは次のようになります。

_systemd─┬─login───bash───tmux: client
        └─tmux: server─┬─3*[bash]
                       └─bash───pstree
_

ユーザーを新しいグループに追加した後、bashから生成された新しいloginはグループを認識します。 newtmuxサーバーとその子はそれを見るでしょう。しかし、すでに実行中tmuxサーバーとその子は実行していません。これは、ユーザーを新しいグループに追加した後に生成された子(シェル)にも当てはまります。

明確にするために:tmuxクライアントとサーバーはSSHクライアントとサーバーとは何の関係もありません。どちらも同じマシンで実行されます。 tmuxは、変更が行われた場所で実行される場合にのみ問題になります。 SSHのクライアント側でのみtmuxについて言及しましたが、変更はSSHのサーバー側で行われました。したがってあなたの場合はtmuxは無関係です

変更が加えられた場所にtmuxがあるとします。 tmux内の新しいシェルが新しいグループに気付くようにするには、tmux内ですでに実行されているすべてのものを終了する(デタッチではなく、実際に終了する)必要があるため、tmuxサーバーも終了します、したがって、新たにスポーンすることができます。サーバーを強制終了することは機能するはずですが、これには明らかな欠点があります。

別のtmuxサーバーを起動することは技術的に可能です。すでに実行中のセッションに接続する必要がない場合は、これが最適な方法です。 _-L_の_-S_および_man 1 tmux_を参照してください。ログイン後にtmuxが自動的に実行される場合、_-L_を渡すために、これを回避する必要がある場合があります。例:

_ssh -t user@Host tmux -L foo
_
1