Reverse proxy with IP cameras question

1. Caddy version (caddy version):

v2.4.6 h1:HGkGICFGvyrodcqOOclHKfvJC0qTU7vny/7FhYp9hNw=

2. How I run Caddy:

systemd

a. System environment:

Ubuntu 20.04.3

b. Command:

n/a

c. Service/unit/compose file:

n/a

d. My complete Caddyfile or JSON config:

My entire file is not needed for the question I have.

	handle_path /axis/* {
		reverse_proxy * http://10.10.3.95:80 {
		}
	}
	handle_path /hikvision/* {
		reverse_proxy * http://10.10.1.61:80 {
		}
	}
	handle_path /trendnet/* {
		reverse_proxy * http://192.168.0.60:80 {
		}
	}

3. The problem I’m having:

For the 3 reverse proxies above, which are IP cameras, hikvision, and trendnet work, but the axis does not. I’ve been speaking to the Axis company and they told me this:

Hello Jeff,

My name is Andre and I am working your case as a Product Specialist from our headquarter in Sweden. I apologize that you are experiencing issues with our devices in conjunction with the network reverse proxy server. I have reviewed the case and we spotted some issues that we think are related to the reverse proxy altering the URL

Example 1:

In this example we assume that you are tyring to access the ONVIF-API of the Axis device to retrieve a image snapshot. As you can see from my remarks in the image, the wrong URL is used, this “axis-work” is no valid API endpoint in our firmware, therefore HTTP 404 Bad Request is the correct response given from the Axis device. The correct URL would have been

http://ip-address/onvif-cgi/jpg/image.cgi?resolution=1920x1080&compression=30

Basically, they’re saying that http://localhost/axis/onvif-cgi/jpg/image.cgi?resolution=1920x1080&compression=30 is wrong, but http://ip-address/onvif-cgi/jpg/image.cgi?resolution=1920x1080&compression=30 (replace ip-address with actual IP) is the right way. The second way is obviously direct and has nothing to do with a reverse proxy.

I mentioned I think this is how a reverse proxy works. Another reply:

Thank you for getting back to me. All the calls that we have seen in the support case so far that you address but fail can be done by just removing this “axis” part of the URI really. All API-interface calls in Axis VAPIX or ONVIF for that matter are predefined and standardized, it is not foreseen any case where the edge device is supposed to work around/best-guess clients that make wrong calls.

From the information I have I do not see further that it is something related to the reverse-proxy setup as such, it is rather a client that makes wrong API calls to the Axis device. I am guessing that you use “axis” to identify that the request shall be send to an Axis device to distinguish between your other vendors devices in the network. We are operating a reverse proxy in our lab as well and it works just fine as long as the API’s are honoured.

Am I the one not understanding? Is he right? Is there a way to configure the reverse proxy such that it’ll see the IP address?

Thank you once again for your time and insights.

The Axis support rep is right:

From the information I have I do not see further that it is something related to the reverse-proxy setup as such, it is rather a client that makes wrong API calls to the Axis device. I am guessing that you use “axis” to identify that the request shall be send to an Axis device to distinguish between your other vendors devices in the network. We are operating a reverse proxy in our lab as well and it works just fine as long as the API’s are honoured.

If the application is not expecting paths to be prefixed with /axis, then you can’t really expect to prefix the path with /axis and expect it to work. Sometimes they are also picky about the Host header of the request, too.

Some applications let you configure a path prefix because they know sometimes people like to do this when reverse proxying, but that that is not a very common feature.

We see this a lot, and I don’t know why people assume they can just change the paths of requests in web applications and expect the applications to still work. We see it so often that @Whitestrake wrote a great wiki article about this:

A reverse proxy simply decodes, then re-encodes, requests between a client and a backend. When you say “obviously direct and has nothing to do with a proxy,” you’re assuming you can tell whether a proxy is being used simply by looking at the URL path. But a URL path doesn’t encode reverse proxy information. The path of a URL and whether a proxy are being used are completely orthogonal concepts (i.e. they have nothing to do with each other).

You can configure a reverse proxy to manipulate the Host or path of a URL (Caddy lets you do this), but this isn’t always enough to make it possible to proxy with a path prefix (see the above linked wiki article).

PS. You can drop reverse_proxy * and just use reverse_proxy. Same thing.

2 Likes

Thanks, Matt!

This topic was automatically closed after 30 days. New replies are no longer allowed.