Project

General

Profile

Actions

Bug #26088

closed

Pagetree of 4.5.2 backend is not loaded via Proxy

Added by Sacha Vorbeck about 13 years ago. Updated over 9 years ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
-
Target version:
-
Start date:
2011-04-18
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
4.5
PHP Version:
Tags:
Complexity:
Is Regression:
No
Sprint Focus:

Description

For security reasons, some of our TYPO3-backends are only accessible via a proxy. Let`s assume that the name of the proxy is "proxy.server2.de" and that it points to a webserver called "direct.server2.de". If I call a TYPO3 4.5.2 backend via proxy, I get the following error:

Connection Problem
Sorry, but an error occurred while connecting to the server. Please check your network connection.

If I look at the http headers in Firefox while loading the BE via Proxy:

00:00:23.630    0.928    717    (1377)    GET    304    application/javascript    http://proxy.server2.de/typo3temp/compressor/flashmessages-b0c0fac69ab73fd0631227ec3ccbfaf4.js?1303115435
00:00:40.573    0.151    595    381    OPTIONS    303    text/html (NS_ERROR_DOM_BAD_URI)    http://direct.server2.de/typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree
00:00:40.897    0.642    595    381    OPTIONS    303    text/html (NS_ERROR_DOM_BAD_URI)    http://direct.server2.de/typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree
00:00:23.734    0.866    598    381    OPTIONS    303    text/html (NS_ERROR_DOM_BAD_URI)    http://direct.server2.de/typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.ExtDirectStateProvider

I can see that /ajax.php is referenced with the name of the webserver. I suppose that the name of the webserver is obtained via TYPO3_SITE_URL or some other global variable.

If this is the case, could you please implement an optional way of setting the server name those components are loaded from? Maybe config.baseURL or a conf-var from the localconfig.php.


Files

Screen-shot-2011-05-30-at-1.jpg (275 KB) Screen-shot-2011-05-30-at-1.jpg SiteGefühl no-lastname-given, 2011-05-31 15:37

Related issues 1 (0 open1 closed)

Is duplicate of TYPO3 Core - Bug #25266: allow redirect to ssl reverse proxyClosed2011-03-07

Actions
Actions #1

Updated by Sacha Vorbeck about 13 years ago

found the problem in line 157 of file:
t3lib/extjs/class.t3lib_extjs_extdirectapi.php

t3lib_div::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir .
Actions #2

Updated by Steffen Gebert about 13 years ago

Hi Sascha,

do all AJAX calls directly go to the direct server, only those from the Page Tree?

Thanks
Steffen

Actions #3

Updated by Sacha Vorbeck about 13 years ago

Hi Steffen,

thanks for your quick reply. As I only work part time, I will check that out on next Tuesday. But I guess it will happen every time TYPO3_SITE_URL is used as it is filled with the host name of the TYPO3 Installation and not with host name of the proxy that the user enters to access the backend.

Using proxys to protect the backend is a standard procedure in (german) gov-institutions and is according to BSI guidelines.

--
all the best,
Sacha

Actions #4

Updated by SiteGefühl no-lastname-given almost 13 years ago

Wir haben vor dem Apache ein IIS reverse Proxy. Bei uns taucht ebenso das Problem auf (Connection Problem und PageTree wird nicht geladen). Es handelt sich dabei in den meisten Fällen um diese Abfragen, die einen absoluten Pfad (vom Webserver, nicht vom Proxy) enthalten:

http://www.webserver.de/typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.ExtDirectStateProvider
http://www.webserver.de/typo3/ajax.php?ajaxID=ModuleMenu::getData
http://www.webserver.de/typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree

Problem tauchte erst nach dem Update von 4.2 auf 4.5 auf. Aktuell haben wir nun 4.5.3 laufen.

Unschöner workaround:

if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
    $_SERVER['SERVER_NAME'] = 'www.domain.de';
    $_SERVER['HTTP_HOST'] = 'www.domain.de';
}

z.B. in die localconf eintragen.

Ob es hilft im IIS Server Variablen zu überschreiben, weiß ich nicht. Wenn jemand weiß, ob und wie das gehen soll, kann er sich gerne bei mir melden. Ich glaube aber auch, dass es besser wäre die TYPO3 Konstanten selbst zu definieren. Z.B. im Install Tool.

Anbei die Fehlermeldung aus Opera, FF zeigt sie nicht an.

Actions #5

Updated by Ernesto Baschny almost 13 years ago

  • Status changed from New to Needs Feedback

All t3lib_div::getIndpEnv calls that request some info about the server URL (including TYPO3_HOST_ONLY, TYPO3_REQUEST_URL, etc) will at the end come from t3lib_div::getIndpEnv('HTTP_HOST') which does indeed consider the HTTP_X_FORWARDED_HOST _SERVER variable.

As long as $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'] is set! So make sure you have $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'] set to the IP of the reverse proxy that is allowed.

If you have that set and still have a problem, there might be places where the $_SERVER variables are accessed directly instead of going through t3lib_div::getIndpEnv. If this happens in the core, it's a core bug, but it might also happen in extensions.

Thanks for your further input on the issue.

Actions #6

Updated by Steffen Gebert almost 13 years ago

Hi,

could you please check, whether the host names are influenced by t3lib_extjs_extdirectapi::getRoutingUrl()?

Thanks
Steffen

Actions #7

Updated by SiteGefühl no-lastname-given almost 13 years ago

Of course, the reverseProxyIP is set. The Frontend works fine, the problem is in the Backend, especially in Modules with the PageTree. Other modules without the PageTree are accessible.

Changing the TYPO3_SITE_URL in t3lib_extjs_extdirectapi::getRoutingUrl() into the Domain-String has no effect.

Actions #8

Updated by Steffen Gebert almost 13 years ago

Changing the TYPO3_SITE_URL in t3lib_extjs_extdirectapi::getRoutingUrl() into the Domain-String has no effect.

It is the right place. You only have to clear the cache, as the ExtDirect API is cached. Think I will have a bugfix soon.

Actions #9

Updated by Steffen Gebert almost 13 years ago

I guess you have $TYPO3_CONF_VARS['SYS']['reverseProxyHeaderMultiValue'] = 'none', don't you?
Please try setting it to first or last.

See t3lib_div::getIndEnv():

case 'HTTP_HOST':
    $retVal = $_SERVER['HTTP_HOST'];
    if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
        $host = self::trimExplode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
            // choose which host in list to use
        if (count($host)) {
            switch ($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyHeaderMultiValue']) {
                case 'last':
                    $host = array_pop($host);
                    break;
                case 'first':
                    $host = array_shift($host);
                    break;
                case 'none':
                default:
                    $host = '';
                    break;
            }
        }
        if ($host) {
            $retVal = $host;
        }
    }
    break;

I don't know, if the value none makes sense at all. first would IMHO be a good value (I assume that the 2nd proxy adds its X-Forwarded-For: line after the 1st proxy's.

Can you confirm this solution?

Actions #10

Updated by Steffen Gebert almost 13 years ago

I think the mentioned code is badly implemented / hard to understand. Description says:

String: "none","first","last": defines which values of a proxy header (eg HTTP_X_FORWARDED_FOR) to use, if more than one is found. "none" discards the value, "first" and "last" use the first/last of the values in the list.

The discards has to be taken seriously. Having none explicitly discards the HTTP_X_FORWARDED_FOR entry, even if there is only one found. IMHO better would be to have an empty default value and the none to be explicitly set (if it is required for any use case).

What's your opinion on this?

Actions #11

Updated by Steffen Gebert almost 13 years ago

Still no feedback? Sascha and Paulina, does this setup work? Should we change the behavior (at least add a hint to reverseProxyIP that reverseProxyHeaderMultiValue has to be set)?

Actions #12

Updated by Christian Kuhn almost 13 years ago

Please update. Imho this is no hard bug at all, maybe only a stupid default with the first / last handling.

Actions #13

Updated by SiteGefühl no-lastname-given almost 13 years ago

I tried many setups! No one solved the problem. The reverseProxyIP is set and the reverseProxyHeaderMultiValue is set to 'last'. But i also tried the first value. Of course i cleared after the config the cache.

Now I'm using the value first. This might be better?
I changed the function into

    public function getRoutingUrl($namespace) {
        $url = '';
        if (TYPO3_MODE === 'FE') {
            $url = t3lib_div::locationHeaderUrl('?eID=ExtDirect&action=route&namespace=');
        } else {
            $url = t3lib_div::locationHeaderUrl(
                t3lib_div::getIndpEnv('http://www.domain.de/') . TYPO3_mainDir .
                'ajax.php?ajaxID=ExtDirect::route&namespace='
            );
        }
        $url .= rawurlencode($namespace);

        return $url;
    }

Did I understand your suggestion right? After clearing the cache there is still the Error "Uncaught exception: ReferenceError: Security violation" and the TYPO3 "Connection Problem".

Actions #14

Updated by Steffen Gebert almost 13 years ago

.... t3lib_div::getIndpEnv('http://www.domain.de/')  ...

You're really using t3lib_div::getIndpEnv('http://www.domain.de/') in there? the getIndpEnv() must not be called with an URL, of course.

Did I understand your suggestion right? After clearing the cache there is still the Error "Uncaught exception: ReferenceError: Security violation" and the TYPO3 "Connection Problem".

And what happens after reloading the backend? I think that's cause by the wrong getIndpEnv() call, resulting in empty return value (if you really use it that way).

I'm just unsure about the IIS. Could you provide the contents of $_SERVER, please? For me with Nginx it worked fine.

Could you go through and debug t3lib_div::getIndpEnv(), section for HTTP_HOST? It should return the host name of your very first proxy server. Important is that this server fills the X-Forwarded-For: header, thus $_SERVER['HTTP_X_FORWARDED_FOR'] is filled with its hostname.

Actions #15

Updated by Marc Wöhlken over 12 years ago

Hi!
Steffen Gebert wrote:

Could you go through and debug t3lib_div::getIndpEnv(), section for HTTP_HOST? It should return the host name of your very first proxy server. Important is that this server fills the X-Forwarded-For: header, thus $_SERVER['HTTP_X_FORWARDED_FOR'] is filled with its hostname.

I am using a fortinet proxy which fills X-Forwarded-For with the clients IP not the proxy IP.

As far as I understand this should be correct according to e.g. http://en.wikipedia.org/wiki/X-Forwarded-For :

The X-Forwarded-For (XFF) HTTP header field is a de facto standard for identifying the *originating IP address of a client* connecting to a web server through an HTTP proxy or load balancer.

EDIT: O.k. did not recognize that the header field should be filled lik "client, proxy1, proxy2, ...,proxyN"

Actions #16

Updated by Steffen Gebert over 12 years ago

Hi Marc,

okay, it should be HTTP_X_FORWARDED_HOST, of course, not as I wrote above HTTP_X_FORWARDED_FOR.

See Apache Docu

X-Forwarded-Host:
The original host requested by the client in the Host HTTP request header.

This sounds more like there will be only one line (so the first/last doesn't make sense).

And as you corrected (which I also didn't understand in the first place) is that there's only one X-Forwarded-For line containing the comma-separated IP addresses of the origin client and proxies in between.

Marc, are you currently suffering this issue and is there a bug in the t3lib_div logic? Maybe we could have a short chat about it. I really suffer feedback for this issue and I would have closed in a few days, if you wouldn't have posted now.

Thanks
Steffen

Actions #17

Updated by Sacha Vorbeck over 12 years ago

Meanwhile we add the following lines to our default localconf.php:

$GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'] = $_SERVER['REMOTE_ADDR'];
$GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyHeaderMultiValue'] = 'first'; 

so far, we don`t have any problems with core functions or extensions in proxy based portals any more.

