Archive

Archive for August, 2011

Sending email as multiple identities with Gmail & Thunderbird

August 22, 2011 1 comment

I just figured this one out, and before I forget it.

I’ve been a user of Thunderbird’s Multiple Identities feature for a while. It allows you to send mail from a single account using multiple identities. So, for example, I have my personal email address for the majority of my email, but I have a second address which is really an alias for my wife and I which we give to day care, schools, etc. And when communicating with said entities I want the email to look as if it came from the alias.

I’m not sure when it changed, but recently even though I have set everything up the same way in Thunderbird, when the email was delivered to the receiver, it would show up as my primary address. Not good.

I immediately suspected the recent releases of Thunderbird, 5.0 & 6.0, but a few searches and I found nothing.

The only other change was switching over to Google Apps to host my personal domain email, I had done that a while ago though. But still poked around anyways.

And wouldn’t you know I found two settings, either one or both of them fixed the problem.

These are both in Mail Settings -> Accounts (note Mail Settings is under the Gear icon in the upper right)

  • First I added the email alias to my account by clicking on Add another email address you own link.
  • Second I set When replying to a message to Reply from the same address the message was sent to.

Not sure which of these fixed the problem, I suspect the second, but either way, now the receiver correctly sees the alias when I choose  to send mail as that identity.

Categories: Computing

SSL Termination, Load Balancers & Java

August 22, 2011 5 comments

So you got this killer Java web app you are developing, or you are deploying some super cool off the shelf application, and you decide to use some sort of SSL Accelerator to offload your HTTPS traffic, and it looks something like this:


Only things aren’t going so well. Maybe all the generated URLs for HTTPS connections are coming out as plain HTTP. Or your web app is attempting something clever and ntify when specific requests are plain HTTP and redirect them over to HTTPS, however even after redirection the app still tries to redirect again.

What Gives?

As you have probably guessed, the introduction of the SSL Accelerator has caused a problem because now all the incoming requests to your web app are coming in as plain HTTP, because HTTPS was terminated upstream somewhere and so your application server never knows about it.  In Java web applications, this generally manifests itself as HttpServletRequest.isSecure() always returning false, wreaking havoc in its wake. The Servlet machinery makes lots of decisions based on the value of isSecure(). All the way down to when you are defining security-constraint elements in web.xml and setting transport-guarantee to CONFIDENTIAL.

So What’s the Fix?

I’ve encountered this quite often, with various SSL Accelerators, Load Balancers and App & Web Servers. In general, the idea is to maintain separate paths for the requests all the way through to the app servers, like so:


In doing so, you can typically configure the back end web or app server to correctly identify the originating scheme of the request (HTTP or HTTPS).

Any Examples?

The Easy – Plain Ol’ Tomcat Backend.

By far the easiest container to work with is Apache Tomcat. The options available in a Connector clearly had this type of configuration in mind. Specifically these are

  • scheme – this tells Tomcat which protocol to use to create links, either http or https.
  • proxyPort – this tells Tomcat what to use as the real originating port, instead of the port the connector is listening on.
  • proxyHost – similarly, this tells Tomcat what to use as the real host name, instead of the host Tomcat is running on.
  • secure – this tells Tomcat whether the Connector is secure or not.
  • SSLEnabled – whether to configure the connector for SSL/TLS or simply Plain HTTP.

So, in the case where you are only using Apache Tomcat in your platform,

The correct configuration can be accomplished by creating two Connectors, one for port 8080 and one for port 8081. These would look like

<!--
     Define the connector on port 8080 to handle
     originating plain HTTP requests. Nothing
     special here. Make sure to set proxyPort
     and proxyHost to the appropriate values
     for your web site.
-->
<Connector port="8080" protocol="HTTP/1.1"
           maxThreads="150" clientAuth="false"
           SSLEnabled="false"
           scheme="http" secure="false"
           proxyPort="80" proxyHost="my.website.com"
/>

<!--
     Define the connector on port 8080 to handle
     originating HTTPS requests. Here we
     set scheme to https and secure to true. Tomcat
     will still serve this as plain HTTP because
     SSLEnabled is set to false.
-->
<Connector port="8081" protocol="HTTP/1.1"
           maxThreads="150" clientAuth="false"
           SSLEnabled="false"
           scheme="https" secure="true"
           proxyPort="443" proxyHost="my.website.com"
/>

And then, of course, configure your load balancer (and SSL Accelerator) to direct traffic to the appropriate ports.

A Little Harder – Tomcat with Apache Httpd

Introducing Apache Httpd into the mix really all that much harder than using simply Tomcat. Here’s the desired traffic pattern.

You may notice that HTTP protocol stops at the Httpd and then from Httpd to Tomcat the protocol switches to AJP. And then there’s the two streams coming into Httpd, but lets tackle Tomcat first. Its actually not very different at all from straight Tomcat.  The only difference is switching to AJP/1.3 for the protocol.

