0% found this document useful (0 votes)
121 views10 pages

Au Sudo PDF

au-sudo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
121 views10 pages

Au Sudo PDF

au-sudo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Make sudo work harder

David Tansley October 06, 2009

The sudo utility allows users to run commands as another, or privileged, user. Sudo has
features not often used by administrators. This article demonstrates some of these features,
such as include files, timeouts, and logical operations.

Introduction
Sudo is a utility that allows systems administrators to give users or groups the ability to run
commands as another user. In other words, command privileges can be delegated, without
compromising the other user's password. This process is carried out by the root user making sudo
entries in the /etc/sudoers file. The file is edited using the visudo command. When delegating
authority, there is an element of trust required that the responsibility you are handing over will be
used with respect. Let's put a urban myth to rest here: sudo is not used purely to allow users to run
certain commands as root; it is mainly used so another user can be delegated to run an application
or system command as the application user/owner. If you currently have sudo installed on your
system, it will not overwrite your existing sudoers file. But as always, make a backup copy of /etc/
sudoers and read the upgrade instructions.

Installing sudo
Download the latest version of sudo.
This article is not an introduction of sudo. Rather, it looks at different sudo features.

For this demonstration I have used sudo version 1.7.2. If you are running AIX® 5.3 , be sure you
have the current gcc version, which is 4.0.0.
# export LIBPATH=/usr/lib
# ./configure --with-aixauth
# make
# make install

To confirm the version installed and to view the build options as well as the current installed
configuration, as root, use:
# sudo -V
Sudo version 1.7.2
Sudoers path: /etc/sudoers
Authentication methods: 'aixauth'

< rest of output truncated>

© Copyright IBM Corporation 2009 Trademarks


Make sudo work harder Page 1 of 10
developerWorks® ibm.com/developerWorks/

Since version 1.6.9, some system environment variables, like LIBPATH, are stripped before
sudo executes the given script or command. This can cause issues with existing commands
that are run under sudo. However, there is a way around this, mostly.

By default:

• sudo is placed in /usr/local/bin. Use this to run commands as another user.


• visudo is placed in /usr/local/sbin. Use this to edit the sudoers file.
• THe sudoers file, if not already present, is placed in /etc. This file holds the sudo entries.
The sudoers file
The /etc/sudoers (commonly known just as sudoers) file governs who and what can be run using
sudo. These entries are carried out by the root user or a user who has root privileges. The most
basic form of a sudo entry in sudoers is:
<user> <host> = <user to alias> <password required> < command to run>

To view what commands a user can run and what other constraints are assigned under sudo, as
the user, run:
sudo -l

To run a sudo command, the general format is:


sudo -u < user to run as> <command to run>

Log it
All commands run as sudo are logged using syslog to /var/adm/messages using the entry in the /
etc/syslog.conf file:
*.debug /var/adm/messages

However, I believe sudo commands should be logged to a separate file, which makes it easier to
view and investigate sudo commands that have been run. Of course, this also helps with keeping
an eye on failed sudo events. Create the file /var/adm/sudo.log, and then in the /etc/sudoers file,
put the following entry:
Defaults logfile=/var/adm/sudo.log
Defaults !syslog

Now all sudo events executed successfully or not go to /var/adm/sudo.log.

Managing sudoers
Over time, your sudoers file will grow with more and more entries, which is to be expected. This
could be because more application environments are being placed on the server, or because
of splitting the delegation of currents tasks down further to segregate responsibility. With many
entries, typos can occur, which is common. Making the sudoers file more manageable by the root

Make sudo work harder Page 2 of 10


ibm.com/developerWorks/ developerWorks®

user makes good administrative sense. Let's look at two ways this can be achieved, or at least a
good standard to build on. If you have many static entries (meaning the same command is run on
every machine where sudo is), put these into a separate sudoers file, which can be achieved using
the include directive.

Having many entries for individual users can also be time consuming when adding or amending
entries. With many user entries, it is good practice to put these into groups. Using groups, you can
literally group users together, and the groups are valid AIX groups.

Now look at these two methods more closely.

Include file
Within large-enterprise environments, keeping the sudoers file maintained is an important and
regularly required task. A solution to make this chore easier is to reorganize the sudoers file. One
way to do this is to extract entries that are static or reusable, where the same commands are run
on every box. Like audit/security or storix backups or general performance reports, with sudo you
can now use the include directive. The main sudoers file can then contain the local entries, and
the include file would barely need editing as those entries are static. When visudo is invoked, it
will scan sudoers when it sees the include entry. It will scan that file, then come back to the main
sudoers and carry on scanning. In reality, it works like this. When you exit out of visudo from the
main sudoers file, it will take you to the include file for editing. Once you quit the include, you are
back to the AIX prompt. You can have more than one include file, but I cannot think of a reason
why you would want more than one.

