Reverse Proxy + Dahua NVR

LouisG

Getting the hang of it
Jun 6, 2019
15
51
NL
I have a Dahua NVR with several cams setup. On my local network and using P2P QR code + iOS app all works well.

I want to use the UI of the NVR to manage IVS rules remotely. I can do this by connecting via a VPN setup to the local network of the NVR.

The problem is that very often the IP ranges are conflicting between my local network and the remote network (both using 192.168.1.x range. So that doesn't work.

I have configured a reverse proxy server (nginx) on my local network to have a (sub)domain.tld pointing to my NVR. This works well to approach the NVR and to use it in (for example) the iOS app (when manually connecting to the NVR insead of using the P2P QR code).

The problem is when trying to view camera images (or trying to configure IVS rues, hence viewing the camera images) via the NVR UI.
I get an error and a message wanting me to download a certificate file. I have tried installing the certificate file but I still cant get an image of the cams.

In my browser console I get an error having to do with the WebSocks connection using the "wss:/" URL scheme.
My reverse proxy only forwards "http://" or "https://" URL schemes.
I'm generating a valig SSL certificate via the reverse proxy for the NVR via Let's Encrypt.

Does anyone have any experience in configuring this type of setup?
 
  • Like
Reactions: mazter
Not sure if you've fixed it yourself, but this was one of the top google results when I was looking. For anyone else looking, here is the nginx config I got to work, just swap <public server name> and <NVR local IP address> for your use case:

Code:
server {
        # SSL configuration
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name <public server name>;

        location /rtspoverwebsocket {
                proxy_pass http://<NVR local IP address>;
                proxy_http_version 1.1;
                proxy_buffering off;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_set_header Host $host;
        }

        location /.well-known {
            root /var/www/certbot;
        }

        location / {
                proxy_pass http://<NVR local IP address>;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
        }

        # ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
        # ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

        ssl_certificate /etc/letsencrypt/live/<public server name>/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/<public server name>/privkey.pem;

        ssl_session_cache shared:le_nginx_SSL:10m;
        ssl_session_timeout 1440m;
        ssl_session_tickets off;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers off;

        ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
}

server {
        listen 80;
        listen [::]:80;

        server_name <public server name>;

    location / {
                return 302 https://$host$request_uri;
        }
}
 
  • Like
Reactions: InovoEntron
No, I wasn't able to fix it yet. Can you tell me the version of the NVR firmware you are running.
I'm running V4.001.0000000.4, Build Date: 2020-07-07
 
Mine is a DHI-NVR4108-P-4KS2 running firmware version V4.001.0000005.1, Build Date: 2021-07-13. I have had it running for a while across several firmware versions though
 
HA I fixed it. Thank you, you pushed me in the right directions.

After I Googled, I came across this issue: Websocket configuration · Issue #723 · jc21/nginx-proxy-manager

I compared your solution and theirs.

The fix is in the part
NGINX:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;

So in NGINX Proxy Manager do
Screenshot_2021-09-13_at_19_01_15.jpg

then the magic part. Set the rtsp port and custom code.

Screenshot 2021-09-13 at 19.01.32.png


now it works.
 
HA I fixed it.

Gday mate, I am in a similar boat, stuck trying to reverse proxy my Dahua NVR. I have Nginx + Cloudflare forward setup.

Following your steps above, what port do you setup on mobile app ?
What about Force SSL, HTTP/2 Support in Nginx?
Thanks.
 
I think you can do that. Suppose you already connected and configured your proxy server to your local network. In that case, I am sure that you will be able to manage your setup remotely. Still, if this doesn't help, I can suggest you use the proxy list. In this way, you will connect to the network by using all the data attached. Still, I will also recommend you speak with a professional in this field since I am not that experienced with this industry. Hope you will find my message helpful, and you will manage to solve your problem.
 
Gday mate, I am in a similar boat, stuck trying to reverse proxy my Dahua NVR. I have Nginx + Cloudflare forward setup.

Following your steps above, what port do you setup on mobile app ?
What about Force SSL, HTTP/2 Support in Nginx?
Thanks.

At the moment I have done this setup only for the web browser. I you use the ports that I have set up in the NVR (custom).
 
True.
The best would be to have in only locally and accessible via a vpn.
There is no difference between using a reverse proxy or using port forwarding. In one case you do not know the (sub) domain in the other case you do not know the port number (or a combination).
With a reverse proxy you can also add a whitelist + authentication + ssl, and then you still have the authentication of the NVR itself.
There is always a balance between security and usability.
 
  • Like
Reactions: nelgnl
At the moment I have done this setup only for the web browser. I you use the ports that I have set up in the NVR (custom).


Noted. I already have port forwarding setup to view cameras remotely by providing account username/password.

I was hoping I could do reverse proxy to the NVR as well.
Thanks.
 
You can make it super secure by using firewall rules to only allow a set of whitelisted IPs access the reverse proxy. For instance my reverse proxy is HAProxy within my pfSense firewall. HaProxy has an ACL that only allows a defined group of public IPs

Sent from my SM-G965U using Tapatalk
 
HA I fixed it. Thank you, you pushed me in the right directions.

After I Googled, I came across this issue: Websocket configuration · Issue #723 · jc21/nginx-proxy-manager

I compared your solution and theirs.

The fix is in the part
NGINX:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;

So in NGINX Proxy Manager do
View attachment 101563

then the magic part. Set the rtsp port and custom code.

View attachment 101565


now it works.
Hi, I am trying to achieve the same but using an Annke NVR.
Reverse proxy works fine but the live views fails to load when accessing through the proxy link.
I am trying to understand what your fix did so that I can replicate your settings.

I tried to set the exact location and code but it did not work.

Any pointer are appreciated!
 
Hi, I am trying to achieve the same but using an Annke NVR.
Reverse proxy works fine but the live views fails to load when accessing through the proxy link.
I am trying to understand what your fix did so that I can replicate your settings.

I tried to set the exact location and code but it did not work.

Any pointer are appreciated!
I also have the same error, please help me
 
Hi

Today I needed to redirect the Dahua nework video recorder through the Apache server in "Reverse Proxy" mode. After some googling I started from this site, so I decided to post my solution here. The following information was helpful:

[Support]: Apache2 reverse proxy not entirely working · Issue #4496 · blakeblackshear/frigate

Code:
<VirtualHost *:80>
  ServerAdmin root@domain.com

  ServerName nvr.domain.com:80

  DocumentRoot "/usr/local/www/apache24/data"

  <If "[percent_sign_without_brackets]{REQUEST_URI} !~ m#/\.well-known/#">
    Redirect "/" "https://nvr.domain.com/"
  </If>
</VirtualHost>

<VirtualHost *:443>
  ServerAdmin root@domain.com
  ServerName nvr.domain.com:443

  ErrorLog "/var/log/httpd-nvr-error.log"
  CustomLog "/var/log/httpd-nvr-ssl_request.log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
  TransferLog "/var/log/httpd-nvr-ssl-access.log"

  AllowEncodedSlashes NoDecode

  SSLEngine on

  SSLCertificateFile "/usr/local/etc/letsencrypt/live/nvr.domain.com/cert.pem"
  SSLCertificateKeyFile "/usr/local/etc/letsencrypt/live/nvr.domain.com/privkey.pem"
  SSLCertificateChainFile "/usr/local/etc/letsencrypt/live/nvr.domain.com/chain.pem"

  ProxyPreserveHost On
  ProxyRequests Off

  DocumentRoot        "/usr/local/www/apache24/data"

  ProxyPass           /.well-known !

  RewriteEngine on
  RewriteCond %{HTTP:Upgrade} =websocket [NC]
  RewriteRule /(.*)  ws:/nvr.ip.local/$1 [P,L]
  RewriteCond %{HTTP:Upgrade} !=websocket [NC]
  RewriteRule /(.*)  http://nvr.ip.local/$1 [P,L]


  ProxyPass           / http://nvr.ip.local/
  ProxyPassReverse    / http://nvr.ip.local/
</VirtualHost>

Local communication, between apache serwer and recorder, is unencrypted. Outside access is encrypted over HTTPS.

Regards,
Marcin