Admidio / admidio

Admidio is a free open source user management system for websites of organizations and groups. The system has a flexible role model so that it’s possible to reflect the structure and permissions of your organization.
https://www.admidio.org
GNU General Public License v2.0
336 stars 131 forks source link

Admidio cant set cookies in Docker environment in combination with Traefik #898

Closed leonfilser closed 4 years ago

leonfilser commented 5 years ago

Hi! I am using Admidio in a Docker environment in combination with Traefik used as a reverse proxy. Everytime I try to login the following error appears:

Der Login kann nicht durchgeführt werden, da Ihr Browser das Setzen von Cookies verbietet!

Damit Sie sich erfolgreich anmelden können, müssen Sie Ihren Browser so einstellen, dass dieser Cookies von 0efb778bedda akzeptiert.

English:

The login cannot be carried out, because your browser forbids the setting of cookies!

In order to log in successfully, you must set your browser to accept cookies from 0efb778bedda.

0efb778bedda. is the ID of my Traefik Container

I did a bit of debugging and found out that in admidio/adm_program/system/bootstrap/constants.php there is (probably) an issue on line 55-60

if(isset($_SERVER['HTTP_X_FORWARDED_SERVER']) && $_SERVER['HTTP_X_FORWARDED_SERVER'] !== $_SERVER['HTTP_HOST'])
{
    // if ssl proxy is used than this proxy is the host and the cookie must be set for this
    define('HOST', $_SERVER['HTTP_X_FORWARDED_SERVER'] . $port . '/' . $_SERVER['HTTP_HOST']); // ssl.example.org/my.domain.net
    define('DOMAIN', strstr($_SERVER['HTTP_X_FORWARDED_SERVER'] . $port . ':', ':', true)); // ssl.example.org
}

I replaced the Code with the following and it turned out to work

if(isset($_SERVER['HTTP_X_FORWARDED_SERVER']) && $_SERVER['HTTP_X_FORWARDED_SERVER'] !== $_SERVER['HTTP_HOST'])
{
    // if ssl proxy is used than this proxy is the host and the cookie must be set for this
    define('HOST', $_SERVER['HTTP_X_FORWARDED_HOST'] . $port . '/' . $_SERVER['HTTP_HOST']); // ssl.example.org/my.domain.net
    define('DOMAIN', strstr($_SERVER['HTTP_X_FORWARDED_HOST'] . $port . ':', ':', true)); // ssl.example.org
}

If you want to I can open a pull request to fix this

Fasse commented 5 years ago

Hmm, I'm not sure if your change will work for proxy servers.

The difference between these two values is the following:

We add this to get the hostname of the proxy server, so it will work on ssl if the proxy server is different. We should test this change with someone who use a proxy server before we add this to the code.

sumnerboy12 commented 4 years ago

Is there any progress on this? I would like to run Admidio in docker with Traefik as the reverse proxy also, and currently I can't login. Any known workarounds?

Fasse commented 4 years ago

@sumnerboy12 Did the workaround also work for you?

sumnerboy12 commented 4 years ago

I didn't try it sorry @Fasse. I was in the middle of migrating a whole load of self-hosted services to docker and didn't fancy having to do manual steps. I will try and give it a go in the next week or so if I find time, and report back.

sumnerboy12 commented 4 years ago

@Fasse I can confirm the workaround is working for me also.

Fasse commented 4 years ago

Ok, I will integrate this change to Admidio 4 and than we will see if users with proxy server have problems with this change within the beta phase.

Fasse commented 4 years ago

So add this fix to Admidio 4 and referenced in the sourcecode to this issue. We will see if other environments still work.

Oberfeldwedler commented 4 years ago

I tested leonfilser's snippet and it worked flawlessly.

Edit: I stumbled upon a problem. Unfortunately your snippet seems to break my back-button.

When clicked, it redirected to:

https://admidio.samdyndns.de/admidio.samdyndns.de/adm_program/modules/dates/dates.php

When returning to the unmodified constants.php, the button now redirects to

https://8458d0f83616/admidio.samdyndns.de/adm_program/modules/dates/dates.php

I'll do some further digging.

if(isset($_SERVER['HTTP_X_FORWARDED_SERVER']) && $_SERVER['HTTP_X_FORWARDED_SERVER'] !== $_SERVER['HTTP_HOST'])
{
    // if ssl proxy is used than this proxy is the host and the cookie must be set for this
    //define('HOST', $_SERVER['HTTP_X_FORWARDED_SERVER'] . $port . '/' . $_SERVER['HTTP_HOST']); // ssl.example.org/my.domain.net

     //This is what i am using:
    define('HOST',  $_SERVER['HTTP_HOST']); // ssl.example.org/my.domain.net
    define('DOMAIN', strstr($_SERVER['HTTP_X_FORWARDED_SERVER'] . $port . ':', ':', true)); // ssl.example.org
}

I have to admit, that i don't really know what I'm doing, but i just removed "$_SERVER['HTTP_X_FORWARDED_SERVER']" and the port from the host constant. This did the trick.

This: https://admidio.samdyndns.de/admidio.samdyndns.de/adm_program/modules/dates/dates.php

Turned into this: https://admidio.samdyndns.de/adm_program/modules/dates/dates.php

