Difference between revisions of "Sudo"

From Noah.org
Jump to navigationJump to search
 
(10 intermediate revisions by the same user not shown)
Line 2: Line 2:
  
 
Use `visudo` to make changes to /etc/sudoers.
 
Use `visudo` to make changes to /etc/sudoers.
 +
 +
== I broke /etc/sudoers and now I can't run sudo to fix it ==
 +
 +
''Install the '''policykit-1''' package:''
 +
<pre>
 +
apt-get install policykit-1
 +
</pre>
 +
 +
It's just like when you lock your keys in the car. If you have the '''policy kit''' utilities installed then you likely have a utility called '''pkexec''' installed. This is like a lightweight sudo, sort of. So just edit '''/etc/sudoers''' or whatever is broken under '''/etc/sudoers.d''' using '''pkexec''' and be on your way:
 +
<pre>
 +
pkexec vim /etc/sudoers
 +
</pre>
 +
If that doesn't work then you'll have to resort to rebooting the machine in '''single user mode''' and edit /etc/sudoers as root.
 +
 +
== Why is root user in the sudoers file? ==
 +
 +
You should see this in your sudoers file:
 +
<pre>
 +
root    ALL=(ALL:ALL) ALL
 +
</pre>
 +
Why does this need to be there? If you are root then why do you need sudo? The reason for this is so that you can run scripts as root that have calls to '''sudo''' in them. If root was in in sudoers then sudo would deny access. It's one of the few quirks about sudo that actually makes sense when you think about it.
 +
 +
== I keep breaking /etc/sudoers ==
 +
 +
Something near the '''includedir''' line in your '''/etc/sudoers''' file will not parse. The problem is that you probably deleted the '''#''' character in front of the '''includedir''' directive. In this case it's supposed to resemble a preprocessor directive in '''C'''. No, it's not a comment. It looks like one and you probably thought you were uncommenting a disabled line. This was a really stupid syntax decision by the '''sudo''' designers. The directive should be '''#includedir'''. Put the '''#''' character back. And make sure there is no space between it and the include, otherwise sudo will then think it's a comment and it will ignore it. Again, stupid syntax.
 +
<pre>
 +
ubuntu@web1:~$ sudo ls /root
 +
>>> /etc/sudoers: syntax error near line 31 <<<
 +
sudo: parse error in /etc/sudoers near line 31
 +
sudo: no valid sudoers sources found, quitting
 +
sudo: unable to initialize policy plugin
 +
</pre>
 +
 +
Your '''/etc/sudoers''' file probably looks something like this:
 +
<pre>
 +
# User privilege specification
 +
root    ALL=(ALL:ALL) ALL
 +
 +
# Members of the admin group may gain root privileges
 +
%admin ALL=(ALL) NOPASSWD:ALL
 +
 +
# Allow members of group sudo to execute any command
 +
%sudo  ALL=(ALL:ALL) ALL
 +
 +
# See sudoers(5) for more information on "#include" directives:
 +
includedir /etc/sudoers.d
 +
</pre>
 +
The '''sudoers''' config file has stupid syntax. The '''#include''' directive must have the pound. Yes, it makes it look like a commented-out line, but it is not. Sudo is stupid. You or someone else probably removed the '''#''' character thinking to "enable" the include.
 +
 +
==  sudo group vs.  admin group ==
 +
 +