Let's call our secondary sudoers file sudo_static.<hostname>. In the examples in this
demonstration the hostname I am using is rs6000. In the main sudoers file, make the entry as
follows:
#include /etc/sudo_static.rs6000

Next, add some entries to the /etc/sudo_static.rs6000 file. You do not have to put in all the sudoers
directives or stanzas. If this file contains entries where they are not required, don't include them.
For example, my include file contains only the following text, and nothing more.
You can use the %h, instead of typing the actual hostname:

#include /etc/sudo_static.%h.
I personally do not use this method because I have experienced returning extra characters
on the hostname. This issue is fixed in sudo 1.7.2 p1.

bravo rs6000 = (root) NOPASSWD: /usr/opt/db2_08_01/adm/db2licd -end


bravo rs6000 = (root) NOPASSWD: /usr/opt/db2_08_01/adm/db2licd
bravo rs6000 = (db2inst) NOPASSWD: /home/db2inst/sqllib/adm/db2start
bravo rs6000 = (db2inst) NOPASSWD: /home/db2inst/sqllib/adm/db2stop force

When you run visudo, and you save and quit the file, visudo will inform you to click Enter to edit
the include sudoers file. Once you have edited the file, sudo will pick up on syntax errors if any, as
with the main file. Alternatively, to edit the include file directly, use:

Make sudo work harder Page 3 of 10


developerWorks® ibm.com/developerWorks/

visudo -f /etc/sudo_static.rs6000

Using groups
Users belonging to a valid AIX group can be included in sudoers, making the sudoers file more
manageable with fewer entries per user. When reorganizing the sudoers entries to include groups,
you may have to create a new groups under AIX to include users that are only allowed to use
sudo for certain commands. To use groups, simply prefix the entries with a '%'. Assume you have
groups called devops and devuat, and with those groups you have the following users:
# lsgroup -f -a users devops

devops:
users=joex,delta,charlie,tstgn

# lsgroup -f -a users devuat


devuat:
users=zebra,spsys,charlie

For the group devops to be allowed to run the /usr/local/bin/data_ext.sh command as dbdftst.

For the group devuat to be allowed to run the commands :/usr/local/bin/data_mvup.sh, /usr/local/
bin/data_rep.sh as dbukuat.

We could have the following sudoers entries:


%devops rs6000 = (dbdftst) NOPASSWD: /usr/local/bin/data_ext.sh
%devuat rs6000 = (dbukuat) /usr/local/bin/data_mvup.sh
%devuat rs6000 = (dbukuat) /usr/local/bin/data_rep.sh

Notice in the previous entries, the group devops users will not be prompted for their password
when executing /usr/local/bin/data_ext.sh; however, the group devuat users will be prompted for
their password. User "charlie" is a member of both groups (devops and devuat), so he can execute
all the above commands.

Timeout with sudo


Sudo has a feature that uses time tickets to determine how long since the last sudo command
was run. During this time period, the user can re-run the command without being prompted for
the password (that's the user's own password). Once this time allotment has ended, the user is
prompted for the password again to re-run the command. If the user gives the correct password,
the command is executed, the ticket is then re-set, and the time clock starts all over again. The
ticket feature will not work if you have NOPASSWD in the user's entry in sudoers. The default
timeout is five minutes. If you wish to change the default value, simply put an entry in sudoers. For
example, to set the timeout value for user "bravo" on any commands he runs to 20 minutes, you
could use:
Defaults:bravo timestamp_timeout=20

Make sudo work harder Page 4 of 10


ibm.com/developerWorks/ developerWorks®

To destroy the ticket, as the user, use:


$ sudo -k

When the ticket is destroyed, the user will be prompted for his password again, when running a
sudo command.

Please do not set the timeout value for all users, as this will cause problems, especially when
running jobs in batch and the batch takes longer to run than normal. To disable this feature, use
the value -1 in the timestamp_timeout variable. The time tickets are directory entries with the name
of the user located in /var/run/sudo.