The default of the according switch construct in getIndpEnv looks like this:

                            case 'last':
                                $ip = array_pop($ip);
                                break;
                            case 'first':
                                $ip = array_shift($ip);
                                break;
                            case 'none':
                            default:
                                $ip = '';
                                break;
                        }

Would it harm to set the default to $ip = array_shift($ip); instead of nothing?

Actions #18

Updated by Tomasz Grzemski about 11 years ago

We had similiar problem in TYPO3 6.0.

The problem was in Apache Proxy Configuration. We needed to use:
ProxyPreserveHost On

This causes that Ajax request will be correct.

Actions #19

Updated by Alexander Opitz almost 11 years ago

Hi,

this issue is very old, does it still exists with newer versions of TYPO3 CMS (4.5 or 6.1)?

Did the mentioned work around helped?

Actions #20

Updated by Alexander Opitz over 10 years ago

  • Status changed from Needs Feedback to Closed
  • Is Regression set to No

No feedback for over 90 days.

If you think, that this is the wrong decision, then please write to the mailinglist typo3.teams.bugs with issue number and an explanation.

Actions #21

Updated by Fedir RYKHTIK about 10 years ago

On latest TYPO3 all worked for me.

This tutorial helped me : http://www.fabrizio-branca.de/nginx-varnish-apache-magento-typo3.html

