Allow trusted proxy via APP_TRUSTED_PROXIES (#9196)

* Allow trusted proxy via APP_TRUSTED_PROXIES
Set to '*' by default to emulate legacy behavior.
Set up doc describing environment variables

* Create helper to parse environment variables into arrays properly.

* Update doc blocks
This commit is contained in:
Tony Murray 2018-09-13 07:26:42 -05:00 committed by GitHub
parent c222d0e516
commit 79333c45f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 271 additions and 5 deletions

48
LibreNMS/Util/Env.php Normal file
View File

@ -0,0 +1,48 @@
<?php
/**
* Env.php
*
* Helpers to interact with environment variables.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Util;
class Env
{
/**
* Parse comma separated environment variable into an array.
*
* @param string $env_name
* @param mixed $default
* @param array $except Ignore these values and return the unexploded string
* @return array|mixed
*/
public static function parseArray($env_name, $default = null, $except = [''])
{
$value = env($env_name, $default);
if (is_string($value) && !in_array($value, $except)) {
$value = explode(',', $value);
}
return $value;
}
}

View File

@ -19,6 +19,7 @@ class Kernel extends HttpKernel
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\Fideloper\Proxy\TrustProxies::class,
];
/**

View File

@ -49,6 +49,7 @@
"oriceon/toastr-5-laravel": "dev-master",
"wpb/string-blade-compiler": "3.4.x-dev",
"fico7489/laravel-pivot": "*",
"fideloper/proxy": "^4.0",
"vlucas/phpdotenv": "2.4.0",
"doctrine/inflector": "1.1.*",

56
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "dda22b18b92903eddb7a35e421dce8bf",
"content-hash": "235afb0a259569a0377d16a27ccc9dc0",
"packages": [
{
"name": "amenadiel/jpgraph",
@ -469,6 +469,60 @@
],
"time": "2018-03-08T16:05:59+00:00"
},
{
"name": "fideloper/proxy",
"version": "4.0.0",
"source": {
"type": "git",
"url": "https://github.com/fideloper/TrustedProxy.git",
"reference": "cf8a0ca4b85659b9557e206c90110a6a4dba980a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fideloper/TrustedProxy/zipball/cf8a0ca4b85659b9557e206c90110a6a4dba980a",
"reference": "cf8a0ca4b85659b9557e206c90110a6a4dba980a",
"shasum": ""
},
"require": {
"illuminate/contracts": "~5.0",
"php": ">=5.4.0"
},
"require-dev": {
"illuminate/http": "~5.6",
"mockery/mockery": "~1.0",
"phpunit/phpunit": "^6.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Fideloper\\Proxy\\TrustedProxyServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Fideloper\\Proxy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Fidao",
"email": "fideloper@gmail.com"
}
],
"description": "Set trusted proxies for Laravel",
"keywords": [
"load balancing",
"proxy",
"trusted proxy"
],
"time": "2018-02-07T20:20:57+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "6.3.3",

View File

@ -167,6 +167,7 @@ return [
*/
Laravel\Tinker\TinkerServiceProvider::class,
Kamaln7\Toastr\ToastrServiceProvider::class,
Fideloper\Proxy\TrustedProxyServiceProvider::class,
/*
* Application Service Providers...

51
config/trustedproxy.php Normal file
View File

@ -0,0 +1,51 @@
<?php
return [
/*
* Set trusted proxy IP addresses.
*
* Both IPv4 and IPv6 addresses are
* supported, along with CIDR notation.
*
* The "*" character is syntactic sugar
* within TrustedProxy to trust any proxy
* that connects directly to your server,
* a requirement when you cannot know the address
* of your proxy (e.g. if using ELB or similar).
*
*/
'proxies' => \LibreNMS\Util\Env::parseArray('APP_TRUSTED_PROXIES', '*', ['', '*', '**']),
/*
* To trust one or more specific proxies that connect
* directly to your server, use an array of IP addresses:
*/
# 'proxies' => ['192.168.1.1'],
/*
* Or, to trust all proxies that connect
* directly to your server, use a "*"
*/
# 'proxies' => '*',
/*
* Which headers to use to detect proxy related data (For, Host, Proto, Port)
*
* Options include:
*
* - Illuminate\Http\Request::HEADER_X_FORWARDED_ALL (use all x-forwarded-* headers to establish trust)
* - Illuminate\Http\Request::HEADER_FORWARDED (use the FORWARDED header to establish trust)
*
* @link https://symfony.com/doc/current/deployment/proxies.html
*/
'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_ALL,
// 'headers' => [
// (defined('Illuminate\Http\Request::HEADER_FORWARDED') ? Illuminate\Http\Request::HEADER_FORWARDED : 'forwarded') => 'FORWARDED',
// \Illuminate\Http\Request::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
// \Illuminate\Http\Request::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
// \Illuminate\Http\Request::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
// \Illuminate\Http\Request::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
// ]
];

