zoneminder
zoneminder copied to clipboard
Web resources should be accessed using relative path
Describe Your Environment
- Version of ZoneMinder 1.36.33
- How you installed ZoneMinder ghcr.io/zoneminder-containers/zoneminder-base:1.36.33
- Full name and version of OS : Host is debian bookworm
- Browser name and version (if this is an issue with the web interface) Firefox
Describe the bug All web elements should be requested using a relative path, as described by ZM_BASE_URL. However, when setup using a reverse proxy on /services/zoneminder, it's appartent that a lot of resources are requested using an absolute path and breaks a lot of features :
- initial access on the provacy policy is done through an absolute header location content ("location: /index.php...")
- access to cgi-bin/nph-zms is done in an absolute manner (
/cgi-bin/nph-zms
) in the htmlsrc="/cgi-bin/nph-zms?...
- /index.php?view=request&request=status&entity=navBar
- var thisUrl = '/index.php';
- and probably many more
rp-nginx/nginx.conf :
server {
listen 80;
server_name rp-nginx;
location /services/zoneminder {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
rewrite ^/services/zoneminder(.*) /$1 break;
proxy_pass http://zoneminder-app:80;
proxy_redirect off;
}
}
docker-compose.yml
services:
# https://github.com/zoneminder-containers/zoneminder-base
# mkdir -p zoneminder-db/data zoneminder-app/{data,config,log}
# chown -R 911:911 zoneminder-*
zoneminder-db:
image: mariadb:11.1.2
stop_grace_period: 60s
networks:
- zoneminder
user: "911:911"
volumes:
- ./zoneminder-db/data:/var/lib/mysql
environment:
# Don't change the database name, this is not supported by the zoneminder's dockerfile startup script yet
MARIADB_DATABASE: zm
MARIADB_ROOT_PASSWORD: abcdef
MARIADB_USER: zoneminder
MARIADB_PASSWORD: abcdef
zoneminder-app:
image: ghcr.io/zoneminder-containers/zoneminder-base:1.36.33
stop_grace_period: 60s
depends_on:
- zoneminder-db
networks:
- zoneminder
- rp-nginx
volumes:
- ./zoneminder-app/data:/data
- ./zoneminder-app/config:/config
- ./zoneminder-app/log:/log
- type: tmpfs
target: /dev/shm
tmpfs:
size: 1000000000
environment:
TZ: "Europe/Paris"
MYSQL_HOST: zoneminder-db
MYSQL_USER: zoneminder
MYSQL_PASSWORD: abcdef
# chown -R 1001:1001 rp-nginx
rp-nginx:
image: nginxinc/nginx-unprivileged:1.25.2
user: "1001:1001"
ports:
- "80:80"
depends_on:
- zoneminder-db
- zoneminder-app
volumes:
- ./rp-nginx/nginx.conf:/etc/nginx/nginx.conf
- nginx-cache:/var/cache/nginx
networks:
- rp-nginx
volumes:
nginx-cache:
name: nginx-cache
networks:
rp-nginx:
zoneminder:
Thanks for opening your first issue here! Just a reminder, this forum is for Bug Reports only. Be sure to follow the issue template!
I can second that. I've read in previous issues that ZM_BASE_URL is deprecated, but the idea is sound.
I also tried injecting a
sub_filter '</head>' '<base href="/my/cams/admin"></head>';
In the browser's js console, I still see lots of red 404 entries.
I also tried setting HTTP headers that, according to spec, are supposed to suggest base URI. Apparently, both
proxy_set_header Content-Location /my/cams/admin;
proxy_set_header Content-Base /my/cams/admin;
We do need a mechanism to reliably hide ZM behind a reverse proxy. Preferably, this mechanism should use either relative URLs or standard absolute URL prefixing mechnisms (
Unfortunately, I'm not a PHP dev and can't contribute much.
Another probably related issue: some URLs are stepping one level up. Say, if my actual base URL is /my/cams/admin, some resources are being fetched from /my/cams (losing the /admin part of the URL).
A temporary somewhat working workaround:
location ~ ^/my/cams/admin/?(.*) {
proxy_pass http://localhost:81/$1$is_args$args;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
sub_filter 'src="/' 'src="';
sub_filter 'href="/' 'href="';
sub_filter '/index.php' 'index.php';
sub_filter_once off;
}
location ~ ^/my/cams/?(.*) {
proxy_pass http://localhost:81/$1$is_args$args;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
sub_filter 'src="/' 'src="';
sub_filter 'href="/' 'href="';
sub_filter '/index.php' 'index.php';
sub_filter_once off;
}
Still, snapshot thumbnails are attempted to fetch from an absolute /index.php. Android app is having trouble automatically detecting cgi-bin (had to specify the path manually; still doesn't load monitors). Prolly something else is broken as well.
At least I can view the stream in the web browser now.
Still, this has to be fixed.
I run ZM behind reverse proxies all the time.... with and with the /zm.... havn't done a more complex url change.
The issue is further complicated by multi-server. Wherever we are using an absolute url, we are likely dealing with a multi-server case.
@connortechnology
- which version?
- can you show us, what's the Live Stream page, what's the cgi-bin URL in the HTML opened in your browser? (no need or the whole URL -- just the beginning; whether slash is there or not)
[here's mine for example
- In the same page, what's the URL of the index.php (browser's devtools → network tab; I'm interested in what's the base URL)
- Have you done any base-url-related configuration server-side?