Безопасный переход пароля root в сценарий оболочки

Я всегда загружаю свой GNU / Linux ноутбук в консольном режиме. Но иногда мне нужно вызвать режим графического интерфейса. он всегда требует ввода пароля root. Поэтому я написал следующий скрипт «gogui.sh» и поместил его в /usr/bin :

 #!/bin/bash echo "mypassword" | sudo service lightdm start 

Это действительно глупая идея, как будто кто-то читает файл, может легко увидеть мой пароль.

Это альтернатива этому?

Передача пароля в sudo в скрипте совершенно бессмысленна. Вместо этого добавьте правило sudo, добавляющее определенную команду, которую вы хотите запустить с тегом NOPASSWD . Позаботьтесь о том, NOPASSWD правило NOPASSWD конкретной NOPASSWD приходилось после любого общего правила.

 saeid ALL = (ALL:ALL) ALL saeid ALL = (root) NOPASSWD: service lightdm start 

Но это, вероятно, не очень полезно. lightdm start запускает приглашение для входа, но вам нужно только это, если вы хотите, чтобы другие пользователи входили в систему графически. Это вам не нужно, если вы хотите начать сеанс GUI. Вместо этого вызовите startx для запуска сеанса GUI из сеанса текстового режима. Это не требует каких-либо дополнительных привилегий.

Возможно, вам нужно будет явно указать ваш оконный менеджер или среду рабочего стола, поскольку startx не может выбрать тот же тип сеанса по умолчанию, который использует lightdm.

 startx -- gnome-session 

Есть несколько вариантов, и один из них – добавить определенную команду с помощью visudo с флагом NOPASSWD:

 %wheel ALL=(ALL) NOPASSWD: /path/to/myscript cat /path/to/myscript #!/bin/bash service lightdm start 

РЕДАКТИРОВАТЬ
Просто заметили в ваших комментариях, что вы упоминаете Unity, так что, похоже, вы используете Ubuntu. Мой первоначальный ответ был направлен на системы SysVinit , но такие команды, как telinit все еще существуют для совместимости и будут работать на дистрибутивах с использованием Systemd или Upstart .

Способ SysV

  telinit 5 

В современных системах Systemd telinit перенаправляется на systemctl .

Системный путь

  systemctl isolate runlevel5.target 

или

  systemctl isolate graphical.target 

Оригинальный ответ:
В более старых не-системных дистрибутивах (например, RHEL / CentOS 6 и старше) самый простой способ переключения из режима консоли в графический интерфейс – с помощью команды telinit . Например, в дистрибутивах RHEL / Centos многопользовательский текстовый режим запускается на уровне 3, а режим многопользовательского графического интерфейса запускается на уровне 5. Переключение с консоли на режим графического интерфейса будет выполняться следующим образом: по умолчанию telinit требует привилегии root. Чтобы запустить это как обычного пользователя без пароля, вам понадобится запись sudoers или установите флаг setuid, установленный в исполняемом файле telinit. Метод sudo является предпочтительным, поскольку его можно ограничить только вашей учетной записью.

Классический путь UNIX делает скрипт setuid :

 $ sudo chown root gogui.sh #not necessary if root is already the owner of the file $ sudo chmod u+s gogui.sh 

Это установит в файле специальный бит разрешения:

 $ ls -l gogui.sh -rwsr-xr-x 1 root root [omitted] gogui.sh 

(Обратите внимание на букву s вместо x в четвертой позиции.)

Если вы это сделаете, все время, когда вы запускаете скрипт, он будет запускаться с привилегиями владельца файла, а не тех пользователей, которые его запускают.

Теперь вы можете упростить свой скрипт gogui.sh только для того, чтобы

 /usr/sbin/service lightdm start 

Обратите внимание, что я добавил явный путь для исполняемого файла (который я нашел, набрав эту which service ): это необходимо в файлах setuid, потому что в противном случае будет выполнена первая программа, называемая service найденной в вашем PATH . Забытие явного пути было бы большой проблемой безопасности, поскольку это означает, что любой пользователь может настроить переменную PATH и запустить программу по своему выбору с привилегиями root.

Если вы хотите, вы можете также chgrp some_group gogui.sh; chmod ox gogui.sh другим пользователям запускать файлы с помощью chgrp some_group gogui.sh; chmod ox gogui.sh chgrp some_group gogui.sh; chmod ox gogui.sh , который сделает файл исполняемым только для членов some_group .

Поскольку вы конкретно ссылаетесь на sudo , придерживайтесь ответа Жиля . Однако, так как ваш вопрос заголовка просто состоял в том, чтобы получить пароль к stdin программы, и у меня была похожая ситуация в последнее время:

 echo $(read -sp "Password: " password; echo $password) | yourcommand 

Я, вероятно, заработаю это, но это сработало.

Говоря о bash , вы можете, вероятно, также использовать

 yourcommand <$(read -sp "Password: " password; echo $password)