Showing posts for tag "ssl"

A Welcome SSL Stay of Execution

Oct 21, 2014 5:52 PM

Tags: ssl

As you likely know from the torrent of posts on Planet Lotus on the topic, IBM announced a hopefully-imminent pair of updates to cover the two main SSL issues that have come to the fore recently: lack of SHA-2 support and the POODLE vulnerability in SSLv3. This is welcome indeed!

Personally, I'm going to stick with the nginx approach for HTTP, even in simple setups, because I've found the extra features you can get (and the promising new ones I haven't tried) to be a dramatic improvement in my server's capabilities. But in the mean time, I'm pleased that the pressure to investigate proxies for other protocols is lessened for the time being. It's not a full SSL revamp (the technote only mentions TLS 1.0 for Domino), but it's something to calm the nerves.

Nonetheless, it's been a good experience to branch out into better ways of running the server. I expect I'll eventually look into mail and LDAP proxying, both to get the highest level of SSL security and to see how useful the other features are (mail load balancing and failover, in particular, would be welcome in my setup).

Setting up nginx in Front of a Domino Server

Sep 18, 2014 1:08 PM

Tags: nginx ssl
  1. Setting up nginx in Front of a Domino Server
  2. Adding Load Balancing to the nginx Setup
  3. Arbitrary Authentication with an nginx Reverse Proxy
  4. Domino and SSL: Come with Me If You Want to Live

As I've mentioned before and now presented on, I'm a big proponent of using a reverse proxy in front of Domino. There are numerous benefits to be gained, particularly when you expand your infrastructure to include multiple back-end servers. But even in the case of a single server, I've found it very worthwhile to set up, and not overly complicated. This example uses nginx and Domino on Ubuntu Linux, but the ideas and some configuration apply much the same way on other OSes and with other web servers.

Domino

The first step involves a bit of configuation on the Domino server. The first is to move Domino off the main port 80, disable SSL, and, ideally, bind it to a local-only IP address. The port setting is familiar - I picked port 8088 here, but it doesn't matter too much what you pick as long as it doesn't conflict with anything else on your server:

The next step is to bind Domino to a local-only adapter so external clients don't access its HTTP stack directly. In this example, I have a LAN-only adapter whose IP address I named "terminus-local" in /etc/hosts, but I imagine "localhost" would work just fine in this case:

Once that's set, the last stage of configuration is to enable the WebSphere connector headers by setting a notes.ini property:

HTTPEnableConnectorHeaders=1

Enabling these will allow us to send specialized headers from our reverse proxy to Domino to make Domino act as if the request is coming to it directly.

After that, restart Domino (or just HTTP, probably).

nginx

Next, it's on to setting up nginx. On Ubuntu/Debian, it's pretty straightforward:

# apt-get install nginx

The main config file /etc/nginx/nginx.conf should be good as-is. The way the Ubuntu config works, you set up individual web site files inside the /etc/nginx/sites-available directory and then create symlinks to them in the /etc/nginx/sites-enabled directory. Out of convention, I name them like "000-somesite" to keep the priority clear. The first file to create is a site to listen on port 80, which will serve entirely as a redirect to SSL. You don't have to do this - instead, you could bring the content from the next file into this one instead of the redirection line. This is usually a good idea, though. This file is 001-http-redirect:

server {
	listen [::]:80;

	return https://$host$request_uri;
}

The only really oddball thing here is the "listen" line. Normally, that would just be "listen 80", but adding the brackets and colons allows it to work on IPv4 and IPv6 on all addresses.

The next file is the important one for doing the proxying, as well as SSL. It's 002-domino-ssl:

server {
        listen [::]:443;

        client_max_body_size 100m;

        ssl on;
        ssl_certificate /etc/nginx/ssl/ssl-unified-noanchor.pem;
        ssl_certificate_key /etc/nginx/ssl/ssl.key;

        location / {
                proxy_read_timeout 240;
                proxy_pass http://localhost:8088;
                proxy_redirect off;
                proxy_buffering off;

                proxy_set_header        Host               $host;
                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;
                proxy_set_header        $WSIS              True;
        }
}

The client_max_body_size line is to allow uploads up to 100MB. One thing to be aware of when using proxies is that they can impose their own limits on request sizes just as Domino does, and nginx's default is relatively low.

nginx's keychain format is almost as simple as just pointing it to your certificate and private key, with one catch: to have intermediate signing certificates (like those from your SSL provider or registrar), you concatenate the certificates into a single file. This tutorial covers it (and this config) nicely.

The core of the reverse proxy comes in with that location / block. In a more-complicated setup, you might have several such blocks to point to different apps, app servers, or local directories, but in this case we're just passing everything directly through to Domino. The first four lines do just that, setting a couple options to account for very-long-loading pages, to point to Domino, and some other options.

The proxy_set_header lines are the payoff for the connector headers we set up in Domino. The first is to pass the correct host name on to Domino so it knows which web site document to use, the second is a fairly standard-outside-of-Domino header for reverse proxies, and then the rest are a set of the available WebSphere (hence "$WS") headers, specifying what Domino should see as the remote address, the remote host name (I don't have nginx configured to do reverse DNS lookups, so it's the same value), the host name again, and whether or not it should act as being over SSL.

Once that's set, create symlinks to these files in the sites-enabled directory from the sites-available directory and restart nginx:

# ln -s ../sites-enabled/001-http-redirect
# ln -s ../sites-enabled/002-domino-ssl
# service nginx restart

Assuming all went well, you should be all set! This gets you a basic one-server proxy setup. The main advantage is the superior SSL handling - nginx's SSL stack is OpenSSL and thus supports all the modern features you'd expect, including SHA-2 certificates and the ability to serve up multiple distinct SSL certificates from the same IP address (this would be done with additional config files using the server_name parameter after listen). Once you have this basis, it's easy to expand into additional features: multiple back-end servers for load balancing and failover, better error messages when Domino crashes (which is more frequent than nginx crashing), and nifty plugins like GeoIP and mod_pagespeed.

Edit 2015-09-16: In my original post, I left out mentioning what to do about those "sites-enabled" documents if you're not running on Ubuntu. There's nothing inherently special about those directories to nginx, so a differently-configured installation may not pick up on documents added there. To make them work in an installation that doesn't initially use this convention, you can add a line like this to the /etc/nginx/nginx.conf (or equivalent) file, at the end of the http code block:

http {
    # ... existing stuff here

    include /etc/nginx/sites-enabled/*;
}

Domino SSL and Reverse Proxies

Aug 18, 2014 10:11 AM

Tags: ssl

Domino's SSL stack has been long-in-the-tooth and awkward to deal with for a while. Until recently, this has mostly just resulted in the sort of stilted way you have to set up SSL keychains, using the Server Certificate Admin database initially and then "IKeyMan" more and more (specifically, an old version you need 32-bit Windows XP for, like a barbarian), but the job eventually got done.

However, as a post from Steve Pitcher points out, this is becoming rapidly impractical. While I generally second his point that Domino's SSL stack needs a revamp, I believe that the primary importance of that will be for the "secondary" protocols - SMTP, IMAP, LDAP - that require SSL for responsible use. For HTTP, however, I'm on board with the spirit of IBM's proposed workaround - IBM HTTP Server - though not the unsuitable reality of a Windows-only implementation.

The reason for this is my general infatuation with reverse proxying over the last few years. It started, actually, with the amazing article PHP: a fractal of bad design, which is required reading on its own, but the pertinent part is in the section on deployment. In it, the author dings PHP for its traditional deployment method of "just jam it directly into the web server" and instead proposes the "reverse proxy in front of an app server" scenario as generally preferable and easy to do. Having seen just that sort of setup with recommended Ruby on Rails deployments - where the Rails app has a small, local-only HTTP server that a "real" server proxies to - that percolated in my mind for a while. Domino is, after all, primarily an app server, and so this criticism of PHP applies just as much to it. A little while later, I had a reason to try that setup in order to host two distinct app types on the same server (ironically - or irresponsibly - deploying that very type of bad PHP setup in the process).

Over time, I improved my setup by using the WebSphere connector headers to cause Domino to view proxied requests as if they were coming directly, using SNI to allow multiple distinct SSL certificates on a single host, adding GeoIP headers at the nginx level, and setting up a sticky-session load balancer to share access between multiple servers and silently fail over when one goes down.

I'm now at the point where I pretty much consider it irresponsible to not use a reverse proxy in front of a production Domino deployment.

Is setting this up as easy as just giving ports 80 and 443 to Domino? Nope, not at all. Is it difficult, though? Not really. I managed to set it up readily, and I'm no admin. Other than a few rough edges IBM should shave off of Domino (such as using the faux-SSL header switching to the crummy single-Internet-Site behavior), I've had the stated benefits and more of an IHS deployment for a long time and without having to use Windows in production. I strongly recommend that everyone view Domino as not a web server - instead, it's a back-end HTTP app server that can serve as a makeshift web server for development, but is best deployed behind a proper front end.

And totally coincidentally, I'll be giving a session on this very topic at MWLUG later this month (in the Open Source track). I'll specifically be discussing nginx, but the same principles would apply with other viable choices like Apache, IHS, or IIS.