Thursday, July 2, 2009

HTTPS Virtual Hosts in Apache

Running multiple web sites that allow HTTPS connections on the same Apache httpd server is problematic. Typically, virtual servers (the individual web sites) use named virtual hosting, where the virtual host which serves the site is chosen based on the host name specified in the HTTP Host header. Named virtual hosting does not work for HTTPS because the server cannot interpret the Host header until the connection has been made, and making the connection requires the completion of the SSL encryption handshake used by HTTPS; SSL certificates (without extensions) can only have a single server host name as their subject, and thus the certificate and connection will only work for a single host name. As a result, the named virtual hosting mechanism never has a chance to operate on the incoming connection and the only remaining way to host multiple sites is to add multiple IP addresses to the host and use IP-based virtual servers.

The keys to supporting multiple sites using HTTPS and name-based virtual hosting are to use either wildcard names (specified in RFC2818) or the x509 version 3 certificate (specified in RFC3280) subject alternative names extension. I have not used wildcard names, although they allow one certificate to work for any number of hostnames below a given domain: *.example.com would allow any of a.example.com, foo.example.com, or elbow.example.com, but would not work for right.elbow.example.com or www.google.com. Wildcard certificates are much more expensive than standard certificates and are not administratively available in my particular work domain.

Subject alternative names, a.k.a. subjectAltNames, allow a certificate to list a number of host names for which it is valid. For example, a single certificate with www.example.com as its (single) subject could list www.example.com, www.example.org, and webapp.example.com as alternate names; the certificate would be recognized as valid for any of those host names.

Generating subjectAltName certificates



Convincing openssl to generate a certificate or certificate signing request requires changes to the openssl.conf file:

  1. Enable extensions:

    [req]
    req_extensions = v3_req

  2. Add a v3_req section including the subjectAltName field:

    [ v3_req ]
    subjectAltName = @alt_names

  3. List the host names in the proper format in the v3_req section:

    [alt_names]
    DNS.1 = web.example.com
    DNS.2 = dspl.example.com
    DNS.3 = nprop.example.com
    DNS.4 = webdir.example.com
    DNS.5 = hpps.example.com
    DNS.6 = remoteuser.example.com
    DNS.7 = esm.example.com
    DNS.8 = etsapprover.example.com
    DNS.9 = ep.example.com
    DNS.10 = cas.example.com
    DNS.11 = wat.example.com
    DNS.12 = ned.example.com

For more information, see Creating a Certificate With Multiple Hostnames and a discussion from the OpenLDAP list.

Apache mod_rewrite



There are at least two ways of configuring httpd to handle multiple web sites with a single certificate. One resembles the normal name-based virtual hosting (with the VirtualHost directive and everything); the other is the one I have used.

In the first, set up httpd to listen on port 443 and to present the certificate with the subjectAltNames:

NameVirtualHost *:443
Listen 443
SSLEngine On
SSLCertificateFile /etc/....
SSLCertificateKeyFile /etc/.....

Then, add all of the necessary named virtual hosts normally, making sure that they are listening on port 443:


ServerName foo.example.com
# Configuration for web site foo.example.com



ServerName bar.example.com
# Configuration for web site bar.example.com


Now, I have not actually done this, but it looks like it should work.

What I have done is used subjectAltName certificates with a reverse proxy httpd configuration, where each of several applications in an application server appears to have its own server name:

Listen 443
SSLEngine On
SSLCertificateFile /etc/....
SSLCertificateKeyFile /etc/.....

RewriteEngine On

RewriteCond %{HTTP_HOST} ^foo\..*$
RewriteRule ^(.*) http://127.0.0.1:8090/foo-2.2$1 [P,L]

RewriteCond %{HTTP_HOST} ^bar\..*$
RewriteRule ^(.*) http://127.0.0.1:8090/bar-2.2$1 [P,L]


Issues



There are a couple of caveats: when present, the subject alt names list may or may not replace the actual subject of the certificate; if a host name is present only in the certificate subject field and is absent from the subjectAltName field then the browsers I have tried will not recognize the certificate as valid for the host name. Not all clients support subjectAltNames; see SAN Certificates: Subject Alternative Name. Further, there are possibly some security issues with multi-host certificates. Check Phishing for Confirmations for details.

Saturday, June 20, 2009

Steve Vinoski, REST, and distributed systems

