I have set up an Apache Web Server 2.4 to act as a proxy for Apache Tomcat 7, communicating via the AJP protocol (mod_proxy_ajp on the Apache side and an AJP connector on the Tomcat side). Everything works great for basic functionality.
Now, I am looking to set some specific AJP attributes, but can't quite get it to work...
Looking at the mod_proxy_ajp page (http://httpd.apache.org/docs/current/mod/mod_proxy_ajp.html), under the Request Packet Structure section, I see a listing of attributes. These attributes include the likes of remote_user, and ssl_cert (code values 0x03 and 0x07, respectively). There is also an "everything else" attribute called req_attribute with code value 0x0A that can be used to set any arbitrary attribute in an AJP request.
Further, on the same page, under the Environment Variables section, it states the following:
Environment variables whose names have the prefix AJP_ are forwarded to the origin server as AJP request attributes (with the AJP_ prefix removed from the name of the key).
This seems straightforward enough, and indeed, I am easily able to set an arbitrary AJP attribute such as "doug-attribute" by setting an Apache environment variable called "AJP_doug-attribute", and assigning a relevant value. After doing such, I can analyze the traffic using Wireshark, and see the "doug-attribute" field show up in the dissected AJP block, prefixed with a hex value of 0x0A (the "req_attribute" type listed above). So far so good.
Now I want to try to set the ssl_cert attribute. In the same fashion, I set an environment variable called "AJP_ssl_cert". Doing so, it does show up in Wireshark, but with prefix code "0x0A". Further, my Java application that wants to read the "javax.servlet.request.x509certificate" does not find the certificate.
However, I also notice some other attributes in the Wireshark capture that are listed on the website, like ssl_cipher and ssl_key_size. But in the capture, they show up as "SSL-Cipher" and "SSL-Key-Size" (and have the appropriate "0x08" and "0x0B" prefix codes). So, I try setting the cert attribute again, this time as "SSL-Cert", but I get the same results as before.
To compare, I altered the Apache configuration to require client certificates, and then provided one in the browser when visiting the associated web page. At this point, I look at the Wireshark capture, and sure enough, there is now an attribute named "SSL-Cert", with code "0x07", and my web application in Tomcat is successfully able to find the certificate.
Is there any way that I can manually set the attributes listed on the mod_proxy_ajp page, or does the module handle them differently from other arbitrary request attributes (like "doug-attribute")? I feel like there must be something I am missing here.
As some background, the reason that I am trying to do this is that I have a configuration with multiple Apache web servers proxying each other, and then at the end, an Apache web server proxying to a Tomcat instance via AJP. All the Apache web servers use SSL and require client certificates. With just one Apache server, Tomcat can receive the user's certificate just fine without any special configuration on my part. However, with multiple, it ultimately receives the server certificate of the previous Apache proxy (set on that machine using the SSLProxyMachineCertificateFile directive).
What I am hoping to do is place the original user's certificate into the headers of the intermediate proxied requests, and then manually set that certificate in the AJP attributes at the back end so that the web application in Tomcat can read the certificate and use it to perform its authorization stuff (this part is already set in stone, otherwise I would just add the certificate as a header and make the Java app read the header).
EDIT: of course, if there is an easier way to accomplish passing the user's certificate through the proxy chain, I'd be more than happy to hear it! :)
Related
here is my setup. I have 4 servers
ARR
Node1
Node2
Node3
I have set the nodes up to use a shared configuration and have set the ARR box up to have a central certificate store ( followed the docs on msdn ). On the ARR box there is a DefaultWebsite as per the standard IIS installation. It has a binding that matches all HTTP traffic ( ie no domain specified ). There is also a ARR rule ( set up by default ) that points all requests to my server farm. Everything is working perfectly for normal HTTP traffic, but when I try HTTPS the requests fail ( browser gives ERR_CONNECTION ). I have stuck to all the defaults an no joy. I have multiple sites with multiple certificates, so I have made sure that all HTTPS bindings on the node are set to use SNI and the CCS. Still HTTPS does not work. However, if I add the HTTPS binding on the ARR box, then the requests go through correctly.
Surely that behavior is not correct? I can't manage https bindings on the ARR box and then all other bindings through a shared config setup? I was under the impression that the ARR box should not even need to have a single site configured, it should simply pick up the request, match the ARR rule and then delegate off to one of the nodes?
Am I missing something here, any help would be greatly appreciated
I think it might have something to do with SSL offloading. When I disable that, I get an error 502 response.
Could it have something to do with compression? I zip all responses using a filter, but surely then even http traffic would fail?
so things always look better in the morning. After a couple hours of googling and several re-installs of IIS I finally found the issue. I had deleted the "Default Website". Then in order to get ARR back up I added back a default website. This allowed all wildcard HTTP traffic through to the server farm. When I tried to add a default HTTPS binding however, the IIS config management console forces you to put in a domain name, which doesn't work if you want a "default" implementation.
So to get around this, I simple manually edited the applicationHost.config file and removed the domain name from the binding entry :
<binding protocol="https" bindingInformation="*:443:" sslFlags="3" />
and that's it....happiness!
I had that error too while migrating a single proxy configuration with multi-sites to a ccs + shared config server.
It happens that the default web site configuration did not import correctly and the https binding did not have a certificate assigned.
I assigned a certificate and the error went away.
I have a few tomcats load balanced behind a VIP(virtualIP) and Apache is configured to talk via AJP to the tomcat VIP. There is a need to know which tomcat served the request for debugging/monitoring purposes. And so the tomcat instance that served the request should ideally send a unique response header .
However I dont see how I can achieve that without writing custom filter code to do that. Ideally I want this unique header value to reside in tomcat conf/properties folder.
Any suggestions ?
We are trying to incorporate ClickTale for our site which is hosted on Acquia. But there seems to be a problem and we would like to hear from people over here if they have come across a similar situation.
We already have HTTPS enabled.
Because of HTTPS, we had to change
our DNS setting from an A record to a CNAME record.
Now based on
this ClickTale Wiki -
http://wiki.clicktale.com/Article/Help_talk:Drupal_integration_module_v1...
whenever we have a reverse proxy, we need to make sure that the IP
address of the proxy is allowed which would mean ClickTale servers
be able to identify the IP address of the end user.
Because we have a CNAME record, we have a canonical URL but we dont have an IP.
How do we deal with this situation? If we do not do anything, will Acquia servers ensure that the right headers are in place such that ClickTale servers could read end users IP?
As per Acquia documentation they use the X-forwarded-for header to forward you the client IP, see https://docs.acquia.com/articles/logging-client-ip-apache-behind-reverse-proxy
So from the doc you quote yourself, i would enable the following:
If your proxy includes the original IP address in the HTTP headers, you could add a module setting in your config.php file to instruct the module to use that header. If your proxy uses a header field called "X-Forwarded-For" (this is common), then add $config['IPAddressHeaderFieldName'] = "X-Forwarded-For"; to your config.php file to utilize this field.
I am trying to integrate the liferay tomcat with apache web server.I successfully integrate the liferay with web server.
Condition:
Life ray deployed on ip say : 10.10.10.70
Apache web server on ip say: 10.10.10.80
I provided all the requirement virtual host requirement in httpd.conf file..and provided the web.server.host in portal-ext.properties file.
Problem: When i run liferay portal i can open it on ip: 10.10.10.70
but when i click on any page link (let say /home)that is present in my portal it moved the request to
10.10.10.80:8080/home instead of 10.10.10.70:8080/home
I want to know how to handle this condition.
Because i dont have any page resource on web server doc folder only contain static css..
You might be a bit more precise what "all the required virtual host settings" are, e.g. what did you configure?
Note that by explicitly configuring hostnames/IP-addresses, you're explicitly overriding the autodetected settings from the request - no matter how you get to your portal, Liferay will generate URLs based on the explicitly configured hostname/port.
What's the point in having an Apache in front and then trying to reach tomcat through the non-apache IP/Port? Typically you might have static resources, rewrites, caches on Apache, so that you'll get different results when you alternatively access tomcat through both URLs.
If you configure Apache to "properly" handle the requests before tomcat sees them, you'll typically not need to configure Liferay at all, because Apache will make the actual hostname that it's requested under available to Tomcat. I'm typically using mod_jk for this and it beautifully handles all the configuration with almost no need to explicitly configure tomcat/liferay. If you don't like this, keep in mind that you're explicitly configuring Liferay for the virtual host setup - naturally this explicitly configured name is what Liferay uses. It would be weird if the explicit value would not be used, right?
I'm trying to use Liferay for http and https
if I include in portal-ext.properties:
company.security.auth.requires.https=true
web.server.protocol=https
Will be working ok with https but in http is showing incorrect themes due is trying to load https://domain.com/theme
If I remove this two lines is working ok for http but not for https.
What can I do?
IMHO mixed mode, e.g. offering http as well as https never gives you what you expect: You expect security from https, but you always risk leaking session information, e.g. being vulnerable to session-hijacking attacks (ala Firesheep). My actual advice would be to go https only if you do https for security. Read on if that's not an option for you, but don't complain when you find information leaking (this is not dependent on Liferay, but for any web-based environment)
What is the exact problem that you have with the themes? (images/css through http?) Which version of Liferay are you using?
Before you specify more, you might want to configure your theme's "virtual path", this will rewrite all the URLs referring to your theme. It's typically used to serve static resources through a webserver or cdn, but it works with any kind of URL. Simply using a protocol-relative URL should work (I love this mostly unknown http feature):
Add this to your theme's liferay-look-and-feel.xml:
<look-and-feel>
<theme id="my" name="My Theme">
<virtual-path>//domain.com/myTheme</virtual-path>
</theme>
</look-and-feel>
note that the URL omits the protocol part, http: or https:, thus the browser will use the same protocol that the whole page is loaded with.
Edit: corrected the xml. Will investigate if there's a problem with protocol-relative URLs in themes.
Edit 2: Something is weird. It seems, virtual-path does not work like this, but I recall it did earlier. Do you add domain.com as cdn.host.http or cdn.host.https? (this would be concatenated)
On related stuff, please check if you're running Apache in front of your appserver. In this case you might forward some traffic for the portal (e.g. in the virtual host for http) but not forward the traffic in the https virtual host.