View File

@ -22,7 +22,7 @@ Like anyone, we appreciate the work people put in to find flaws in software and
to do so with LibreNMS, this will lead to better quality and more secure software for everyone.
If you think you've found a vulnerability and want to discuss it with some of the core team then
you can email us at [team@librenms.org](team@librenms.org) and we will endeavour to get back to
you can email us at [team@librenms.org](mailto:team@librenms.org) and we will endeavour to get back to
as quick as we can, this is usually within 24 hours.
We are happy to attribute credit to the findings but we ask that we're given a chance to patch

View File

@ -0,0 +1,46 @@
# Environment Variables
LibreNMS allows certain settings to be set via the environment or through the .env file.
## Database
Set the variables to connect to the database. The default values are shown below.
```dotenv
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=librenms
DB_USERNAME=librenms
DB_PASSWORD=
DB_SOCKET=
```
## Trusted Reverse Proxies
A comma separated list of trusted reverse proxy IPs or CIDR.
For legacy reasons the default is `'*'`, which means any proxy is allowed.
`'**'` means trust any proxy up the chain.
```dotenv
APP_TRUSTED_PROXIES=192.168.1.0/24,192.167.8.20
```
## User / Group
The user and group that LibreNMS should operate as.
Group will default to the same as the user if unset.
```dotenv
LIBRENMS_USER=librenms
LIBRENMS_GROUP=librenms
```
## Debug
Increases the amount of information shown when an error occurs.
> WARNING: This may leak information, do not leave enabled.
```dotenv
APP_DEBUG=true
```

View File

@ -32,6 +32,7 @@ source: Support/FAQ.md
- [Why would alert un-mute itself](#faq32)
- [How do I change the Device Type?](#faq33)
- [Where do I update my database credentials?](#faq-where-do-i-update-my-database-credentials)
- [My reverse proxy is not working](#my-reverse-proxy-is-not-working)
### Developing
- [How do I add support for a new OS?](#faq8)
@ -370,11 +371,18 @@ $config['db_pass'] = '';
$config['db_name'] = '';
```
.env:
[.env](../Support/Environment-Variables.md#database):
```bash
DB_HOST=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
DB_PORT=
```
```
### My reverse proxy is not working
Make sure your proxy is passing the proper variables.
At a minimum: X-Forwarded-For and X-Forwarded-Proto (X-Forwarded-Port if needed)
You also need to [Set the proxy or proxies as trusted](../Support/Environment-Variables.md#trusted-reverse-proxies)

View File

@ -31,9 +31,13 @@ $config['log_dir'] = $config['install_dir'].'/logs';
// MySQL Debug level
$config['mysql_log_level'] = 'ERROR';
//MySQL port
//MySQL Settings
$config['db_port'] = 3306;
$config['db_socket'] = null;
$config['db_name'] = 'librenms';
$config['db_user'] = 'librenms';
$config['db_pass'] = null;
$config['db_socket'] = null;
// What is my own hostname (used to identify this host in its own database)
$config['own_hostname'] = 'localhost';

View File

@ -54,6 +54,7 @@ pages:
- 5. Advanced Setup:
- Support/1-Minute-Polling.md
- Fast Ping Checking: Extensions/Fast-Ping-Check.md
- Support/Environment-Variables.md
- Configuration docs: Support/Configuration.md
- Authentication Options: Extensions/Authentication.md
- Two-Factor Auth: Extensions/Two-Factor-Auth.md

View File

@ -0,0 +1,51 @@
<?php
/**
* EnvTest.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Tests\Unit\Util;
use LibreNMS\Tests\TestCase;
use LibreNMS\Util\Env;
class EnvTest extends TestCase
{
public function testParseArray()
{
putenv('PARSETEST=one,two');
$this->assertSame(['one', 'two'], Env::parseArray('PARSETEST'), 'Could not parse simple array');
$this->assertSame(['default'], Env::parseArray('PARSETESTNOTSET', 'default'), 'Did not get default value as expected');
$this->assertSame(null, Env::parseArray('PARSETESTNOTSET'), 'Did not get null as expected when env not set');
$this->assertSame(3, Env::parseArray('PARSETESTNOTSET', 3), 'Did not get default value (non-array) as expected');
$this->assertSame('default', Env::parseArray('PARSETESTNOTSET', 'default', ['default']), 'Did not get default value as expected, excluding it from exploding');
putenv('PARSETEST=');
$this->assertSame([''], Env::parseArray('PARSETEST', null, []), 'Did not get empty string as expected when env set to empty');
putenv('PARSETEST=*');
$this->assertSame('*', Env::parseArray('PARSETEST', null, ['*', '*']), 'Did not properly ignore exclude values');
// clean the environment
putenv('PARSETEST');
}
}