0

Yes, it is recommended to use visudo to edit sudoers file. But I'm not satisfied with verbally recommending it. Can shell give a warning or require a confirmation when I'm editing the file in a wrong way?

I would like to catch the following situations:

$ sudo vim /etc/sudoers
/etc $ sudo nano sudoers
$ sudo cp what/ever/file /etc/sudoers.d/a
Gqqnbig
  • 239
  • 2
    Nothing keeps an administrator from doing bad stuff. Where do you stop? What about rm sudoers or cat > sudoers? With great sudo comes great responsibility. – pLumo May 05 '21 at 08:29
  • First lines of my sudoers file are `#

    This file MUST be edited with the 'visudo' command as root.

    #`

    – pLumo May 05 '21 at 08:32
  • @pLumo then how about cat > sudoers? – Gqqnbig May 05 '21 at 08:40
  • I can't get - what's wrong or bad in doing sudo nano /etc/sudoers or maybe sudo mcedit /etc/sudoers - what if vi/vim is not "my favorite editor of all times" and I like and have installed something else, for example Mindnight Commander which features "mcedit"? – ivan.ukr May 05 '21 at 08:49
  • 2
    @ivan.ukr This is not about vi vs nano, but visudo vs any other means of editing the file. visudo can use nano or whatever Editor is set as default. – pLumo May 05 '21 at 08:54
  • 2
    visudo checks that /etc/sudoers has valid syntax after editing, no matter what editor is used, and refuses to replace it if it's invalid. sudo "$EDITOR" /etc/sudoers does not do any checking, which means you can easily find yourself with a broken sudoers file (and unable to use sudo to fix it - better hope that root has a password so you can use su instead). – cas May 05 '21 at 09:20
  • 1
    note: "valid syntax" is not the same as "does what you want/meant". – cas May 05 '21 at 09:22

2 Answers2

3

Note: I would not do the following. It is not safe, and also there are enough other possibilites to destroy your system. Why exactly picking this one?

With great sudo rights, comes great responsibility.


However, to keep even root from editing sudoers file, you can make it immutable by running:

sudo chattr +i /etc/sudoers

Then add the followign aliases to your .rc or .profile file, e.g. .bashrc:

alias visudo="sudo chattr -i /etc/sudoers; sudo visudo; sudo chattr +i /etc/sudoers;"
alias sudo='sudo '

It will change visudo command to first reset immutable flag, then run visudo , at the end make it immutable again. See here why we need the second alias.

After resourcing the file or restarting the shell, you can use sudo visudo as normal, but not edit it otherwise.


This is just the general idea, it needs to be enhanced to enable other arguments of visudo and the files below /etc/sudoers.d/. Instead of an alias, you could also use a function or script.


Note, this is not really safe:

  • the moments you have visudo running, the file is not immutable
  • any sudo user can run chattr -i to unset the immutable flag at any time
  • you train yourself a behavior to not think before doing stuff
pLumo
  • 22,565
  • That's awesome. I came up with another idea. As I'm using zsh, I learned it supports preexec hook. Would the hook be able to cancel a command? Or are there any widgets that could do this? – Gqqnbig May 06 '21 at 03:25
0

I'm here to present my awkward solution. I'm using zsh and it is a zsh widget (command line plugin).

When the current directory is sudoders.d, or the command line contains sudoers, zsh will give a warning, unless the command is "cd" or "visudo".

The code covers the senarios of vim, nano, cp, rm, cat > .

I believe you may make it better, but that's the basic idea.

#! /usr/bin/zsh

function catchEditSudoers { if ([[ $BUFFER =~ .sudoers. ]] && [[ ! $BUFFER =~ .visudo. ]] && [[ ! $BUFFER =~ "cd .*" ]]) || ([[ $PWD =~ ".*/sudoers.d" ]] && [[ ! $BUFFER =~ .visudo. ]] && [[ ! $BUFFER =~ "cd .*" ]]); then zle -R "It's recommanded to use visudo to edit sudoers. Continue anyway? (y/n)" read -k reply if [[ $reply == y ]]; then zle accept-line else zle send-break fi

else
    zle accept-line
fi

}

zle -N catchEditSudoers_widget catchEditSudoers

bindkey '^M' catchEditSudoers_widget

Source the file in your .zshrc.

Gqqnbig
  • 239