Issue Details (XML | Word | Printable)

Key: MDL-9276
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Petr Skoda
Reporter: Rafael del Aguila
Votes: 0
Watchers: 2
Operations

Add/Edit UI Mockup to this issue
If you were logged in you would be able to see more operations.
Moodle

Errors with Moodle behind a reverse proxy

Created: 11/Apr/07 01:16 AM   Updated: 10/Sep/09 09:11 PM
Return to search
Component/s: Course
Affects Version/s: 1.6.4
Fix Version/s: 2.0

Environment: Server: Linux with Apache 2.2
Issue Links:
Relates
 

Participants: Carlos Alexandre S. da Fonseca, Elvira Nieto, James Mitchell, Jason Dilworth, Joacim Breiler, Petr Skoda and Rafael del Aguila
Security Level: None
Resolved date: 06/Jan/09
Affected Branches: MOODLE_16_STABLE
Fixed Branches: MOODLE_20_STABLE


 Description  « Hide
We use moodle behind an Apache web server configured with mod_proxy and we get error in some elements (links, styles, ...) in some pages.
The internal and external name of the published application is not the same so we have the following configuration:

in the backend web server with Moodle 1.6.4 and Apache 2.0 we have:
    in config.php
        $CFG->wwwroot = "http://external_public_name/estudios";

in the frontend web server with Apache 2.2 we have:
    in httpd.conf
         ProxyPass /estudios http://internal_server_name/moodle
         ProxyPassReverse /estudios http://internal_server_name/moodle

When we login into Moodle and go to a course, in the Topic outline screen, for example
        http://external_public_name/estudios/course/view.php?id=2

the central block styles are not aplied.

The reason is that body class is not well formed.
If we see the source code of the generated page we see over line 65

<body class="http:--internal_servere_namecourse course-2" id="http:--internal_server_namecourse-view">

I supose the correct one must be <body class="course course-2" id="course-view">

This is only one error, we have detected more of the same type in the docs link in the footer of pages and in the nav bar of archives page.

We have already tested it in Moodle 1.7 and 1.8 and the same errors ocurred.

Regards

Rafael

 All   Comments   Change History   Version Control      Sort Order: Ascending order - Click to sort in descending order
Petr Skoda added a comment - 11/Apr/07 01:48 AM
You can not use two URLs for one Moodle instance, you can find more info here: http://docs.moodle.org/en/masquerading

Rafael del Aguila added a comment - 12/Apr/07 06:19 PM
I have read http://docs.moodle.org/en/masquerading
This article explain that "You can not use internal ip address or internal server name in config.php if you want to access the server from Internet too. If you want to use Moodle server from Internet, use real DNS hostname in $CFG->wwwroot."
If you re-read my first post I use real DNS hostname in my config.php

$CFG->wwwroot = "http://external_public_name/estudios ";

The problem arise when url published in the reverse proxy [ /estudios ] is not the same that the url published in the internal server [ /moodle ]

Beyond this error, I think this limitation has no sense.
Why need Moodle work with absolute URLs?
Relative URLs are much more flexible than absolute ones and allow a correct work behind reverse proxy.
It must be an imperative improvement.

In addition, almost all pages work fine in my configuration, only some errors are displayed in some pages where absolute urls are bad used.

I think the errors come from the function me() and/or qualified_me() in weblib.php


Petr Skoda added a comment - 12/Apr/07 06:48 PM
The main reason why there are absolute urls is that people copy/pase urls from address bar. Decision to use absolute urls was done long ago and I am sure it will not be changed. If you want more info, please search the forums.

