diff --git a/config/global.ini.php b/config/global.ini.php index 3cb99030981e176c21cd4af281936d20e2cc633c..218c1dee5f6be3411b5ae7634bd8c490540667b9 100644 --- a/config/global.ini.php +++ b/config/global.ini.php @@ -186,18 +186,18 @@ reverse_proxy = 0 ; List of proxy headers for client IP addresses ; -; CloudFlare +; CloudFlare (CF-Connecting-IP) ;proxy_client_headers[] = HTTP_CF_CONNECTING_IP ; -; ISP proxy +; ISP proxy (Client-IP) ;proxy_client_headers[] = HTTP_CLIENT_IP ; -; de facto standard +; de facto standard (X-Forwarded-For) ;proxy_client_headers[] = HTTP_X_FORWARDED_FOR ; List of proxy headers for host IP addresses ; -; de facto standard +; de facto standard (X-Forwarded-Host) ;proxy_host_headers[] = HTTP_X_FORWARDED_HOST ; The release server is an essential part of the Piwik infrastructure/ecosystem diff --git a/core/ProxyHeaders.php b/core/ProxyHeaders.php new file mode 100644 index 0000000000000000000000000000000000000000..8116f492367b933a3c1b4690dbd84fdcdc8a5471 --- /dev/null +++ b/core/ProxyHeaders.php @@ -0,0 +1,100 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * @version $Id$ + * + * @category Piwik + * @package Piwik + */ + +/** + * Proxy headers + * + * @package Piwik + */ +class Piwik_ProxyHeaders +{ + /** + * Get protocol information, with the exception of HTTPS + * + * @return string protocol information + */ + public static function getProtocolInformation() + { + if(Piwik_Common::getRequestVar('clientProtocol', 'http', 'string') == 'https') + { + return 'https'; + } + + if(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) + { + return 'SERVER_PORT=443'; + } + + if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') + { + return 'X-Forwarded-Proto'; + } + + if(isset($_SERVER['HTTP_X_FORWARDED_SCHEME']) && strtolower($_SERVER['HTTP_X_FORWARDED_SCHEME']) == 'https') + { + return 'X-Forwarded-Scheme'; + } + + if(isset($_SERVER['HTTP_X_URL_SCHEME']) && strtolower($_SERVER['HTTP_X_URL_SCHEME']) == 'https') + { + return 'X-Url-Scheme'; + } + + return null; + } + + /** + * Get headers present in the HTTP request + * + * @return array HTTP headers + */ + private static function getHeaders($recognizedHeaders) + { + $headers = array(); + + foreach($recognizedHeaders as $header) + { + if(isset($_SERVER[$header])) + { + $headers[] = $header; + } + } + + return $headers; + } + + /** + * Detect proxy client headers + * + * @return array Proxy client HTTP headers + */ + public static function getProxyClientHeaders() + { + return self::getHeaders(array( + 'HTTP_CF_CONNECTING_IP', + 'HTTP_CLIENT_IP', + 'HTTP_X_FORWARDED_FOR', + )); + } + + /** + * Detect proxy host headers + * + * @return array Proxy host HTTP headers + */ + public static function getProxyHostHeaders() + { + return self::getHeaders(array( + 'HTTP_X_FORWARDED_HOST', + )); + } +} diff --git a/core/Updates/1.1.php b/core/Updates/1.1.php index f5a4dce64222bddd53e288afeed2019dd0b03123..15d1a187f98a515d55cb2e2a1fe3f6026b7bff70 100644 --- a/core/Updates/1.1.php +++ b/core/Updates/1.1.php @@ -17,7 +17,9 @@ class Piwik_Updates_1_1 extends Piwik_Updates { static function update($schema = 'Myisam') { - $rootLogin = Zend_Registry::get('config')->superuser->login; + $config = Zend_Registry::get('config'); + + $rootLogin = $config->superuser->login; try { // throws an exception if invalid Piwik::checkValidLoginString($rootLogin); @@ -26,5 +28,30 @@ class Piwik_Updates_1_1 extends Piwik_Updates . $e->getMessage() . ' Edit your config/config.ini.php to change it.'); } + + $generalInfo = $config->General->toArray(); + if(!isset($generalInfo['proxy_client_headers']) && count($headers = Piwik_ProxyHeaders::getProxyClientHeaders()) > 0) + { + $generalInfo['proxy_client_headers'] = $headers; + } + if(!isset($generalInfo['proxy_host_headers']) && count($headers = Piwik_ProxyHeaders::getProxyHostHeaders()) > 0) + { + $generalInfo['proxy_host_headers'] = $headers; + } + if(isset($headers)) + { + if(is_writable( Piwik_Config::getDefaultUserConfigPath() )) + { + $config->General = $generalInfo; + $config->__destruct(); + Piwik::createConfigObject(); + } + else + { + throw new Exception('You appear to be using a proxy server. Edit your config/config.ini.php to configure proxy_client_headers[] and/or proxy_host_headers[].'); + } + } + + Piwik_Updater::updateDatabase(__FILE__, self::getSql()); } } diff --git a/lang/en.php b/lang/en.php index f5f584584ffb9756ab36016ad8ad1a0739cadf7b..cdb002624b9a9bc8739111b41aac83d9e03c906d 100644 --- a/lang/en.php +++ b/lang/en.php @@ -568,8 +568,8 @@ $translations = array( 'Installation_SystemCheckAutoUpdateHelp' => 'Note: Piwik\'s One Click update requires write-permissions to the Piwik folder and its contents.', 'Installation_SystemCheckError' => 'An error occured - must be fixed before you proceed', 'Installation_SystemCheckWarning' => 'Piwik will work normally but some features may be missing', - 'Installation_SystemCheckProtocol' => 'Protocol', - 'Installation_SystemCheckProtocolHelp' => 'If you are behind a reverse proxy, add these lines to config/config.ini.php under the [General] section:', + 'Installation_SystemCheckReverseProxy' => 'Reverse Proxy', + 'Installation_SystemCheckReverseProxyHelp' => 'It appears you are behind a reverse proxy. These lines will be added to config/config.ini.php:', 'Installation_SystemCheckIpv4' => 'IPv4', 'Installation_SystemCheckIpv4Help' => 'You should disable IPv6 in your web server configuration.', 'Installation_SystemCheckTracker' => 'Tracker status', diff --git a/plugins/Installation/Controller.php b/plugins/Installation/Controller.php index fd6bd633fbfd1c966f0c6d7940d6979304f86c57..76246058c7e29e798e1d53830888b40da2b85c3b 100644 --- a/plugins/Installation/Controller.php +++ b/plugins/Installation/Controller.php @@ -104,6 +104,8 @@ class Piwik_Installation_Controller extends Piwik_Controller $this->skipThisStep( __FUNCTION__ ); $view->infos = self::getSystemInformation(); + $this->session->general_infos = $view->infos['general_infos']; + $view->helpMessages = array( 'zlib' => 'Installation_SystemCheckZlibHelp', 'SPL' => 'Installation_SystemCheckSplHelp', @@ -565,8 +567,14 @@ class Piwik_Installation_Controller extends Piwik_Controller $dbInfos = $this->session->db_infos; $config->database = $dbInfos; + if(!empty($this->session->general_infos)) + { + $config->General = $this->session->general_infos; + } + unset($this->session->superuser_infos); unset($this->session->db_infos); + unset($this->session->general_infos); } /** @@ -671,9 +679,9 @@ class Piwik_Installation_Controller extends Piwik_Controller $infos = array(); + $infos['general_infos'] = array(); $infos['directories'] = Piwik::checkDirectoriesWritable(); $infos['can_auto_update'] = Piwik::canAutoUpdate(); - $serverSoftware = isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : ''; if(preg_match('/^Microsoft-IIS\/(.+)/', $serverSoftware, $matches) && version_compare($matches[1], '7') >= 0) @@ -815,14 +823,6 @@ class Piwik_Installation_Controller extends Piwik_Controller $infos['isWindows'] = Piwik_Common::isWindows(); - $infos['protocol_ok'] = true; - $infos['protocol'] = self::getProtocolInformation(); - if(Piwik_Url::getCurrentScheme() == 'http' && - $infos['protocol'] !== null) - { - $infos['protocol_ok'] = false; - } - $integrityInfo = Piwik::getFileIntegrityInformation(); $infos['integrity'] = $integrityInfo[0]; @@ -840,42 +840,21 @@ class Piwik_Installation_Controller extends Piwik_Controller $infos['tracker_status'] = Piwik_Common::getRequestVar('trackerStatus', 0, 'int'); - return $infos; - } - - /** - * Get protocol information, with the exception of HTTPS - * - * @return string protocol information - */ - public static function getProtocolInformation() - { - if(Piwik_Common::getRequestVar('clientProtocol', 'http', 'string') == 'https') - { - return 'https'; - } - - if(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) + $infos['protocol'] = Piwik_ProxyHeaders::getProtocolInformation(); + if(Piwik_Url::getCurrentScheme() == 'http' && $infos['protocol'] !== null) { - return 'SERVER_PORT=443'; + $infos['general_infos']['reverse_proxy'] = '1'; } - - if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') - { - return 'X-Forwarded-Proto'; - } - - if(isset($_SERVER['HTTP_X_FORWARDED_SCHEME']) && strtolower($_SERVER['HTTP_X_FORWARDED_SCHEME']) == 'https') + if(count($headers = Piwik_ProxyHeaders::getProxyClientHeaders()) > 0) { - return 'X-Forwarded-Scheme'; + $infos['general_infos']['proxy_client_headers'] = $headers; } - - if(isset($_SERVER['HTTP_X_URL_SCHEME']) && strtolower($_SERVER['HTTP_X_URL_SCHEME']) == 'https') + if(count($headers = Piwik_ProxyHeaders::getProxyHostHeaders()) > 0) { - return 'X-Url-Scheme'; + $infos['general_infos']['proxy_host_headers'] = $headers; } - return null; + return $infos; } /** diff --git a/plugins/Installation/templates/systemCheck.tpl b/plugins/Installation/templates/systemCheck.tpl index 8525a3b20acf15d5d715c4dd8e1f73ac4f42f9ec..93062f9939567aa54d0f53c5c82ef2ab6904b449 100644 --- a/plugins/Installation/templates/systemCheck.tpl +++ b/plugins/Installation/templates/systemCheck.tpl @@ -226,12 +226,14 @@ {/foreach} </td> </tr> + {if isset($infos.general_infos.reverse_proxy)} <tr> - <td class="label">{'Installation_SystemCheckProtocol'|translate}</td> + <td class="label">{'Installation_SystemCheckReverseProxy'|translate}</td> <td> - {if $infos.protocol_ok}{$ok}{else}{$warning} {$infos.protocol}<br /><i>{'Installation_SystemCheckProtocolHelp'|translate}</i><br /><br /><code>[General]</code><br /><code>reverse_proxy = 1</code><br />{/if} + {$warning} {$infos.protocol}<br /><i>{'Installation_SystemCheckReverseProxyHelp'|translate}</i><br /><br /><code>[General]</code><br /><code>reverse_proxy = 1</code><br /> </td> </tr> + {/if} <tr> <td class="label">{'Installation_SystemCheckIpv4'|translate}</td> <td>