How do I run commands as a non-root user in a script started with root permissions?

Что такое sudo

sudo — это утилита, предоставляющая привилегии root для выполнения административных операций в соответствии со своими настройками. Она позволяет легко контролировать доступ к важным приложениям в системе. По умолчанию, при установке Ubuntu первому пользователю (тому, который создаётся во время установки) предоставляются полные права на использование sudo. Т.е. фактически первый пользователь обладает той же свободой действий, что и root. Однако такое поведение sudo легко изменить, об этом см. ниже в пункте про настройку sudo.

с помощью приложения на PHP порождать некие процессы, работающие от конкретного (отличного от пользователя, от которого работает web-сервер) пользователя.

Файлы web-сервера как и положено валяются где-то в /var/www. Apache работает от пользователя www-data.

Shell script лежит (условно) в /var/www/script.sh. Полные права доступа (rwx) к нему имеет только root, все остальные делать с ним ни чего не могут. Он тщательно проверяет входные параметры (существование пути, существование бинарника и другие проверки) и запускает экземпляр приложения следующей командой:

su -s /bin/bash -c "cd $APP_PATH; ./$APP_BIN $APP_PARAMS > /dev/null 2>&1 &" "$USER_NAME"
su -s /bin/bash -c "cd /home/app/; ./bin -p 27100 > /dev/null 2>&1 &" username

Остается позволить www-data запускать script.sh от root-а. Ставим sudo,

идем в /etc/sudoers и добавляем:

www-data ALL=(root) NOPASSWD: /var/www/script.sh

По ощущениям этого достаточно и по тем же ощущениям подозрения — слишком просто.

Теперь из PHP вызываем наш скрипт:

shell_exec("cd /var/www/; sudo ./script.sh -p 27100");

Не работает 🙁

Пробуем по другому (через консоль):

su -s /bin/bash www-data
cd /var/www/
sudo ./script.sh -p 27100

А NOPASSWD на что? Да и вообще какого хрена пароль у www-data? 🙁

Собственно, что я делаю не так?

Понятное дело, что православность решения мягко говоря под сомнением, но пока хочется «добить» хотя бы его (силы-то и время уже потрачены). Другие решения придут (надеюсь) позднее с новым опытом.

sudo -u node bash

The context
I am writing a provision.sh script for Vagrant, to set up a server running Ubuntu 16.04.3 with all the packages required to deliver an app with Meteor 1.6.

Subsequently, I want to switch back to being root and log in gain immediately as meteor, in order to start using nvm to install Node.js.

You’ll find a heavily commented script below. Vagrant runs this script each time I call vagrant reload --provision.

What command should I be using instead of sudo -u node bash?


echo "# whoami" && whoami && echo "^^^^ root expected"
echo "As root, create non-sudo user meteor:"
pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
useradd -m -p $pass meteor
echo "User meteor created. ls -al /home/meteor:"
ls -al /home/meteor
echo "Install curl as root:"
apt-get install -y curl
echo "Trying sudo -u meteor bash"
sudo -u meteor bash #### THIS IS THE LINE THAT FAILS ###

echo "$ whoami" && whoami && echo "^^^^^^ meteor expected"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
echo "ls -al /home/meteor/.nvm # should be populated"
ls -al /home/meteor/.nvm

echo "ls -al /root/.nvm # should not exist"
ls -al /root/.nvm

echo "command -v nvm will fail silently until we log out and back in again"
#command -v nvm
exit

#### Because the script is still running as root, it halts here ####

echo "# whoami" && whoami && echo "^^^^ should be root"
sudo -u meteor bash
echo "$ whoami" && whoami && echo "^^^^^^ should be meteor"
echo "command -v nvm should work now"
command -v nvm

Содержание

