In order to keep systems maintainable and security at a respectable level, sudo is used to perform actions as super-user or application user. Groups
The groups used to specify various security levels are:
| Groupname | sudo Alias | GroupID |
|---|---|---|
| sysadm | SYSADMIN | 10001 |
| appadm | APPADMIN | 10002 |
| dba | DBAADMIN | 10003 |
Every sudoers related group has to have a gid in the range 10000-10200
Sudo file contents
# /etc/sudoers # # This file MUST be edited with the 'visudo' command as root. # # See the man page for details on how to write a sudoers file. # Host alias specification # User alias specification User_Alias SYSADM = %sysadm User_Alias APPADM = %appadm User_Alias DBAADM = %dba # Cmnd alias specification # Default settings Defaults !lecture,tty_tickets,!fqdn Defaults:SYSADM !authenticate Defaults:APPADM !authenticate Defaults:DBAADM !authenticate ### OLD Cmnd_Alias SUDO_ROOT = /bin/su - Cmnd_Alias REMOTE_ACCESS = /usr/bin/ssh, /usr/bin/scp # Members of the unixbeheer group may gain root privileges SYSADM ALL = (ALL) NOPASSWD: ALL # Members of the itsupport group may gain application privileges APPADM ALL = (tomcat,apache) NOPASSWD: ALL # Memebers of the dba group my gain oracle privileges DBAADM ALL = (oracle) NOPASSWD: ALL ### OLD settings # User privilege specification root ALL=(ALL) SETENV: ALL #%wheel ALL=(ALL) SETENV: SUDO_ROOT
# sudoers file. # # This file MUST be edited with the 'visudo' command as root. # # See the sudoers man page for the details on how to write a sudoers file. # # Host alias specification # User alias specification # Example: User_Alias ALIAS = username, %group # User_Alias SUDOALIAS = %unixgroup User_Alias SYSADMIN = %sysadm User_Alias APPADMIN = %appadm User_Alias DBAADMIN = %dba # Cmnd alias specification # Example: Cmnd_Alias DOWN = /usr/sbin/shutdown, /usr/sbin/reboot, /usr/sbin/init # Cmnd_Alias KILL = /usr/sbin/kill # Defaults specification Defaults: SYSADMIN !authenticate Defaults: APPADMIN !authenticate Defaults: DBAADMIN !authenticate ## Generic defaults Defaults syslog=auth Defaults !logfile Defaults !lecture Defaults tty_tickets Defaults !fqdn # Runas alias specification Runas_Alias SYSADMIN = root,operator Runas_Alias APPADMIN = itsupport,apache,tomcat,tibadmin Runas_Alias DBAADMIN = oracle # User privilege specification # alias/user/group hostfrom (runas_user) commands **** ALL=(ALL) NOPASSWD: ALL **** ALL=(ALL) NOPASSWD: ALL **** ALL=(APPADMIN) NOPASSWD: ALL **** ALL=(DBAADMIN) NOPASSWD: ALL
The created user aliases consist of unix groups. Each unix group consists of users from a specific department. This is done to keep people from editing the sudoers file when new employees are hired or employees leave the company.
The generic defaults keeps sudo from displaying an annoying warning each time someone tries to use sudo without permission.
Furthermore defaults are set per group. In this case users of the mentioned aliases are not asked for a password when running ‘sudo command’. Privilege substitution
Syntax:
<user_alias> <host_alias> = (<runas_alias>) <cmnd_alias>
Create user script (cr_user.sh)
#!/bin/bash
#
### Description:
#
# $0 -u username -s servername <-g PRIMARYGROUP> <-G ADDITIONALGROUPS>
#
# Create user 'username' on server 'servername'.
#
### Prerequisities
# Exit code
# * User exists on current server [200]
# * User is assigned to primary and secondary groups on current server [201]
# * User has created a public/private keypair (sshkeygen -t dsa) [202]
#
### User management
#
# New users are created using this script, you need to point the servername flag (-s)
# to localhost in order to create the user locally.
#
# For normal users, the UID range 1000-1100 is reserved.
# System users should be assigned a UID in the range 0-500 (nagios and apache are system users)
# Application users should obtain a UID between 2000-2100
#
### Group management
#
# The new sudoers file is based on group membership. The GID's 10000 - 10100 are
# reserved for primary groups.
# Currently the following groups have been created:
# sysadmin - Unix Administrators (most powerfull users)
# appadmin - Application Administrators (application management)
# oracledba - Oracle DBA users (oracle management)
#
# Each new user that is created on the local machine must be assigned to one of
# the above groups with the -g option of this script.
#
###
do_usage() {
echo " ***Usage:***"
echo "$0 -u <username> -s <servername> [-h] [-g <primary group>] [-G <additional groups>]"
echo ""
echo " -u Username to create on remote server"
echo " -s Servername where to create the user"
echo " -h This help message"
echo " -g Primary group User is member of (unixadm,appadm,dba)"
echo " -G Additional groups user is member of (comma seperated)"
echo ""
echo "Examples:"
echo " 1. Create user oracle on server poekoe"
echo " $0 -u oracle -s poekoe"
echo ""
echo " 2. Create user testuser on this server as member of unixadm and wheel"
echo " $0 -u testuser -s localhost -g unixadm -Gwheel"
echo ""
echo "Note:"
echo " Use localhost as servername to create a local user"
echo ""
exit 1
}
do_help_no_ssh_pubkeys() {
echo " ***ERROR***"
echo "User $USRNAME has no ssh keys in his .ssh directory!"
echo ""
echo "They can be created by running the following command:"
echo " ssh-keygen -t dsa -C '$USRNAME@`hostname`'"
echo ""
echo "Remember to specify a passphrase for improved security"
echo ""
exit 202
}
### Get all user fields from the /etc/passwd file
do_get_user_info() {
let USRCOUNT=0
for USRDATA in "`cat /etc/passwd | grep $USRNAME`"; do
let USRCOUNT++
USRUID=`echo $USRDATA | cut -d : -f 3`
USRGID=`echo $USRDATA | cut -d : -f 4`
USRFNAME="`echo $USRDATA | cut -d : -f 5`"
USRDIR=`echo $USRDATA | cut -d : -f 6`
USRSHELL=`echo $USRDATA | cut -d : -f 7`
done
if [ -z "$USRDATA" ]; then
exit 200
fi
if [ $USRCOUNT -gt 1 ]; then
echo "User $USRNAME has $USRCOUNT records in /etc/passwd, please investigate."
exit 1
fi
if [ -z "$USRUID" ]; then
echo "User $USRNAME has no UID"
exit 200
fi
if [ -z "$USRGID" ]; then
echo "User $USRNAME has no GID"
exit 200
fi
if [ -z "$USRFNAME" ]; then
echo "User $USRNAME has no Full Name / Comment"
exit 200
fi
if [ -z "$USRDIR" ]; then
echo "User $USRNAME has no home directory"
exit 200
fi
if [ -z "$USRSHELL" ]; then
echo "User $USRNAME has no shell"
exit 200
fi
}
### Get required fields from the /etc/group file
do_get_group_info() {
let NUMGROUPS=0
for GRPDATA in `cat /etc/group | grep $USRNAME | cut -d : -f 1,3`; do
GRPNAME=`echo $GRPDATA | cut -d : -f 1`
GRPGID=`echo $GRPDATA | cut -d : -f 2`
if [ $NUMGROUPS -gt 0 ]; then
USRGROUPS="$USRGROUPS,$GRPNAME"
CRGROUP="$CRGROUP ; if [ \"\`grep $GRPGID /etc/group\`\" = \"\" ]; then groupadd -g $GRPGID $GRPNAME; fi"
else
USRGROUPS="-G $GRPNAME"
CRGROUP="if [ \"\`grep $GRPGID /etc/group\`\" = \"\" ]; then groupadd -g $GRPGID $GRPNAME; fi"
fi
let NUMGROUPS++
done
# Does the user have the correct amount of groups (one or more) ?
if [ $NUMGROUPS -lt 1 ]; then
echo "User is not member of any secondary group. Membership of at least 1 secondary group is required!"
exit 201
fi
# Create primary GID if needed.
PRIGRPNAME=`cat /etc/group | grep $USRGID | cut -d : -f 1`
if [ "$PRIGRPNAME" != "" ]; then
CRGROUP="$CRGROUP ; if [ \"\`grep $USRGID /etc/group\`\" = \"\" ]; then groupadd -g $USRGID $PRIGRPNAME; fi"
else
echo "Unable to map $USRGID to groupname. Please check manualy"
exit 1
fi
}
do_check_group() {
echo -n "Checking for existence of group $1..."
if [ "`cat /etc/group | cut -d : -f 1 | grep $1`" = "" ]; then
echo " [!!]"
echo " - Group $1 does not exist in /etc/group"
exit
else
echo " [OK]"
fi
}
do_check_ssh_key() {
for PUBKEYS in `find $USRDIR/.ssh -name '*.pub'`; do
PUBKEY=`cat $PUBKEYS`
done
if [ -z "$PUBKEY" ]; then
do_help_no_ssh_pubkeys
exit 202
fi
}
do_prep_create_user() {
CRUSER="useradd -u $USRUID -g $USRGID $USRGROUPS -m -d $USRDIR -s $USRSHELL -c '$USRFNAME' $USRNAME" ;# Create user command
CRUSER="$CRUSER; mkdir -p $USRDIR/.ssh/" ;# Create ssh basedir for user
CRUSER="$CRUSER; echo \"$PUBKEY\" > $USRDIR/.ssh/authorized_keys" ;# Create authorized_keys for user
CRUSER="$CRUSER; ln -s $USRDIR/.ssh/authorized_keys $USRDIR/.ssh/authorized_keys2" ;# Create authorized_keys2 for user
CRUSER="$CRUSER; chown -R $USRUID:$USRGID $USRDIR/.ssh" ;# Fix ownership for ssh keyfiles
CRUSER="$CRUSER; chmod 600 $USRDIR/.ssh/authorized_keys" ;# Fix permissions for ssh keyfiles
}
do_create_user_remotely() {
echo ""
export CRUSER
ssh $SVRNAME "$CRUSER"
}
do_create_user_local() {
echo ""
bash -c "$CRUSER"
echo ""
do_help_no_ssh_pubkeys
}
### Main
# Currently only root is allowed to run this script
# in a distant future this script should be run by
# members of the unix admin group
if [ "$UID" -ne "0" ]; then
echo "This script must be run by the superuser (root)"
echo
exit 255
fi
## GetOpt confused me, so here's the syntax
# getopt paramchar: == -paramchar +argument
# example: ./progname -u argh == getopts u:
# getopt paramchar == -paramchar
# example: ./progname -h == getopts h
while getopts g:G:hs:u: PARAM ; do
case $PARAM in
h)
do_usage
;;
u)
USRNAME="$OPTARG"
;;
s)
SVRNAME="$OPTARG"
;;
g)
USRGID="$OPTARG"
;;
G)
USRGROUP="$OPTARG"
;;
esac
done
# Check if all required parameters are given
if [ -z "$USRNAME" -o -z "$SVRNAME" ]; then
do_usage
fi
if [ "$SVRNAME" != "localhost" ]; then
do_get_user_info
do_get_group_info
do_check_ssh_key
do_prep_create_user
echo "Sanity checks were met, now the following commands will be run on host $SVRNAME:"
echo "# Create groups"
echo " $CRGROUP"
echo "#---"
echo "# Create user"
echo " $CRUSER"
do_create_user_remotely
else
if [ "`grep $USRNAME /etc/passwd`" != "" ]; then
echo "User $USRNAME already exists."
exit 255
fi
### Check if the GID assigned to the new user is supported by the sudo config.
let VALIDGROUP=0
for PRIGRP in `cat /etc/group | grep 100[0-9][0-9] | cut -d : -f 1`; do
GROUPLIST="$PRIGRP,$GROUPLIST"
if [ "$USRGID" = "$PRIGRP" ]; then
let VALIDGROUP=1
fi
done
# Check if user has correct GID
if [ $VALIDGROUP -eq 0 ]; then
echo "$USRGID is not a valid primary group. User must be assigned (using -g) to one of the following groups:"
echo " $GROUPLIST"
exit 201
fi
### Check for valid groupnames on all user assigned groups
for GRP in `echo $USRGID,$USRGROUP | sed -e 's/\,/\ /g'`; do
do_check_group $GRP
done
### Apply default user settings if applicable
if [ -z "$USRFNAME" ]; then
USRFNAME="-c 'Added by cr_user script'"
fi
if [ -z "$USRSHELL" ]; then
USRSHELL="-s /bin/bash"
fi
if [ -z "$USRDIR" ]; then
USRDIR="-d /export/home/$USRNAME"
fi
if [ ! -z "$USRGID" ]; then
USRGID="-g $USRGID"
fi
if [ ! -z "$USRGROUP" ]; then
USRGROUP="-G $USRGROUP"
fi
CRUSER="`which useradd` -m $USRFNAME $USRGID $USRGROUP $USRSHELL $USRDIR $USRNAME"
echo "Sanity checks were met, now the following command will be executed:"
echo " $CRUSER"
do_create_user_local
fi