FastCGIConfiguration
NOTE: This page is a mess of facts some of which are very outdated for 2008 year. Need big refactoring.
http://soljerome.com/blog/category/linux/nginx/, 4/22/2011 blog post about setting up
- RT 3.8
- nginx
- MySQL
- Ubuntu 10.04
-- MarkB
FastCGI is a variant to run RT server. You may want to read ManualApacheConfig to decide what you want to use.
Even if you decided to use FastCGI then anyway you must read ManualApacheConfig. It's sort of mandatory reading :)
Configuring RT to run in FastCGI mode is dead simple. However, configuring Apache is hard. If you are considering a single web server to use with RT, you might like to consider a fast and simple solution such as lighttpd, nginx or any of the commercial and free web servers available that support FastCGI.
Configuring RT 3.2 and newer to run in FastCGI mode
When installing RT, run:
./configure \ --with-web-user="webuser" \ --with-web-group="webgroup" \ --with-rt-user="webuser" \ --with-rt-group="webgroup"
Don't forget to include other configuration options that matter to you, like --prefix. You will still need to customize [=etc/RT_SiteConfig.pm] using [=etc/RT_Config.pm] as a base, before you run `make install
'. If you do not have `root' access to the server you are installing to, you can use `fakeroot
' or a similar utility to use `make install
'.
Configuring RT to run as a dynamic FastCGI application
A dynamic FastCGI application is one in which the application process is dynamically started and stopped by the webserver process, on demand.
RT's FastCGI handler defaults to assuming it is being run as as a dynamic application. So, configure your web server to start bin/mason_handler.fcgi
inside the RT installation directory for requests that it is to handle. The first time RT is accessed the web server will attempt to start RT.
Note that this is a less-than-ideal approach, security wise, since the RT application runs under the same user-id as the web server. A better approach would be to have the web server somehow switch users when starting RT. This is commonly achieved via set-uid wrappers, which are generally hard to debug when things go wrong. Also, you will be relying on the process manager included with your web server.
Configuring RT to run as a static/external FastCGI application
A static/external FastCGI application is one in which the application is started manually or independently of the webserver, and the webserver connects to it when needed. This makes it easy to setup user separation between the RT process and the webserver process, but you lose out on the ability for the webserver to dynamically determine how many RT processes need to be running.
This is achieved by running the bin/mason_handler.fcgi
script as the configured RT user, setting FCGI_SOCKET_PATH
in the process environment to the location of the application socket, or a /hostname:port/ combination. This is a feature of the CGI::Fast
perl module, so you may need to upgrade your version of that module if your version does not support this feature.
Note that the FastCGI handler for RT does not currently include a process manager, instead single threading requests. This is likely to be addressed in a later version of either CGI::Fast
or RT, but for small installations this is usually acceptable. A simple workaround is simply to start more than one RT daemon.
Note that running RT in single threaded FastCGI mode is the only time that it is actually /safe/ to turn off the [=$WebFlushDbCacheEveryRequest] configuration option.
You will need to set up a script that starts RT after your web server. For best results, use a SysV-style /etc/init.d/
script. Here is an example of such a script:
#!/bin/sh RTPATH=/path/to/rt RTUSER=rt FCGI_SOCKET_PATH=$RTPATH/var/appSocket case $1 in start) echo -n "Starting RT: mason_handler.fcgi" cd $RTPATH export FCGI_SOCKET_PATH su $RTUSER -c perl bin/mason_handler.fcgi & echo ;; stop) echo -n "Stopping RT: " PIDS=`ps axww | awk '/[m]ason_handler.fcgi/ { print $1}'` if [ -n "$PIDS" ] then echo -n kill -TERM $PIDS kill $PIDS echo else echo RT not running fi ;; restart|force-reload) $0 stop $0 start ;; *) echo "Usage: /etc/init.d/rt { stop | start | restart }" exit 1 ;; esac
(this example corresponds to the lighttpd setup example)
Web-server specific FastCGI notes
Configuring RT to run with lighttpd
A small patch needs to be applied to lighttpd 1.3.x, as its FastCGI support is slightly broken. See LighttpdPatch for the patch. Lighttpd 1.4.x does not have the problem.
First, make sure that "mod_fastcgi"
is uncommented in the server.modules
option. Then you can use a fastcgi.server
configuration setting similar to:
fastcgi.server = ( "/rt" => ( "rt" => ( "socket" => "/path/to/rt/var/appSocket", "check-local" => "disable" ) ) )
Information for lighttpd is included as it is the easiest to setup open source web server that supports FastCGI that I am aware of. However, the process is just as simple using commercial web servers, like Zeus, LiteSpeed or thttpd professional, and no doubt other web servers with FastCGI support like Roxen or Pi3web.
Configuring RT to run with Apache
RT 3.2 includes a significant change to the FastCGI handler. It is no longer "setgid" to the RT group. Perl's setid support has been deprecated for the last several releases and a number of platforms don't bundle the "sperl" or "suidperl" executable by default. Additionally, when perl is run SetUID or SetGID, the interpreter is automatically switched into /taint mode/, in which all incoming data, no matter the source is considered suspect. At first, this seems like a great idea. But perl's taint mode is a big sledgehammer used to hit small nails. Many perl libraries aren't tested in taint mode and will fail when least expected. Moving away from a SetGID FastCGI handler will enable more users to have a smoother RT experience. It does require some changes in how you set up and configure RT.
Beginning with RT 3.2, you have several choices about how to configure RT to run as a FastCGI:
1. Install RT as the user your webserver runs as
Pros: Very easy to configure
Cons: Your webserver has access to RT's private database password
How To
First, determine whether you are using mod_fastcgi or mod_fcgid. I believe mod_fastcgi is older and supports older versions of Apache (i.e. Apache 1.x). The mod_fcgid is newer and is included with newer versions of Fedora Linux, etc. RT does not care which module is being used, but the configuration syntax is different for each module.
If you are using mod_fastcgi (apache 1.x), you'll want to add something like the following to your httpd.conf:
NOTE: Most FastCGI options are available only in apache's server config context, not in virtual host sections.
# Tell FastCGI to put its temporary files somewhere sane. FastCgiIpcDir /tmp # Number of processes is tunable, but you need at least 3 or 4 FastCgiServer /opt/rt3/bin/mason_handler.fcgi -idle-timeout 120 -processes 4 <VirtualHost rt.example.com> AddHandler fastcgi-script fcgi ScriptAlias / /opt/rt3/bin/mason_handler.fcgi/ </VirtualHost>
If you are using mod_fcgid, you'll want to add something like the following to your httpd.conf:
<VirtualHost rt.example.com> ServerName rt.example.com DocumentRoot /opt/rt3/share/html AddHandler fcgid-script fcgi ScriptAlias / /opt/rt3/bin/mason_handler.fcgi/ </VirtualHost>
2. Make your webserver user a member of the "rt" group
Pros: Easy to configure
Cons: Your webserver has access to RT's private database password
How To
Install RT normally. Add whichever user your webserver runs as (whatever you set --with-web-user to) to the "rt" group (whatever you set --with-rt-group to) in /etc/groups.
To find out what user your webserver runs as, look for the line
User some-user-name
in your apache httpd.conf. Common values are www, www-data, web and nobody.
3. Run RT using _suexec_ or a similar mechanism
Pros: More secure
Cons: Sometimes very difficult to configure
How To
Apache's suexec utility allows you run CGI programs as specific users. Because that's a relatively heavy responsibility, it's very, very conservative about what it's willing to do for you. On top of that, Apache's mod_fastcgi plugin doesn't respect all of suexec's features. While suexec is designed to execute CGI scripts in a given virtual host's DocumentRoot, It can only execute FastCGI scripts in the system's main DocumentRoot.
This means you have to copy the RT FastCGI handler into your main DocumentRoot
The following example VirtualHost will run RT as a FastCGI on Apache 1.3 on a Debian Linux server.
# Tell FastCGI to put its temporary files somewhere sane. FastCgiIpcDir /tmp # Tell FastCGI that it should use apache's "suexec" binary to call any FastCGI script. # This is a GLOBAL setting FastCgiWrapper /usr/lib/apache/suexec # You need to copy the rt mason_handler.fcgi into a directory inside the main server DocumentRoot # That directory must be owned by the user and group that will execute the FastCGI script # In this case, that directory is /var/www/rt # To find the local DocumentRoot, run "suexec -V" as root and look for the # -D DOC_ROOT parameter. # Apache 1.3 discards the user and group parameters on the FastCgiServer line. # Apache 2.0 requires them. FastCgiServer /var/www/rt/mason_handler.fcgi -idle-timeout 120 -user rt -group rt -processes 4 <VirtualHost rt.example.com> DocumentRoot /opt/rt3/share/html # Set the rt user and group as the executing user for this virtual host. # For apache 2 you need # SuexecUserGroup rt rt # instead User rt Group rt AddHandler fastcgi-script fcgi ScriptAlias / /var/www/rt/mason_handler.fcgi/ </VirtualHost>
Configuring RT3 to run with nginx
The patch listed below is no longer required with the latest version of nginx (http://www.nginx.net),
Here is a quick excerpt that shows how to run rt3 with a FastCGI socket,
server { listen 80; server_name localhost; location / { root /usr/local/rt3/share/html; fastcgi_pass unix:/var/run/rt3/rt3.socket; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param PATH_INFO $fastcgi_script_name; } location /NoAuth/ { alias /usr/local/rt3/share/html/NoAuth/; }
It seems that declaring SCRIPT_NAME /and/ PATH_INFO clobbers some functions so be sure to use only PATH_INFO.
A small patch needs to be applied to mason_handler.fcgi to run properly under FastCGI witn nginx. Problem - nginx not send PATH_INFO to fastcgi server.
First apply next patch to mason_handler.fcgi:
--- ./bin/mason_handler.fcgi 2005-12-02 08:23:20.000000000 -0500 +++ /usr/local/rt3/bin/mason_handler.fcgi 2005-12-02 11:54:56.000000000 -0500 @@ -68,11 +68,17 @@ Module::Refresh->refresh if $RT::DevelMode; RT::ConnectToDatabase(); + my $path_info = $cgi->script_name; + $path_info =~ s/^\///; + $cgi->path_info($path_info); + $RT::Logger->crit($path_info); + if ( ( !$Handler->interp->comp_exists( $cgi->path_info ) ) && ( $Handler->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { $cgi->path_info( $cgi->path_info . "/index.html" ); } - + + $RT::Logger->crit($cgi->path_info); eval { $Handler->handle_cgi_object($cgi); }; if ($@) { $RT::Logger->crit($@);
Then create config for vhost that you want run rt3 on:
(example of config for fastcgi socket path - /tmp/request_tracker and rt3 installation path - /usr/local/rt3/
server { listen IP_ADDRESS:PORT; server_name domain.com; location /images/ { alias /usr/local/rt3/share/html/NoAuth/images/; } location / { fastcgi_pass unix:/tmp/request_tracker; fastcgi_x_powered_by off; # default on fastcgi_param DOCUMENT_ROOT /usr/local/rt3/share/html; fastcgi_param SCRIPT_FILENAME /usr/local/rt3/share/html$fastcgi_script_name; fastcgi_param PATH_TRANSLATED /usr/local/rt3/share/html$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param REDIRECT_STATUS 200; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param SERVER_SOFTWARE "nginx/0.3.15"; fastcgi_param GATEWAY_INTERFACE "CGI/1.1"; fastcgi_param SERVER_NAME $server_name; fastcgi_param SERVER_NAME $server_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param REMOTE_USER $remote_user; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; } location ~* .+\.(html|js|css)$ { ....same as above location.... } location /NoAuth/ { alias /usr/local/rt3/share/html/NoAuth/; } }
All tested and working with rt 3.5.5
Other information about nginx and FastCGI can be found on our site - http://www.nginx.info (now russian only, will be translated soon)
PS. If you want run rt3 with prefix - domain.com/prefix/, so need to remove that prefix for path_info (in perl code of patch above)
RT 3.0 FastCGI configuration
!FastCGI configuration for Apache 2.0
(assumes FastCGI is already installed)
This is roughly what I had to do to get RequestTracker working using FastCGI on RedHat9 system.
1. Install suidperl package, if not already installed.
2. Edit first line of /opt/rt3/bin/mason_handler.fcgi to be
#!/usr/bin/suidperl
3. Add the following to /etc/httpd/conf/httpd.conf
LoadModule fastcgi_module modules/mod_fastcgi.so FastCgiIpcDir /tmp FastCgiServer /opt/rt3/bin/mason_handler.fcgi -idle-timeout 300 -processes 5 <VirtualHost *> ServerName rt-host-name.example.org DocumentRoot /opt/rt3/share/html AddHandler fastcgi-script fcgi ScriptAlias / /opt/rt3/bin/mason_handler.fcgi/ <Location /> AddDefaultCharset UTF-8 SetHandler fastcgi-script </Location> </VirtualHost>
!FastCGI configuration for Apache 1.3
LoadModule fastcgi_module libexec/apache/mod_fastcgi.so AddModule mod_fastcgi.c
Outside the vhost:
FastCgiServer /opt/rt3/bin/mason_handler.fcgi -idle-timeout 300 -processes 5
In your vhost:
AddHandler fastcgi-script fcgi ScriptAlias / /opt/rt3/bin/mason_handler.fcgi/ <Location /> AddDefaultCharset UTF-8 SetHandler fastcgi-script </Location>
Since the default Apache install includes a Directory directive blocking access to / and another to allow for the DocumentRoot, you might need to add something like:
<Directory "/opt/rt3"> Order allow,deny Allow from all </Directory>
To allow access to that directory, too. The symptom is getting '403 Forbidden' and a line like 'client denied by server configuration' in your Apache error log, even for index.html. -- HowardJones