The '''admin''' group in Ubuntu is deprecated. It is often found in '''sudoers''' files for backward compatibility. [https://help.ubuntu.com/community/RootSudo#Allowing_other_users_to_run_sudo "The admin group has been deprecated and no longer exists in Ubuntu 12.04."]
 +
 +
You may still see this:
 +
<pre>
 +
# Members of the admin group may gain root privileges
 +
%admin ALL=(ALL) ALL
 +
 +
# Allow members of group sudo to execute any command
 +
%sudo  ALL=(ALL:ALL) ALL
 +
</pre>
 +
 +
== NOPASSWD does not work ==
 +
 +
If you set the NOPASSWD option for a user or group in '''sudo''' and it does not seem to work then you most likely have the order of statements wrong. The last statement in a '''sudoers''' file wins. Don't forget the files imported from '''/etc/sudoers.d'''. For example, the following will not work if '''noah''' is also a member of the '''sudo''' group because the '''sudo''' group definition comes after and overrides the '''NOPASSWD''' option.
 +
<pre>
 +
noah ALL=(ALL) NOPASSWD:ALL
 +
 +
# Allow members of group sudo to execute any command
 +
%sudo ALL=(ALL:ALL) ALL
 +
</pre>
 +
The fix is to define the '''noah''' user options after the '''sudo''' group.
 +
<pre>
 +
# Allow members of group sudo to execute any command
 +
%sudo ALL=(ALL:ALL) ALL
 +
 +
noah ALL=(ALL) NOPASSWD:ALL
 +
</pre>
  
 
== Set timestamp timeout ==
 
== Set timestamp timeout ==
  
The following sets the timestamp timeout to 30 minutes for the given YOUR_USERNAME.
+
The following sets the timestamp timeout to 30 minutes for the given username, '''noah'''.
 +
<pre>
 +
Defaults:noah timestamp_timeout=30
 +
</pre>
  
 +
The following sets the timestamp timeout to 30 minutes for all users:
 
<pre>
 
<pre>
Defaults:YOUR_USERNAME timestamp_timeout=30
+
Defaults timestamp_timeout=30
 
</pre>
 
</pre>
  
The following sets the timestamp timeout to 30 minutes for all users:
+
== Remove timestamp ==
  
 +
Sometimes for scripting you want sudo authentication to be consistent. If sudo is going to ask for a password then it is preferable to have it ask every time rather than ask once and then not again unless a timeout is reached in which case it will ask again. This can be difficult to script for. It's easier just to expect the password every time. You can pass '''sudo''' an option, '''-k''' to clear the timestamp. Note that there is a similar '''-K''' option (capital K) which must be use alone without a command to be run. Also note that the '''NOPASSWD''' option will still override the '''-k''' option.
 
<pre>
 
<pre>
Defaults timestamp_timeout=30
+
sudo -k id
 
</pre>
 
</pre>
  
 
== No password ==
 
== No password ==
  
Allow a specific user to sudo without a password:
+
Allow a specific user, '''noah''' to sudo without a password:
 
 
 
<pre>
 
<pre>
YOUR_USERNAME ALL=NOPASSWD: ALL
+
noah ALL=(ALL) NOPASSWD:ALL
 
</pre>
 
</pre>
  
Allow all users in the admin group to sudo without a password:
+
Allow all users in the '''admin''' group to sudo without a password:
 
 
 
<pre>
 
<pre>
%admin ALL=NOPASSWD: ALL
+
%admin ALL=(ALL) NOPASSWD:ALL
 
</pre>
 
</pre>

Latest revision as of 15:05, 11 November 2015


Use `visudo` to make changes to /etc/sudoers.

I broke /etc/sudoers and now I can't run sudo to fix it

Install the policykit-1 package:

apt-get install policykit-1

It's just like when you lock your keys in the car. If you have the policy kit utilities installed then you likely have a utility called pkexec installed. This is like a lightweight sudo, sort of. So just edit /etc/sudoers or whatever is broken under /etc/sudoers.d using pkexec and be on your way:

pkexec vim /etc/sudoers

If that doesn't work then you'll have to resort to rebooting the machine in single user mode and edit /etc/sudoers as root.

Why is root user in the sudoers file?

You should see this in your sudoers file:

root    ALL=(ALL:ALL) ALL

Why does this need to be there? If you are root then why do you need sudo? The reason for this is so that you can run scripts as root that have calls to sudo in them. If root was in in sudoers then sudo would deny access. It's one of the few quirks about sudo that actually makes sense when you think about it.

I keep breaking /etc/sudoers

Something near the includedir line in your /etc/sudoers file will not parse. The problem is that you probably deleted the # character in front of the includedir directive. In this case it's supposed to resemble a preprocessor directive in C. No, it's not a comment. It looks like one and you probably thought you were uncommenting a disabled line. This was a really stupid syntax decision by the sudo designers. The directive should be #includedir. Put the # character back. And make sure there is no space between it and the include, otherwise sudo will then think it's a comment and it will ignore it. Again, stupid syntax.

ubuntu@web1:~$ sudo ls /root
>>> /etc/sudoers: syntax error near line 31 <<<
sudo: parse error in /etc/sudoers near line 31
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin

Your /etc/sudoers file probably looks something like this:

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) NOPASSWD:ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:
includedir /etc/sudoers.d

The sudoers config file has stupid syntax. The #include directive must have the pound. Yes, it makes it look like a commented-out line, but it is not. Sudo is stupid. You or someone else probably removed the # character thinking to "enable" the include.

sudo group vs. admin group

The admin group in Ubuntu is deprecated. It is often found in sudoers files for backward compatibility. "The admin group has been deprecated and no longer exists in Ubuntu 12.04."

You may still see this:

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

NOPASSWD does not work

If you set the NOPASSWD option for a user or group in sudo and it does not seem to work then you most likely have the order of statements wrong. The last statement in a sudoers file wins. Don't forget the files imported from /etc/sudoers.d. For example, the following will not work if noah is also a member of the sudo group because the sudo group definition comes after and overrides the NOPASSWD option.

noah ALL=(ALL) NOPASSWD:ALL

# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL

The fix is to define the noah user options after the sudo group.

# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL

noah ALL=(ALL) NOPASSWD:ALL

Set timestamp timeout

The following sets the timestamp timeout to 30 minutes for the given username, noah.

Defaults:noah timestamp_timeout=30

The following sets the timestamp timeout to 30 minutes for all users:

Defaults timestamp_timeout=30

Remove timestamp

Sometimes for scripting you want sudo authentication to be consistent. If sudo is going to ask for a password then it is preferable to have it ask every time rather than ask once and then not again unless a timeout is reached in which case it will ask again. This can be difficult to script for. It's easier just to expect the password every time. You can pass sudo an option, -k to clear the timestamp. Note that there is a similar -K option (capital K) which must be use alone without a command to be run. Also note that the NOPASSWD option will still override the -k option.

sudo -k id

No password

Allow a specific user, noah to sudo without a password:

noah ALL=(ALL) NOPASSWD:ALL

Allow all users in the admin group to sudo without a password:

%admin ALL=(ALL) NOPASSWD:ALL