I am trying to remove the use of AJP from an existing installation for security reasons, but cannot find any info on how to do so.
Specifically, my original Apache config has JKMount directives in it, which I have replaced with ProxyPass and ProxyPassReverse directives, but the original Kerberos authentication doesn't appear to be getting passed through to Tomcat any more.
(I now have mod_proxy_http and mod_proxy enabled.)
Google is definitely not my friend in this case.
CodePudding user response:
There isn't really a standard way to forward the authenticated user name from Apache to Tomcat using mod_proxy_http
, but you can easily create one:
- Configure Apache 2 to send an
X-Forwarded-User
header (if we have an authenticated user):
RequestHeader unset X-Forwarded-User
RequestHeader set X-Forwarded-User "expr=%{REMOTE_USER}" "expr=-n %{REMOTE_USER}"
- Compile (and put it in
$CATALINA_BASE/lib
) aValve
on Tomcat's side that will retrieve theX-Forwarded-User
from "trusted" hosts:
import java.io.IOException;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import org.apache.catalina.connector.CoyotePrincipal;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
public class RemoteUserValve extends ValveBase {
private static String remoteUserHeader = "X-Forwarded-User";
// Same as in RemoteIpValve
private static Pattern internalProxies = Pattern
.compile("10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|" "192\\.168\\.\\d{1,3}\\.\\d{1,3}|"
"169\\.254\\.\\d{1,3}\\.\\d{1,3}|" "127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|"
"172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|" "172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|"
"172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}|" "0:0:0:0:0:0:0:1|::1");
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (internalProxies.matcher(request.getRemoteAddr()).matches()) {
final String user = request.getHeader(remoteUserHeader);
if (user != null && !user.isEmpty()) {
request.setUserPrincipal(new CoyotePrincipal(user));
}
}
getNext().invoke(request, response);
}
}
- Add the valve to
servers.xml
<Engine name="Catalina">
<Valve className="fully.qualified.name.RemoteUserValve" />
...
</Engine>
I wouldn't consider this very secure, but it provides the same level of security as the equivalent AJP feature.