2

I have a tomcat application running with an apache reverse proxy. I'm trying to restrict access to the manager and host-manager contexts from localhost only.

So I uncommented the following line on context.xml file from both contexts:

<!--
Remove the comment markers from around the Valve below to limit access to
the manager application to clients connecting from localhost
-->
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
     allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />

But when I try to access these contexts from localhost it always shows me the error 403 page.

I didn't get the d+ thing in the allow attribute so I also tried allow="127\.0\.0\.1|::1|0:0:0:0:0:0:0:1" too with no luck.

Is there something wrong in my context.xml configuration?

Does it behave different when filtering connections when they pass first through apache's mod_proxy (ProxyPass ajp://localhost:8009)?

Thanks

  • en.wikipedia.org/wiki/HTTP_403 – dawud Jun 12 '15 at 19:51
  • I don't get it. Should I expect a 401 response instead of 403? I was able to access the manager context before I introduced the ip limitation. Could you explain it a bit better? – ylima Jun 12 '15 at 20:07
  • You don't say how are you trying to access the restricted contexts, through apache o directly against tomcat. Since tomcat and apache seem to be colocated, it might be easier for you to restrict access in apache. – dawud Jun 12 '15 at 20:15
  • Well, I'm sorry if it wasn't clear. The whole tomcat server is acessible only through the apache proxy. I'd prefer to use tomcat to restrict access in this case since it would be related to the context itself not to it's Location. This way I get more flexibility to change the url where the context is available without having to update apache configuration and lowering the risk of some mistake. Is it possible? – ylima Jun 12 '15 at 20:28
  • Does anyone has a clue of where to investigate? – ylima Jun 14 '15 at 2:48
0

There are two different mechanisms in play here: restricting access to a context (which is done using the RemoteAddrValve) and the built-in RBAC in server.xml:

<Resource name="UserDatabase" auth="Container"
          type="org.apache.catalina.UserDatabase"
          description="User database that can be updated and saved"
          factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
          pathname="conf/tomcat-users.xml" />

The following has been tested using tomcat-8.0.23:

A stock configuration only modified to restrict access from localhost to the manager context by modifying the apache-tomcat-8.0.23/webapps/manager/META-INF/context.xml file to remove the comments on the valve:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
      allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> 

Without further modifications, an attempt to access the context fails with a 401 HTTP error:

$ curl -v -L localhost:8080/manager/
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /manager/ HTTP/1.1
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=F3F2A25463ED1CD49E154FA5428B853A; Path=/manager/; HttpOnly
< Location: http://localhost:8080/manager/html;jsessionid=F3F2A25463ED1CD49E154FA5428B853A?org.apache.catalina.filters.CSRF_NONCE=B5CB272DF379F59A8158583826850550
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 0
< Date: Sun, 14 Jun 2015 08:47:27 GMT
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/manager/html;jsessionid=F3F2A25463ED1CD49E154FA5428B853A?org.apache.catalina.filters.CSRF_NONCE=B5CB272DF379F59A8158583826850550'
* Found bundle for host localhost: 0x256e460
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (::1) port 8080 (#0)
> GET /manager/html;jsessionid=F3F2A25463ED1CD49E154FA5428B853A?org.apache.catalina.filters.CSRF_NONCE=B5CB272DF379F59A8158583826850550 HTTP/1.1
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Server: Apache-Coyote/1.1
< Cache-Control: private
< Expires: Thu, 01 Jan 1970 01:00:00 GMT
< WWW-Authenticate: Basic realm="Tomcat Manager Application"
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 2474
< Date: Sun, 14 Jun 2015 08:47:27 GMT

After modifying the apache-tomcat-8.0.23/conf/tomcat-users.xml file to add the following:

<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="manager-gui"/>

and attempt to access the context, this time using authentication, succeeds:

$ curl -v -L -utomcat:tomcat localhost:8080/manager/
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'tomcat'
> GET /manager/ HTTP/1.1
> Authorization: Basic dG9tY2F0OnRvbWNhdA==
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=7890CA71EC221A152BDB4F04B66BE49E; Path=/manager/; HttpOnly
< Location: http://localhost:8080/manager/html;jsessionid=7890CA71EC221A152BDB4F04B66BE49E?org.apache.catalina.filters.CSRF_NONCE=92DAD506CB8E9E24E8454BBA94567F84
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 0
< Date: Sun, 14 Jun 2015 08:48:09 GMT
<
* Connection #0 to host localhost left intact
* Issue another request to this URL: 'http://localhost:8080/manager/html;jsessionid=7890CA71EC221A152BDB4F04B66BE49E?org.apache.catalina.filters.CSRF_NONCE=92DAD506CB8E9E24E8454BBA94567F84'
* Found bundle for host localhost: 0x69e4c0
* Re-using existing connection! (#0) with host localhost
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'tomcat'
> GET /manager/html;jsessionid=7890CA71EC221A152BDB4F04B66BE49E?org.apache.catalina.filters.CSRF_NONCE=92DAD506CB8E9E24E8454BBA94567F84 HTTP/1.1
> Authorization: Basic dG9tY2F0OnRvbWNhdA==
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Cache-Control: private
< Expires: Thu, 01 Jan 1970 01:00:00 GMT
< Set-Cookie: JSESSIONID=42B0B26688726A802B665B0B33D1690B; Path=/manager/; HttpOnly
< Content-Type: text/html;charset=utf-8
< Transfer-Encoding: chunked
< Date: Sun, 14 Jun 2015 08:48:09 GMT

Now, if you try to use a different interface to perform the request (i.e. not localhost), you will hit a 403 HTTP error, regardless you use authentication or not:

$ curl --interface wlp6s0 -v -L -utomcat:tomcat localhost:8080/manager/
*   Trying ::1...
*   Trying 127.0.0.1...
* Local Interface wlp6s0 is ip 192.168.1.187 using address family 2
* SO_BINDTODEVICE wlp6s0 failed with errno 1: Operation not permitted; will do regular bind
* Local port: 0
* Connected to localhost (127.0.0.1) port 8080 (#0)
* Server auth using Basic with user 'tomcat'
> GET /manager/ HTTP/1.1
> Authorization: Basic dG9tY2F0OnRvbWNhdA==
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 403 Forbidden
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=2F3ADE627300D4D264478927D1F0BBFC; Path=/manager/; HttpOnly
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 3196
< Date: Sun, 14 Jun 2015 09:06:52 GMT
<

This is as expected, as we are restricting access from localhost only.

In short, if you get a 403 error response, check the interface tomcat is listening to:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

$ ss -tulpan | grep LISTEN.*8080

and the interface you are using for the request.

  tcp    LISTEN     0      100                   :::8080                 :::*      users:(("java",pid=32490,fd=48))
  • Well, knowing that the problem might be occurring because the server is not receiving my connections from the loopback interface I decided to insert a AccessLogValve. Tomcat is logging requests from my server's public IP when I try to access it from localhost. I think I've found the problem. I'm just thinking about how to solve it now. – ylima Jun 15 '15 at 14:27
0

So, knowing that my requests were being sent from my server's public ip I changed my context.xml to:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
 allow="xxx\.xxx\.xxx\.xxx|127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />

Where xxx.xxx.xxx.xxx is the serve's public ip. It's now working.

Thanks for helping

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.