Steve Vinoski, co-author of Advanced CORBA Programming with C++, has a couple of podcasts that I just discovered; based on his columns in Internet Computing, Welcome to "The Functional Web", and Scala and Lift - Functional Recipes for the Web. While poking around, I ran across a few previous columns that I wish everyone I work with who deals with distributed systems (i.e. everyone I work with) would read.

The latter, in particular, has this gem:
Developers who favor technologies that promote interface specialization typically raise two specific objections to the REST uniform-interface constraint. One is that different resources should each have specific interfaces and methods that more accurately reflect their precise functionality. This is rooted in the fact that most programming languages (especially those that are object-oriented) promote the development of specific interfaces, procedures, and methods for different software artifacts. This notion is so ingrained in many developers’ minds that they consider it counterintuitive to apply a uniform general-purpose interface to anything — even to the heterogeneous services and resources found in a typical distributed system. Yet, those who raise this objection fail to properly consider the effects of networking and distribution.

...thus summing up roughly thirty years of what's-wrong-with-RPC arguments.

Wednesday, March 25, 2009

Adobe Flex Messaging (or BlazeDS) Vs. OSGi

Although I have not finished my series on creating JRuby on Rails applications using OSGi and the SpringSource dm Server, I have moved on a bit to converting a small number of Adobe Flex applications to the server platform. (Adobe Flex, the Flash-based application development platform. Not flex, the lexical analyzer thing that goes with Bison.)

I do not want to go into all of the details of our framework/stack/platform/thingy that I am adapting the Flex applications for, but I do want to provide a quick description of what I needed to do to deploy the Flex app in our framework.

SSdmS will deploy any .war file I have run across, but to integrate it into the OSGi environment I did need to add some metadata to the MANIFEST.MF:

Bundle-SymbolicName: my.webapp
Bundle-Version: 2.0.0
Bundle-Name: webapp
Bundle-Classpath: WEB-INF/classes,WEB-INF/lib/my.servicelocator-0.0.3.jar
Import-Package:
javax.servlet;specification-version="[2.4.0,3.0.0)",
javax.servlet.http;specification-version="[2.4.0,3.0.0)",
org.osgi.framework;specification-version="[1.4.0,2.0)",
org.osgi.util.tracker;specification-version="1.3.3",
...
flex.messaging; version="[3.0.0.544,4.0)"
Bundle-Activator: my.osgi.OsgiServiceProvider
Module-Type: Web
Web-ContextPath: /webapp
Eclipse-RegisterBuddy: flex-messaging

Most of the additions are typical: Bundle-Name, Bundle-SymbolicName, etc. The Bundle-Classpath I modified to add a service locator package that provides the interface between our application and our framework. That package also provides the Bundle-Activator and requires a small stack of packages to be imported. Module-Type and Web-ContextPath are extensions for the SSdmS. Eclipse-RegisterBuddy I will get to in a minute.

Note: On my OSGi wishlist is a way to look into contained jar files to find Import-Package statements that should be added to the containing jar file. For example, org.osgi.framework is not needed by any of the application code, but is needed by the my.servicelocator jar; it would be nice if the requisite Import-Package statements did not have to live in the application's manifest. (And yes, the service locator kind of needs to live in the application bundle, although I might be able to revisit that.)

The one package I am importing there that is important is flex.messaging, which comes from a flex-messaging bundle. The flex.messaging package provides access to everything this application needs from the Flex messaging system, specifically flex.messaging.MessageBrokerServlet and flex.messaging.HttpFlexSession, both mentioned in the web.xml configuration file.

What does the flex-messaging bundle look like? Here is the bnd file I used to create it:

-classpath: \
../orig/flex-messaging-common.jar, \
../orig/flex-messaging-core.jar, \
../orig/flex-messaging-opt.jar, \
../orig/flex-messaging-proxy.jar, \
../orig/flex-messaging-remoting.jar, \
../orig/cfgatewayadapter.jar

