Some companies do not allow usage of sudo or su – root due to security reasons. E.g.:
I have written a cron job for CentOS Linux that allows non-root users to trigger different init.d executables on their own without using sudo.
User just adds a token (e.g.: httpd graceful) to a trigger file within their home directory and waits for the root cron job. The root cron job picks up the token every two minutes, validates it and then runs the desired init.d script.
This method works on all System V systems and is useful for Apache, MySQL, Samba and many other middleware that has to be installed by root, but used by non-root or unprivileged application administrators. Ok admin, first put following files to the non-root users home directory:
- Configuration file
- Empty trigger file
- Empty log file
- Cron job as bash script file
The administrator has to ensure, that file permissions and ownership is set properly to avoid abuse. Here is an example from the view of the non-root user peter:
[peter ~]$ ls -l service-ctrl.* -rw-r--r-- 1 root peter 511 Sep 11 22:22 service-ctrl.cfg -rw-r--r-- 1 root peter 511 Sep 11 22:22 service-ctrl.cfg.bak -rw-r--r-- 1 root peter 167 Sep 11 22:22 service-ctrl.log -rwxr--r-- 1 root root 2828 Sep 11 22:22 service-ctrl.sh -rw-rw-r-- 1 root peter 0 Sep 11 22:22 service-ctrl.trigger
The configuration file contains a list of services and their options. E.g.:
[peter ~]$ grep ^srvlst service-ctrl.cfg srvlst+=("httpd start stop restart graceful status") srvlst+=("iptables status")
The configuration file allows the administrator (=root) to enable the usage of specific services and options on a per-user basis. The default service for testing purposes is: /etc/init.d/ntpd status
[peter ~]$ grep ^srvlst service-ctrl.sh srvlst+=("ntpd status") # Default service for testing.
The root cron job is quite simple:
[root ~]# crontab -l | grep service-ctrl */2 * * * * /home/users/peter/service-ctrl.sh >/dev/null 2>&1 # Service controller
The trigger file is used by the non-root user to add the token. E.g.:
[peter ~]$ echo "ntpd status" > service-ctrl.trigger
Once triggered, user has to wait for the root cron job which picks up the token:
[peter ~]$ tail -f service-ctrl.log 2015-09-11 22:33:01 Trigger: ntpd status 2015-09-11 22:33:01 Running: /etc/init.d/ntpd status ntpd (pid 4164) is running...
After execution, cron job clears the token file to avoid any loops.
Configuration file
#!/bin/bash ########################################## # service-ctrl.cfg # # This file is sourced by service-ctrl.sh ########################################## # Peter Wellmann # Version 11.09.2015 # https://denken24.de/?p=526 ########################################## # Define service and options here: #srvlst+=("fail2ban start stop restart status") #srvlst+=("httpd start stop restart graceful status") ##########################################
Cron job (bash script)
#!/bin/bash ########################################## # service-ctrl.sh ########################################## # Run service scripts for non-root users. # # This script is triggerd by a root cron job. # # Activate/Trigger: # echo "<service> <option>" > service-ctrl.trigger ########################################## # (c) Peter Wellmann # Version 11.09.2015 # https://denken24.de/?p=526 ########################################## # Set globals timestamp="%Y-%m-%d %T" cfgfile="service-ctrl.cfg" trigger="service-ctrl.trigger" logfile="service-ctrl.log" # Check file permissions an ownership cd `dirname $0` 2>/dev/null if [ $? -ne 0 ]; then echo "Error! Invald script directory: `dirname $0`"; exit 1; fi /usr/bin/stat -c "%A %G" "${trigger}" 2>/dev/null | grep "^-...rw-.--" | grep -v "root$" -q if [ $? -ne 0 ]; then echo "Error! Invalid permission or ownership assigned to: ${trigger}"; exit 1; fi /usr/bin/stat -c "%A %G" "${logfile}" 2>/dev/null | grep "^-...r--.--" | grep -v "root$" -q if [ $? -ne 0 ]; then echo "Error! Invalid permission or ownership assigned to: ${logfile}"; exit 1; fi /usr/bin/stat -c "%A %U" "${cfgfile}" 2>/dev/null | grep "^-rw-r--.--\ root$" -q if [ $? -ne 0 ]; then echo "Error! Invalid permission or ownership assigned to: ${cfgfile}"; exit 1; fi ########################################## # Prepare service array srvlst=() # Init empty service array srvlst+=("ntpd status") # Default service for testing. See service-ctrl.cfg for additional services! source ${cfgfile} # load additional services from cfg file ########################################## # Anything todo? if [ ! -s "${trigger}" ]; then exit 0; fi # Redirect all output to log file exec >> "${logfile}" 2>&1 # Common functions log() { if [[ -n "$1" ]]; then echo "$(date +"${timestamp}") $1"; fi; return 0 } error() { if [[ -n "$1" ]]; then log "Error! $1"; exit 1; fi; return 0 } # Main loop triggerary=(`grep ^[a-z] "${trigger}" -m 1`) log "Trigger: ${triggerary[0]} ${triggerary[1]}" # Check service script if [ -x "/etc/init.d/${triggerary[0]}" ]; then # walk through allowed services for srvid in "${!srvlst[@]}"; do srvary=(${srvlst[$srvid]}) # srvary[0]-->service srvary[>=1]-->options for((i=1; i<${#srvary[@]}; i++)); do if [[ "${triggerary[0]} ${triggerary[1]}" == "${srvary[0]} ${srvary[$i]}" ]]; then log "Running: /etc/init.d/${triggerary[0]} ${triggerary[1]}" /etc/init.d/${triggerary[0]} ${triggerary[1]} fi done done else log "Service script not executable: /etc/init.d/${triggerary[0]}" fi # Clear trigger file while keeping ownership echo -n > "${trigger}" # Cleanup (shorten) log file to 1000 lines /bin/sed -i -e :a -e '$q;N;1001,$D;ba' ${logfile} exit 0 #EOF
Schreibe einen Kommentar