Browse Source

Init script improvements: Check that config file is owned by root and not group/world writable

Ask Solem 11 years ago
parent
commit
c68d5bdc53
3 changed files with 137 additions and 4 deletions
  1. 19 0
      docs/tutorials/daemonizing.rst
  2. 62 2
      extra/generic-init.d/celerybeat
  3. 56 2
      extra/generic-init.d/celeryd

+ 19 - 0
docs/tutorials/daemonizing.rst

@@ -43,6 +43,25 @@ which is a shell (sh) script.  You can add environment variables and the
 configuration options below to this file.  To add environment variables you
 configuration options below to this file.  To add environment variables you
 must also export them (e.g. ``export DISPLAY=":0"``)
 must also export them (e.g. ``export DISPLAY=":0"``)
 
 
+.. Admonition:: Superuser privileges required
+
+    The init scripts can only be used by root,
+    and the shell configuration file must also be owned by root.
+
+    Unprivileged users do not need to use the init script,
+    instead they can use the :program:`celery multi` utility (or
+    :program:`celery worker --detach`):
+
+    .. code-block:: bash
+
+        $ celery multi start worker1 \
+            --pidfile="$HOME/run/celery/%n.pid" \
+            --logfile=""$HOME/log/celery/%n.log"
+
+        $ celery multi restart worker1 --pidfile="$HOME/run/celery/%n.pid"
+
+        $ celery multi stopwait worker1 --pidfile="$HOME/run/celery/%n.pid"
+
 .. _generic-initd-celeryd-example:
 .. _generic-initd-celeryd-example:
 
 
 Example configuration
 Example configuration

+ 62 - 2
extra/generic-init.d/celerybeat

@@ -20,6 +20,15 @@
 # Cannot use set -e/bash -e since the kill -0 command will abort
 # Cannot use set -e/bash -e since the kill -0 command will abort
 # abnormally in the absence of a valid process ID.
 # abnormally in the absence of a valid process ID.
 #set -e
 #set -e
+VERSION=10.0
+echo "celery init v${VERSION}."
+
+if [ "$EUID" != "0" ]; then
+    echo "Error: This program can only be used by the root user."
+    echo "       Unpriviliged users must use 'celery beat --detach'"
+    exit 1
+fi
+
 
 
 # May be a runlevel symlink (e.g. S02celeryd)
 # May be a runlevel symlink (e.g. S02celeryd)
 if [ -L "$0" ]; then
 if [ -L "$0" ]; then
@@ -31,14 +40,65 @@ SCRIPT_NAME="$(basename "$SCRIPT_FILE")"
 
 
 # /etc/init.d/celerybeat: start and stop the celery periodic task scheduler daemon.
 # /etc/init.d/celerybeat: start and stop the celery periodic task scheduler daemon.
 
 
+# Make sure executable configuration script is owned by root
+_config_sanity() {
+    local path="$1"
+    local owner=$(stat -Lr "$path" | awk '{print $5}')
+    local perm=$(stat -Lr "$path" | awk '{print $3}')
+
+    if [ "$owner" != "0" ]; then
+        echo "Error: Config script '$path' must be owned by root!"
+        echo
+        echo "Resolution:"
+        echo "Review the file carefully and make sure it has not been "
+        echo "modified with mailicious intent.  When sure the "
+        echo "script is safe to execute with superuser privileges "
+        echo "you can change ownership of the script:"
+        echo "    $ sudo chown root '$path'"
+        exit 1
+    fi
+
+    if [ "$(($perm & 02))" -ne 0 ]; then  # S_IWOTH
+        echo "Error: Config script '$path' cannot be writable by others!"
+        echo
+        echo "Resolution:"
+        echo "Review the file carefully and make sure it has not been "
+        echo "modified with malicious intent.  When sure the "
+        echo "script is safe to execute with superuser privileges "
+        echo "you can change the scripts permissions:"
+        echo "    $ sudo chmod 640 '$path'"
+        exit 1
+    fi
+    if [ "$(($perm & 020))" -ne 0 ]; then  # S_IWGRP
+        echo "Error: Config script '$path' cannot be writable by group!"
+        echo
+        echo "Resolution:"
+        echo "Review the file carefully and make sure it has not been "
+        echo "modified with malicious intent.  When sure the "
+        echo "script is safe to execute with superuser privileges "
+        echo "you can change the scripts permissions:"
+        echo "    $ sudo chmod 640 '$path'"
+        exit 1
+    fi
+}
+
+scripts=""
+
 if test -f /etc/default/celeryd; then
 if test -f /etc/default/celeryd; then