В любой Linux-системе обязательно есть один привилегированный пользователь — root. Этот пользователь имеет права на выполнение любых действий, удаление любых файлов и изменение любых параметров. Как-то ограничить свободу действий root практически невозможно. С другой стороны, все остальные пользователи системы обычно не имеют большинства необходимых прав, например, прав на установку программ, поскольку это является административной операцией, права на которую есть только у root. Ещё одной распространённой операцией, доступной только суперпользователю, является копирование и изменение файлов в системных папках, куда обычный пользователь доступа не имеет.

Раньше данная проблема решалась достаточно просто: при обладании паролем root можно было зайти в систему под его аккаунтом либо временно получить его права, используя команду su. Потом выполнить все необходимые операции и вернуться обратно под обычного пользователя. В принципе, такая схема работает неплохо, однако у неё есть много существенных недостатков, в частности, невозможно никак (точнее, очень сложно) ограничивать административные привилегии только определённым кругом задач.

Поэтому в современных дистрибутивах Linux вместо root аккаунта для администрирования используется утилита sudo.

В Ubuntu по умолчанию root аккаунт вообще отключён, т.е. вы никаким способом не сможете попасть под root, не включив его. root именно что отключён, т.е. он присутствует в системе, под него всего лишь нельзя зайти. Если вы хотите вернуть возможность использовать root, смотрите ниже пункт о включении root аккаунта.

This is my simple bash:

cat test.sh

#!/bin/bash 
echo "hello"
su - root -c /path/to/script.sh <<EOF
password                              
EOF
whoami
echo "good bye"

But I get this error:

./test.sh
hello
su: must be run from a terminal
<current-user>
good bye
cat test2.sh
#!/bin/bash 
echo "hello"
sudo su <<EOF
password                              
EOF
whoami
echo "good bye"

Again another error

cat test3.sh
#!/bin/bash 
echo "hello"
su root <<EOF
password                              
EOF
whoami
echo "good bye"

when I try:

#!/bin/bash
echo "hello"
sudo -s <<EOF
<password>
echo Now I am root
id                                                                      
echo "yes!"
EOF
whoami
echo "good bye"

Then the output is:

./script.sh
hello
[sudo] password for <user>:

I also changed my script to:

#!/usr/bin/expect -f
spawn sudo -s <<EOF
expect "assword for user:"
send -- "password\r"
expect eof

and output is:

spawn sudo -s <<EOF
[sudo] password for user:
/bin/bash: <<EOF: command not found

Also which sh output is /bin/sh

How can I resolve the error in these three scripts?

asked Feb 18, 2014 at 17:45

MLSC's user avatar

7 gold badges21 silver badges28 bronze badges

You can pipe the password and send it in the command inside the script.

echo "password" | sudo -S 

But it is not a good idea to send the password in the command line. If you need more information on how to login as root from the script, you can look at the answer provided here.

However, if it is for experimental purposes, we can use the expect to enter the password from command line. The script needs be modified like below.

#!/usr/bin/expect -f 
spawn sudo -s <<EOF 
expect "assword for username:" 
send -- "user-password\r" 
expect eof

The last line is needed since we need to press the Enter after inputting the password. As Tian suggested, it is not a good idea to send the root password in the shell script.

Community's user avatar

answered Feb 18, 2014 at 17:48

Ramesh's user avatar

43 gold badges140 silver badges215 bronze badges

Embedding the root password in the script isn’t a good idea, from a security point of view, this is probably why su attempts to get it initially from a terminal.

Дополнительно:  Flash Tool v2.4.3 Мод [Unlocked] APK

answered Feb 18, 2014 at 17:58

X Tian's user avatar

X Tian

2 gold badges33 silver badges48 bronze badges

I GOT ANSWER FROM here

However, now that you are aware of the risks, it is possible to use sudo -kS to have sudo read the password from stdin:

sudo -kSs << EOF
password
whoami
echo "Not a good idea to have a password encoded in plain text"
EOF

Community's user avatar

answered Feb 18, 2014 at 19:35

MLSC's user avatar

7 gold badges21 silver badges28 bronze badges