<Connector port="8009" protocol="AJP/1.3"
           maxThreads="150" clientAuth="false"
           SSLEnabled="false"
           scheme="http" secure="false"
           proxyPort="80" proxyHost="my.website.com"
/>

<Connector port="8010" protocol="AJP/1.3"
           maxThreads="150" clientAuth="false"
           SSLEnabled="false"
           scheme="https" secure="true"
           proxyPort="443" proxyHost="my.website.com"
/>

Now, for Httpd. This is solved by setting up a separate virtual servers for each port, and passing them off to the appropriate Tomcat Connector using mod_jk and separate worker pools for each Tomcat Connector.

JkWorkersFile /etc/httpd/conf/workers.properties

<VirtualHost *:80>
    DocumentRoot /var/www/html
    ServerName my.website.com

    JkMount /webapp/* tomcat-8009

</VirtualHost>

<VirtualHost *:81>
    DocumentRoot /var/www/html
    ServerName my.website.com

    JkMount /webapp/* tomcat-8010

</VirtualHost>

And now the workers.properties file.

worker.list= tomcat-8009, tomcat-8010

worker.tomcat-8009.type=ajp13
tomcat.tomcat-8009.host=server1
tomcat.tomcat-8009.port=8009

worker.tomcat-8010.type=ajp13
tomcat.tomcat-8010.host=server1
tomcat.tomcat-8010.port=8010

And that’s it. The one caveat here, is that although originating from HTTPS and plain-HTTP follow different paths even through Httpd, Httpd doesn’t really know that. So if you are doing anything interesting other than serving static content from Httpd, you may have an issue, for example if you are running PHP or something else that may need to care, you may be out of luck.

The Difficult – Less Configurable Application Servers

The Tomcat team as really taken a lot of time to provide a highly configurable platform, but what if this is not your target deployment platform, and you are faced with attempting to do SSL Termination on a platform that isn’t so helpful. One example that I’ve got a bunch of experience with is what was called Sun Java System Web Server and now Oracle iPlanet Web Server. Although I did enjoy working with it, the platform did not provide such an easy method of integrating an external SSL Accelerator.

But all is not lost. Fortunately Java Servlets version 2.3 and newer provide some facilities that can help. Servlets 2.3 provide two interesting features, Filters and Wrappers.

Filters provide a method for you to do some pre-processing of requests before your Servlets, JSP and anything else is invoked (they also can do post-processing but we don’t need that here.)

Wrappers provide a method for you enclose a Request or Response in your own object.

The two, together can help you fake the Java machinery into setting HttpServletRequest.isSecure() and HttpServletRequest.getScheme() into returning the correct values depending on the original protocol.

Lets look at creating a Wrapper first. Its as simple as

public class FakeSecurityRequestWrapper extends HttpServletRequestWrapper {
    public FakeSecurityRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    public boolean isSecure() {
        return true;
    }

    public String getScheme() {
        return "https";
    }
}

Pretty trivial. Now to create a Filter to inject the wrapped Request into the machinery.

public class FakeSecurityFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {

        FakeSecurityRequestWrapper fakereq =
            new FakeSecurityRequestWrapper(req);
        chain.doFilter(fakereq, res);
    }
}

Now just plumb this up in your Web App’s web.xml as the first filter in the chain, and you are there. Well, most of the way there. there’s the opposite problem now. Every request, no matter what the originating protocol, appear to be HTTPS. In a mixed protocol environment, that is still a problem.

No worries, we can do it! Yes, with a little more tweaking, it should be possible to support a mixed protocol environment.

And its with a little trick from the load balancer or SSL Accelerator. Most of them that I have run into allow you to modify the request as its passing through the appliance. To the idea is to insert a Header into the HTTP request for request that have gone through the SSL Accelerator. A typical flow would look something like this.


I won’t go into the configuration on the SSL Accelerator/Load Balancer end, but lets look at enhancing the Filter to handle mixed protocols. In this example, we’ll assume the Accelerator/LB sets the header X-Original-Protocol to https for requests coming through it. The doFilter() method becomes

    public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {

        String origProto = req.getHeader("X-Original-Protocol");
        if (origProto != null && origProto.equals("https")) {
            FakeSecurityRequestWrapper fakereq =
                new FakeSecurityRequestWrapper(req);
            chain.doFilter(fakereq, res);
        } else {
            chain.doFilter(req, res);
        }
    }

Voila. Now the Java Servlet machinery should be handling a mixed protocol environment just fine. This technique should work with just about any web container, be it WebLogic, JBoss, SJSWS/IWS or GlassFish.

Its arguable whether this method is more straight forward than the other previous methods, but it does have it down sides, which for me, make it less desirable. It does require a little programming, and needs actively integrated into each web app you are deploying and I don’t like having to muck with 3rd party web.xml files if I don’t need to, and for that I leave this as a last resort option.

I’m sure there are other techniques for working with SSL Accelerators, these are just the methods that worked for me so far. Hope others find them useful.

Categories: Computing