Actions #22

Updated by Sacha Vorbeck almost 10 years ago

We still have a problem in TYPO3 6.1 when combining a proxy and SSL.

Here`s my Apache BE-access log:

backend call via https:

192.xxx.xxx.xxx - - [27/May/2014:10:03:40 +0200] "GET /typo3/backend.php HTTP/1.1" 200 6588 "-" 
192.xxx.xxx.xxx - - [27/May/2014:10:03:41 +0200] "GET /typo3/ajax.php?_dc=1401177896523&ajaxID=BackendLogin%3A%3AisTimedOut&skipSessionUpdate=1 HTTP/1.1" 200 443 "https://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:03:41 +0200] "POST /typo3/ajax.php?ajaxID=ModuleMenu::getData HTTP/1.1" 200 12286 "https://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:03:42 +0200] "OPTIONS /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree HTTP/1.1" 200 473 "-" 
192.xxx.xxx.xxx - - [27/May/2014:10:03:42 +0200] "OPTIONS /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree HTTP/1.1" 200 473 "-" 
192.xxx.xxx.xxx - - [27/May/2014:10:03:42 +0200] "OPTIONS /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.ExtDirectStateProvider HTTP/1.1" 200 473 "-" 
192.xxx.xxx.xxx - - [27/May/2014:10:03:43 +0200] "OPTIONS /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.ExtDirectStateProvider HTTP/1.1" 200 473 "-" 
192.xxx.xxx.xxx - - [27/May/2014:10:03:42 +0200] "GET /typo3/mod.php?M=web_list HTTP/1.1" 200 19449 "https://typo3-proxy.domain.com/typo3/backend.php" 

backend call via http:

192.xxx.xxx.xxx - - [27/May/2014:10:04:28 +0200] "GET /typo3/backend.php HTTP/1.1" 200 6588 "-" 
192.xxx.xxx.xxx - - [27/May/2014:10:04:29 +0200] "GET /typo3/ajax.php?_dc=1401177944605&ajaxID=BackendLogin%3A%3AisTimedOut&skipSessionUpdate=1 HTTP/1.1" 200 443 "http://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:04:29 +0200] "POST /typo3/ajax.php?ajaxID=ModuleMenu::getData HTTP/1.1" 200 12286 "http://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:04:30 +0200] "POST /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree HTTP/1.1" 200 2011 "http://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:04:30 +0200] "POST /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.ExtDirectStateProvider HTTP/1.1" 200 1395 "http://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:04:30 +0200] "POST /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree HTTP/1.1" 200 97870 "http://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:04:30 +0200] "GET /typo3/mod.php?M=web_list HTTP/1.1" 200 19450 "http://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:04:31 +0200] "POST /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree HTTP/1.1" 200 4685 "http://typo3-proxy.domain.com/typo3/backend.php" 
192.xxx.xxx.xxx - - [27/May/2014:10:04:33 +0200] "POST /typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.ExtDirectStateProvider HTTP/1.1" 200 1960 "http://typo3-proxy.domain.com/typo3/backend.php" 

So if I load the backend via proxy + https/SSL, the POST requests for "/typo3/ajax.php?ajaxID=ExtDirect::route&namespace=TYPO3.Components.PageTree" won`t be executed and the page tree is not shown.

