RFC: RT install w/o setgid Perl or mod_perl

I’ve only recently discovered RT and joined the list, so I apologize
in advance if any of this is an FAQ. I didn’t see anything similar in
the list archives, and I thought people might be interested in how I
have RT (2.0.13) set up. I’d also like to hear any suggestions that
anyone may have on how to improve my configuration.

Background Information

My group’s primary function is to run systems that host central
services such as mail, LDAP, news, web servers, etc. We don’t run the
applications that run on our systems; we just provide the underlying
platform on which our customers install and manage their
applications.

As a result of this division of responsibilities, we’ve developed a
lot of infrastructure to allow our customers to control as much of
their software and data as possible, even though they don’t have root
access. In particular, we create a unique pseudo-user for each
application, and we try to install everything related to the
application in the pseudo-user’s home directory. The customer then
su’s to the pseudo-user to manage the service.

For example, for our LDAP service, we created a pseudo-user named
"ldap" with home directory “/services/ldap”. All of the LDAP server
software, directory data, and support scripts are owned by this user
and installed in its home directory.

For web-based services, we’ve established this convention for
URL-to-directory mappings:

DIRECTORY URL
~pseudouser/public_html/http http://hostname/pseudouser/
~pseudouser/public_html/https https://hostname/pseudouser/

Rather than just using an Apache “Alias” directive to establish this
mapping, we use mod_rewrite to rewrite the requested URL internally
using ~pseudouser notation. This allows us to use Apache’s suEXEC
mechanism to invoke CGI scripts as the appropriate pseudo-user, rather
than as user httpd.

Goals for RT Installation

Given that we already have infrastructure in place for running
applications as pseudo-users, I wanted to use the same model for my RT
installation. In particular, I had two main goals:

  1. Install RT under a single pseudo-user account and run every part
    of it as that user. (I created a pseudo-user named “rt” with a
    home directory of “/services/rt” for this purpose.)

  2. Use my site’s existing perl and apache packages instead of
    creating special builds just for RT. (This means no set[ug]id
    perl scripts and no mod_perl.)

These goals presented several interesting challenges.

Installation Process

Because the RT installation procedure assumes that you’ll be running
different parts as different users, it includes commands that chown
various files, so it must be run as root. After closely scrutinizing
what it was going to do, I ran it as root, but quickly chown’ed all of
the installed files to user rt. I also removed all of the set[ug]id
bits.

RT Mail Gateway

Since rt-mailgate could not be a setgid script, I needed to find a way
to run it as user “rt”. The RT docs say to run it directly from
sendmail’s aliases file, as follows:

sysmgr: “|/services/rt/rt2/bin/rt-mailgate --queue sysmgr --action correspond”

That would result in rt-mailgate being run as user daemon. To get
around this, I changed the alias to point to the rt user:

sysmgr: rt

Then, as user rt, I use procmail to run rt-mailgate with the
appropriate options depending on what address the message was sent to.
Thus, rt-mailgate gets run as user rt.

RT Web Interface

The next problem was getting the web interface to run as user rt
instead of as user httpd. In this case, even though I didn’t want to
use mod_perl in the first place, the fact that I couldn’t worked out
in my favor, since FastCGI can be configured to use Apache’s suEXEC
mechanism to run external programs as alternate users.

The first problem I ran into in setting up FastCGI was a mod_perl
dependency problem in mason_handler.fcgi. Commenting out this line
seemed to fix it:

use HTML::Mason::ApacheHandler;

(I hope commenting this out doesn’t have any bad side-effects, but I
haven’t noticed any problems so far. Is this a bug, or is there
something weird about my setup?)

Next, in order to be processed by our mod_rewrite rules and suEXEC,
the FastCGI handler had to be installed in ~rt/public_html/https.
However, since I had installed RT in ~rt/rt2, I solved this problem
with a hard link. (The down-side of this is that I’ll probably need
to recreate the hard link when I upgrade RT.)

Finally, I needed to create a symlink ~rt/public_html/https/images ->
~rt/rt2/WebRT/html/images so that the images would be accessible.

Here are the relevant snippets from httpd.conf:

LoadModule fastcgi_module /usr/local/libexec/mod_fastcgi.so

AddModule mod_fastcgi.c

AddHandler fastcgi-script .fcgi FastCgiWrapper /usr/local/sbin/suexec FastCgiIpcDir /var/lib/httpd
<IfModule mod_rewrite.c>
    RewriteEngine on

    ### Allow the translated subrequest to pass straight through.
    RewriteCond %{IS_SUBREQ}                =true
    RewriteRule ^/~rt/https/ -       [L,PT]

    ### In case the rewritten URI leaks out to the browser,
    ### redirect it back to the advertised location.
    RewriteRule ^/~(rt)(/https)?(/(.*))?$      /$1/$4    [R=permanent,L]

    ### Redirect to add trailing '/' for directory names.
    RewriteRule ^/(rt)$           /$1/      [R=permanent,L]

    ### Handle requests for the advertised URIs by translating them
    ### and passing them through in a subrequest.
    RewriteRule ^/rt/images(/(.*))?$        /~rt/https/images/$2     [L,PT]
    RewriteRule ^/rt/(.*)$  /~rt/https/mason_handler.fcgi/$1         [L,PT]
</IfModule>

Running the RT web interface as user rt eliminated the need for the
WebRT/data and WebRT/sessiondata directories to be owned by user
httpd.

Conclusion and Suggestions

There were a lot of issues that needed to be identified and addressed
in order to install RT under its own pseudo-user. However, once this
was done, the procedure was actually fairly easy.

Based on this experience, here are a few off-the-cuff suggestions, for
whatever they’re worth:

  • Change the installation procedure to use autoconf. This would make
    it easier to install different parts of RT in different locations
    and with different options. It would also make it easier to build
    distributable packages of RT.

  • Change the installation procedure not to assume that different
    files and directories need to have different ownerships. This
    would allow RT to be installed by a user other than root.

  • Improve the documentation. In particular, the installation
    instructions need to be more precise and more detailed.

Well, I think that’s it for now… Please let me know if you have any
questions, comments, or suggestions. Thanks!

Mark D. Roth roth@feep.net
http://www.feep.net/~roth/

I want to thank you for the wonderful writeup you did on installing RT
as a NON-ROOT user. This is just wonderful stuff.

Thanks. I’m glad you found it useful.

For me, I really want to see RT succeed, but the install process needs
to be cleaned up, and the dependencies should also be cleaned up as
well.

The biggest problem I had with the dependencies was in figuring out
which perl modules weren’t needed because I’m not using mod_perl. In
fact, I’m still not sure that I’ve got this completely sorted out; I
may have some modules installed that I don’t really need.

Mostly, not having to re-install new stuff each and every time RT
changes, and making the installs more compartmental, so that if you do
upgrade, you only re-install stuff local to that version of RT, and
not globally to the entire web server.

I agree completely.

I think the main point here is that we need the ability to package it
up for easy installation. Different sites will want to build
different types of packages (RPM, Solaris pkg, AIX lpp, HP-UX sw,
Encap, etc), but as long as we have the ability to control which
directories the various parts of the package get installed into (ala
autoconf’s --prefix, --bindir, --libdir, et al), packaging up RT
should be no more difficult than any other software. Once we can
build packages, we can let the packing system handle dependencies and
other installation issues for us.

Anyway, those are my suggestions, for whatever they’re worth. :wink:

Mark D. Roth roth@feep.net
http://www.feep.net/~roth/

Thanks very much for the writeup of how you did your RT installation.
I’m sure folks will find it useful.

  • Change the installation procedure to use autoconf. This would make
    it easier to install different parts of RT in different locations
    and with different options. It would also make it easier to build
    distributable packages of RT.

I’m not actually finding it difficult to install RT in a completely different
directory structure using only alternative makefile variables passed to
make on the commandline by my packaging system’s build mechanism
(I needed to make one change to RT’s makefile to more easily move the config
file) The current RT 2.1 dev series makes all this even easier.

  • Change the installation procedure not to assume that different
    files and directories need to have different ownerships. This
    would allow RT to be installed by a user other than root.

  • Improve the documentation. In particular, the installation
    instructions need to be more precise and more detailed.

It sounds like you’re setting up RT as a service for paying customers.
If you’re interested in improvements to RT’s installation support and
documentation, there are a couple of ways you can help make them happen:

1) Sign up for the rt-doc-workers mailinglist and submit updated
and expanded documentation

2) Sponsor additional RT development; say an alternative installation
designed to run as a single user.

3) Buy a support contract. Every support contract gets you top-notch
RT support. Additionally, it helps make sure that I can continue
to develop RT in the future. 

4) Contribute new code to implement new functionality that you need.
Before contributing any significant code to RT, you should subscribe
to the rt-devel mailinglist and describe what you're looking to do
in order to get some feedback before going forward.

Information on support options is available from http://bestpractical.com

Thanks,

Jesse

http://www.bestpractical.com/products/rt – Trouble Ticketing. Free.

I’m not actually finding it difficult to install RT in a completely different
directory structure using only alternative makefile variables passed to
make on the commandline by my packaging system’s build mechanism
(I needed to make one change to RT’s makefile to more easily move the config
file) The current RT 2.1 dev series makes all this even easier.

I’m not so much suggesting that the current method makes it
impossible, but that it would be much easier for most users if it used
autoconf. Most users are already familiar with autoconf because of
the huge number of packages that use it. It’s essentially the
de-facto standard these days.

In any event, if the Makefile method has improved in the development
series, that may be good enough. However, because the Makefile
variables aren’t familiar to most users, it’s even more important to
improve the documentation of the installation procedure.

It sounds like you’re setting up RT as a service for paying customers.

No, I’m only looking at it for my group’s internal use.

If you’re interested in improvements to RT’s installation support and
documentation, there are a couple of ways you can help make them happen:
[…]

If I have time to add any improvements, I’ll definitely contribute
them back. However, like many organizations these days, we don’t have
the budget to buy support.

Thanks for the feedback!

Mark D. Roth roth@feep.net
http://www.feep.net/~roth/

Mark,

I want to thank you for the wonderful writeup you did on installing RT
as a NON-ROOT user. This is just wonderful stuff.

For me, I really want to see RT succeed, but the install process needs
to be cleaned up, and the dependencies should also be cleaned up as
well.

Mostly, not having to re-install new stuff each and every time RT
changes, and making the installs more compartmental, so that if you do
upgrade, you only re-install stuff local to that version of RT, and
not globally to the entire web server.

Does this make sense?

John
John Stoffel - Senior Unix Systems Administrator - Lucent Technologies
stoffel@lucent.com - http://www.lucent.com - 978-399-0479