Have You tried /etc/sudoers?

your_user ALL=(ALL) NOPASSWD: /path/to/script.sh

(edit with: sudoedit /etc/sudoers)
then, You will be able to run:

sudo /path/to/script without password

answered Nov 3, 2014 at 2:00

Marcin Fabrykowski's user avatar

How do I run commands as a non-root user in a script started with root permissions?

Тема: Запуск скрипта с правами ROOT  (Прочитано 7681 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн
schetilin

service network-manager restartчерез ярлык на рабочем столе

#!/bin/bash
service network-manager restart

при запуске — окно с требованием пароля

Пробовал выставить владельца и группу в root и установить бит SUID. Не помогло, все равно пароль требует..
В интернете вычитал что SUID не работает со скриптами.

Написал прогу (freepascal)

begin
  fpSystem ('service network-manager restart');
end.

Скомпилил. Выставил владельца и группу в root и установить бит SUID и SGIT. Не помогло, все равно пароль требует..

Как запустить этот гребаный service network-manager restart без запроса пароля.

p.s. Пробовал запихнуть рестарт network-manager в скрипт в /etc/pm/sleep.d/ — падает плазма  :'( (Kubuntu 16.04)

« Последнее редактирование: 25 Января 2017, 23:02:04 от schetilin »

За глупые вопросы ногами не пинать, я новичок


Morisson

sudo visudoА еще лучше:

sudo EDITOR=nano visudo(например, вместо nano может быть любой твой любимый консольный редактор)В конец добавить:

ты ALL=(ALL) NOPASSWD: /путь/до/твоего_скрипта


Пользователь добавил сообщение 25 Января 2017, 23:02:36:


schetilin, действовать там очень аккуратно, неправильный пробел может сломать sudo, и это оптимистичный вариант

« Последнее редактирование: 25 Января 2017, 23:06:54 от Morisson »


Оффлайн
schetilin

Код: [Выделить]

ты ALL=(ALL) NOPASSWD: /путь/до/твоего_скрипта

Спасибо помогло. Прописал своего пользователя, путь и имя программы (та что на паскале), а в .desktop файле добавил sudo. Все заработало без запроса пароля.

За глупые вопросы ногами не пинать, я новичок


Morisson

schetilin, так делать небезопасно 😉


Оффлайн
schetilin

schetilin, так делать небезопасно 😉

Да я понимаю. Но у меня в ноуте после выхода из спящего режима wifi отваливается. Помогает перезапуск network-manager. Я то и из консоли могу перезапустить, и пароль набрать :) А вот отец пароль 3 дня набирать будет. Поэтому требовалось свести все действия  клику мышкой.

За глупые вопросы ногами не пинать, я новичок


Morisson

« Последнее редактирование: 25 Января 2017, 23:32:04 от Morisson »


Оффлайн
schetilin

Пробовал. Выше (в p.s.) писал. При рестарте network-manager падает плазма. Как побороть не нашел.
В общем заработало и ладно. Меня и так устроит.
Еще раз спасибо.

« Последнее редактирование: 25 Января 2017, 23:34:46 от schetilin »

За глупые вопросы ногами не пинать, я новичок


Оффлайн
Heider

schetilin, не обязательно делать рестарт NM, можно через nmcli делать, он от обычного пользователя работает.

nmcli connection up <Название подключения>
Можно и по-другому. Там много разных возможностей.


Оффлайн
schetilin

После выхода из ждущего режима ноут не «не подключается к сети автоматически», а просто не видит ни одной сети wifi.

Предыстория:
Сломался роутер. Ноут настроил для раздачи wifi (сам он в это время шнурком подключен был). Переустановил систему с 14.10 на 16.04 Снова настроил для раздачи wifi. Купил новый роутер. Удалил подключение как точки доступа, подключился к роутеру по wifi. После сна не видит не только мою сеть, а вообще ни одной. Такое ощущение, что выключается wifi-модуль. Помогает рестарт нетворк-менетжера или перезагрузка :) (вкл/выкл режима «в самолете» не помагает)