Joacim Breiler added a comment - 10/Aug/07 04:49 PM - edited
We are running moodle on a server at "http://localserver:8088/" and a reverse proxy (pound - http://www.apsis.ch/pound/).
Pound handles all calls to "https://example.com/moodle" and directs the traffic to to the local server.

We got the same symptoms as described above by Rafael. The module chat wouldn't even load, giving a blank page...

We solved the issue (we havn't noticed any side effects yet) by modifing the function qualified_me() in /lib/weblib.php.

The function parses the URL from $CFG->wwwroot and uses this information together with information from $_SERVER
to build an absolute url.

Replace the function qualified_me() with the one below, and set "$CFG->using_reverseproxy = true" in your config.php.

function qualified_me() {

global $CFG;

$result = $CFG->wwwroot . me();

if( !$CFG->using_reverseproxy )
{
if (!empty($CFG->wwwroot)) { $url = parse_url($CFG->wwwroot); }

if (!empty($url['host'])) { $hostname = $url['host']; } else if (!empty($_SERVER['SERVER_NAME'])) { $hostname = $_SERVER['SERVER_NAME']; } else if (!empty($_ENV['SERVER_NAME'])) { $hostname = $_ENV['SERVER_NAME']; } else if (!empty($_SERVER['HTTP_HOST'])) { $hostname = $_SERVER['HTTP_HOST']; } else if (!empty($_ENV['HTTP_HOST'])) { $hostname = $_ENV['HTTP_HOST']; } else { notify('Warning: could not find the name of this server!'); return false; }

if (!empty($url['port'])) { $hostname .= ':'.$url['port']; } else if (!empty($_SERVER['SERVER_PORT'])) {
if ($_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443 ) { $hostname .= ':'.$_SERVER['SERVER_PORT']; }
}

if (isset($_SERVER['HTTPS'])) { $protocol = ($_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'; } else if (isset($_SERVER['SERVER_PORT'])) { # Apache2 does not export $_SERVER['HTTPS'] $protocol = ($_SERVER['SERVER_PORT'] == '443') ? 'https://' : 'http://'; } else { $protocol = 'http://'; }

$url_prefix = $protocol.$hostname;
$result = $url_prefix . me();
}

return $result;
}


Carlos Alexandre S. da Fonseca added a comment - 10/Sep/07 10:43 PM - edited
I have the same problem, but there is when i try to modify a profile, the action url in the form point to non existem address
because of qualified_me() end me() functions

my solutions was put de same folder name in the moodle application

for example:

ProxyPass /estudios http://internal_server_name/moodle
ProxyPassReverse /estudios http://internal_server_name/moodle

i change to :

ProxyPass /estudios http://internal_server_name/estudios
ProxyPassReverse /estudios http://internal_server_name/estudios

and works, but i think the moodle don't need to have this limitation

the problem its the me() function takes varieable from $_SERVER,
and takes the worng name of moodle folder , in this case, returns /moodle/any_thing.php

so the URL http://external_public_name/moodle/any_thing.php don't exist
( this is retuned from qualified_my() )

if the me() function only returns de script name (any_thing.php), the qualified_me function
could be

$result = $CFG->wwwroot .'/'. me();

PS: i'm using moodle 1.8 with this new formslib


Jason Dilworth added a comment - 29/May/08 12:04 AM
I've been having what I think is the same problem, but using MS ISA 2006 ;/ as the reverse proxy server.
The solution on that system was to put in a couple of Link Translations in the 'Firewall Policy' area as follows:

replace <form action="http://(internal-name)/user/editadvanced.php" method="post"
with <form action="https://(external-name)/user/editadvanced.php" method="post"
replace <form action="http://(internal-name)/blog/edit.php" method="post"
with <form action="https://(external-name)/blog/edit.php" method="post"

These were the only 2 pages that were causing problems in version 1.8.4 - user profile and blog editing pages.


James Mitchell added a comment - 31/Jul/08 10:53 AM
My simplier solution

open weblib.php find me() and replace

function me() {

with

function me() { return str_replace('/somefolder','',notreal_me()); }
function notreal_me() {

This renames me() to notreal_me() and then creates a new me() which replaces /somefolder with nothing..

e.g. if your reverse proxy is from xxx.com/ to yyy.com/~xxx then you replace /somefolder with /~xxx

You'll need to do this after every update of moodle you do..


Petr Skoda added a comment - 06/Jan/09 06:11 AM
reopening

Petr Skoda added a comment - 06/Jan/09 06:46 AM
Reverse proxies are now supported, but the "one address" limitation will not be removed. I can be enabled in config.php - see config-dist.php
I think it could be used probably in some load balancing configurations.

thanks for the report, please test and reopen if needed!


Elvira Nieto added a comment - 10/Sep/09 09:11 PM
Hello,

my solution is the next:

File: /lib/formslib.php
Function: moodleform()

The code must be:

function moodleform($action=null, $customdata=null, $method='post', $target='', $attributes=null) {
if (empty($action)){ # @author: Elvira Nieto <aquesabenlasnubes@gmail.com> # $action = strip_querystring(qualified_me()); #Change it by: $action = basename($_SERVER['SCRIPT_NAME']); # The rest code will not change ..... }

Not forget that $CFG->wwwroot variable must be configured in config.php

Best Regards