Those variables
As discussed earlier, sudo will strip out potentially dangerous system variables. To check out what
variables are kept and which ones are stripped, use sudo -V. The output will give you a listing of
preserved and stripped variables. Stripping out the LIBPATH is clearly an inconvenience. There
are a couple of ways around this--either write a wrapper script or specify the environments on
the command line. Looking at the wrapper script solution first, suppose you have an application
that stops or starts a DB2® instance. You could create a bare-bones script that would keep the
variables intact. In Listing 1. rc.db2, notice that you source the instance profile, which in turn
exports various LIBPATH and DB2 environment variables, keeping the environment variable intact,
by using:
. /home/$inst/sqllib/db2profile

For completeness, the entries in sudoers to execute this is and not strip out any system
environment variables are:
bravo rs6000 = (dbinst4) NOPASSWD: /home/dbinst4/sqllib/adm/db2start
bravo rs6000 = (dbinst4) NOPASSWD: /home/dbinst4/sqllib/adm/db2stop force
bravo rs6000 = (dbinst4) NOPASSWD: /usr/local/bin/rc.db2 stop db2inst4
bravo rs6000 = (dbinst4) NOPASSWD: /usr/local/bin/rc.db2 start db2inst4

Note in this example, user "bravo" can execute the above commands as user "dbinst4." Typically,
the user would run:
sudo -u dbinst4 /usr/local/bin/rc.db2 stop db2inst4
sudo -u dbinst4 /usr/local/bin/rc.db2 start db2inst4

Listing 1. rc.db2
#!/bin/sh
# rc.db2
# stop/start db2 instances

# check to see if db2 inst is runningdb2_running(){state=`ps -ef |grep db2sysc


