Есть ли причина иметь shebang, указывающий на /bin/sh, а не на /bin/bash?
Да. В отличном ответе @Marco это хорошо описано.
Что я должен использовать в моем shebang?
При написании собственных скриптов, вы должны указывать в shebang на самое общее, что вы тестировали.
В моей системе (Centos 6.6),
sh
связан симлинком сbash
:$ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Dec 2 2014 /bin/sh -> bash
Это означает, что я всегда использую
#!/bin/bash
в моем shebang, если я не проверил, что в моем скрипте нет bashims.Устанавливая в shebang значение
#!/bin/sh
, вы обещаете, что скрипт будет работать со всеми реализациямиsh
.Это гораздо большее обещание, чем сказать, что скрипт будет работать с bash.
Вот пример скрипта, который будет вести себя неправильно в зависимости от того, какую реализацию
sh
использует система:#!/bin/sh n=1 a=$((++n)) echo $n
При использовании
bash
скрипт будет печатать:2
При использовании
dash
скрипт выведет:1
Если я хочу использовать
#!/bin/sh
, что мне нужно сделать?
- Проверьте скрипт с помощью
checkbashisms
- Обратите внимание, что он не найдет все bashims. Он не нашел башизм в моем скрипте выше- Проверьте скрипт, используя другую реализацию
sh
. Я обычно тестирую сdash
, однако я ожидаю, что некоторые башизмы или дашимы все равно могут проскочить.На странице DashAsBinSh в вики Ubuntu есть много интересной информации.
Вы даете sudo-user
возможность выполнять любые команды от имени любого пользователя. Это включает в себя возможность изменять/etc/sudoers
с помощью любого инструмента, который не требует выполнения подпроцессов -. Вы можете подумать, что это исключает visudo
, но, строго говоря, вам не нужно visudo
для редактирования /etc/sudoers
.
Как, например:
sudo-user$ sudo sed --in-place -e '/^sudo-user/s/NOEXEC://' /etc/sudoers
...и пользователь только что снял ограничение NOEXEC:
.
Ограничение, которое пользователь может снять по своему желанию, не является истинным ограничением.
Кроме того, NOEXEC:
может вызвать проблемы. Это не только предотвращает выходы из оболочки :, но и предотвращает прямой запуск любой другой программы программой, выполняемой с помощью sudo
из . Это может иметь много последствий.
Например, если ваш sudo-user
останавливает, а затем перезапускает демон cron
(, т.е. чтобы остановить запланированные задания на время некоторого обслуживания ), перезапущенный демон cron
не сможет фактически выполнять какие-либо запланированные задания из-за ограничения NOEXEC:
.
NOEXEC:
существует для того, чтобы системный администратор мог применять его к тщательно отобранным программам, способным выполнять свои задачи без exec()
включения каких-либо подпроцессов -. Слепое применение его ко всему ко всему вызовет проблемы.
Из справочной страницы sudoers(5)
:
User specification
User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \
(':' Host_List '=' Cmnd_Spec_List)*
Cmnd_Spec_List ::= Cmnd_Spec |
Cmnd_Spec ',' Cmnd_Spec_List
Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Tag_Spec* Cmnd
Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' |
'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')
Это подробное описание того, как создать строку спецификации пользователя для файла sudoers
. Это может быть немного утомительно читать, но она содержит необходимую информацию.
Давайте разберемся, используя ваш пример строки:
sudo-user ALL=(ALL) NOEXEC: NOPASSWD: ALL
Вся строка известна как пользовательская спецификация или User_Spec
.
Он разбивается следующим образом:
User_List
в вашем примере есть только один пользователь:sudo-user
Host_List
имеет только одну запись,ALL
Cmnd_Spec_List
в вашем примере(ALL) NOEXEC: NOPASSWD: ALL
: Host_List = Cmnd_Spec_List
единиц (звездочка после круглых скобок предполагает, что таких дополнительных единиц может быть ноль или больше.)В вашем Cmnd_Spec_List
нет запятых, поэтому в нем только одна Cmnd_Spec
.
Cmnd_Spec
распадается на:
Runas_Spec
:в вашем случае(ALL)
SELinux_Spec
, которого нет в вашем примере Tag_Spec
s, это та часть, о которой вы хотите знать Cmnd
, команда, которая в вашем случае ALL
. А одинарное Tag_Spec
— это просто одно из перечисленных ключевых слов с двоеточием в конце, без запятой, пробела или другого явно указанного разделителя. Строка Cmnd_Spec ::=
говорит нам, где именно поставить пробелы в этой строке. Поскольку нет инструкций по размещению пробелов или любых других разделителей между тегами, не делайте этого.
Итак, просто поставьте теги один за другим , вот так:
sudo-user ALL=(ALL) NOEXEC:NOPASSWD: ALL
Объединяя два приведенных ответа, как насчет этого?:
Defaults noexec
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
sudo-user ALL=(ALL) EXEC:NOPASSWD: ALL
fred ALL=(ALL) NOPASSWD: user_allowed_commands
На самом деле, я предлагаю предоставить неограниченный доступ пользователю sudo -. Кажется, это рекомендуемый метод (в Ubuntu и др., по крайней мере ), а не использование root. Я уже проверяю каталог /etc/sudoers, как это происходит. Это позволяет fred запускать список команд в «пользователь _разрешенные _команды» (, предполагая, что fork/exec не нужен, что кажется маловероятным, TBH -, или я неправильно понимаю, что делает noexec?)
Я хотел бы добавить это от @telcoM :Ограничение, которое пользователь может снять по своему желанию, не является истинным ограничением.
Во всех реализациях SELinux, которые я видел, он не является неизменным, поэтому любой пользователь может запустить setenforce permissive, и все ограничения будут сняты.