You are currently browsing the category archive for the ‘Nginx’ category.

Jobs in the Jenkins continuous integration software can be configured to link SCM commit details to a repository browser. Unfortunately the Subversion plugin (and perhaps all the SCM options) only allows one repository browser for all SVN repos in a given job ( My project uses two svn repos, Core and Rind, so this limitation, of course, poses an inconvenience.

Luckily, I was able to find a solution that works for my project. I noticed that the current Core revision numbers are in the 10K range and the Rind revisions are in the 50K range. Ah ha!, an opportunity for an Apache Rewrite rule.

I chose WebSVN for the repository browser and installed the WebSVN2 plugin (the WebSVN bundled with Jenkins is for the WebSVN 1.x series). For the browser URL configuration I used a fake repname (TBD) in the query string.

and then used the following Apache RewriteRules to redirect to the proper repo in WebSVN based on the revision number.

RewriteEngine on
RewriteCond %{QUERY_STRING} repname=TBD&(.*)rev=([1234]\d{4,4})
  RewriteRule ^(.+)$ $1?repname=GUS&%1rev=%2 [R,L,NE]
RewriteCond %{QUERY_STRING} repname=TBD&(.*)rev=([56789]\d{4})
  RewriteRule ^(.+)$ $1?repname=ApiDB&%1rev=%2 [R,L,NE]

That is, if the rev number matches a number between 10000 and 49999 then redirect to the Core repo in WebSVN. If rev number matches a number over 50000 then redirect to the Rind repo.

In both cases the Rewrite depends on the repname being TBD so we do not trigger rewrites when normally browsing WebSVN.

This scheme depends on conditions and assumptions that happen to fit our project:

– We only care about current and future revisions (>10000). That’s ok, Jenkins will not need to link to revisions that predate this setup.

– Rind will always get more commits than Core such that Core revisions will always lag behind Rind revisions. This has been the case for the past 6 years, I don’t expect it to change.

– Core revisions will not exceed 49999 for the life of this Rewrite. If it does (unlikely, it’s taken 6 years to get to the 10K range) we can update the rules.

Obviously this is not a suitable solution for everyone.


I initially started with sventon behind an Nginx proxy before deciding that WebSVN was going be easier for me to maintain in the long run (simply due to my system infrastructure and experience, not due to any complaint against sventon). For the record, this is where I was heading with the Nginx rewrite rules. I did not follow through with testing so I do not know if it works as is, but perhaps it’s a starting point for someone.

if ($request_uri ~ "revision=(.+)" ) {
  set $revision $1;

if ($revision ~ "[1234]\d{4}") {
  rewrite ^$revision?;
if ($revision ~ "[56789]\d{4}") {
  rewrite ^$revision?;

A mod_rpaf story.

My Apache virtual hosts are dynamically configured from a library of Perl code using PerlSections.
A configuration file for one virtual looks something like:

<VirtualHost *:80>
  require 'conf/lib/';

Aside from boostrapping all the basic virtual host configuration, establishes basic authentication (via mod_auth_tkt) for the <Location /> of the virtual host. Authentication is the desired default but, for some specific virtual hosts, I want to disable the authentication requirements. This I can do by appending a new <Location /> after the Perl Section.

<VirtualHost *:80>
  require 'conf/lib/';
 <Location />
  Allow from any

This effectively overrides the deny from declared by the perl library and makes the site public. This has been working fine for me for years. Recently though, I put an Nginx reverse-proxy in front of some of my virtual hosts and installed mod_rpaf into Apache so the IP address it logged would be the client’s and not the proxy server.

There I hit a snag. Apache/mod_rpaf was ignoring the X-Forwarded-For header and only logging the IP address of the proxy. Actually the GET '/' request was logging correctly, but that was insufficient and no consolation.

Client logging was done correctly if I used a static, hand-crafted Apache configuration file (not using the Perl library) so I knew mod_rpaf was installed correctly. I began to suspect the dynamic Perl configuration and that made me nervous; I really didn’t want to give that up completely.

Well, cutting to the chase, it turns out that the ‘Allow from any’ added to disable the basic authentication was the culprit. I’ve been using ‘Allow from any’ for years and it does indeed allow any host access but looking at it anew today it suddenly struck me as being wrong. It’s normally ‘Allow from all‘, I must have had ‘Satisfy any‘ on the brain when I originally started using the override – propagating around through thoughtless copying/pasting. On a whim I changed it to ‘Allow from all‘ and, w00t!, mod_rpaf began logging the correct client address.

Are ‘allow from any’ and ‘allow from all’ supposed to mean different things to Apache? A little Googling turns up examples of people using ‘allow from any’ but I don’t see any indication that it has a special meaning.

I’m using the Apache mod_rpaf module to capture client IP addresses in the X-Forwarded-For header passed by an Nginx reverse proxy. This is good for logging and CGI environments but mod_rpaf does not fix up the client IP address sufficiently to be used in Apache’s allow/deny access control directives.

Almlys has a nice workaround.

Quoting the juicy bit from Almlys’s blog posting:

SetEnvIf X-Forwarded-For ^172\.26\.0\.17 let_me_in
Order allow,deny
allow from env=let_me_in


I’ve been exploring using Nginx to front our Apache websites. I found a fair amount of documentation online but most of it was for nginx on top of a backend application running on the same host – so, lots of examples of load balancing among various ports on In my case I have name-based Apache virtual hosts running at different IP addresses. Also my goal is not to set up automatic load balancing – our session-based application will not work well with it – but rather I want to be able to rapidly and manually switch a web address to a different machine so I can perform maintenance on or updates to the offline systems.

To summarise, I want the publically accessible website to be a proxy server to our internal, Apache name-based virtual hosts w1 or w2. I want to be able to choose which of w1 or w2 services the client’s request.
Read the rest of this entry »


April 2017
« May