Bundle-SymbolicName: flex-messaging
Bundle-Name: BlazeDS - Common Library
Bundle-Version: 3.0.0.544
Export-Package: \
!coldfusion.*, \
*;version=${Bundle-Version};-split-package:=merge-first
Import-Package: \
coldfusion.flex.rmi; resolution:=optional, \
com.ibm.*; resolution:=optional, \
edu.emory.mathcs.backport.java.util.concurrent.*; version="[3.0.0,4.0)", \
flex.data.messages; resolution:=optional, \
jrun.*; resolution:=optional, \
jrunx.*; resolution:=optional, \
oracle.security.jazn.*; resolution:=optional, \
org.apache.commons.httpclient.*; version="[3.0.1,4.0)", \
org.apache.xpath.*; version="[2.7.0,3.0)", \
org.jgroups.*; resolution:=optional, \
weblogic.*; resolution:=optional, \
*
Private-Package: coldfusion.*
Eclipse-BuddyPolicy: registered,dependent


Yes, I am sucking all of the gunk from a stack of jar files into this single bundle: all of the Flex messaging stuff seems to be fairly closely interrelated and I don't see any of our applications using any single part of it without also needing most. I am exporting all of the flex.* packages and importing the stuff I recognize at specific versions and the stuff I have never heard of optionally.

Now, I maintain a list, the Big List o' Evil. On this list, I put things that I see as, well, evil. Not just small evil, though, like cell phones and black licorice. Big evil, like persistent objects, Sun's Access Manager stuff, and (important in this case) remote procedure calls. RPC (and related things like CORBA and SOAP) are not only the wrong way to do networking, they are seductive. They seem to work, they seem to make things easy, then they rip off your leg, rub the bloody stump in margarita salt, and set out to club your puppy with your own ex-appendage.

In this particular case, Adobe Messaging Framework is serializing an object on the browser, Flash side and sending the serialization across the wire to be re-inflated into a Java object on the server side. The specific problem is that the de-serialization code needs access to a class from the application bundle, but the de-serialization code lives in the flex-messaging bundle and has no way to get at the application's class. ClassNotFound! (The new "Fail!")

Anyway, adding the "Eclipse-BuddyPolicy: dependent" header to the flex-messaging solves the problem by reversing the incoming links to the flex-messaging bundle: when it needs an application class, it (eventually) follows the "flex.messaging" imports back to the application bundle and finds the application class. To do this, it is using an Eclipse Equinox-specific hack, although I understand the new standard work from OSGi might possibly address something like this issue.

I added the "registered" buddy policy and the Eclipse-RegisterBuddy header in an attempt to speed up the lookups. It also marks the application bundle as somehow special. (A scarlet RegisterBuddy?)

[Later....]

Yes, and I just got bitten by what I think is the Class.forName caching problem. Buddy classloading works fine, until the web application is updated without restarting the server. Then message de-serialization fails silently until the server is restarted. I have checked the source, and BlazeDS is using Class.forName.

I suspect at this point I am hosed and every Flex web application is going to have its own copy of the assorted messaging jars.

Monday, March 23, 2009

Updated the "Developing for SpringSource dm Server in Eclipse" post

I have updated the Developing for the SpringSource dm Server in Eclipse introduction with the new URLs and file names.

[24 March 2009] ....and Corey just pointed me to http://www.springsource.org/spring-ide-2.2.2, which announced new, consolidated versions of Spring IDE and dm Server Tools, along with a new update site.

Wednesday, February 4, 2009

Edsger Dijksta

I was poking around on the 'net, looking for fountain pen information to match the snazzy Pilot Petit 1 from JetPens that I just bought, when I ran across a mention of Prof. Dijkstra and his fascination with fountain pens and ink. I seem to recall a story about his experimentation with inks in order to find a formulation that was suitably archival, which reputedly led to fame in the ink world. In any case, what I tripped over was this paragraph from EWD 951:
The winter will, however, go down into the Books of History as "The Winter in which We Found the Old Mont Blancs". I love my Mont Blanc but for many years am aware of the fact that the company stopped making this model about a decade it is the model with the built-in pump that takes much more ink than its replacement, which accepts cartridges as well. Since it is nice to have a spare, it has become second nature for me to try new models whenever I encounter them. One afternoon I went to the village stationery shop to buy European staples, saw a new Mont Blanc, tried it and did not like it, when the saleslady behind the counter said with great hesitation "When you object to using an ink pot, I have another model, but it is very old.....". The dear soul sold me her treasure for the original price. After that find Ria suggested that we should try that other branch in Someren, where Netty van Gasteren and Wim Feijen bought the remaining three copies. They too still had their original price tags and were even cheaper; on top of that they even got fl. 10,- discount per pen! So much for the stationery shops in little Brabantian villages.

