Showing posts for tag "apache"

Better Living Through Reverse Proxies

May 30, 2013, 3:59 PM

  1. Putting Apache in Front of Domino
  2. Better Living Through Reverse Proxies

A while ago, I set up Apache as a reverse proxy in front of Domino. Initially, that was in order to serve a WordPress site on the same server, but since then it has more than proven its worth in other ways, mostly in the areas of fault tolerance and SSL support.

IBM recognizes those benefits, which is why Domino 9 on Windows comes bundled with IHS; however, I am a responsible admin, so I don't run Windows on my main servers. Fortunately, stock Apache does the job nicely... or it does usually. Filled with enthusiasm for this kind of setup, I rolled out a small Linode VM dedicated entirely to running Apache as a proxy (sort of like their NodeBalancers, but manual). Unfortunately, I started running into a problem where sometimes sites fronted by it (such as this one) would not properly include their host information and would instead load the main I Know Some Guys site, which is the default on Domino. I wasn't able to find a fix that actually worked, so I decided to use that as an excuse to switch to a cute little number named Nginx.

So far, my experience with Nginx has been fantastic. The config files are like a cleaned-up version of Apache's and it matches it for each feature I've needed (namely, load balancing, easy config, and multiple SSL certificates). As a nice bonus, I didn't have to do any of the config massaging I had to for Apache in order to get XSP's funky resource-aggregation rules to work. If you have the means, I highly recommend it.

 

My latest foray into proxying also gave me an opportunity to look back into my main bugbears with the setup: Domino tracking the proxy server's IP instead of the original requester's and its lack of knowledge of SSL (which causes it to redirect from an SSL login page to a non-SSL one). Fortunately, it turns out that these problems have been sort-of-solved for years via a notes.ini setting added as part of Domino's terminal WebSphere infection: HTTPEnableConnectorHeaders.

By enabling that on my Domino server, I was able to start providing some of those headers. The remote-host headers ("$WSRA" and "$WSRH") work perfectly: setting that to the incoming host causes Domino to act just like that was the original requester, namely filling that in for the REMOTE_HOST field in classic and facesContext.getExternalContext().getRequest().getRemoteAddr() in XPages.

Unfortunately, I was stymied when I set "$WSIS" to True. Though it does indeed cause Domino to acknowledge that the incoming request is via SSL, it does it TOO well: Domino appears to revert to its behavior of only acknowledging a single SSL site, so it caused requests to essentially ignore the Host (and "$WSSN") headers. So that problem remains unsolved.

 

Still, I feel pretty good about my switch to Nginx and my abuse of the HTTP connector headers and look forward to tinkering some more. For reference, here is the config I use for the standard HTTP proxy ("arcturus" is the short name I gave for the main upstream target):

server {
    listen 80;
	
    location / {
        proxy_pass http://arcturus;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header    Host            $host;
        proxy_set_header    X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header    $WSRA           $remote_addr;
        proxy_set_header    $WSRH           $remote_addr;
        proxy_set_header    $WSSN           $host;
    }
}

Putting Apache in Front of Domino

Dec 8, 2012, 1:59 PM

Tags: apache admin
  1. Putting Apache in Front of Domino
  2. Better Living Through Reverse Proxies

The other day, for my side-project company, I wanted to set up hosting for a WordPress site, ideally without setting up another whole server. The first two ideas I had were pretty terrible:

  1. Hosting it on Domino directly with PHP via CGI. Even if this worked, I assume the performance would be pretty poor and I'd have no confidence in its general longevity.
  2. Hosting it on Apache on another port and using Domino to proxy through. While Domino does have some minor proxy capabilities, they didn't strike me as particularly thorough or suitable for the task.

Since the second option involved running two web servers anyway, I decided to flip it around and do the more-common thing: making Apache the main server and switching Domino to another port. Fortunately, even though it's been years since I ran an Apache server and I'd consider myself novice at best, the process has been exceptionally smooth and has brought with it a couple benefits:

  1. Apache's virtual-host support works perfectly, allowing me to host just the one named site and pass through all other requests to Domino.
  2. My crummy SSL setup works better with Apache, allowing for a poor-man's multi-host-name SSL with my one basic StartSSL certificate. Not only does Apache support SNI for down the line, but in the mean time I can use the same certificate for multiple names (with the usual "mis-matched name" warning) - since Apache handles all requests and funnels them over with the host name to Domino via HTTP, I don't run into the usual Domino problem of only the one SSL-enabled Web Site document being active.
  3. I'm now ready to add load-balancing servers at any time with just a one-line adjustment in my Apache config.

The actual configuration of Apache on my Linux machine was pretty straightforward, with the layout of the configuration directory making it fairly self-explanatory. I linked the modules I wanted from the /etc/apache2/mods-available directory to /etc/apache2/mods-enabled (namely, proxy, proxy_balancer, proxy_http, php5, rewrite, and ssl). Then, I set up a couple NameVirtualHost lines in ports.conf:

NameVirtualHost *:80
NameVirtualHost *:443

Then, I set up a new default site in /etc/apache2/sites-available and linked it to /etc/apache2/sites-enabled/000-domino:

<VirtualHost *:80>
        <Proxy balancer://frostillicus-cluster>
                BalancerMember http://ceres.frostillic.us:8088
                ProxySet stickysession=SessionID
        </Proxy>
        ProxyPass / balancer://frostillicus-cluster/ nocanon
        ProxyPassReverse / balancer://frostillicus-cluster/
        ProxyPreserveHost On
        AllowEncodedSlashes On
</VirtualHost>

That last directive is an important note, and I missed it at first. The "optimize CSS and JS" option in 8.5.3 creates URLs with encoded slashes and, by default, Apache's proxy breaks them, leading to 404 errors in apps that use it. If you turn on AllowEncodedSlashes, though, all is well. Note also the ProxySet line: if that's working correctly (I haven't tested it yet since I don't have a second host set up), that should make sure that browser sessions stick to the same server.

For SSL, I'm not sure what the absolute best way to do it is, but I set it up as another proxy just pointing to the HTTP version locally, so I don't have to set up multiple SSL sites for each virtual host (put into a new site document, 002-ssl):

<VirtualHost *:443>
        ProxyPass / http://127.0.0.1/
        ProxyPassReverse / http://127.0.0.1/
        ProxyPreserveHost On

        SSLEngine On
        SSLProtocol all -SSLv2
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM

        SSLCertificateFile /path/to/ssl.crt
        SSLCertificateKeyFile /path/to/ssl-decrypt.key
        SSLCertificateChainFile /path/to/sub.class1.server.ca.pem
        SSLCACertificateFile /path/to/ca.pem
</VirtualHost>

With that config, SSL seems to work exactly like I want: all my sites have an SSL counterpart that acts just like the normal one, much like with Domino normally.

It's only been running like this a couple days, so we'll see if I run into any more trouble, but so far this seems to be a solid win for my hosting, other than the increase in memory usage. I'm looking forward to having another clustermate in the same location so I can try out the load balancing down the line.