-
Bug
-
Resolution: Fixed
-
Major
-
3.5, 3.10.5, 3.11.1
-
MOODLE_310_STABLE, MOODLE_311_STABLE, MOODLE_35_STABLE
-
MOODLE_310_STABLE, MOODLE_311_STABLE
-
m40_
MDL-63770_Allow_Unbalanced_Port_On_Reverse_Proxying -
Easy
-
I'm running Moodle 3.5 stable in a docker container (nginx + php-fpm). External port number doesn't match internal port number (e.g. 8080:80).
This setup causes an infinite redirect, because the port numbers don't match here: https://github.com/dimaip/moodle/blob/c092f75791be10f8f2ee382cd73ac1cdcf3a6feb/lib/setuplib.php#L852
I tried to enable `$CFG->reverseproxy` to circumvent the problem. That gives me `Reverse proxy enabled, server can not be accessed directly, sorry` error becuase that check only evaluates host names, and not port numbers.
A possible fix would be to change this line https://github.com/moodle/moodle/blob/master/lib/setuplib.php#L907
into `if (!empty($CFG->reverseproxy) && $rurl['host'] === $wwwroot['host'] && $rurl['port'] === $wwwroot['port']) {`
For reference, my container has these fastcgi params: https://github.com/psmb/docker-neos-alpine/blob/master/root/etc/nginx/fastcgi_params
To reproduce
Prepare the test environment
- You can use the Moodle Docker Toolbox, by selecting any DB Server - the fastest in your setup - and prepare the Moodle DB:
# export MOODLE_DOCKER_WWWROOT=/path/to/moodle/moodle/
# export MOODLE_DOCKER_PHP_VERSION=7.3
# export MOODLE_DOCKER_DB=mysql
# export MOODLE_DOCKER_WEB_HOST=<Docker Engine IP/Host e.g. 1.2.3.4, even 127.0.0.1>
# export MOODLE_DOCKER_WEB_PORT=81
# cp config.docker-template.php $MOODLE_DOCKER_WWWROOT/config.php
# bin/moodle-docker-compose up -d
# Check the public port for the private port 80/tcp binding: it should be 81
# bin/moodle-docker-compose port webserver 80
127.0.0.1:81
Due to the localhost binding above - it depends on your Docker environment versions - , if your Docker Host is running on a different host you should apply the following change to moodle-docker code:
# bin/moodle-docker-compose down -v
$ git diff
diff --git a/webserver.port.yml b/webserver.port.yml
index bff93e6..0edfdb7 100644
--- a/webserver.port.yml
+++ b/webserver.port.yml
@@ -2,6 +2,7 @@ version: "2"
services:
webserver:
environment:
+ MOODLE_DOCKER_WEB_HOST: "${MOODLE_DOCKER_WEB_HOST}"
MOODLE_DOCKER_WEB_PORT: "${MOODLE_DOCKER_WEB_PORT}"
ports:
- - "${MOODLE_DOCKER_WEB_PORT}:80"
+ - "${MOODLE_DOCKER_WEB_HOST}:${MOODLE_DOCKER_WEB_PORT}:80"
and re-apply the sequence of command above to get:
# bin/moodle-docker-compose port webserver 80
0.0.0.0:81
Finally:
# bin/moodle-docker-compose exec webserver php admin/cli/install_database.php --agree-license \
--fullname="Docker Moodle Test MDL-63770" --shortname="docker_moodle_MDL-63770" \
--adminpass="test" --adminemail="admin@example.com"
-------------------------------------------------------------------------------
== Setting up database ==
-->System
[...]
-->logstore_standard
++ Success ++
Installation completed successfully.
Before applying the fix
- [EXPECTED] Browse the hostname above, prepending http:// and using the public port above (81): Moodle home appears and you are able to successfully log in as admin/test. Log out and close the browser.
- Change the Web Server configuration:
# bin/moodle-docker-compose exec webserver sh -c 'echo "UseCanonicalName On\nUseCanonicalPhysicalPort On" > /etc/apache2/conf-enabled/usecanonicalphysicalport.conf'
# bin/moodle-docker-compose restart webserver
- [EXPECTED] Try browsing the same home: you'll get an error from your browser telling about too many redirects, like: ERR_TOO_MANY_REDIRECTS
- Allow Port Forwarding by enabling Reverse Proxy setting in Moodle:
# sed -i '$i ''$CFG->reverseproxy = true;' $MOODLE_DOCKER_WWWROOT/config.php
- [ERROR] Browse again the same target above: no more redirects but Error code: reverseproxyabused
- Stop the environment, without closing the shell
# bin/moodle-docker-compose down -v