Возможно остались хвосты от предыдущих настроек (режим точки доступа) и они дают такой эффект?
Позже попытаюсь разобраться, а пока хоть так :)

За глупые вопросы ногами не пинать, я новичок


I have a script that does a number of different things, most of which do not require any special privileges. However, one specific section, which I have contained within a function, needs root privileges.

I don’t wish to require the entire script to run as root, and I want to be able to call this function, with root privileges, from within the script. Prompting for a password if necessary isn’t an issue since it is mostly interactive anyway. However, when I try to use sudo functionx, I get:

sudo: functionx: command not found

As I expected, export didn’t make a difference. I’d like to be able to execute the function directly in the script rather than breaking it out and executing it as a separate script for a number of reasons.

Is there some way I can make my function «visible» to sudo without extracting it, finding the appropriate directory, and then executing it as a stand-alone script?

The function is about a page long itself and contains multiple strings, some double-quoted and some single-quoted. It is also dependent upon a menu function defined elsewhere in the main script.

I would only expect someone with sudo ANY to be able to run the function, as one of the things it does is change passwords.

Gilles 'SO- stop being evil''s user avatar

asked Mar 11, 2016 at 4:54

BryKKan's user avatar

I will admit that there’s no simple, intuitive way to do this, and this is a bit hackey. But, you can do it like this:

function hello()
{
    echo "Hello!"
}

# Test that it works.
hello

FUNC=$(declare -f hello)
sudo bash -c "$FUNC; hello"

Or more simply:

sudo bash -c "$(declare -f hello); hello"

It works for me:

$ bash --version
GNU bash, version 4.3.42(1)-release (x86_64-apple-darwin14.5.0)
$ hello
Hello!
$
$ FUNC=$(declare -f hello)
$ sudo bash -c "$FUNC; hello"
Hello!

Basically, declare -f will return the contents of the function, which you then pass to bash -c inline.

If you want to export all functions from the outer instance of bash, change FUNC=$(declare -f hello) to FUNC=$(declare -f).

To address the comments about quoting, see this example:

$ hello()
> {
> echo "This 'is a' test."
> }
$ declare -f hello
hello ()
{
    echo "This 'is a' test."
}
$ FUNC=$(declare -f hello)
$ sudo bash -c "$FUNC; hello"
Password:
This 'is a' test.

Gilles 'SO- stop being evil''s user avatar

answered Mar 11, 2016 at 5:13

Will's user avatar

17 silver badges26 bronze badges

I’ve written my own Sudo bash function to do that, it works to call functions and aliases :

function Sudo {
        local firstArg=$1
        if [ $(type -t $firstArg) = function ]
        then
                shift && command sudo bash -c "$(declare -f $firstArg);$firstArg $*"
        elif [ $(type -t $firstArg) = alias ]
        then
                alias sudo='\sudo '
                eval "sudo $@"
        else
                command sudo "$@"
        fi
}

answered Apr 19, 2018 at 12:03

SebMa's user avatar

4 gold badges22 silver badges36 bronze badges

The «problem» is that sudo clears the environment (except for a handful of allowed variables) and sets some variables to pre-defined safe values in order to protect against security risks. in other words, this is not actually a problem. It’s a feature.

For example, if you set PATH="/path/to/myevildirectory:$PATH" and sudo didn’t set PATH to a pre-defined value then any script that didn’t specify the full pathname to ALL commands it runs (i.e. most scripts) would look in /path/to/myevildirectory before any other directory. Put commands like ls or grep or other common tools in there and you can easily do whatever you like on the system.

The easiest / best way is to re-write the function as a script and save it somewhere in the path (or specify the full path to the script on the sudo command line — which you’ll need to do anyway unless sudo is configured to allow you to run ANY command as root), and make it executable with chmod +x /path/to/scriptname.sh