via HTTP everything works fine.

Actions #23

Updated by Jigal van Hemert almost 10 years ago

  • Status changed from Closed to New

Re-opened per request by Sacha Vorbeck.

Actions #24

Updated by Fedir RYKHTIK almost 10 years ago

Very important moment for Apache vhost after You've configured Nginx:

    SetEnvIf HTTPS on HTTPS=on
Actions #25

Updated by Patrick Lenk almost 10 years ago

I can confirm that.

In the backend an absolute path is used from the webserver not from the proxy.

Example for my SSL Proxy: https://webserver.com/username

Actions #26

Updated by Sacha Vorbeck over 9 years ago

Found another occurence of this problem. This time in the frontend when using RSA for frontend logins. TYPO3 Version 6.2.6:

On line 47 of file /typo3/sysext/rsaauth/Classes/Hook/FrontendLoginHook.php

$additionalHeader .= '<script type="text/javascript" src="' . \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $javascriptPath . $file . '"></script>';

So if you use a SSL Proxy, FE users can`t log-in when using RSA-auth because the JS files for the PW encryption are linked like this:

<script type="text/javascript">var TYPO3FrontendLoginFormRsaEncryptionPublicKeyUrl = '\/index.php?eID=FrontendLoginRsaPublicKey';</script>
<script type="text/javascript" src="http://www.domain.de/typo3/sysext/rsaauth/resources/jsbn/jsbn.js&quot;&gt;&lt;/script>
<script type="text/javascript" src="http://www.domain.de/typo3/sysext/rsaauth/resources/jsbn/prng4.js&quot;&gt;&lt;/script>
<script type="text/javascript" src="http://www.domain.de/typo3/sysext/rsaauth/resources/jsbn/rng.js&quot;&gt;&lt;/script>
<script type="text/javascript" src="http://www.domain.de/typo3/sysext/rsaauth/resources/jsbn/rsa.js&quot;&gt;&lt;/script>
<script type="text/javascript" src="http://www.domain.de/typo3/sysext/rsaauth/resources/jsbn/base64.js&quot;&gt;&lt;/script>
<script type="text/javascript" src="http://www.domain.de/typo3/sysext/rsaauth/resources/FrontendLoginFormRsaEncryption.min.js&quot;&gt;&lt;/script>

As the server is only reachable via https the files can`t be loaded.

Actions #27

Updated by Mathias Schreiber over 9 years ago

  • Status changed from New to Closed

dupe

Actions

Also available in: Atom PDF