Calling all apache + tomcat configuration experts
April 2, 2018 9:43 PM   Subscribe

Now that Let's Encrypt supports wildcard certificates, I want to move away from using GoDaddy forwards to something native to our apache + tomcat installation that will allow subdomains to be "sticky" masks for tomcat instances. I've been playing with configuration files all day and can't find the right combination of knobs.

I have a web application, call it MyApp, that has several versions running (say, MyApp-Prod, MyApp-Test, MyApp-Dev). It is housed as Tomcat instances that are served by Apache 2.4 + mod_jk, so there's an ajp connector set up for each.

These are accessible at https://example.com/MyApp/, https://example.com/MyApp-Test/ and https://example.com/MyApp-Dev/ (for SSL). They also accept non-SSL connections so that I can use GoDaddy's DNS forwarding service to make http://customer1.example.com/ be a sticky (masked) alias for one of the 3 endpoints (say, http://www.example.com/MyApp/). I do this because some customers are more beta software-friendly and can be pointed at one of the less-stable versions (and sometimes this is only temporary); this way they can just bookmark http://customer1.example.com/ and never have to worry about it. That's worked okay but I'd like to move wholly onto HTTPS; now that Let's Encrypt let me get a wildcard cert for *.example.com I think this should be possible with the right magic setup of apache + mod_jk + mod_proxy. So here's what I want to do, and I can't seem to come up with the right combination of things to do it:

1) Have the apache server handle all the SSL and just handle the tomcat-served content via AJP.
2) Be able to setup up proxying so https://customer1.example.com/ really resolves as https://www.example.com/MyApp/ (or is handled by that tomcat context, anyhow). This includes rewriting stuff coming back from Tomcat to map www.example.com/MyApp/ appropriately.
3) Say I have a single-serving JSP page doing some special thing at https://www.example.com/MyApp/foo/singleServing.jsp -- can I make http://bar.example.com/ point at just that app?

Things I've tried: About umpteen variations on ProxyPass; disabling tomcat requiring secure connections (it's ok if the apache -> tomcat part is insecure, they're on the same machine/private network); RewriteEngine rules to rejigger bits of requests; setting up a Connector in the tomcat server.xml file with proxyName="foo.example.com".

Some things work, e.g., rewrite rules to force non-SSL requests over to HTTPS. I have sometimes gotten (e.g., ProxyPass will serve a page like www.example.com/MyApp/foo/singleServing.jsp as its index, but all the [relative] references on the page don't resolve properly).

Anyone know what I'm missing or can point me to a good tutorial? Lots of stuff is googlable on sub-problems but I think the addition of SSL to the mix is making my particular problem a mismatch for a lot of the stuff I've seen on stackoverflow and the like.
posted by axiom to Computers & Internet (5 answers total) 1 user marked this as a favorite
 
Response by poster: s/MyApp-Prod/MyApp/g
posted by axiom at 10:49 PM on April 2, 2018


So you say you already run separate Tomcat instances for each version of your app. Is there any reason why you can't just deploy each app to the root of Tomcat (i.e., at / rather than /MyApp/ or /MyApp-Dev/, etc.) and just configure Apache to proxy each host to the root of the desired Tomcat instance via port number? That way you don't really need to worry about URL rewriting, which is probably where most of your issues are.
posted by bunyip at 10:54 PM on April 2, 2018 [1 favorite]


I would highly recommend you put nginx in front of your Tomcat installs. It can easily handle the ssl and url rewrites.
posted by pyro979 at 4:28 AM on April 3, 2018


Response by poster: Sorry, I meant individual tomcat contexts, not instances. Only one server process. I was able to work around some of my issues by creating a separate service container for each and putting them each as the ROOT webapp in each service. I'm still experimenting with possibilities with mod_rewrite.
posted by axiom at 7:19 PM on April 4, 2018


Best answer: I eventually figured it out. In case anyone finds this page in the future, here's the crux of an apache conf file setting up a vhost mapping foo.example.net to www.example.net/myapp:
<VirtualHost *:443>
  ServerName foo.example.net
  ServerAdmin support@example.com

  SSLEngine on
  SSLCertificateFile /etc/letsencrypt/live/example.net-0001/cert.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example.net-0001/privkey.pem
  SSLCertificateChainFile /etc/letsencrypt/live/example.net-0001/chain.pem

  ProxyRequests Off
  ProxyPreserveHost On
  ProxyHTMLEnable On
  ProxyHTMLExtended On
  SSLProxyEngine On
  #expand, proxy, then recompress gzip streams
  SetOutputFilter INFLATE;proxy-html;DEFLATE
  #these also result in gzip handled properly, but are slower
  #RequestHeader unset Accept-Encoding
  #ProxyHTMLCharsetOut *

  <Location "/">
    ProxyPass https://www.example.net/myapp/
    ProxyPassReverse https://www.example.net/myapp/
    ProxyPassReverseCookieDomain "www.example.net" "foo.example.net"
    ProxyPassReverseCookiePath /myapp /
  </Location>

  <Location "/myapp/">
    ProxyPass https://www.example.net/myapp/
    ProxyPassReverse https://www.example.net/myapp/
    ProxyPassReverseCookieDomain "www.example.net" "foo.example.net"
    ProxyPassReverseCookiePath /myapp /myapp
  </Location>

</VirtualHost>
There are two proxies, one for the root and one for /myapp/, because the app pages will sometimes use references like <img src="/myapp/images/pic.png"> and I didn't want to replace all of those to cope.
posted by axiom at 8:56 PM on April 7, 2018


« Older Derelict house next door being rehabbed. What do I...   |   Gender neutral, trans inclusive resources on... Newer »
This thread is closed to new comments.