{"id":172,"date":"2022-10-28T00:30:45","date_gmt":"2022-10-28T00:30:45","guid":{"rendered":"https:\/\/www.akasistemas.com\/blog\/?p=172"},"modified":"2022-10-28T00:30:45","modified_gmt":"2022-10-28T00:30:45","slug":"dahua-apache-reverse-proxy","status":"publish","type":"post","link":"https:\/\/www.akasistemas.com\/blog\/index.php\/2022\/10\/28\/dahua-apache-reverse-proxy\/","title":{"rendered":"Dahua &#8211; Apache Reverse Proxy"},"content":{"rendered":"\n<p>Bienvenidos a una nueva entrada en nuestro blog empresarial, esperamos que este articulo sea de ayuda.<\/p>\n\n\n\n<p>En esta ocasi\u00f3n nos alejaremos moment\u00e1neamente de la linea regular y nos centraremos en el segmento de la video vigilancia, particularmente con la marca Dahua.<\/p>\n\n\n\n<p>Por lo general el adquirir una c\u00e1mara para nuestro uso personal no representa mayor problema, sin embargo cuando necesitamos algunas configuraciones particulares la situaci\u00f3n cambia y es que en este caso se requiere que una o varias c\u00e1maras dahua se puedan consumir a trav\u00e9s de un proxy reverso que trabaja con apache.<\/p>\n\n\n\n<p>En primera instancia la configuraci\u00f3n parecer\u00eda sencilla, ya que solo ser\u00eda definir unas entradas de proxypass y ya quedar\u00eda. Pero no, dahua no nos lo coloca sencillo y es que la forma en que esta construido el servidor web de la c\u00e1mara es complejo, las rutas est\u00e1n cargadas dentro de archivos javascript, mismos que son llamados por scripts previamente cargados, lo que anula la funcionalidad del proxy reverso.<\/p>\n\n\n\n<p>Por lo tanto de las pocas salidas practicas viables fue el usar un modulo de apache para sobre-escribir estas rutas de los archivos .js tarea que en un inicio pensamos delegar al modulo mod_substitute, pero r\u00e1pidamente nos dimos cuenta que las tareas de sustituci\u00f3n son limitadas a una sola expresi\u00f3n regular, por lo tanto necesitamos un modulo mas robusto y en este punto fue donde nos encontramos con este fant\u00e1stico proyecto de <strong>Gilles Darold<\/strong>, mismo a quien damos todo el cr\u00e9dito posible y enlazamos para su consulta y apoyo.<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/darold\/modproxyperlhtml\">https:\/\/github.com\/darold\/modproxyperlhtml<\/a><\/p>\n\n\n\n<p>Este modulo por decirlo de alguna forma nos permite realizar m\u00faltiples sustituciones sobre el contenido, lo cual resuelve en gran medida la problem\u00e1tica inicial. Su funcionamiento detallado lo pueden consultar en el enlace previo.<\/p>\n\n\n\n<p>Una vez realizadas las sustituciones en tiempo real del contenido de las urls, nos encontramos con el detalle de los websocket, esto ser\u00eda un detalle menor si no fuese porque la c\u00e1mara transmite su video a trav\u00e9s de websockets.<\/p>\n\n\n\n<p>Esta limitante la resolvimos con el modulo mod_rewrite. Dicho lo anterior vamos a ver el ejemplo completo y a realizar los peque\u00f1os comentarios.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>#Iniciamos con la definici\u00f3n de una variable la cual usaremos para trabajar sobre un subdirectorio de la url. Aqu\u00ed asumimos que tendremos varias c\u00e1maras sobre el mismo virtualhost, accediendo de la siguiente forma: http:\/\/ip_o_dominio\/<strong>cam1<\/strong><\/p>\n\n\n\n<p><em>Define path_cam1 <strong>cam1<\/strong><\/em><br><\/p>\n\n\n\n<p>#Seguidamente definimos un directorio sobre el cual haremos la definici\u00f3n del proxy reverso.<br><em>&lt;Location \/${path_cam1}><\/em><br><\/p>\n\n\n\n<p>#Activamos el modulo RewriteEngine, este nos permitir\u00e1 capturar la solicitud del websocket y dirigirla adecuadamente, esto es fundamental para el stream de video.<\/p>\n\n\n\n<p><br><em>RewriteEngine On<br>RewriteCond %{HTTP:Upgrade} websocket [NC]<br>RewriteCond %{HTTP:Connection} upgrade [NC]<br>RewriteRule ^\/?(.*) &#8220;ws:\/\/192.168.5.253\/$1&#8221; [P,L]<\/em><br><\/p>\n\n\n\n<p>#Definimos el proxy reverso<br><em>ProxyPass http:\/\/192.168.5.253<br>ProxyPassReverse http:\/\/192.168.5.253<\/em><br><\/p>\n\n\n\n<p>#Activamos el modulo ModProxyPerlHtml, para hacer uso de este es mandatorio instalarlo previamente seg\u00fan instrucciones de su sitio en github.<\/p>\n\n\n\n<p><br><em>PerlInputFilterHandler Apache2::ModProxyPerlHtml<br>PerlOutputFilterHandler Apache2::ModProxyPerlHtml<br>SetHandler perl-script<\/em><br><\/p>\n\n\n\n<p># Definici\u00f3n de las expresiones regulares, mismas que se encargar\u00e1n de modificar el contenido para que sea posible acceder a la camara a trav\u00e9s del proxy inverso.<\/p>\n\n\n\n<p><br><em>PerlAddVar ProxyHTMLRewrite &#8220;src\\=(\\&#8221;)(jsBase|jsCore|js)(\\\/) src\\=$1${path_cam1}$3$2$3&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(OutsideCmd)\\&#8221; $1$2${path_cam1}$2$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\\/web_caps\\\/) \\\/${path_cam1}$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(splayerCore\\\/SPlayer) ${path_cam1}\\\/$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;\\\/jsBase\\\/lib) \\&#8221;\\\/${path_cam1}\\\/jsBase\\\/lib&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8217;)(\\.)(\\\/)(jsBase)(\\&#8217;) $1$2$3${path_cam1}\/$4$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8217;)(\\.)(\\.)(\\\/)(js)(\\&#8217;) $1$2$3$4${path_cam1}$4$5$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8217;)(\\.)(\\.)(\\\/)(html)(\\&#8217;) $1$2$3$4${path_cam1}$4$5$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8217;)(\\.)(\\.)(\\\/)(platformHtm)(\\&#8217;) $1$2$3$4${path_cam1}$4$5$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8217;\\\/jsCore\\\/app&#8217;) \\&#8217;\\\/${path_cam1}\\\/jsCore\\\/app\\'&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8217;css\\\/) \\&#8217;${path_cam1}\\\/css\\\/&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8217;css_FS\\\/&#8217;) \\&#8217;${path_cam1}\\\/css_FS\\\/'&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8217;jsBase\\\/) \\&#8217;${path_cam1}\\\/jsBase\\\/&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\\/current_config\\\/) \\\/${path_cam1}$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\\/default_lang\\\/) \\\/${path_cam1}$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\\/custom_lang\\\/) \\\/${path_cam1}$1&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;splayerCore\\\/splayerAdapter.js\\&#8221;) \\&#8221;${path_cam1}\\\/splayerCore\\\/splayerAdapter.js\\&#8221;&#8221;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(js\\\/index\\.js) $1\\.\\.\\\/$2&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(m|p)(\\=\\&#8221;)(js|html)(\\\/)(\\&#8221;) $1$2\\.\\.$4$3$4$5&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(html)(\\\/\\&#8221;)(\\+b\\.) $1$2${path_cam1}$2$3$4$5&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(jsCore\\\/pageBase)(\\&#8221;) $1$2${path_cam1}\\\/$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(jsCore\\\/ability)(\\&#8221;) $1$2${path_cam1}\\\/$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(jsCore\\\/rpc)(\\&#8221;) $1$2${path_cam1}\\\/$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(jsCore\\\/rpcLogin)(\\&#8221;) $1$2${path_cam1}\\\/$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(jsCore\\\/mTokenOperator)(\\&#8221;) $1$2${path_cam1}\\\/$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(jsCore\\\/h5player)(\\&#8221;) $1$2${path_cam1}\\\/$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(jsCore\\\/plugin)(\\&#8221;) $1$2${path_cam1}\\\/$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(e\\=\\[)(\\&#8221;)(\\\/)(js)(\\\/\\&#8221;) $1$2$3${path_cam1}$3$4$5&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(module)(\\\/)(audioWorker|videoWorker)(\\.js\\&#8221;) $1${path_cam1}$3$2$3$4$5&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(module)(\\\/)(public|Sylvester|mp4remux|WebGLCanvas|audioPlayer|streamDrawer|videoMediaSource|workerManager|WebsocketServer|playerControl|ivs)(\\&#8221;) $1$2${path_cam1}$2$3$4$5$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(RPC2\\_Login|RPC2)(\\&#8221;) $1$2${path_cam1}$2$3$1&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(\\&#8221;)(\\\/)(RPC2\\_Loadfile|RPC2_Notify_Method) $1$2${path_cam1}$2$3&#8243;<br>PerlAddVar ProxyHTMLRewrite &#8220;(rtspoverwebsocket) ${path_cam1}\\\/$1&#8221;<\/em><br><\/p>\n\n\n\n<p>#cerramos la definici\u00f3n del directorio<br><em>&lt;\/Location><\/em><br><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>La anterior mec\u00e1nica se deber\u00eda replicar para todas las c\u00e1maras que se tengan.<\/p>\n\n\n\n<p>NOTA: Esta re-escritura a sido probada en c\u00e1maras DH-IPC-HFW1431S1N-S4 V2.820.0000000.48, por lo tanto es probable que en otros modelos sean necesarias algunas modificaciones.<\/p>\n\n\n\n<p>Por ultimo mencionar algunas herramientas utilizadas para lograr este objetivo:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>tcpdump<\/li><li>Wireshark<\/li><li>Herramientas de desarrollador Mozilla Firefox<\/li><li>https:\/\/regex101.com\/<\/li><\/ul>\n\n\n\n<p>Con esto finalizamos esta entrada, como siempre si hay alguna duda pueden contactarnos a trav\u00e9s de nuestras redes sociales, whatsapp, telegram o nuestro men\u00fa de contacto en nuestra pagina web.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bienvenidos a una nueva entrada en nuestro blog empresarial, esperamos que este articulo sea de ayuda. En esta ocasi\u00f3n nos alejaremos moment\u00e1neamente de la linea regular y nos centraremos en el segmento de la video vigilancia, particularmente con la marca Dahua. Por lo general el adquirir una c\u00e1mara para nuestro uso personal no representa mayor &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.akasistemas.com\/blog\/index.php\/2022\/10\/28\/dahua-apache-reverse-proxy\/\" class=\"more-link\">Continuar leyendo<span class=\"screen-reader-text\"> &#8220;Dahua &#8211; Apache Reverse Proxy&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-172","post","type-post","status-publish","format-standard","hentry","category-apache"],"_links":{"self":[{"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/172","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=172"}],"version-history":[{"count":1,"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/172\/revisions"}],"predecessor-version":[{"id":173,"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/172\/revisions\/173"}],"wp:attachment":[{"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=172"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=172"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.akasistemas.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=172"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}