My setup and my Headers: Docker traefik as a reverse proxy php:7.4-fpm nginx:1.19.2 nginx.conf ``` # user 1006 1006; pid /tmp/nginx.pid; events { worker_connections 1024; ## Default: 1024 } http { include mime.types; index index.php; client_body_temp_path /tmp/client_temp; proxy_temp_path /tmp/proxy_temp_path; fastcgi_temp_path /tmp/fastcgi_temp; uwsgi_temp_path /tmp/uwsgi_temp; scgi_temp_path /tmp/scgi_temp; # Upstream to abstract backend connection(s) for php upstream php { # server unix:/tmp/php-cgi.socket; server php:9000; } server { ## Your website name goes here. server_name admidio.samdyndns.de; ## Your only path reference. root /var/www/html/admidio; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location / { # This is cool because no php is touched for static content. # include the "?$args" part so non-default permalinks doesn't break when using query string try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini include fastcgi_params; fastcgi_intercept_errors on; fastcgi_pass php; #The following parameter can be also included in fastcgi_params file fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; } } } ``` ``` X-Real-Ip: 93.213.207.172 X-Forwarded-Server: 8458d0f83616 X-Forwarded-Proto: https X-Forwarded-Port: 443 X-Forwarded-Host: admidio.samdyndns.de X-Forwarded-For: 93.213.207.172 Upgrade-Insecure-Requests: 1 Sec-Fetch-User: ?1 Sec-Fetch-Site: none Sec-Fetch-Mode: navigate Sec-Fetch-Dest: document Cookie: ADMIDIO_Biketeam_admidio_adm_SESSION_ID=pd8fu4k2ctf0ng6n1ns7c6fr5r; ADMIDIO_Biketeam_admidio_adm_cookieconsent_status=dismiss; ADMIDIO_Biketeam_admidio_adm_AUTO_LOGIN_ID=2%3AAbwoauaNKI2voIw3k30yvpkd5VxsOOFjADMO3LWQ Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7 Accept-Encoding: gzip, deflate, br Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Host: admidio.samdyndns.de Content-Length: Content-Type: PHP_EXTRA_CONFIGURE_ARGS=--enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --disable-cgi HOSTNAME=eae7974e7a71 PHP_INI_DIR=/usr/local/etc/php HOME=/ PHP_LDFLAGS=-Wl,-O1 -pie PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 PHP_MD5= PHP_VERSION=7.4.10 GPG_KEYS=42670A7FE4D0441C8E4632349E4FDC074A4EF02D 5A52880781F755608BF815FC910DEB46F53EA312 PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 PHP_ASC_URL=https://www.php.net/distributions/php-7.4.10.tar.xz.asc PHP_URL=https://www.php.net/distributions/php-7.4.10.tar.xz PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PHPIZE_DEPS=autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c PWD=/var/www/html PHP_SHA256=c2d90b00b14284588a787b100dee54c2400e7db995b457864d66f00ad64fb010 HTTP_X_REAL_IP=93.213.207.172 HTTP_X_FORWARDED_SERVER=8458d0f83616 HTTP_X_FORWARDED_PROTO=https HTTP_X_FORWARDED_PORT=443 HTTP_X_FORWARDED_HOST=admidio.samdyndns.de HTTP_X_FORWARDED_FOR=93.213.207.172 HTTP_UPGRADE_INSECURE_REQUESTS=1 HTTP_SEC_FETCH_USER=?1 HTTP_SEC_FETCH_SITE=none HTTP_SEC_FETCH_MODE=navigate HTTP_SEC_FETCH_DEST=document HTTP_COOKIE=ADMIDIO_Biketeam_admidio_adm_SESSION_ID=pd8fu4k2ctf0ng6n1ns7c6fr5r; ADMIDIO_Biketeam_admidio_adm_cookieconsent_status=dismiss; ADMIDIO_Biketeam_admidio_adm_AUTO_LOGIN_ID=2%3AAbwoauaNKI2voIw3k30yvpkd5VxsOOFjADMO3LWQ HTTP_ACCEPT_LANGUAGE=de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7 HTTP_ACCEPT_ENCODING=gzip, deflate, br HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 HTTP_USER_AGENT=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 HTTP_HOST=admidio.samdyndns.de SERVER_NAME=admidio.samdyndns.de SERVER_PORT=80 SERVER_ADDR=172.21.0.5 REMOTE_PORT=52408 REMOTE_ADDR=172.21.0.2 SERVER_PROTOCOL=HTTP/1.1 DOCUMENT_ROOT=/var/www/html/admidio DOCUMENT_URI=/index.php REQUEST_URI=/ SCRIPT_NAME=/index.php SCRIPT_FILENAME=/var/www/html/admidio/index.php CONTENT_LENGTH= CONTENT_TYPE= REQUEST_METHOD=GET QUERY_STRING= SERVER_SOFTWARE=nginx GATEWAY_INTERFACE=CGI/1.1 FCGI_ROLE=RESPONDER PHP_SELF=/index.php REQUEST_TIME_FLOAT=1601213563.4432 REQUEST_TIME=1601213563 ```
Fasse commented 1 year ago

Now also changed the condition check from if (isset($_SERVER['HTTP_X_FORWARDED_SERVER']) && $_SERVER['HTTP_X_FORWARDED_SERVER'] !== $_SERVER['HTTP_HOST']) to if (isset($_SERVER['HTTP_X_FORWARDED_HOST']) && $_SERVER['HTTP_X_FORWARDED_HOST'] !== $_SERVER['HTTP_HOST'])