Edgewall Software

Changes between Version 9 and Version 10 of ApacheSuexec


Ignore:
Timestamp:
Feb 21, 2015, 1:08:31 PM (3 years ago)
Author:
Jun Omae
Comment:

Cosmetic changes, again

Legend:

Unmodified
Added
Removed
Modified
  • ApacheSuexec

    v9 v10  
    1  = Trac and Apache suEXEC
     1= Trac and Apache suEXEC
    22
    33Trac in CGI-mode doesn't play very well with [http://httpd.apache.org/docs/suexec.html Apache suEXEC]. The suEXEC feature provides users of the Apache HTTP Server the ability to run CGI and SSI 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.
    44
    5 Setting the TRAC_ENV environment variable as described in TracInstall will not work when using suEXEC feature, because the environment variables are filtered and only a limited subset reaches the CGI program.
     5Setting the `TRAC_ENV` environment variable as described in TracInstall will not work when using suEXEC feature, because the environment variables are filtered and only a limited subset reaches the CGI program.
    66
    77There are obvious workarounds to make things work:
    8  1. Recompile suexec to let it pass the TRAC_ENV variable; this requires root permissions and therefore not advisable.
    9  1. Change our trac.cgi script to set the TRAC_ENV variable by itself, to do this we edit trac.cgi file and add to the start of the script:
    10     {{{
    11 import os;os.environ['TRAC_ENV'] = '/path/to/projectenv'
     8 1. Recompile suexec to let it pass the `TRAC_ENV` variable; this requires root permissions and therefore not advisable.
     9 1. Change our `trac.cgi` script to set the `TRAC_ENV` variable by itself, to do this we edit `trac.cgi` file and add to the start of the script:
     10    {{{#!python
     11import os
     12os.environ['TRAC_ENV'] = '/path/to/projectenv'
    1213    }}}
    1314 1. Make a wrapper script:
    14 {{{
    15 
     15{{{#!sh
    1616#!/bin/bash
    17 
    1817export TRAC_ENV='/path/to/projectenv'
    1918exec /path/to/trac/trac.cgi
     
    2423== Multiple Projects under suEXEC
    2524
    26 When hosting multiple projects under suEXEC, you can either copy the CGI script and change the TRAC_ENV setting for each script, or make a wrapper script around it. Here is a script to work around the stripping of environment variables done by suEXEC:
     25When hosting multiple projects under suEXEC, you can either copy the CGI script and change the `TRAC_ENV` setting for each script, or make a wrapper script around it. Here is a script to work around the stripping of environment variables done by suEXEC:
    2726
    28 {{{
     27{{{#!sh
     28#!/bin/bash
     29user="marcenuc"
    2930
    30  #!/bin/bash
    31  user="marcenuc"
    32 
    33  prj="${PATH_INFO#/}"
    34  prj="${prj%%/*}"
    35  export TRAC_ENV="/home/${user}/.trac/prj/${prj}"
    36  export SCRIPT_NAME="/~${user}/prj/${prj}"
    37  export PATH_INFO="${PATH_INFO#/${prj}}"
    38  export PYTHONPATH="/home/${user}/sw/lib/python2.3/site-packages"
    39  exec ./trac.cgi
     31prj="${PATH_INFO#/}"
     32prj="${prj%%/*}"
     33export TRAC_ENV="/home/${user}/.trac/prj/${prj}"
     34export SCRIPT_NAME="/~${user}/prj/${prj}"
     35export PATH_INFO="${PATH_INFO#/${prj}}"
     36export PYTHONPATH="/home/${user}/sw/lib/python2.3/site-packages"
     37exec ./trac.cgi
    4038}}}
    4139
     
    4644The above script works well if you want to have a Trac instance for each user, but it doesn't really help if you have several projects under the same site, !SourceForge style. In order to solve this under Linux Red Hat with Plesk, I did the following:
    4745
    48 First, from the Apache configuration ('''vhost.conf''' in this case), replace '''DOMAIN''' with the domain you are adding:
    49 {{{
     46First, from the Apache configuration (`vhost.conf` in this case), replace `DOMAIN` with the domain you are adding:
     47{{{#!apache
    5048RewriteEngine on
    5149RewriteRule ^/projects/+$                                    /projects/index.php  [L]
     
    7977}}}
    8078
    81 Now add the folder '''~/httpdocs/projects'''.
     79Now add the folder `~/httpdocs/projects`.
    8280
    83 In that folder, either symlink '''trac.cgi''' or place a copy, and add '''index.php'''. Index.php acts as the default page when a project without an existing Trac environment is requested.
     81In that folder, either symlink `trac.cgi` or place a copy, and add `index.php`. `index.php` acts as the default page when a project without an existing Trac environment is requested.
    8482
    85 Now, for the wrap.cgi bash script:
    86 {{{
    87 
    88  #!/bin/bash
    89  DOMAIN="trac.edgewall.com"
    90  project="${SCRIPT_NAME#/projects/}"
    91  export TRAC_ENV="/home/httpd/vhosts/${DOMAIN}/private/tracs/${project}"
    92  export SCRIPT_NAME="/projects/${project}"
    93  export PATH_INFO="${PATH_INFO#/${SCRIPT_NAME}}"
    94  exec ./trac.cgi
     83Now, for the `wrap.cgi` bash script:
     84{{{#!sh
     85#!/bin/bash
     86DOMAIN="trac.edgewall.com"
     87project="${SCRIPT_NAME#/projects/}"
     88export TRAC_ENV="/home/httpd/vhosts/${DOMAIN}/private/tracs/${project}"
     89export SCRIPT_NAME="/projects/${project}"
     90export PATH_INFO="${PATH_INFO#/${SCRIPT_NAME}}"
     91exec ./trac.cgi
    9592}}}
    9693
     
    105102My layout is as follows:
    106103
    107  * Project Trac installations are in /home/tracker/Trac/Projects/project-a /home/tracker/Trac/Projects/project-b, etc.
     104 * Project Trac installations are in `/home/tracker/Trac/Projects/project-a`, `/home/tracker/Trac/Projects/project-b`, etc.
    108105 * The Trac site is a separate vhost from our other Web pages.
    109  * The Trac site lives in /home/tracker/Trac/htdocs/.
    110  * /home/tracker/Trac/cgi-bin is a symlink to /var/www/cgi-bin/tracker/ (see below).
    111  * URLs are !http://trac.example.com/projects/project-a, etc.
     106 * The Trac site lives in `/home/tracker/Trac/htdocs/`.
     107 * `/home/tracker/Trac/cgi-bin` is a symlink to `/var/www/cgi-bin/tracker/` (see below).
     108 * URLs are `http://trac.example.com/projects/project-a`, etc.
    112109
    113 Red Hat compiles suExec so that it only executes CGI scripts that live below /var/www. You cannot symlink individual scripts, but you can symlink a directory. This means that we can't drop CGI scripts under doc root. The scripts will have to live in the cgi-bin subdirectory. Scripts must also not be group-writable.
     110Red Hat compiles suExec so that it only executes CGI scripts that live below `/var/www`. You cannot symlink individual scripts, but you can symlink a directory. This means that we can't drop CGI scripts under doc root. The scripts will have to live in the `cgi-bin` subdirectory. Scripts must also not be group-writable.
    114111
    115112The Trac vhost is defined as follows:
    116 {{{
     113{{{#!apache
    117114<VirtualHost *:80>
    118115    ServerAdmin webmaster@example.com
     
    134131}}}
    135132Notes:
    136  * The !ScriptAlias line enables CGI script invocation in the named subdirectory. This subdirectory must be a symlink to a directory under /var/www/cgi-bin/.
    137  * The second !RewriteRule finds the project name and appends anything following it to the rewritten URL. Normally, the result of a !RewriteRule is appended to the path to doc root. The PT ("Pass Through") flag prevents this, so /cgi-bin/tracwrap.cgi is invoked as a script.
     133 * The !ScriptAlias line enables CGI script invocation in the named subdirectory. This subdirectory must be a symlink to a directory under `/var/www/cgi-bin`.
     134 * The second !RewriteRule finds the project name and appends anything following it to the rewritten URL. Normally, the result of a !RewriteRule is appended to the path to doc root. The PT ("Pass Through") flag prevents this, so `/cgi-bin/tracwrap.cgi` is invoked as a script.
    138135 * The E flag in torgny's example is superfluous, as suExec strips it from the environment anyway.
    139136
    140 As above, the tracwrap.cgi script sets environment variables for trac.cgi depending on the project name:
    141 {{{
    142 
     137As above, the `tracwrap.cgi` script sets environment variables for `trac.cgi` depending on the project name:
     138{{{#!sh
    143139#!/bin/bash
    144 proj=${SCRIPT_URL#/projects/}
    145 project=${proj%${PATH_INFO}}
     140proj="${SCRIPT_URL#/projects/}"
     141project="${proj%${PATH_INFO}}"
    146142export TRAC_ENV="/home/tracker/Trac/Projects/${project}"
    147143export SCRIPT_NAME="/projects/${project}"
    148144exec ./trac.cgi
    149145}}}
    150 I found that the variables you need to manipulate are quite different than in torgny's example. SCRIPT_URL contains the entire local URL, e.g., "/projects/project-a/login" and PATH_INFO already contains anything after the project name. So to get the project name, you need to strip "/project/" off the front of ${SCRIPT_URL} and "${PATH_INFO}" off the end. On entry, SCRIPT_NAME contains "tracwrap.cgi", not anything related to the project name.
    151 
     146I found that the variables you need to manipulate are quite different than in torgny's example. `SCRIPT_URL` contains the entire local URL, e.g., `"/projects/project-a/login"` and `PATH_INFO` already contains anything after the project name. So to get the project name, you need to strip `"/project/"` off the front of `${SCRIPT_URL}` and `"${PATH_INFO}"` off the end. On entry, `SCRIPT_NAME` contains `"tracwrap.cgi"`, not anything related to the project name.
    152147
    153148----