• No results found

Creating users and groups for software daemons

In document securing debian howto en pdf (Page 174-179)

If your software runs a daemon that does not need root privileges, you need to create a user for it. There are two kind of Debian users that can be used by packages: static uids (assigned

bybase-passwd, for a list of static users in Debian see ‘Operating system users and groups’ on page188) and dynamic uids in the range assigned to system users.

In the first case, you need to ask for a user or group id to thebase-passwd. Once the user is available there the package needs to be distributed including a proper versioned depends to thebase-passwdpackage.

In the second case, you need to create the system user either in thepreinstor in thepostinstand make the package depend onadduser (>= 3.11).

The following example code creates the user and group the daemon will run as when the package is installed or upgraded:

[...]

case "$1" in

install|upgrade)

# If the package has default file it could be sourced, so that # the local admin can overwrite the defaults

[ -f "/etc/default/packagename" ] && . /etc/default/packagename

# Sane defaults:

[ -z "$SERVER_HOME" ] && SERVER_HOME=server_dir

[ -z "$SERVER_USER" ] && SERVER_USER=server_user

[ -z "$SERVER_NAME" ] && SERVER_NAME="Server description" [ -z "$SERVER_GROUP" ] && SERVER_GROUP=server_group

# Groups that the user will be added to, if undefined, then none. ADDGROUP=""

# create user to avoid running server as root # 1. create group if not existing

if ! getent group | grep -q "^$SERVER_GROUP:" ; then echo -n "Adding group $SERVER_GROUP.."

addgroup --quiet --system $SERVER_GROUP 2>/dev/null ||true echo "..done"

fi

# 2. create homedir if not existing

test -d $SERVER_HOME || mkdir $SERVER_HOME # 3. create user if not existing

if ! getent passwd | grep -q "^$SERVER_USER:"; then echo -n "Adding system user $SERVER_USER.."

adduser --quiet \ --system \

--no-create-home \ --disabled-password \

$SERVER_USER 2>/dev/null || true echo "..done"

fi

# 4. adjust passwd entry usermod -c "$SERVER_NAME" \

-d $SERVER_HOME \ -g $SERVER_GROUP \

$SERVER_USER

# 5. adjust file and directory permissions

if ! dpkg-statoverride --list $SERVER_HOME >/dev/null then

chown -R $SERVER_USER:adm $SERVER_HOME chmod u=rwx,g=rxs,o= $SERVER_HOME fi

# 6. Add the user to the ADDGROUP group if test -n $ADDGROUP

then

if ! groups $SERVER_USER | cut -d: -f2 | \ grep -qw $ADDGROUP; then

adduser $SERVER_USER $ADDGROUP fi

fi ;;

configure) [...]

You have to make sure that the init.d script file:

• Starts the daemon dropping privileges: if the software does not do thesetuid(2)or

seteuid(2)call itself, you can use the--chuidcall ofstart-stop-daemon.

• Stops the daemon only if the user id matches, you can use the start-stop-daemon --useroption for this.

• Does not run if either the user or the group do not exist:

if ! getent passwd | grep -q "^server_user:"; then echo "Server user does not exist. Aborting" >&2 exit 1

fi

if ! getent group | grep -q "^server_group:" ; then echo "Server group does not exist. Aborting" >&2 exit 1

If the package creates the system user it can remove it when it is purged in its postrm. This has some drawbacks, however. For example, files created by it will be orphaned and might be taken over by a new system user in the future if it is assigned the same uid1. Consequently, removing system users on purge is not yet mandatory and depends on the package needs. If unsure, this action could be handled by asking the administrator for the prefered action when the package is installed (i.e. throughdebconf).

The following example code2removes the user and groups created before only, and only if, the uid is in the range of dynamic assigned system uids and the gid is belongs to a system group:

case "$1" in purge) [...]

# find first and last SYSTEM_UID numbers

for LINE in ‘grep SYSTEM_UID /etc/adduser.conf | grep -v "^#"‘; do case $LINE in

FIRST_SYSTEM_UID*)

FIST_SYSTEM_UID=‘echo $LINE | cut -f2 -d ’=’‘ ;;

LAST_SYSTEM_UID*)

LAST_SYSTEM_UID=‘echo $LINE | cut -f2 -d ’=’‘ ;;

*) ;; esac done

# Remove system account if necessary CREATEDUSER="server_user"

if [ -n "$FIST_SYSTEM_UID" ] && [ -n "$LAST_SYSTEM_UID" ]; then if USERID=‘getent passwd $CREATEDUSER | cut -f 3 -d ’:’‘; then

if [ -n "$USERID" ]; then

if [ "$FIST_SYSTEM_UID" -le "$USERID" ] && \ [ "$USERID" -le "$LAST_SYSTEM_UID" ]; then

echo -n "Removing $CREATEDUSER system user.." deluser --quiet $CREATEDUSER || true

echo "..done" fi

fi fi fi

# Remove system group if necessary

1Some relevant threads discussing these drawbacks include http://lists.debian.org/

debian-mentors/2004/10/msg00338.html and http://lists.debian.org/debian-devel/2004/ 05/msg01156.html

2This might eventually be introduced as a dh_adduser in debhelper. See #81967 (http://bugs.

debian.org/81697), #291177 (http://bugs.debian.org/291177) and #118787 (http://bugs.debian. org/118787).

CREATEDGROUP=server_group

FIRST_USER_GID=‘grep ^USERS_GID /etc/adduser.conf | cut -f2 -d ’=’‘ if [ -n "$FIST_USER_GID" ] then

if GROUPGID=‘getent group $CREATEDGROUP | cut -f 3 -d ’:’‘; then if [ -n "$GROUPGID" ]; then

if [ "$FIST_USER_GID" -gt "$GROUPGID" ]; then echo -n "Removing $CREATEDGROUP group.."

delgroup --only-if-empty $CREATEDGROUP || true echo "..done" fi fi fi fi [...]

Running programs with a user with limited privileges makes sure that any security issue will not be able to damage the full system. It also follows the principle ofleast privilege. Also con- sider you can limit privileges in programs through other mechanisms besides running as non- root3. For more information, read the Minimize Privileges (http://www.dwheeler.com/ secure-programs/Secure-Programs-HOWTO/minimize-privileges.html) chapter of theSecure Programming for Linux and Unix HOWTObook.

Chapter 10

Before the compromise

In document securing debian howto en pdf (Page 174-179)