#!/bin/sh # vim: tabstop=4 # # author: chris friedhoff - chris@friedhoff.org # version: pcaps4server 5 Tue Mar 11 2008 # # # changelog: # 1 - initial release pcaps4convenience # 1 - 2007.02.15 - initial release # 2 - 2007.11.02 - changed to new setfcaps api; each app is now callable; supressed error of id # 3 - 2007.12.28 - changed to libcap2 package setcap/getcap # 4 - renamed to pcaps4server # removed suid0 and convenience files, # they are now in pcaps4suid0 resp. pcaps4convenience # 5 - changed 'attr -S -r' to 'setcap -r' and removed attr code # # ########################################################################### # change the installation of different server to be able not to run as root # and have their own unpriviledged user. The binary has the needed POSIX # Capabilities. # to ensure that the server is really started as his respective user, we set # the suid bit (BUT NOT 0)! # paths are hard coded and derive from a slackware system # change it to your needs !! ########################################################################### VERBOSE="-v" #VERBOSE="" APPS="" message(){ printRedMessage "$1" } printRedMessage(){ # print message red and turn back to white echo -e "\n\033[00;31m $1 ...\033[00;00m\n" } printGreenMessage(){ # print message red and turn back to white echo -e "\033[00;32m $1 ...\033[00;00m\n" sleep 0.5 } checkReturnCode(){ if [ "$?" != "0" ]; then printRedMessage "!! I'M HAVING A PROBLEM !! THE RETURNCODE IS NOT 0 !! I STOP HERE !!" exit 1 else printGreenMessage ":-)" sleep 0.5 fi } p4r_test(){ #for now, we work with root if [ "$( id -u )" != "0" ]; then echo "Sorry, you must be root !" exit fi } # apache 1.3 ######## #APPS="$APPS apache1" apache1_convert(){ message "converting apache1" if [ "$( id -g apache 2>/dev/null )" == "" ]; then groupadd -g 60 apache fi if [ "$( id -u apache 2>/dev/null )" == "" ]; then useradd -g apache -d / -u 600 apache fi sed -i -e "{s|^\(User\).*|\1 apache|; s|^\(Group\) .*|\1 apache|}" /etc/apache/httpd.conf chown $VERBOSE -R apache:apache /var/run/apache/ chown $VERBOSE -R apache:apache /etc/apache/ chown $VERBOSE -R apache:apache /var/log/apache/ chown $VERBOSE apache:apache /usr/sbin/httpd chmod $VERBOSE u+s /usr/sbin/httpd setcap cap_net_bind_service=ep /usr/sbin/httpd checkReturnCode } apache1_revert(){ message "reverting apache1" chown $VERBOSE -R root:root /var/run/apache/ chown $VERBOSE -R root:root /etc/apache/ chown $VERBOSE -R root:root /var/log/apache/ chown $VERBOSE root:root /usr/sbin/httpd chmod $VERBOSE u-s /usr/sbin/httpd setcap -r /usr/sbin/httpd checkReturnCode sed -i -e "{s|^\(User\).*|\1 nobody|; s|^\(Group\).*|\1 nogroup|}" /etc/apache/httpd.conf userdel apache groupdel apache } # apache 2.x ######## APPS="$APPS apache2" apache2_convert(){ message "converting apache2" if [ "$( id -g apache 2>/dev/null )" == "" ]; then groupadd -g 60 apache fi if [ "$( id -u apache 2>/dev/null )" == "" ]; then useradd -g apache -d / -u 600 apache fi sed -i -e "{s|^\(User\).*|\1 apache|; s|^\(Group\) .*|\1 apache|}" /etc/httpd/httpd.conf chown $VERBOSE -R apache:apache /var/run/httpd/ chown $VERBOSE -R apache:apache /etc/httpd/ chown $VERBOSE -R apache:apache /var/log/httpd/ chown $VERBOSE apache:apache /usr/sbin/httpd chmod $VERBOSE u+s /usr/sbin/httpd #setfcaps -c cap_net_bind_service=p -e /usr/sbin/httpd setcap cap_net_bind_service=ep /usr/sbin/httpd checkReturnCode } apache2_revert(){ message "reverting apache2" chown $VERBOSE -R root:root /var/run/httpd/ chown $VERBOSE -R root:root /etc/httpd/ chown $VERBOSE -R root:root /var/log/httpd/ chown $VERBOSE root:root /usr/sbin/httpd chmod $VERBOSE u-s /usr/sbin/httpd setcap -r /usr/sbin/httpd checkReturnCode sed -i -e "{s|^\(User\).*|\1 nobody|; s|^\(Group\).*|\1 nogroup|}" /etc/httpd/httpd.conf userdel apache groupdel apache } # samba ####### APPS="$APPS samba" samba_convert(){ message "converting samba" if [ "$( id -g samba 2>/dev/null )" == "" ]; then groupadd -g 61 samba fi if [ "$( id -u samba 2>/dev/null )" == "" ]; then useradd -g samba -d / -u 610 samba fi chown $VERBOSE -R samba:samba /var/log/samba chown $VERBOSE -R samba:samba /etc/samba chown $VERBOSE -R samba:samba /var/run/samba chown $VERBOSE -R samba:samba /var/cache/samba chown $VERBOSE samba:samba /usr/sbin/smbd /usr/sbin/nmbd chmod $VERBOSE u+s /usr/sbin/smbd /usr/sbin/nmbd setcap cap_net_bind_service,cap_sys_resource,cap_dac_override=ep /usr/sbin/smbd checkReturnCode setcap cap_net_bind_service=ep /usr/sbin/nmbd checkReturnCode } samba_revert(){ message "reverting samba" chown $VERBOSE -R root:root /var/log/samba chown $VERBOSE -R root:root /etc/samba chown $VERBOSE -R root:root /var/run/samba chown $VERBOSE -R root:root /var/cache/samba chown $VERBOSE root:root /usr/sbin/smbd /usr/sbin/nmbd chmod $VERBOSE u-s /usr/sbin/smbd /usr/sbin/nmbd setcap -r /usr/sbin/smbd checkReturnCode setcap -r /usr/sbin/nmbd checkReturnCode userdel samba groupdel samba } # bind ###### APPS="$APPS bind" bind_convert(){ message "converting bind" if [ "$( id -g bind 2>/dev/null )" == "" ]; then groupadd -g 62 bind fi if [ "$( id -u bind 2>/dev/null )" == "" ]; then useradd -g bind -d / -u 620 bind fi chown $VERBOSE -R bind:bind /var/run/named chown $VERBOSE -R bind:bind /var/named chown $VERBOSE bind:bind /etc/rndc.key chown $VERBOSE bind:bind /usr/sbin/named chmod $VERBOSE u+s /usr/sbin/named setcap cap_net_bind_service=ep /usr/sbin/named checkReturnCode } bind_revert(){ message "reverting bind" chown $VERBOSE -R root:root /var/run/named chown $VERBOSE -R root:root /var/named chown $VERBOSE root:root /etc/rndc.key chown $VERBOSE root:root /usr/sbin/named chmod $VERBOSE u-s /usr/sbin/named setcap -r /usr/sbin/named checkReturnCode userdel bind groupdel bind } # dhcpd ####### APPS="$APPS dhcpd" dhcpd_convert(){ message "converting dhcpd" if [ "$( id -g dhcpd 2>/dev/null )" == "" ]; then groupadd -g 63 dhcpd fi if [ "$( id -u dhcpd 2>/dev/null )" == "" ]; then useradd -g dhcpd -d / -u 630 dhcpd fi chown $VERBOSE dhcpd:dhcpd /var/run/dhcpd chown $VERBOSE dhcpd:dhcpd /etc/dhcpd.conf chown $VERBOSE -R dhcpd:dhcpd /var/state/dhcp/ chown $VERBOSE dhcpd:dhcpd /usr/sbin/dhcpd chmod $VERBOSE u+s /usr/sbin/dhcpd setcap cap_net_bind_service,cap_net_raw=ep /usr/sbin/dhcpd checkReturnCode } dhcpd_revert(){ message "reverting dhcpd" chown $VERBOSE root:root /var/run/dhcpd chown $VERBOSE root:root /etc/dhcpd.conf chown $VERBOSE -R root:root /var/state/dhcp/ chown $VERBOSE root:root /usr/sbin/dhcpd chmod $VERBOSE u-s /usr/sbin/dhcpd setcap -r /usr/sbin/dhcpd checkReturnCode userdel dhcpd groupdel dhcpd } # cupsd ####### APPS="$APPS cupsd" cupsd_convert(){ message "converting cupsd" if [ "$( id -g cupsd 2>/dev/null )" == "" ]; then groupadd -g 64 cupsd fi if [ "$( id -u cupsd 2>/dev/null )" == "" ]; then useradd -g cupsd -d / -u 640 cupsd fi sed -i -e "{s|^\(User\).*|\1 cupsd|; s|^\(Group\) .*|\1 cupsd|}" /etc/cups/cupsd.conf chown $VERBOSE -R cupsd:cupsd /etc/cups chown $VERBOSE -R cupsd:cupsd /var/cache/cups chown $VERBOSE -R cupsd:cupsd /var/log/cups chown $VERBOSE -R cupsd:cupsd /var/spool/cups chown $VERBOSE -R cupsd:cupsd /var/run/cups chown $VERBOSE cupsd:cupsd /usr/sbin/cupsd chmod $VERBOSE u+s /usr/sbin/cupsd setcap cap_net_bind_service,cap_dac_read_search=ep /usr/sbin/cupsd checkReturnCode } cupsd_revert(){ message "reverting cupsd" chown $VERBOSE -R root:root /etc/cups chown $VERBOSE -R root:lp /var/cache/cups chown $VERBOSE -R root:root /var/log/cups chown $VERBOSE -R root:root /var/spool/cups chown $VERBOSE root:lp /var/run/cups chown $VERBOSE lp:sys /var/run/cups/certs chmod $VERBOSE 750 /var/run/cups/certs chown $VERBOSE root:root /usr/sbin/cupsd chmod $VERBOSE u-s /usr/sbin/cupsd setcap -r /usr/sbin/cupsd checkReturnCode sed -i -e "{s|^\(User\).*|\1 lp|; s|^\(Group\) .*|\1 sys|}" /etc/cups/cupsd.conf userdel cupsd groupdel cupsd } usage_message(){ echo "Try 'pcaps4server help' for more information" } p4r_usage(){ echo echo "pcaps4server" echo echo "pcaps4server stores the needed POSIX Capabilities for server binaries to" echo "run successful into their Permitted and Effective Set." echo "The server are now able to run as an unpriviledged user." echo "For each server software an unpriviledged user is added the system." echo "The ownership of all the respective paths are changed to this user." echo "To ensure that the server is starting as this unpriviledgesd user, the" echo "suid bit (NOT 0) is set." echo "Effectively this means every user can start this server daemons (for now)." echo "All paths are hard coded!" echo "You have been warned. Enjoy!" echo echo "Your Filesystem has to support extended attributes and your kernel must have" echo "support for POSIX File Capabilities (CONFIG_SECURITY_FILE_CAPABILITIES)." echo echo "Usage: pcaps4server [PROG] [con(vert)|rev(ert)|help]" echo echo " con|convert - from setuid0 to POSIX Capabilities" echo " rev|revert - from POSIX Capabilities back to setui0" echo " help - this help message" echo echo " PROG: $APPS" echo } case "$1" in con|convert) p4r_test for j in $APPS; do ${j}_convert done exit ;; rev|renvert) p4r_test for j in $APPS; do ${j}_revert done exit ;; help) p4r_usage exit ;; esac for i in ${APPS}; do if [ "$1" == "$i" ]; then case "$2" in con|convert) p4r_test ${i}_convert exit ;; rev|revert) p4r_test ${i}_revert exit ;; *) usage_message exit 1 ;; esac fi done usage_message