Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper handling of request_uri in double nginx reverse proxy?

So, essentially I am running Joomla in a Docker php7-fpm container, then I have an nginx container where a joomla.conf file is defined as follows:

#https://docs.joomla.org/nginx

server {
  listen 8081;

  error_log  /var/log/nginx/error.log;
  access_log /var/log/nginx/access.log;

  server_name php-docker.local;

  root /usr/src/joomla;
  index index.php index.html index.htm default.html default.htm;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  # deny running scripts inside writable directories
  location ~* /(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$ {
    return 403;
    error_page 403 /403_error.html;
  }

  location ~ \.php$ {
    fastcgi_pass  joomla:9000;
    fastcgi_index index.php;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;

    include fastcgi_params;
    #include /etc/nginx/fastcgi.conf;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

And this works as expected... going to http://:8081 loads everything correctly.

Now, 8081 is just temporarily exposed in the nginx container, what I essentially want to do is setup a reverse proxy such that http:///joomla will be the final endpoint.

For this, I am struggling with the following conf file:

server{

  listen 80;
  server_name _;

  location /joomla/ {
    proxy_pass          http://localhost:8081/;

    proxy_set_header    Referer           $http_referer;
    proxy_set_header    X-Forwarded-Port  $server_port;
    proxy_set_header    X-Forwarded-Proto $http_x_forwarded_proto;
    proxy_set_header    Host              $host;
    proxy_set_header    X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header    X-Forwarded-Host  $host;
  }

}

What happens is that the HTML is served correctly, however, none of the assets are. This is because the URLs in Joomla are generated by a JURI class, which seems to rely on $request_uri, which by when it appears to arrive to Joomla is already lost.

https://github.com/joomla/joomla-cms/blob/6ab2a6e9010e7e04c260b9eba17dc76e866dd3e6/libraries/joomla/uri/uri.php#L87

So every link or reference to a file, script, or css renders like this:

http://localhost/login

http://localhost/images/headers/maple.jpg

Instead of:

http://localhost/joomla/login

http://localhost/joomla/images/headers/maple.jpg

However, when I access the second set of URL, I can access the link/asset without a problem... but of course once again, no images, templates, js or links being rendered correctly.

I prefer not to touch joomla.conf unless something is wrong, as for site.conf I would only like to translate URI segments to map requests to other applications, e.g.:

/joomla -> localhost:8081
/phpbb -> localhost:8082
/someapp -> localhost:8083
like image 289
dukeofgaming Avatar asked Jun 30 '17 02:06

dukeofgaming


People also ask

How do you check if NGINX reverse proxy is working?

To check the status of Nginx, run systemctl status nginx . This command generates some useful information. As this screenshot shows, Nginx is in active (running) status, and the process ID of the Nginx instance is 8539.

When you configure NGINX as a reverse proxy for Apache both may listen to the same port?

You do that by configuring NGINX as a reverse proxy for Apache. With this setup, NGINX will listen for all incoming requests to port 80 and pass them on to Apache, which is listening in on port 8080.

What is $Request_uri?

REQUEST_URI is the path component of the URI in the request. For example, /tq_info. php . REQUEST_FILENAME is the result of trying to find the file in the local filesystem by applying the URI path to the document root or any alias that might have been defined.

What is URI in NGINX?

It is exactly the $uri/ part that makes nginx assuming an URI can be a directory name and looking for an index file presence inside it.


2 Answers

The cleanest solution would be to modify your upstreams to provide unique paths for all the resources.

It is generally a much easier task to remove parts of a URL from the upstream (with a unique prefix) than to add extra parts to a non-unique one. This is because you can always catch the longer URL and know exactly what it refers to, subsequently returning a 301 or 302 redirect to a shorter and more concise version.

On the other hand, faced with a short request URL, like /, it would be difficult to know for sure which app it may refer to (unless you look into the $http_referer variable, too, and then conditionally issue the redirect based on where the URL request comes from), or unless you implement some sort of spaghetti rules to detect which individual URLs refer to which applications (if you go this route, the map directive may come in handy).

Additionally, consider that, security-wise and when cookies get involved, it is not the best practice to run multiple independent applications on a single domain — a compromise in one application can easily lead to security violations in all the other ones.

like image 112
cnst Avatar answered Oct 27 '22 01:10

cnst


As Rinos said, you need to configurate the $live_site var in configuration.php, as this:

public $live_site = '/joomla/';

I've made a complete example in Github that works well after editing that file, and it uses your configs.


enter image description here


 Becomes:


enter image description here

like image 29
Robert Avatar answered Oct 27 '22 00:10

Robert