I feel better about my collection of IBM "clicky" keyboards, purchased cheaply or outright stolen.
Needless to say, I bought myself a typewriter the other day, a Triumph/ "satellite III". It is electronic and in its more advanced features so user-friendly that the corresponding sections in the (46-page!) manual are utterly baffling. So far, the alphabet works.

Wednesday, January 28, 2009

Combinator?

I just ran across some comments in the online Real World Haskell about the pronunciation of "combinators". Since I've wondered about that myself (and know I've gotten it wrong before), here are the comments:


Tim Stewart 2008-02-26

Is there an official pronunciation of combinators? I took a poll in #haskell once and com-bine-uh-tors won, with com-bin-ay-tors in second place.


none 2008-06-04

I've sometimes heard com-BIN-a-tor but it's sounded pretentious. I say it sort of like one would say "terminator". I've never heard com-bine-uh-tor.


Now, "com-bine-uh-tor" sounds like an evil robot from an animated TV series to me. I'm going with "com-bin-ay-tors", with the accent on the "ay". Maybe.

Saturday, January 10, 2009

Scala problem #1

I have been playing off and on with Scala, and overall I like the language so far. It seems to decently satisfy the constraints of compatibility with the JVM and those of a reasonably modern language. However, while reading chapter six of Programming in Scala, I think I have spotted a potentially irritating problem.

One thing I note about Scala is that its designers went out of their way to fight the verbosity inherent in Java. Many of the syntactic features of Scala appear to be present only to make common cases terse. (That is both a strength and weakness of Perl, although I usually find it a weakness. To recognize it in a language that has actually been designed is disquieting.)

Consider class parameters and the primary constructor built from them and the body of a class. These features allow a simple, minimal, immutable class to be written simply as:

class Rational(n:Int, d:Int) {
override def toString = n + "/" + d
}

The n and d parameters automatically become final fields of the generated class, set by the generated primary constructor. Disassembling the class with javap -private produces:

Compiled from "test.scala"
public class Rational extends java.lang.Object implements scala.ScalaObject{
private final int d;
private final int n;
public Rational(int, int);
public java.lang.String toString();
public int $tag() throws java.rmi.RemoteException;
}


One downside to class parameters is that, as fields, they cannot be accessed by other objects of the same class as in:

def add(that:Rational):Rational = new Rational(n * that.d + that.n * d, d * that.d)

The expression "that.d" will not compile. For that and possibly other reasons, it is possible to introduce explicit fields into the class:

class Rational2(n:Int, d:Int) {
val numer = n
val denom = d
override def toString = numer + "/" + denom
}


Given this code, the expression "that.numer" would compile and work correctly. Further, Programming in Scala notes,

Even though n and d are used in the body of the class, given they are only used inside constructors, the Scala compiler will not emit fields for them. Thus, given this code the Scala compiler will generate a class with two Int fields, one for numer and one for denom.

javap shows the result:

Compiled from "test.scala"
public class Rational2 extends java.lang.Object implements scala.ScalaObject{
private final int denom;
private final int numer;
public Rational2(int, int);
public java.lang.String toString();
public int denom();
public int numer();
public int $tag() throws java.rmi.RemoteException;
}


However, what happens if, when you are introducing the explicit fields, you forget to remove all of the references to the class parameters?

class Rational3(n:Int, d:Int) {
val numer = n
val denom = d
override def toString = n + "/" + d
}

(Note the use of n and d in toString.) javap now produces:

Compiled from "test.scala"
public class Rational3 extends java.lang.Object implements scala.ScalaObject{
private final int denom;
private final int numer;
private final int d;
private final int n;
public Rational3(int, int);
public java.lang.String toString();
public int denom();
public int numer();
public int $tag() throws java.rmi.RemoteException;
}


There are four fields in the resulting object. In this case, there is no problem, since denom and d are initialized to the same values and are final (and likewise numer and n). But another reason to use explicit fields is to allow them to vary, to not be final.

class Rational4(n:Int, d:Int) {
var numer = n
var denom = d
override def toString = n + "/" + d
}

The resulting code makes numer and denom non-final, and other methods can alter them. However, toString will always print the values of n and d set when the object was constructed. Whoopsie.