motioneye-project / motioneye

A web frontend for the motion daemon.
GNU General Public License v3.0
3.95k stars 650 forks source link

Reverse proxy on Apache returns only text #1532

Open Aspire1Inspire2 opened 4 years ago

Aspire1Inspire2 commented 4 years ago

I have been trying to reverse proxy motioneye with Apache2 for the last two days with no success. I always get a page with only text: image

The proxy configuration I used in my virtual host file is as following: ProxyPreserveHost On ProxyPass "/motioneye" "http://localhost:8765" ProxyPassReverse "/motioneye" "http://localhost:8765"

Did I do something wrong? I spent tons of time googling what happened with no luck. Could we add some instruction on what modules/setup we need to use for Apache2?

dmak commented 4 years ago

I've got the same problem. It looks like motionEye cannot learn the base URL from Referer request header and there is no configuration option to tune that. So it keeps requesting resources from root like

http://www.host.com/static/css/jquery.timepicker.css?v=0.41

instead of

http://www.host.com/motioneye/static/css/jquery.timepicker.css?v=0.41

Maybe server_name, but Running Behind Nginx does not say one should use it. See also issue #1482.

Aspire1Inspire2 commented 4 years ago

I've got the same problem. It looks like motionEye cannot learn the base URL from Referer request header and there is no configuration option to tune that. So it keeps requesting resources from root like

http://www.host.com/static/css/jquery.timepicker.css?v=0.41

instead of

http://www.host.com/motioneye/static/css/jquery.timepicker.css?v=0.41

Maybe server_name, but Running Behind Nginx does not say one should use it.

The strange thing is the reverse proxy works when I am doing http to http, it failed only when I am trying to do https to http.

But if https to http could not work for motioneye, it defeats the whole point of using reverse proxy. I can just open the port on my firewall to access motion eye without reverse proxy. For me, reverse proxy's only merit is the security through https.

dmak commented 4 years ago

I've got the working configuration (1):

<Location "/motioneye/">
        ProxyPass               http://localhost:8765/
        ProxyPassReverse        http://localhost:8765/
</Location>

Mind the trailing slash in location and in proxy URL. Equivalent configuration (2):

ProxyPass        "/motioneye/" "http://localhost:8765/"
ProxyPassReverse "/motioneye/" "http://localhost:8765/"

In order to handle ULRs not ending with slash I suggest to use the following one (3):

RewriteEngine on
RewriteRule /motioneye$         /motioneye/ [R,L]
RewriteRule /motioneye/(.*)$    http://localhost:8765/$1 [P,L]

Note that (1), (2), (3) are all alternatives (if you mix them, make sure you have a proper understanding). I personally have chosen (3).

Proxying MotionEye from HTTPS-enabled vhost works fine. At least I was able to login and display camera setup dialog.

Aspire1Inspire2 commented 4 years ago

Thanks! It works for https now. Could we possibly add this to the Wiki?

seabird commented 3 years ago

Ok, glad it was resolved, but I cant seem to manage this. My v-host setup with apache:

<VirtualHost *:80>
   ServerName camera.my-domain.com
   Redirect permanent / https://camera.my-domain.com/
</VirtualHost>

<VirtualHost *:443>
  ServerName  camera.my-domain.com
  ProxyPreserveHost On
<Location "/motioneye/">
        ProxyPass               http://localhost:8765/
        ProxyPassReverse        http://localhost:8765/
</Location>
RewriteEngine on
RewriteRule /motioneye$         /motioneye/ [R,L]
RewriteRule /motioneye/(.*)$    http://localhost:8765/$1 [P,L]
</VirtualHost>

Could someone clarify their file to set this up?

seabird commented 3 years ago

oops, mine isn't located at "/motioneye"/. Changing "/" worked.

lepidas commented 3 years ago

Hi to all, soon I will try this. I have one question, what is this location "/motioneye"/ ; It's a location of or for what;

dmak commented 3 years ago

I have one question, what is this location "/motioneye"/ ; It's a location of or for what;

This is a virtual location to be mapped. See Location Directive.

lepidas commented 3 years ago

I have one question, what is this location "/motioneye"/ ; It's a location of or for what;

This is a virtual location to be mapped. See Location Directive.

I understand this, I don't understand your setup that lead you to have this directive "/motioneye"/. Iam asking this to understand better for my setup which is a little bit complicated, trying to go deeper....

dmak commented 3 years ago

I don't understand your setup that lead you to have this directive "/motioneye/"

This is because if motioneye is accessed without a trailing slash, it does not compute base URL correctly (let's assume this is a feature) and as a consequence cannot load resources (e.g. CSS, see the issue description). Hence there is a need to make a redirect for the path that does not end with slash.

@seabird You have mixed two equivalent configurations. You could leave only this part (i.e. remove <Location> block):

RewriteEngine on
RewriteRule /motioneye$        /motioneye/               [R,L]
RewriteRule /motioneye/(.*)$   http://localhost:8765/$1  [P,L]

and it should work just fine.

lepidas commented 3 years ago

Hi to all,

I have succesfully managed to reverse proxy on Apache but one thing. I don't know what to do with the Video Streaming > Streaming URL https://domain.com:8081 It doesn't load this page https://domain.com:8081

<VirtualHost *:80>
  ServerName domain.com

  <IfModule proxy_module>
    ProxyPreserveHost on

    RequestHeader set X-Forwarded-Proto "https"

    ProxyPass / http://localhost:8765/
    ProxyPassReverse / http://localhost:8765/

  </IfModule>

        ErrorLog ${APACHE_LOG_DIR}/motioneye_error.log
    CustomLog ${APACHE_LOG_DIR}/motioneye_access.log combined

RewriteEngine on
RewriteCond %{SERVER_NAME} =domain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
  ServerName domain.com

  <IfModule proxy_module>
    ProxyPreserveHost on

    RequestHeader set X-Forwarded-Proto "https"

    ProxyPass / http://localhost:8765/
    ProxyPassReverse / http://localhost:8765/

  </IfModule>

        ErrorLog ${APACHE_LOG_DIR}/motioneye_error.log
    CustomLog ${APACHE_LOG_DIR}/motioneye_access.log combined

RewriteEngine on
# Some rewrite rules in this file were disabled on your HTTPS site,
# because they have the potential to create redirection loops.

SSLCertificateFile /etc/letsencrypt/live/domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>