| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> |
| <HTML> |
| <HEAD> |
| <TITLE>Apache suEXEC Support</TITLE> |
| </HEAD> |
| <!-- Background white, links blue (unvisited), navy (visited), red (active) --> |
| <BODY |
| BGCOLOR="#FFFFFF" |
| TEXT="#000000" |
| LINK="#0000FF" |
| VLINK="#000080" |
| ALINK="#FF0000" |
| > |
| <!--#include virtual="header.html" --> |
| |
| <H1 ALIGN="CENTER">Apache suEXEC Support</H1> |
| |
| <P ALIGN="LEFT"> |
| <OL> |
| <LH><BIG><STRONG>CONTENTS</STRONG></BIG></LH> |
| <LI><A HREF="#what">What is suEXEC?</A></LI> |
| <LI><A HREF="#before">Before we begin.</A></LI> |
| <LI><A HREF="#model">suEXEC Security Model.</A></LI> |
| <LI><A HREF="#install">Configuring & Installing suEXEC</A></LI> |
| <LI><A HREF="#enable">Enabling & Disabling suEXEC</A></LI> |
| <LI><A HREF="#debug">Debugging suEXEC</A></LI> |
| <LI><A HREF="#jabberwock">Beware the Jabberwock: Warnings & |
| Examples</A></LI> |
| </OL> |
| </P> |
| |
| <H3><A NAME="what">What is suEXEC?</A></H3> |
| <P ALIGN="LEFT"> |
| The <STRONG>suEXEC</STRONG> feature -- introduced in Apache 1.2 -- provides |
| Apache users the ability to run <STRONG>CGI</STRONG> and <STRONG>SSI</STRONG> |
| programs under user IDs different from the user ID of the calling web-server. |
| Normally, when a CGI or SSI program executes, it runs as the same user who is |
| running the web server. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| Used properly, this feature can reduce considerably the security risks involved |
| with allowing users to develop and run private CGI or SSI programs. However, |
| if suEXEC is improperly configured, it can cause any number of problems and |
| possibly create new holes in your computer's security. If you aren't familiar |
| with managing setuid root programs and the security issues they present, we |
| highly recommend that you not consider using suEXEC. |
| </P> |
| |
| <P ALIGN="CENTER"> |
| <STRONG><A HREF="suexec.html">BACK TO CONTENTS</A></STRONG> |
| </P> |
| |
| <H3><A NAME="before">Before we begin.</A></H3> |
| <P ALIGN="LEFT"> |
| Before jumping head-first into this document, you should be aware of the |
| assumptions made on the part of the Apache Group and this document. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| First, it is assumed that you are using a UNIX derivate operating system that |
| is capable of <STRONG>setuid</STRONG> and <STRONG>setgid</STRONG> operations. |
| All command examples are given in this regard. Other platforms, if they are |
| capable of supporting suEXEC, may differ in their configuration. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| Second, it is assumed you are familiar with some basic concepts of your |
| computer's security and its administration. This involves an understanding |
| of <STRONG>setuid/setgid</STRONG> operations and the various effects they |
| may have on your system and its level of security. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| Third, it is assumed that you are using an <STRONG>unmodified</STRONG> |
| version of suEXEC code. All code for suEXEC has been carefully scrutinized and |
| tested by the developers as well as numerous beta testers. Every precaution has |
| been taken to ensure a simple yet solidly safe base of code. Altering this |
| code can cause unexpected problems and new security risks. It is |
| <STRONG>highly</STRONG> recommended you not alter the suEXEC code unless you |
| are well versed in the particulars of security programming and are willing to |
| share your work with the Apache Group for consideration. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| Fourth, and last, it has been the decision of the Apache Group to |
| <STRONG>NOT</STRONG> make suEXEC part of the default installation of Apache. |
| To this end, suEXEC configuration is a manual process requiring of the |
| administrator careful attention to details. It is through this process |
| that the Apache Group hopes to limit suEXEC installation only to those |
| who are determined to use it. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| Still with us? Yes? Good. Let's move on! |
| </P> |
| |
| <P ALIGN="CENTER"> |
| <STRONG><A HREF="suexec.html">BACK TO CONTENTS</A></STRONG> |
| </P> |
| |
| <H3><A NAME="model">suEXEC Security Model</A></H3> |
| <P ALIGN="LEFT"> |
| Before we begin configuring and installing suEXEC, we will first discuss |
| the security model you are about to implement. By doing so, you may |
| better understand what exactly is going on inside suEXEC and what precautions |
| are taken to ensure your system's security. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <STRONG>suEXEC</STRONG> is based on a setuid "wrapper" program that is |
| called by the main Apache web server. This wrapper is called when an HTTP |
| request is made for a CGI or SSI program that the administrator has designated |
| to run as a userid other than that of the main server. When such a request |
| is made, Apache provides the suEXEC wrapper with the program's name and the |
| user and group IDs under which the program is to execute. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| The wrapper then employs the following process to determine success or |
| failure -- if any one of these conditions fail, the program logs the failure |
| and exits with an error, otherwise it will continue: |
| <OL> |
| <LI><STRONG>Was the wrapper called with the proper number of arguments?</STRONG> |
| <BLOCKQUOTE> |
| The wrapper will only execute if it is given the proper number of arguments. |
| The proper argument format is known to the Apache web server. If the wrapper |
| is not receiving the proper number of arguments, it is either being hacked, or |
| there is something wrong with the suEXEC portion of your Apache binary. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the user executing this wrapper a valid user of this system?</STRONG> |
| <BLOCKQUOTE> |
| This is to ensure that the user executing the wrapper is truly a user of the system. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is this valid user allowed to run the wrapper?</STRONG> |
| <BLOCKQUOTE> |
| Is this user the user allowed to run this wrapper? Only one user (the Apache |
| user) is allowed to execute this program. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Does the target program have an unsafe hierarchical reference?</STRONG> |
| <BLOCKQUOTE> |
| Does the target program contain a leading '/' or have a '..' backreference? These |
| are not allowed; the target program must reside within the Apache webspace. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target user name valid?</STRONG> |
| <BLOCKQUOTE> |
| Does the target user exist? |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target group name valid?</STRONG> |
| <BLOCKQUOTE> |
| Does the target group exist? |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target user <EM>NOT</EM> superuser?</STRONG> |
| <BLOCKQUOTE> |
| Presently, suEXEC does not allow 'root' to execute CGI/SSI programs. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target userid <EM>ABOVE</EM> the minimum ID number?</STRONG> |
| <BLOCKQUOTE> |
| The minimum user ID number is specified during configuration. This allows you |
| to set the lowest possible userid that will be allowed to execute CGI/SSI programs. |
| This is useful to block out "system" accounts. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target group <EM>NOT</EM> the superuser group?</STRONG> |
| <BLOCKQUOTE> |
| Presently, suEXEC does not allow the 'root' group to execute CGI/SSI programs. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target groupid <EM>ABOVE</EM> the minimum ID number?</STRONG> |
| <BLOCKQUOTE> |
| The minimum group ID number is specified during configuration. This allows you |
| to set the lowest possible groupid that will be allowed to execute CGI/SSI programs. |
| This is useful to block out "system" groups. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Can the wrapper successfully become the target user and group?</STRONG> |
| <BLOCKQUOTE> |
| Here is where the program becomes the target user and group via setuid and setgid |
| calls. The group access list is also initialized with all of the groups of which |
| the user is a member. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Does the directory in which the program resides exist?</STRONG> |
| <BLOCKQUOTE> |
| If it doesn't exist, it can't very well contain files. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the directory within the Apache webspace?</STRONG> |
| <BLOCKQUOTE> |
| If the request is for a regular portion of the server, is the requested directory |
| within the server's document root? If the request is for a UserDir, is the requested |
| directory within the user's document root? |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the directory <EM>NOT</EM> writable by anyone else?</STRONG> |
| <BLOCKQUOTE> |
| We don't want to open up the directory to others; only the owner user may be able |
| to alter this directories contents. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Does the target program exist?</STRONG> |
| <BLOCKQUOTE> |
| If it doesn't exists, it can't very well be executed. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target program <EM>NOT</EM> writable by anyone else?</STRONG> |
| <BLOCKQUOTE> |
| We don't want to give anyone other than the owner the ability to change the program. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target program <EM>NOT</EM> setuid or setgid?</STRONG> |
| <BLOCKQUOTE> |
| We do not want to execute programs that will then change our UID/GID again. |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Is the target user/group the same as the program's user/group?</STRONG> |
| <BLOCKQUOTE> |
| Is the user the owner of the file? |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Can we successfully clean the process environment to ensure safe operations?</STRONG> |
| <BLOCKQUOTE> |
| suEXEC cleans the process' environment by establishing a safe execution PATH (defined |
| during configuration), as well as only passing through those variables whose names |
| are listed in the safe environment list (also created during configuration). |
| </BLOCKQUOTE> |
| </LI> |
| <LI><STRONG>Can we successfully become the target program and execute?</STRONG> |
| <BLOCKQUOTE> |
| Here is where suEXEC ends and the target program begins. |
| </BLOCKQUOTE> |
| </LI> |
| </OL> |
| </P> |
| |
| <P ALIGN="LEFT"> |
| This is the standard operation of the the suEXEC wrapper's security model. |
| It is somewhat stringent and can impose new limitations and guidelines for |
| CGI/SSI design, but it was developed carefully step-by-step with security |
| in mind. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| For more information as to how this security model can limit your possibilities |
| in regards to server configuration, as well as what security risks can be avoided |
| with a proper suEXEC setup, see the <A HREF="#beware">"Beware the Jabberwock"</A> |
| section of this document. |
| </P> |
| |
| <P ALIGN="CENTER"> |
| <STRONG><A HREF="suexec.html">BACK TO CONTENTS</A></STRONG> |
| </P> |
| |
| <H3><A NAME="install">Configuring & Installing suEXEC</A></H3> |
| <P ALIGN="LEFT"> |
| Here's where we begin the fun. The configuration and installation of suEXEC is |
| a four step process: edit the suEXEC header file, compile suEXEC, place the |
| suEXEC binary in its proper location, and configure Apache for use with suEXEC. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <STRONG>EDITING THE SUEXEC HEADER FILE</STRONG><BR> |
| - From the top-level of the Apache source tree, type: |
| <STRONG><code>cd support [ENTER]</code></STRONG> |
| </P> |
| |
| <P ALIGN="LEFT"> |
| Edit the <code>suexec.h</code> file and change the following macros to |
| match your local Apache installation. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <EM>From support/suexec.h</EM> |
| <PRE> |
| /* |
| * HTTPD_USER -- Define as the username under which Apache normally |
| * runs. This is the only user allowed to execute |
| * this program. |
| */ |
| #define HTTPD_USER "www" |
| |
| /* |
| * UID_MIN -- Define this as the lowest UID allowed to be a target user |
| * for suEXEC. For most systems, 500 or 100 is common. |
| */ |
| #define UID_MIN 100 |
| |
| /* |
| * GID_MIN -- Define this as the lowest GID allowed to be a target group |
| * for suEXEC. For most systems, 100 is common. |
| */ |
| #define GID_MIN 100 |
| |
| /* |
| * USERDIR_SUFFIX -- Define to be the subdirectory under users' |
| * home directories where suEXEC access should |
| * be allowed. All executables under this directory |
| * will be executable by suEXEC as the user so |
| * they should be "safe" programs. If you are |
| * using a "simple" UserDir directive (ie. one |
| * without a "*" in it) this should be set to |
| * the same value. suEXEC will not work properly |
| * in cases where the UserDir directive points to |
| * a location that is not the same as the user's |
| * home directory as referenced in the passwd file. |
| * |
| * If you have VirtualHosts with a different |
| * UserDir for each, you will need to define them to |
| * all reside in one parent directory; then name that |
| * parent directory here. IF THIS IS NOT DEFINED |
| * PROPERLY, ~USERDIR CGI REQUESTS WILL NOT WORK! |
| * See the suEXEC documentation for more detailed |
| * information. |
| */ |
| #define USERDIR_SUFFIX "public_html" |
| |
| /* |
| * LOG_EXEC -- Define this as a filename if you want all suEXEC |
| * transactions and errors logged for auditing and |
| * debugging purposes. |
| */ |
| #define LOG_EXEC "/usr/local/etc/httpd/logs/cgi.log" /* Need me? */ |
| |
| /* |
| * DOC_ROOT -- Define as the DocumentRoot set for Apache. This |
| * will be the only hierarchy (aside from UserDirs) |
| * that can be used for suEXEC behavior. |
| */ |
| #define DOC_ROOT "/usr/local/etc/httpd/htdocs" |
| |
| /* |
| * SAFE_PATH -- Define a safe PATH environment to pass to CGI executables. |
| * |
| */ |
| #define SAFE_PATH "/usr/local/bin:/usr/bin:/bin" |
| </PRE> |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <STRONG>COMPILING THE SUEXEC WRAPPER</STRONG><BR> |
| You now need to compile the suEXEC wrapper. At the shell command prompt, |
| type: <STRONG><CODE>cc suexec.c -o suexec [ENTER]</CODE></STRONG>. |
| This should create the <STRONG><em>suexec</em></STRONG> wrapper executable. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <STRONG>COMPILING APACHE FOR USE WITH SUEXEC</STRONG><BR> |
| By default, Apache is compiled to look for the suEXEC wrapper in the following |
| location. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <EM>From src/httpd.h</EM> |
| <PRE> |
| /* The path to the suEXEC wrapper */ |
| #define SUEXEC_BIN "/usr/local/etc/httpd/sbin/suexec" |
| </PRE> |
| </P> |
| |
| <P ALIGN="LEFT"> |
| If your installation requires location of the wrapper program in a different |
| directory, edit src/httpd.h and recompile your Apache server. |
| See <A HREF="install.html">Compiling and Installing Apache</A> for more |
| info on this process. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <STRONG>COPYING THE SUEXEC BINARY TO ITS PROPER LOCATION</STRONG><BR> |
| Copy the <STRONG><em>suexec</em></STRONG> executable created in the |
| exercise above to the defined location for <STRONG>SUEXEC_BIN</STRONG>. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <STRONG><CODE>cp suexec /usr/local/etc/httpd/sbin/suexec [ENTER]</CODE></STRONG> |
| </P> |
| |
| <P ALIGN="LEFT"> |
| In order for the wrapper to set the user ID, it must me installed as owner |
| <STRONG><em>root</em></STRONG> and must have the setuserid execution bit |
| set for file modes. If you are not running a <STRONG><em>root</em></STRONG> |
| user shell, do so now and execute the following commands. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <STRONG><CODE>chown root /usr/local/etc/httpd/sbin/suexec [ENTER]</CODE></STRONG><BR> |
| <STRONG><CODE>chmod 4711 /usr/local/etc/httpd/sbin/suexec [ENTER]</CODE></STRONG> |
| </P> |
| |
| <P ALIGN="CENTER"> |
| <STRONG><A HREF="suexec.html">BACK TO CONTENTS</A></STRONG> |
| </P> |
| |
| <H3><A NAME="enable">Enabling & Disabling suEXEC</A></H3> |
| <P ALIGN="LEFT"> |
| After properly installing the <STRONG>suexec</STRONG> wrapper |
| executable, you must kill and restart the Apache server. A simple |
| <STRONG><CODE>kill -1 `cat httpd.pid`</CODE></STRONG> will not be enough. |
| Upon startup of the web-server, if Apache finds a properly configured |
| <STRONG>suexec</STRONG> wrapper, it will print the following message to |
| the console: |
| </P> |
| |
| <P ALIGN="LEFT"> |
| <CODE>Configuring Apache for use with suexec wrapper.</CODE> |
| </P> |
| |
| <P ALIGN="LEFT"> |
| If you don't see this message at server startup, the server is most |
| likely not finding the wrapper program where it expects it, or the |
| executable is not installed <STRONG><EM>setuid root</EM></STRONG>. Check |
| your installation and try again. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| One way to use <STRONG>suEXEC</STRONG> is through the |
| <a href="mod/core.html#user"><STRONG>User</STRONG></a> and |
| <a href="mod/core.html#group"><STRONG>Group</STRONG></a> directives in |
| <a href="mod/core.html#virtualhost"><STRONG>VirtualHost</STRONG></a> |
| definitions. By setting these directives to values different from the |
| main server user ID, all requests for CGI resources will be executed as |
| the <STRONG>User</STRONG> and <STRONG>Group</STRONG> defined for that |
| <STRONG><VirtualHost></STRONG>. If only one or |
| neither of these directives are specified for a |
| <STRONG><VirtualHost></STRONG> then the main |
| server userid is assumed.<p> |
| |
| <STRONG>suEXEC</STRONG> can also be used to to execute CGI programs as |
| the user to which the request is being directed. This is accomplished by |
| using the <STRONG>~</STRONG> character prefixing the user ID for whom |
| execution is desired. |
| The only requirement needed for this feature to work is for CGI |
| execution to be enabled for the user and that the script must meet the |
| scrutiny of the <a href="#model">security checks</a> above. |
| |
| <P ALIGN="CENTER"> |
| <STRONG><A HREF="suexec.html">BACK TO CONTENTS</A></STRONG> |
| </P> |
| |
| <H3><A NAME="debug">Debugging suEXEC</A></H3> |
| <P ALIGN="LEFT"> |
| The suEXEC wrapper will write log information to the location defined in |
| the <code>suexec.h</code> as indicated above. If you feel you have |
| configured and installed the wrapper properly, have a look at this log |
| and the error_log for the server to see where you may have gone astray. |
| </P> |
| |
| <P ALIGN="CENTER"> |
| <STRONG><A HREF="suexec.html">BACK TO CONTENTS</A></STRONG> |
| </P> |
| |
| <H3><A NAME="jabberwock">Beware the Jabberwock: Warnings & Examples</A></H3> |
| <P ALIGN="LEFT"> |
| <STRONG>NOTE!</STRONG> This section may not be complete. For the latest |
| revision of this section of the documentation, see the Apache Group's |
| <A HREF="http://www.apache.org/docs/suexec.html">Online Documentation</A> |
| version. |
| </P> |
| |
| <P ALIGN="LEFT"> |
| There are a few points of interest regarding the wrapper that can cause |
| limitations on server setup. Please review these before submitting any |
| "bugs" regarding suEXEC. |
| <UL> |
| <LH><STRONG>suEXEC Points Of Interest</STRONG></LH> |
| <LI>Hierarchy limitations |
| <BLOCKQUOTE> |
| For security and efficiency reasons, all suexec requests must |
| remain within either a top-level document root for virtual |
| host requests, or one top-level personal document root for |
| userdir requests. For example, if you have four VirtualHosts |
| configured, you would need to structure all of your VHosts' |
| document roots off of one main Apache document hierarchy to |
| take advantage of suEXEC for VirtualHosts. (Example forthcoming.) |
| </BLOCKQUOTE> |
| </LI> |
| <LI>suEXEC's PATH environment variable |
| <BLOCKQUOTE> |
| This can be a dangerous thing to change. Make certain every |
| path you include in this define is a <STRONG>trusted</STRONG> |
| directory. You don't want to open people up to having someone |
| from across the world running a trojan horse on them. |
| </BLOCKQUOTE> |
| </LI> |
| <LI>Altering the suEXEC code |
| <BLOCKQUOTE> |
| Again, this can cause <STRONG>Big Trouble</STRONG> if you try |
| this without knowing what you are doing. Stay away from it |
| if at all possible. |
| </BLOCKQUOTE> |
| </LI> |
| </UL> |
| |
| <P ALIGN="CENTER"> |
| <STRONG><A HREF="suexec.html">BACK TO CONTENTS</A></STRONG> |
| </P> |
| |
| <!--#include virtual="footer.html" --> |
| </BODY> |
| </HTML> |