1

Это моя ситуация:

  • Я добавил новую группу в мой пользователь.
  • Я проверил /etc/group правильно настроен.
  • Если я сделаю su - myuser группа будет показана с id -a
  • Но выход из системы и повторный вход (через ssh) не перезагружают группу: id -a не показывает новую группу

Это как SSH-соединение повторно использовало какой-то процесс со старыми настройками группы.

Что бы это могло быть?

Дополнительная информация:

  • Я использую tmux , но на клиенте. На сервере, на котором я sshing (и где я меняю группы), tmux работает.
  • Возможно, это связано с совместным использованием SSH-соединения.

1 ответ1

0

так как соединение ssh повторно использовало какой-то процесс со старыми настройками группы

После того, как вы упомянули совместное использование SSH-соединения, становится очевидным, что это виновник. Чтобы понять проблему, давайте посмотрим, как процесс в Linux несет информацию о своем владельце.


Порождая новые процессы

Все процессы происходят от процесса с PID 1 (init upstart или systemd , Который принадлежит пользователю root . Процесс может дублировать себя, смотрите man 2 fork ; или он может заменить свой собственный образ другим, см. man 3 exec . Обычный способ для программы A порождать программу B - это разветвление, поэтому временно существует два экземпляра A , а затем exec для B (новый A становится B). Теперь есть A (родительский процесс) и B (дочерний процесс).

Каждый процесс несет информацию о своем владельце и группах, см. man 2 getuid , man 2 getgid , man 2 getgroups . Когда порождается дочерний процесс, он обычно наследует эту информацию.

Чтобы создать процесс, принадлежащий пользователю, отличному от root , в какой-то момент привилегированный процесс должен сменить своего владельца. Он использует setuid(2) , setgid(2) , setgroups(2) и аналогичные для достижения этой цели. Обычно задается желаемый UID, и из него выводятся группы (включая дополнительные группы). Это момент, когда новая группа становится активной.

После запуска непривилегированного процесса его дочерние элементы (если таковые имеются) просто наследуют информацию, не запрашивая ОС для текущего набора групп, к которым принадлежит пользователь. В этот момент новая группа не может стать активной. Есть исключения: такие программы, как su , sg или sudo с установленным флагом и принадлежащие пользователю root запускаются как привилегированные. После того, как они удостоверились, что пользователю разрешено выполнить действие, ситуация идентична уже обсужденной, где новая группа становится активной.

Поэтому su - myuser замечает новую группу, потому что она меняет пользователей за кулисами. Получение текущего набора групп, к которым принадлежит пользователь, является частью этого процесса.

С другой стороны, id показывает, что он унаследовал от оболочки. Эта информация старая; это время, когда его привилегированный предок манипулировал своим идентификатором пользователя.

Примечание id myuser заметит новую группу. Единственный id извлекает информацию, связанную с ним (с помощью getgroups(2) и т.д.), В то время как id myuser запрашивает у ОС текущую информацию о выбранном пользователе.

Вывод таков: ваша оболочка (и ее дочерние элементы) заметят новую группу, если она является потомком какого-то привилегированного процесса, поэтому переход между пользователем 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

Поскольку второй bash был создан после привилегированного login после того, как я внес изменение, он будет знать о новой группе. В этом базовом случае работает подход "выйти и снова войти".

GUI (все еще без SSH)

Рассмотрим примерную часть дерева процессов:

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

После добавления моего пользователя в новую группу новая оболочка (новая вкладка) в konsole не увидит изменения. И не будет xterm , если я создам его из плазмы KDE (plasmashell). Но если бы я войти через /dev/tty2 правильно установить и экспортировать переменную DISPLAY затем икру xterm оттуда, оболочка в xterm будет видеть изменения. В обоих случаях xterm отображается на том же рабочем столе KDE, но первый происходит (косвенно) из привилегированного процесса, который давно переключил пользователей, до изменения; последний происходит (косвенно) из привилегированного процесса, который переключил пользователей минуту назад, после изменения.

SSH

В моих ветках Debian sshd (SSH daemon) снова и снова вилки, соответствующая часть дерева процессов выглядит так:

systemd───sshd───sshd───sshd───bash
^^^^^^^^^^^^^^^^^^^^^               these are owned by root
                        ^^^^^^^^^^^ these are owned by my user

После того, как я подключился во второй раз, без совместного использования подключения:

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 появился из старого sshd принадлежащего моему пользователю. Этот sshd содержит старую информацию о моих группах, новый bash унаследовал ее.

Я верю, что то же самое происходит в вашем случае.

tmux

Проблема не ограничивается sshd . Возьми tmux . В общем случае использования tmux , после входа пользователя tmux может быть запущен непосредственно как оболочка входа или косвенно из (не tmux) оболочки входа (вручную или как .bashrc ; с или без exec). Инструмент подключается как клиент к серверу tmux принадлежащему пользователю. Если для данного пользователя еще нет сервера, он будет запущен. Именно сервер запускает "финальную" оболочку. Дерево процессов может выглядеть так:

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

После того, как я добавлю своего пользователя в новую группу, новый bash созданный при login , увидит группу. Новый сервер tmux и его дети увидят его. Но уже работающий сервер tmux и его дочерние элементы этого не делают; это верно даже для потомка (оболочки), порожденного после добавления моего пользователя в новую группу.

Для ясности: клиент и сервер tmux не имеют ничего общего с клиентом и сервером SSH; они оба работают на одной машине. tmux будет иметь значение только в том случае, если он запускается там, где было внесено изменение. Вы упомянули tmux на стороне клиента SSH, а изменение было сделано на стороне сервера SSH; так что в вашем случае tmux имеет значения.

Предположим, у меня есть tmux где было сделано изменение. Чтобы новые оболочки внутри tmux заметили новую группу, мне нужно завершить (не отсоединять, действительно выйти) все, что уже запущено внутри tmux , так что мой сервер tmux завершает работу, чтобы его можно было порождать заново. Убийство сервера должно работать, но это имеет очевидные недостатки.

Запуск отдельного сервера tmux технически возможен. Если мне не нужно присоединяться к уже запущенному сеансу, это путь. Смотрите -L и -S в man 1 tmux . Если tmux запускается автоматически после входа в систему, мне может понадобиться обойти это, чтобы передать -L , например:

ssh -t user@host tmux -L foo

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .