Installing Under Sudo(8), Setuid(2) or Setgid(2) Wrapper

About this HowTo

MoinMoin versions
1.7,1.8,1.9 and later
Platforms
POSIX, Linux, BSD, Mac OS X, and other unix

This page describes issues peculiar to setuid/setgid wrapper use. You should already have performed BasicInstallation, and have read WikiInstanceCreation. If using apache, you should also have read ApacheOnLinux.

These issues affect principly how you configure permissions during WikiInstanceCreation and web server integration. Details will depend on local administration policies, so check with your web and/or host administrator before you begin.

/!\ This page will not tell you what policies you need to secure your wiki installation. It should answer the questions necessary to install MoinMoin under a setuid/setgid wrapper often used to implement security policy.

Applicability

Common Language

You should already be familiar with unix permissions and links. If not consider some of the references in the bibliography. This section reiterates briefly what may be unfamiliar due to infrequent use, or differing terminology.

Feel free to skip this section, but if you encounter problems, you may want to return here first.

Unix platforms protect themselves and their customers from malfunctioning or malicious software by enforcing division and delegation of authority, called file access permissions. Each unix platform keeps a list of users that can each be either a human customer, or a virtual customer called an office. Authority to read, to write, and/or to execute a file is granted or denied by masking the process effective user id and/or effective group id with the file mode. Everything (e.g. ordinary files, directories, devices, ...) whose access is allocated by unix is a file ^1. Authority to set each file mode with chmod(1) is delegated to exactly one ^2 user called the file owner. Delegation of file ownership to a user is performed with chown(1) by an office called root. Each unix platform keeps a list of groups. Each file has exactly one group membership. Each user has membership in one or more groups. Each file owner can set file membership with chgrp(1) to a group in which the owner is a member.

As an example, web page files are usually owned by an office (e.g. www) and members in a group (e.g. www). Files are usually editted (read and written) by owner, www, but are usually read-only to the web agent (e.g. wwwrun), a member in group www, and unreadable to others (not user www nor members of group www). Humans alter the web files by editting or publishing as office, www. Humans read the web files through their browser by running a web agent as wwwrun, a member of group www.

Each process (also a file) has an owner, and its user and group is normally the same as the process that called it. root can change the user and group of a process from its original login user/group id to an effective user/group id. Most unix platforms provide pre-configured processes and files with changed user and group to exercise limited root authority called privilege for non-root users, processes, and files.

setuid(2) and setgid(2) are a pair of unix security tools that grant privilege by changing the effective user id or effective group id of a process. Most unix platforms implement additional file mode bits. When an executable file is executed by root or a privileged process, if the set user id or set group id mode bit is set, the process will be started with effective user and/or group id set to that of the executable file.

Local policy may grant setuid privilege to all users, to no users (except root), to a single group, or to some set of users or groups. Local policy may deny setuid privilege to all files (except those required for kernal operation), to all but compiled binary files (as determined by heuristic), or some set filtered by user, group, path, ...

sudo(8) is a popular tool for managing setuid privilege. suExec is a popular apache extension available (when compiled from source) for managing setuid privilege.

A setuid wrapper is an executable file which exists only to change process user and/or group before calling another executable file. Nominally the setuid wrapper passes its arguments and inputs through unaltered and returns output unaltered. The advantage of a setuid wrapper is that it can be equipped to enforce limitations, locally scrutinized, and rendered tamper-resistant more easily than the executables it calls.

Permissions Required

{i} Nominal installation grants moin.cgi callers write privilege for all files and directories under data and underlay, but wiki admin policy may choose to restrict this. If moin.cgi is not used for testing and maintenance, and called exclusively from the setuid wrapper, then moin.cgi actually needs no access privileges.

(!) typical intranet web server

Wrapper Configuration

(!) Ask local admin or try the following in the order presented.

moin.cgi (no wrapper)

