Tutorial, Internet, Hardware, Software, Os, Linux, Android, Security, Mikrotik

06 December, 2012


Let’s say you run a front end system like a reverse proxy, load balancer or http accelerator (e.g. big-ip, squid, pound, varnish, apache, nginx, etc), which pass dynamic requests to back end application servers, then you’re likely to have to deal with your applications seeing client requests as coming from the IP(s) of your front end boxes.
This presents a slew of quality of life reducing issues, unless of course your back end system is Apache, in which case you can use mod_rpaf to make your life pleasant again.
Without it, you’d have to do painful things like patch your applications, which grab the client IP from the REMOTE_ADDR server variable, to use the X_FORWARDED_FOR header, if present, instead. For example:

1
2
3
4
5
6
// If set, use IP provided by our front end rproxy
if ($_SERVER["HTTP_X_FORWARDED_FOR"]) {
     $realclientip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} else {     $realclientip = $_SERVER["REMOTE_ADDR"];
mod_rpaf solves this much more easily, it works as follows:
It changes the remote address of the client visible to other Apache modules when two conditions are satisfied. First condition is that the remote client is actually a proxy that is defined in httpd.conf. Secondly if there is an incoming X-Forwarded-For header and the proxy is in its list of known proxies it takes the last IP from the incoming X-Forwarded-For header and changes the remote address of the client in the request structure.
If you’re on Debian (or one of its derivatives — Ubuntu, etc), get it with:
ak@gd:~$ aptitude install libapache2-mod-rpaf
Modify “/etc/apache2/mods-available/rpaf.conf” to include IP(s) of your front end boxes and enable with:

ak@gd:~$ a2enmod rpaf
ak@gd:~$ apache2ctl -t
ak@gd:~$ apache2ctl restart

Now, mod_rpaf will grab IP from X_FORWARDED_FOR header and place it in REMOTE_ADDR server variable. You can verify with:
1
2
3
4
5
6
7
8
<?php
$clientip = $_SERVER['HTTP_CLIENT_IP'];
$remoteaddr = $_SERVER['REMOTE_ADDR'];
$xforwardedfor = $_SERVER['HTTP_X_FORWARDED_FOR'];
echo " <li>HTTP_CLIENT_IP:  $clientip</li>\n";
echo " <li>REMOTE_ADDR:  $remoteaddr</li>\n";
echo " <li>HTTP_X_FORWARDED_FOR:  $xforwardedfor</li>\n";
?>

Geesus, that was easy. Gotta love Apache with its plethora of delicious modules. Using a 
distro like Debian that makes them super easy to get is nice too. Now, I can stop patching
 apps and go ride a board.
I’m used to System V style commands used in Red Hat / Fedora and derivatives as well as SUSE, so I found Debian service management methods unintuitive at first.
Below are a couple of personal notes I made on the subject to help myself out, as I was getting used to the Debian way of things…
List existing services:

ls /etc/rc2.d/S*
Manage services [start,stop,reload,etc]:

/etc/init.d/service command
Make service start on boot:

update-rc.d name defaults
The ‘defaults’ value makes the service start in runlevels 0123 and stop in 456. Alternatively, you can specify which runlevels the service will start and stop in with:

update-rc.d name start runlevel stop runlevel
To remove service from starting on boot:

update-rc.d name remove
BTW, for a really excellent breakdown of update-rc.d options, check out this well written post.
If you install sysvconfig (apt-get install sysvconfig) you can also use System V style commands to start/stop services:

service name command
Unfortunately, even having installed sysvconfig in Debian, the command to list all services with status (e.g. running, unused, etc) is still missing. In SUSE, you’d run it with:

service -s
And would get a nice little list like this:
serv1ce-s.png
In the absence of the above, you could just list running processes with ‘ps’.. Another option is to list files in /var/run whose filename ends with ‘pid’, as each of those corresponds to a service:

find . /var/run | grep pid
Yet another option, with sysvconfig installed on Debian, is to just run:

sysvconfig
…which produces a clean and simple ncurses GUI which allows to manage service startup and edit runlevels:

sysvc0nfig.gif