answered Mar 11, 2016 at 5:32

cas's user avatar

7 gold badges118 silver badges183 bronze badges

You can combine functions and aliases

function hello_fn() {
    echo "Hello!" 
}

alias hello='bash -c "$(declare -f hello_fn); hello_fn"' 
alias sudo='sudo '

then sudo hello works

answered Jun 7, 2019 at 6:05

hbt's user avatar

3 silver badges3 bronze badges

New Answer. Add this to your ~/.bashrc to run functions. As a bonus, it can run aliases too.

ssudo () # super sudo
{
  [[ "$(type -t $1)" == "function" ]] &&
    ARGS="$@" && sudo bash -c "$(declare -f $1); $ARGS"
}
alias ssudo="ssudo "

answered Aug 20, 2021 at 8:39

Rucent88's user avatar

4 gold badges23 silver badges32 bronze badges

Here’s a variation on Will’s answer. It involves an additional cat process, but offers the comfort of heredoc. In a nutshell it goes like this:

f () 
{
    echo ok;
}

cat <<EOS | sudo bash
$(declare -f f)
f
EOS

If you want more food for thought, try this:

#!/bin/bash

f () 
{ 
    x="a b"; 
    menu "$x"; 
    y="difficult thing"; 
    echo "a $y to parse"; 
}

menu () 
{
    [ "$1" == "a b" ] && 
    echo "here's the menu"; 
}

cat <<EOS | sudo bash
$(declare -f f)
$(declare -f menu)
f
EOS

The output is:

here's the menu
a difficult thing to pass

Here we’ve got the menu function corresponding with the one in the question, which is «defined elsewhere in the main script». If the «elsewhere» means its definition has already been read at this stage when the function demanding sudo is being executed, then the situation is analogous. But it might not have been read yet. There may be another function that will yet trigger its definition. In this case declare -f menu has to be replaced with something more sophisticated, or the whole script corrected in a way that the menu function is already declared.

voices's user avatar

3 gold badges15 silver badges30 bronze badges

answered Jan 25, 2018 at 21:08

My take on this, built upon other answers, but as far as I can see the only one properly handling function arguments and quoting:

sudo-function() {
    (($#)) || { echo "Usage: sudo-function FUNC [ARGS...]" >&2; return 1; }
    sudo bash -c "$(declare -f "$1");$(printf ' %q' "$@")"
}
$ args() { local i=0; while (($#)); do echo "$((++i))=$1"; shift; done; }
$ sudo-function args a 'b c' "d 'e'" 'f "g"'
1=a
2=b c
3=d 'e'
4=f "g"
super-sudo() {
    (($#)) || { echo "Usage: super-sudo CMD [ARGS...]" >&2; return 1; }
    local def ftype; ftype=$(type -t $1) ||
    { echo "not found: $1" >&2; return 1; }
    if [[ "$ftype" == "function" ]]; then def=$(declare -f "$1")
    else def=$(declare -p PATH); fi  # file or builtin
    sudo bash -c "${def};$(printf ' %q' "$@")"
}
alias super-sudo='super-sudo '  # so it runs aliases too

As most (all?) answers, it has a few limitations:

  • Does not work if FUNC calls other functions
  • As sudo, it might not work as expected if mixed with redirections and process substitutions < >>, <(), etc.

And a small bonus: bash-completion!

complete -A function sudo-function
complete -c super-sudo

answered Jun 4, 2022 at 21:43

MestreLion's user avatar

12 silver badges19 bronze badges

I don’t know if this is the best way to do it, but it works for me, and I’ve been using it for years.

{

    function run_as_root {
        local function_name="${FUNCNAME[0]}";
        local return_value=0;
                
        # notify entry to function
        
        Echo-enter ${function_name}; 

        # make sure we're running as root. Recall program as root if not.

        if (( $EUID != 0 )); then
        
            echo "Will now run as root...."; # - ${gc_sl_file}"

            play_norm_sound;

            # need to preserve HOME environmental variable as it's used for  
            # directory referencing, per change in Ubu 20.04

            sudo --preserve-env=HOME -u root ${@}; 
            return_value=$?;
            
            if [ ${g_debug_mode} = true ]; then 
                echo "Returned from sudo call to self with return value: "  \
                        "${return_value};" >> ${gc_logfile};
                
            fi  

            # might not need this
            # ensure return value is nonzero so we don't run program operations again
            
            if [[ ${return_value} -ne 0 ]]; then 

                echo "We had a nonzero return value from root:${return_value}." | tee -a ${gc_logfile};
                play_err_sound;
            fi
            
        else    # we are already in root
                
            # shift input parameters to get rid of script call as first parameter
            
            shift
            
            # run rest of program. 
            ##### NOTE: This should be standard for all programs that use this function.

            main ${@};
            return_value=$?;
            
        fi
        
        Echo-return "${function_name}" "${return_value}";
        
        return ${return_value}
    }
}

AdminBee's user avatar

20 gold badges47 silver badges71 bronze badges

answered Feb 10 at 8:44

Randyman99's user avatar

Assuming that your script is either (a) self-contained or (b) can source its components based on its location (rather than remembering where your home directory is), you could do something like this:

  • use the $0 pathname for the script, using that in the sudo command, and pass along an option which the script will check, to call the password updating. As long as you rely on finding the script in the path (rather than just run ./myscript), you should get an absolute pathname in $0.
  • since the sudo runs the script, it has access to the functions it needs in the script.
  • at the top of the script (rather, past the function declarations), the script would check its uid and realize that it was run as the root user, and seeing that it has the option set to tell it to update the password, go and do that.

Scripts can recur on themselves for various reasons: changing privileges is one of those.

answered Mar 11, 2016 at 20:06

Thomas Dickey's user avatar

Thomas Dickey

9 gold badges170 silver badges268 bronze badges

Entirely transparent, it has the same behavior as the real sudo command, apart from adding an additional parameter:

enter image description here

cmdnames () {
    { printf '%s' "$PATH" | xargs -d: -I{} -- find -L {} -maxdepth 1 -executable -type f -printf '%P\n' 2>/dev/null; compgen -b; } | sort -b | uniq
    return 0
}
sudo () {
    local flagc=0
    local flagf=0
    local i
    if [[ $# -eq 1 && ( $1 == "-h" || ( --help == $1* && ${#1} -ge 4 ) ) ]]; then
        command sudo "$@" | perl -lpe '$_ .= "\n  -c, --run-command             run command instead of the function if the names match" if /^  -C, / && ++$i == 1'
        return ${PIPESTATUS[0]}
    fi
    for (( i=1; i<=$#; i++ )); do
        if [[ ${!i} == -- ]]; then
            i=$((i+1))
            if [[ $i -gt $# ]]; then break; fi
        else
            if [[ ${!i} == --r ]]; then
                command sudo "$@" 2>&1 | perl -lpe '$_ .= " '"'"'--run-command'"'"'" if /^sudo: option '"'"'--r'"'"' is ambiguous/ && ++$i == 1'
                return ${PIPESTATUS[0]}
            fi
            if [[ ${!i} == -c || ( --run-command == ${!i}* && $(expr length "${!i}") -ge 4 ) ]]; then
                flagf=-1
                command set -- "${@:1:i-1}" "${@:i+1}"
                i=$((i-1))
                continue
            fi
            command sudo 2>&1 | grep -E -- "\[${!i} [A-Za-z]+\]" > /dev/null && { i=$((i+1)); continue; }
        fi
        cmdnames | grep "^${!i}$" > /dev/null && flagc=1
        if [[ ! ( flagc -eq 1 && flagf -eq -1 ) ]]; then
            if declare -f -- "${!i}" &> /dev/null; then flagf=1; fi
        fi
        break
    done
    if [[ $flagf -eq 1 ]]; then
        command sudo "${@:1:i-1}" bash -sc "shopt -s extglob; $(declare -f); $(printf "%q " "${@:i}")"
    else
        command sudo "$@"
    fi
    return $?
}

mtk's user avatar

35 gold badges90 silver badges128 bronze badges

answered Jan 31, 2022 at 22:34

Mario Palumbo's user avatar

My solution is to throw sudo as the last argument of the function or use the empty one:

f () {
local arg1=$1
local arg2=$2
local mysudo="$3" # can be empty if not given
$mysudo mycommand $arg1 $arg2
}
f 1 2 # without sudo
f 1 2 sudo # with sudo

That is quite straightforward.

answered Feb 6 at 22:12

biocyberman's user avatar

Запуск графических программ с правами администратора

Для запуска графических программ с правами администратора можно воспользоваться диалогом запуска программ, вызываемым по умолчанию сочетанием клавиш Alt+F2.

Допустим, нам необходимо запустить файловый менеджер Nautilus с правами администратора, чтобы через графический интерфейс как-то изменить содержимое системных папок. Для этого необходимо ввести в диалог запуска приложений команду

gksudo nautilus

Вместо gksudo можно подставить gksu, кроме того, пользователи KDE должны вместо gksudo писать kdesu. У вас попросят ввести свой пароль, и, если вы обладаете нужными правами, Nautilus запуститься от имени администратора. Запуск любого графического ПО можно производить с правами администратора, просто написав в диалоге запуска

gksudo <имя_команды>

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

Sudo не спрашивает пароль

sudo без пароля — чудовищная дыра в безопасности, кому попало разрешено делать что угодно. Если вы разрешили это намеренно — срочно верните обратно как было.

Однако, в некоторых случаях sudo внезапно перестаёт требовать пароль само по себе. Если сделать visudo, то можно увидеть примерно такую строку, которую пользователь вроде бы не добавлял:

ALL ALL=(ALL) NOPASSWD:ALL

Скорее всего, эта катастрофичная строка была добавлена при установке программы типа Connect Manager от МТС или Мегафона. В таком случае, её нужно поменять на строку, разрешающую с правами root запускать только этот Connect Manager, примерно так:

юзернейм ALL= NOPASSWD: /путь/к/программе

Есть и другие варианты решения проблемы, небольшое обсуждение здесь.

Где используется sudo

sudo используется всегда, когда вы запускаете что-то из меню Администрирования системы. Например, при запуске Synaptic вас попросят ввести свой пароль. Synaptic — это программа управления установленным ПО, поэтому для её запуска нужны права администратора, которые вы и получаете через sudo вводя свой пароль.

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

Настройка sudo и прав доступа на выполнение различных команд

sudo позволяет разрешать или запрещать пользователям выполнение конкретного набора программ. Все настройки, связанные с правами доступа, хранятся в файле /etc/sudoers. Это не совсем обычный файл. Для его редактирования необходимо (в целях безопасности) использовать команду

sudo visudo
%admin ALL=(ALL) ALL

Подробнее о синтаксисе и возможностях настройки этого файла можно почитать выполнив

man sudoers

Если вы допустите ошибку при редактировании этого файла, то вполне возможно полностью лишитесь доступа к административным функциям. Если такое случилось, то необходимо загрузиться в recovery mode, при этом вы автоматически получите права администратора и сможете всё исправить. Кроме того, отредактировать этот файл можно с LiveCD.

Разрешение пользователю выполнять команду без ввода пароля

Для того, что бы система не запрашивала пароль при определенных командах необходимо в sudoers после строки # Cmnd alias specification добавить строку, где через запятую перечислить желаемые команды с полным путём(путь команды можно узнать, выполнив which имя_команды:

# Cmnd alias specification
Cmnd_Alias SHUTDOWN_CMDS = /sbin/shutdown, /usr/sbin/pm-hibernate, /sbin/reboot

И в конец файла дописать строку

имя_пользователя ALL=(ALL) NOPASSWD: SHUTDOWN_CMDS

Внимание! Вышеописанные действия не отменяют необходимости ввода команды sudo перед вашей командой

Создание синонимов (alias`ов)

Для того, чтобы не только не вводить пароль для sudo, но и вообще не вводить sudo, сделайте следующее:
откройте файл .bashrc, находящейся в вашем домашнем каталоге

  ~bashrc 

и добавьте в конец файла строки

 =
 =
 pm-hibernate=
 =
 = 

Ссылки

  • Настройка sudo — топик на форуме о времени действия пароля

Запуск программ с правами администратора в терминале

Для запуска в терминале команды с правами администратора просто наберите перед ней sudo:

sudo <команда>

У вас попросят ввести ваш пароль. Будьте внимательны, пароль при вводе никак не отображается, это нормально и сделано в целях безопасности, просто вводите до конца и нажимайте Enter. После ввода пароля указанная команда исполнится от имени root.

Система какое-то время помнит введённый пароль (сохраняет открытой sudo-сессию). Поэтому при последующих выполнениях sudo ввод пароля может не потребоваться. Для гарантированного прекращения сессии sudo наберите в терминале

sudo -K

Кроме того, часто встречаются ошибки, связанные с каналами в Linux. При исполнении команды

sudo cat test.txt | grep text > result.txt

с правами root исполнится только cat, поэтому файл result.txt может не записаться. Нужно либо писать sudo перед каждой командой, либо временно переходить под суперпользователя.

Использование традиционного root аккаунта и команды su

Разблокировка учетной записи root приводит неоправданным рискам (работая постоянно под рутом вы имеете 100500 способов «отстрелить себе ногу»), а также упрощает получение доступа к вашему компьютеру злоумышленником.

Ubuntu 11.04 и младше

Для входа под root достаточно задать ему пароль:

sudo passwd root

Ubuntu 11.10 и старше

Начиная с версии 11.10 был установлен менеджер входа lightdm, и дело со входом под root обстоит немного сложнее.

1. Устанавливаем root пароль.
Введите в терминал:

sudo passwd root
gksu gedit /etc/lightdm/lightdm.conf

В конце файла допишите:

greeter-show-manual-login=true

3. Перезагружаем lightdm.
Введите в терминал:

sudo service lightdm restart

Для обратной блокировки учетной записи root вам потребуется откатить изменения в настройках lightdm, а также заблокировать учетную запись root командой в терминале:

sudo passwd -l root

Получение прав суперпользователя для выполнения нескольких команд

Иногда возникает необходимость выполнить подряд несколько команд с правами администратора. В этом случае можно временно стать суперпользователем одной из следующих команд:

sudo -s
sudo -i

После этого вы перейдёте в режим суперпользователя (с ограничениями, наложенными через настройки sudo), о чём говорит символ # в конце приглашения командной строки. Данные команды по действию похожа на su, однако:
sudo -s — не меняет домашний каталог на /root, домашним остается домашний каталог пользователя вызвавшего sudo -s, что обычно очень удобно.
sudo -i — сменит так же и домашний каталог на /root.

Для выхода обратно в режим обычного пользователя наберите exit или просто нажмите Ctrl+D.

Время действия введённого пароля

Возможно, вы хотите изменить промежуток времени, в течение которого sudo действует без ввода пароля. Этого легко добиться добавив в /etc/sudoers (visudo) примерно следующее:

Defaults:foo timestamp_timeout=20

Здесь sudo для пользователя foo действует без необходимости ввода пароля в течение 20 минут.
Если вы хотите, чтобы sudo всегда требовал ввода пароля, сделайте timestamp_timeout равным 0.

Оцените статью
Master Hi-technology
Добавить комментарий