{i} Most linux distros and many host administrators deny setuid privilege to scripts (non-binaries) as a security hole more easily altered and examined than compiled binaries.

  1. Install MoinMoin according to BasicInstallation.

  2. Apply SetuidFixReplaceOsAccess patch as necessary ^3.

  3. Create an instance according to WikiInstanceCreation except that USER and GROUP are those of the wiki server (able to write data pages, caches, logs, ..., and able to read and execute MoinMoin python script) rather than the web server.

  4. Install and configure moin.cgi according to ApacheOnLinux through Configure MoinMoin.

  5. Before Test the wiki:
    1. Set the user and group mode id bits.
      •      > chmod +s $WIKILOCATION/$INSTANCE/cgi-bin/moin.cgi
             > ls -l $WIKILOCATION/$INSTANCE/cgi-bin/moin.cgi
             -rwsr-sr-x  1 wiki wiki ... .../cgi-bin/moin.cgi
    2. If you do not see 's' in the owner and group section of the mode,
      • if the web agent does not have r and x permission, or if the user and group name are not those of the wiki server, you need to take corrective action.
    3. Try standalone execution
      •      > $WIKILOCATION/$INSTANCE/moin.cgi | grep Status:
             Status: 200 ...
    4. If you do not see Status: 200 ...

    5. or see Status: 5...

    6. then you have installation problems unrelated to web server integration,
    7. and need to see TroubleShooting

  6. Continue with Test the wiki in ApacheOnLinux

  7. If you see an offer to create the wiki home page, you have successfully integrated moin.cgi with your web server, and can begin adding content.
  8. If you see Status: 5xx MoinMoin Internal Error

    • then moin.cgi does not have setuid privilege and you should try using an approved wrapper.

sudo(8) (custom wrapper)

sudo(8) is probably the most common privilege manager in use for linux. To allow intermediate testing, this approach installs an insecure wiki and then secures the wiki.

  1. Install MoinMoin according to BasicInstallation.

  2. Apply SetuidFixReplaceOsAccess patch as necessary ^3.

  3. Create and test an insecure instance according to WikiInstanceCreation using the web agent (wwwrun) and group (www).

  4. Authorize the web agent (wwwrun) to run moin.cgi as wiki agent (wiki).
    1. Use visudo(8) to insert the following sudoers(5) entry (change wwwrun, wiki, $USER, $GROUP, $WIKILOCATION/$INSTANCE to correct explicit values)
      • wwwrun   ALL = (wiki) NOPASSWD:SETENV:$WIKILOCATION/$INSTANCE/cgi-bin/moin.cgi
    2. Test authorization with a temporary gateway.
      1. Backup insecure moin.cgi
        • mv "$WIKILOCATION/$INSTANCE"/cgi-bin/moin.{cgi,save}
      2. Use temporary gateway to report effective user id
        • echo whoami > "$WIKILOCATION/$INSTANCE/cgi-bin/moin.cgi"
      3. Change owner to wiki agent and verify change.
        • sudo chown $USER.$GROUP "$WIKILOCATION/$INSTANCE"/cgi-bin/moin.cgi
          sudo chmod 550 "$WIKILOCATION/$INSTANCE"/cgi-bin/moin.cgi
          ls -l "$WIKILOCATION/$INSTANCE"/cgi-bin/moin.cgi
      4. Execution as web agent (wwwrun) or anyone else not privileged, should report permission denied.
        • sudo -u wwwrun "$WIKILOCATION/$INSTANCE"/cgi-bin/moin.cgi
      5. Execution as web agent (wwwrun) with limited privilege should report wiki agent ($USER)
        • sudo -u wwwrun sudo -u $USER "$WIKILOCATION/$INSTANCE"/cgi-bin/moin.cgi
      6. Restore insecure moin.cgi
        • mv "$WIKILOCATION/$INSTANCE"/cgi-bin/moin.{save,cgi}
  5. Create sudo(8) wrapper (change /var/www/cgi-bin, $USER, $WIKILOCATION/$INSTANCE to correct explicit values).
    • cat > "/var/www/cgi-bin/moin.cgi" <<EOF
      sudo -u $USER -E "$WIKILOCATION/$INSTANCE/cgi-bin/moin.cgi
      EOF
      chmod ug+x "/var/www/cgi-bin/moin.cgi"
    • note -E to preserve environment
  6. Restrict permissions (change $USER, $GROUP, $WIKILOCATION/$INSTANCE to correct explicit values)
    • chmod -R o-rwx "$WIKILOCATION/$INSTANCE"
      chown -R $USER.$GROUP "$WIKILOCATION/$INSTANCE"
  7. Test wrapper (change wwwrun, /var/www/cgi-bin to correct explicit values).
    1. Execution of gateway as web agent (wwwrun) or any other unprivileged user should fail.
      • sudo -u wwwrun "$WIKILOCATION/$INSTANCE"/cgi-bin/moin.cgi
    2. Execution of gateway as web agent through wrapper should return html.
      • sudo -u wwwrun /var/www/cgi-bin/moin.cgi
  8. Insert wrapper into web server configuration (change /etc/apache2/httpd.local.conf, /wiki, /var/www/cgi-bin to correct explicit values).
    1. Replace wiki ScriptAlias in /etc/apache2/httpd.local.conf.

      • ScriptAlias /wiki /var/www/cgi-bin/moin.cgi
    2. Remove wiki directory privileges from /etc/apache2/httpd.local.conf.
      • <Directory "$WIKILOCATION/$INSTANCE/cgi-bin"> ... </Directory>
  9. Test secure instance.