|grep -v grep| awk '$1=="'${inst}'" { print $1 }'`
if [ "$state" = "" ]
then
return 1
else
return 0

Make sudo work harder Page 5 of 10


developerWorks® ibm.com/developerWorks/

fi}

usage ()

{
echo "`basename $0` start | stop <instance>"
}

# stop db2
stop_db2 ()
{
echo "stopping db2 instance as user $inst"
if [ -f /home/$inst/sqllib/db2profile ]; then
. /home/$inst/sqllib/db2profile
else
echo "Cannot source DB2..exiting"
exit 1
fi
/home/$inst/sqllib/adm/db2stop force
}

# start db2
start_db2 ()
{
echo "starting db2 instance as user $inst"
if [ -f /home/$inst/sqllib/db2profile ]; then
. /home/$inst/sqllib/db2profile
else
echo "Cannot source DB2..exiting"
exit 1
fi
/home/$inst/sqllib/adm/db2start
}

# check we get 2 params


if [ $# != 2 ]
then
usage
exit 1
fi

inst=$2

case "$1" in
Start|start)
if db2_running
then
echo "db2 instance $inst appears to be already running"
exit 0
else
echo " instance not running as user $inst..attempting to start it"
start_db2 $inst

fi
;;
Stop|stop)
if db2_running
then
echo "instance running as $inst..attempting to stop it"
stop_db2 $inst
else
echo "db2 instance $inst appears to be not running anyway"
exit 0
fi
;;
*) usage
;;

Make sudo work harder Page 6 of 10


ibm.com/developerWorks/ developerWorks®

esac

The other way to preserve system environment variables is to use the Defaults !env_reset
directive, like in sudoers:
Defaults !env_reset

Then from the command line, specify the environment variable name with its value:
$ sudo LIBPATH=″/usr/lib:/opt/db2_09_05/lib64″ -u delta /usr/local/bin/datapmp

If you do not put the !env_reset entry in, you will get the following error from sudo when you try to
run the command:
sudo: sorry, you are not allowed to set the following environment variables: LIBPATH

If you find that sudo is also stripping out other environment variables, you can specify the variable
name in sudoers so that sudo keeps those variables intact (with the Defaults env_keep +=
directive). For instance, suppose sudo was stripping out the application variables DSTAGE_SUP
and DSTAGE_META from one of my suodo-ised scripts. To preserve these variables, I could put
the following entries in sudoers:
Defaults env_keep += "DSTAGE_SUP"
Defaults env_keep += "DSTAGE_META"

Notice that I give the variable name and not the variable value. The values are already contained
in my script like this:
export DSTAGE_SUP=/opt/dstage/dsengine; export DSTAGE_META=/opt/dstage/db2

Now when the sudo script is executed, the above environment variables are preserved.

Securing the sudo path


A default PATH within sudoers can be imposed using the secure_path directive. This directive
specifies where to look for binaries and commands when a user executes a sudo command.
This option clearly tries to lock down specific areas where a user runs a sudo command, which is
good practice. Use the following directive in sudoers, specifying the secure PATH with its search
directories:
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/opt/freeware/bin:/usr/sbin"

Getting restrictive
Restrictions can be put in place to restrict certain commands to users. Assume you have a group
called dataex, whose members are "alpha," "bravo," and "charlie." Now, that group has been
allowed to run the sudo command /usr/local/bin/mis_ext * , where the asterisk represents the
many parameters passed to the script. However, user "charlie" is not allowed to execute that script

Make sudo work harder Page 7 of 10


developerWorks® ibm.com/developerWorks/

if the parameter is import. This type of condition can be met by using the logical NOT '!' operator.
Here is how that is achieved in sudoers:
%dataex rs6000 = (dbmis) NOPASSWD: /usr/local/bin/mis_ext *
charlie rs6000 = (dbmis) NOPASSWD: !/usr/local/bin/mis_ext import

Note that the logical NOT operator entries go after the non-restrictive entry. Many conditional NOT
entries can be applied on the same line; just make sure that they are comma separated, like so:
charlie rs6000 = (dbmis) NOPASSWD: /usr/local/bin/aut_pmp *

charlie rs6000 = (dbmis) NOPASSWD: !/usr/local/bin/aut_pmp create,


!/usr/local/bin/aut_pmp delete, !/usr/local/bin/aut_pmp amend

When in visudo, do not think just saving the sudo entry and staying in visudo will make the
changes effective; it won't. You must exit visudo for the changes to take effect.

Rolling out sudo commands


Rolling out sudo commands to remote hosts in an enterprise environment is best done using a
ssh script as root, and the keys should have been exchanged between the hosts, for password-
less logins. Let's look at one example of how to do this. With geographically remote machines,
if you get a hardware issue of some sort (disk or memory), the IBM® engineer will be on-site to
replace the failing hardware. There will be occasions when they require the root password to carry
out their task. One procedure you might want to put in place is for the engineer to gain access
to root they must use sudo. Informing the engineer prior to the visit of the password would be
advantageous. Listing 2 demonstrates one way you could roll out this configuration. Looking more
closely at Listing 2, use a for loop containing a list of hosts you are pushing out to. (Generally,
though, you would have these hosts in a text file and read them in using a while loop.) Using
the 'here' document method, make a backup copy of sudoers, and an entry is then appended to
sudoers, like so:
# -- ibmeng sudo root
ibmeng host1 = (root) NOPASSWD:ALL

Next, the user "ibmeng" is created, and the password is set for the user using chpasswd. In this
demonstration, it is ibmpw. A message is then appended to their profile, informing the user how to
sudo to root. So when the engineer logs in, he is presented with the message:
IBM Engineer, to access root account type: sudo -u root su -

Of course the account for ibmeng would be locked after the visit.

Listing 2. dis_ibm
#!/bin/sh
# dis_ibm
dest_hosts='host1 host2 host3 host4'

for host in $dest_hosts


do

Make sudo work harder Page 8 of 10


ibm.com/developerWorks/ developerWorks®

echo "doing [$host]"

$ssh -T -t -l root $host<<'mayday'


host=`hostname`
cp /etc/sudoers /etc/sudoers.bak

if [ $? != 0 ]
then
echo "error: unable to cp sudoers file"
exit 1
fi
echo "# -- ibmeng sudo root\nibmeng $host = (root) NOPASSWD:ALL">>/etc/sudoers

mkuser su=false ibmeng


if [ $? = 0 ]
then
echo "ibmeng:ibmpw" | chpasswd -c
else
echo "error: unable to create user ibmeng and or passwd"
exit 1
fi
chuser gecos='IBM engineer acc' ibmeng
if [ -f /home/ibmeng/.profile ]
then
echo "echo \"IBM Engineer, to access root account type: sudo -u root su -"\"
>>/home/ibmeng/.profile
fi
mayday
done

Conclusion
Sudo allows you to control who can run what commands as whom. But you must be able to
understand the features of sudoers fully to gain maximum understanding of its implications and
responsibility.

Make sudo work harder Page 9 of 10


developerWorks® ibm.com/developerWorks/

Related topics
• Learn more about and download sudo.
• Download IBM product evaluation versions and get your hands on application development
tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.

© Copyright IBM Corporation 2009


(www.ibm.com/legal/copytrade.shtml)
Trademarks
(www.ibm.com/developerworks/ibm/trademarks/)

Make sudo work harder Page 10 of 10

You might also like