+    scripts="/etc/default/celeryd"
+    _config_sanity /etc/default/celeryd
     . /etc/default/celeryd
     . /etc/default/celeryd
 fi
 fi
 
 
-if test -f /etc/default/${SCRIPT_NAME}; then
-    . /etc/default/${SCRIPT_NAME}
+EXTRA_CONFIG="/etc/default/${SCRIPT_NAME}"
+if test -f "$EXTRA_CONFIG"; then
+    scripts="$scripts, $EXTRA_CONFIG"
+    _config_sanity "$EXTRA_CONFIG"
+    . "$EXTRA_CONFIG"
 fi
 fi
 
 
+echo "Using configuration: $scripts"
+
 CELERY_BIN=${CELERY_BIN:-"celery"}
 CELERY_BIN=${CELERY_BIN:-"celery"}
 DEFAULT_USER="celery"
 DEFAULT_USER="celery"
 DEFAULT_PID_FILE="/var/run/celery/beat.pid"
 DEFAULT_PID_FILE="/var/run/celery/beat.pid"

+ 56 - 2
extra/generic-init.d/celeryd

@@ -28,9 +28,17 @@
 #
 #
 # You can then configure this by manipulating /etc/default/little-worker.
 # You can then configure this by manipulating /etc/default/little-worker.
 #
 #
+VERSION=10.0
+echo "celery init v${VERSION}."
+if [ "$EUID" != "0" ]; then
+    echo "Error: This program can only be used by the root user."
+    echo "       Unprivileged users must use the 'celery multi' utility, "
+    echo "       or 'celery worker --detach'."
+    exit 1
+fi
 
 
 
 
-# May be a runlevel symlink (e.g. S02celeryd)
+# Can be a runlevel symlink (e.g. S02celeryd)
 if [ -L "$0" ]; then
 if [ -L "$0" ]; then
     SCRIPT_FILE=$(readlink "$0")
     SCRIPT_FILE=$(readlink "$0")
 else
 else
@@ -47,7 +55,53 @@ DEFAULT_CELERYD="-m celery worker --detach"
 
 
 CELERY_DEFAULTS=${CELERY_DEFAULTS:-"/etc/default/${SCRIPT_NAME}"}
 CELERY_DEFAULTS=${CELERY_DEFAULTS:-"/etc/default/${SCRIPT_NAME}"}
 
 
-test -f "$CELERY_DEFAULTS" && . "$CELERY_DEFAULTS"
+# Make sure executable configuration script is owned by root
+_config_sanity() {
+    local path="$1"
+    local owner=$(stat -Lr "$path" | awk '{print $5}')
+    local perm=$(stat -Lr "$path" | awk '{print $3}')
+
+    if [ "$owner" != "0" ]; then
+        echo "Error: Config script '$path' must be owned by root!"
+        echo
+        echo "Resolution:"
+        echo "Review the file carefully and make sure it has not been "
+        echo "modified with mailicious intent.  When sure the "
+        echo "script is safe to execute with superuser privileges "
+        echo "you can change ownership of the script:"
+        echo "    $ sudo chown root '$path'"
+        exit 1
+    fi
+
+    if [ "$(($perm & 02))" -ne 0 ]; then  # S_IWOTH
+        echo "Error: Config script '$path' cannot be writable by others!"
+        echo
+        echo "Resolution:"
+        echo "Review the file carefully and make sure it has not been "
+        echo "modified with malicious intent.  When sure the "
+        echo "script is safe to execute with superuser privileges "
+        echo "you can change the scripts permissions:"
+        echo "    $ sudo chmod 640 '$path'"
+        exit 1
+    fi
+    if [ "$(($perm & 020))" -ne 0 ]; then  # S_IWGRP
+        echo "Error: Config script '$path' cannot be writable by group!"
+        echo
+        echo "Resolution:"
+        echo "Review the file carefully and make sure it has not been "
+        echo "modified with malicious intent.  When sure the "
+        echo "script is safe to execute with superuser privileges "
+        echo "you can change the scripts permissions:"
+        echo "    $ sudo chmod 640 '$path'"
+        exit 1
+    fi
+}
+
+if [ -f "$CELERY_DEFAULTS" ]; then
+    _config_sanity "$CELERY_DEFAULTS"
+    echo "Using config script: $CELERY_DEFAULTS"
+    . "$CELERY_DEFAULTS"
+fi
 
 
 # Sets --app argument for CELERY_BIN
 # Sets --app argument for CELERY_BIN
 CELERY_APP_ARG=""
 CELERY_APP_ARG=""