runas(8) (approved wrapper)

/!\ As of 2009-04-27 00:00:00 author was not equipped to test this runas(8) procedure. If you are so equipped, please test this section, update accordingly, and remove this warning.

  1. Install MoinMoin according to BasicInstallation.

  2. Apply SetuidFixReplaceOsAccess patch as necessary ^3.

  3. Create an instance according to WikiInstanceCreation except that USER and GROUP are those of the wiki server (able to write data pages, caches, logs, ..., and able to read and execute MoinMoin python script) rather than the web server.

  4. Install and configure moin.cgi according to ApacheOnLinux through Configure MoinMoin.

  5. Before Test the wiki:
    1. Create the wrapper.
      •      > runas $USER $GROUP "$WIKILOCATION/$INSTANCE/cgi-bin/moin.cgi" |
               cat > "$WIKILOCATION/$INSTANCE/cgi-bin/wiki
    2. Set the user and group mode id bits.
      •      > chmod +s $WIKILOCATION/$INSTANCE/cgi-bin/wiki
             > ls -l $WIKILOCATION/$INSTANCE/cgi-bin/wiki
             -rwsr-sr-x  1 wiki wiki ... .../cgi-bin/wiki
    3. If you do not see 's' in the owner and group section of the mode,
      • if the web agent does not have r and x permission, or if the user and group name are not those of the wiki server, you need to take corrective action.
    4. Try standalone execution
      •      > $WIKILOCATION/$INSTANCE/cgi-bin/wiki | grep Status:
             Status: 200 ...
    5. Edit the config file from Configure Apache in ApacheOnLinux to change moin.cgi to wiki

      •      ScriptAlias /mywiki /usr/local/share/moin/mywiki/cgi-bin/wiki
    6. If you do not see Status: 200 ...

    7. or see Status: 5...

    8. then you have installation problems unrelated to web server integration,
    9. and need to see TroubleShooting

  6. Continue with Test the wiki in ApacheOnLinux

  7. If you see an offer to create the wiki home page, you have successfully integrated moin.cgi with your web server, and can begin adding content.
  8. If you see Status: 5xx MoinMoin Internal Error

    • then wiki does not have setuid privilege and you should try the custom wrapper.

moin.c (custom wrapper)

  1. Install MoinMoin according to BasicInstallation.

  2. Apply SetuidFixReplaceOsAccess patch as necessary ^3.

  3. Create an instance according to WikiInstanceCreation except that USER and GROUP are those of the wiki server (able to write data pages, caches, logs, ..., and able to read and execute MoinMoin python script) rather than the web server.

  4. Install and configure moin.cgi according to ApacheOnLinux through Configure MoinMoin.

  5. Before Test the wiki:
    1. Make a directory to keep the wrapper source.
      •      > mkdir "$WIKILOCATION/$INSTANCE"/src
    2. Copy this wrapper to $WIKILOCATION/$INSTANCE/src/moin.c
      • /* moin.c -- wrapper to allow moin.cgi to run setgid
         *
         * Richard Brooksby, 2005-02-10
         *
         * This is a simple wrapper that executes the normal moin.cgi
         * script.  Since this is a binary, it can have its setgid bit set
         * and therefore have access to the necessary wiki directories
         * without compromising general security or having to have files
         * writeable by the Apache server in general.
         *
         * 2005-02-10  RB  Created.
         */
        
        #include <unistd.h>
        #include <stdio.h>
        
        int main(int argc, char *argv[])
        {
          execv("/home/rb/www/www.brooksby.org/moin/bin/moin.cgi", argv);
          perror("execv");
          return 1;
        }
    3. Copy and edit moin.c to point at moin.cgi
      •      > OLD="/home/rb/www/www.brooksby.org/moin/src/moin.cgi"
             > NEW="$WIKILOCATION/$INSTANCE/cgi-bin/moin.cgi"
             > cat "$WIKILOCATION/$INSTANCE"/bin/moin.c |
               perl -pe 's:'"$OLD"':'"$NEW"':;' |
               cat > "$WIKILOCATION/$INSTANCE"/src/wiki.c
    4. Compile
      •      > gcc -pedantic -std=c99 -o "$WIKILOCATION/$INSTANCE/cgi-bin/wiki" \
               "$WIKILOCATION/$INSTANCE/src/wiki.c"
    5. Set the user and group mode id bits.
      •      > chmod +s $WIKILOCATION/$INSTANCE/cgi-bin/wiki
             > ls -l $WIKILOCATION/$INSTANCE/cgi-bin/wiki
             -rwsr-sr-x  1 wiki wiki ... .../cgi-bin/wiki
    6. If you do not see 's' in the owner and group section of the mode,
      • if the web agent does not have r and x permission, or if the user and group name are not those of the wiki server, you need to take corrective action.
    7. Try standalone execution
      •      > $WIKILOCATION/$INSTANCE/cgi-bin/wiki | grep Status:
             Status: 200 ...
    8. Edit the config file from Configure Apache in ApacheOnLinux

      •      ScriptAlias /mywiki /usr/local/share/moin/mywiki/cgi-bin/wiki
    9. If you do not see Status: 200 ...

    10. or see Status: 5...

    11. then you have installation problems unrelated to web server integration,
    12. and need to see TroubleShooting

  6. Continue with Test the wiki in ApacheOnLinux

  7. If you see an offer to create the wiki home page, you have successfully integrated moin.cgi with your web server, and can begin adding content.
  8. If you see Status: 5xx MoinMoin Internal Error

    • then moin does not have setuid privilege and you should consider the additional concerns.

additional concerns

In addition to one of the above configuration steps, local policy may require

Ask your host and web admin.

Footnotes

1. Not every "identifiable thing" bundled with a unix platform is managed by the operating system. Network interfaces (e.g. eth0), X windows, and many other "identifiable thing"s are managed by executables running on the platform. The executables themselves (e.g. routed(8)) and the files (e.g. /etc/hosts) and devices (e.g. /dev/pty0) used are managed by unix.

2. Because root can grant itself ownership of any file, and then as owner grant root unlimited access, most unix platforms grant root unlimited access to any file.

3. The SetuidFixReplaceOsAccess patch is necessary if any of the files named in the patch use os.access().

Bibliography

MoinMoin: HowTo/Install MoinMoin under sudo, setuid, or setgid wrapper (last edited 2010-10-25 12:40:59 by Unw)