mirror of
https://github.com/flarum/framework.git
synced 2024-11-26 10:14:16 +08:00
Fixes wrong IP address when using a reverse proxy (#2236)
Added reverse proxy support to preserve forwarded IPs
This commit is contained in:
parent
89a2a9786e
commit
a6cb962f97
|
@ -25,6 +25,7 @@ use Flarum\Http\RouteHandlerFactory;
|
|||
use Flarum\Http\UrlGenerator;
|
||||
use Flarum\Locale\LocaleManager;
|
||||
use Flarum\Settings\Event\Saved;
|
||||
use Illuminate\Support\Arr;
|
||||
use Laminas\Stratigility\MiddlewarePipe;
|
||||
|
||||
class AdminServiceProvider extends AbstractServiceProvider
|
||||
|
@ -48,6 +49,7 @@ class AdminServiceProvider extends AbstractServiceProvider
|
|||
$this->app->singleton('flarum.admin.middleware', function () {
|
||||
return [
|
||||
'flarum.admin.error_handler',
|
||||
'flarum.admin.proxy_middleware',
|
||||
HttpMiddleware\ParseJsonBody::class,
|
||||
HttpMiddleware\StartSession::class,
|
||||
HttpMiddleware\RememberFromCookie::class,
|
||||
|
@ -66,6 +68,15 @@ class AdminServiceProvider extends AbstractServiceProvider
|
|||
);
|
||||
});
|
||||
|
||||
$this->app->bind('flarum.admin.proxy_middleware', function () {
|
||||
$config = $this->app->make('flarum.config');
|
||||
|
||||
return new HttpMiddleware\ProxyAddress(
|
||||
Arr::get($config, 'reverse_proxy.enabled', false),
|
||||
Arr::get($config, 'reverse_proxy.allowed', ['127.0.0.1'])
|
||||
);
|
||||
});
|
||||
|
||||
$this->app->singleton('flarum.admin.handler', function () {
|
||||
$pipe = new MiddlewarePipe;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ use Flarum\Http\Middleware as HttpMiddleware;
|
|||
use Flarum\Http\RouteCollection;
|
||||
use Flarum\Http\RouteHandlerFactory;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Illuminate\Support\Arr;
|
||||
use Laminas\Stratigility\MiddlewarePipe;
|
||||
|
||||
class ApiServiceProvider extends AbstractServiceProvider
|
||||
|
@ -45,6 +46,7 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||
$this->app->singleton('flarum.api.middleware', function () {
|
||||
return [
|
||||
'flarum.api.error_handler',
|
||||
'flarum.api.proxy_middleware',
|
||||
HttpMiddleware\ParseJsonBody::class,
|
||||
Middleware\FakeHttpMethods::class,
|
||||
HttpMiddleware\StartSession::class,
|
||||
|
@ -64,6 +66,15 @@ class ApiServiceProvider extends AbstractServiceProvider
|
|||
);
|
||||
});
|
||||
|
||||
$this->app->bind('flarum.api.proxy_middleware', function () {
|
||||
$config = $this->app->make('flarum.config');
|
||||
|
||||
return new HttpMiddleware\ProxyAddress(
|
||||
Arr::get($config, 'reverse_proxy.enabled', false),
|
||||
Arr::get($config, 'reverse_proxy.allowed', ['127.0.0.1'])
|
||||
);
|
||||
});
|
||||
|
||||
$this->app->singleton('flarum.api.handler', function () {
|
||||
$pipe = new MiddlewarePipe;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class CreateDiscussionController extends AbstractCreateController
|
|||
protected function data(ServerRequestInterface $request, Document $document)
|
||||
{
|
||||
$actor = $request->getAttribute('actor');
|
||||
$ipAddress = Arr::get($request->getServerParams(), 'REMOTE_ADDR', '127.0.0.1');
|
||||
$ipAddress = $request->getAttribute('ipAddress');
|
||||
|
||||
if (! $request->getAttribute('bypassFloodgate')) {
|
||||
$this->floodgate->assertNotFlooding($actor);
|
||||
|
|
|
@ -63,7 +63,7 @@ class CreatePostController extends AbstractCreateController
|
|||
$actor = $request->getAttribute('actor');
|
||||
$data = Arr::get($request->getParsedBody(), 'data', []);
|
||||
$discussionId = Arr::get($data, 'relationships.discussion.data.id');
|
||||
$ipAddress = Arr::get($request->getServerParams(), 'REMOTE_ADDR', '127.0.0.1');
|
||||
$ipAddress = $request->getAttribute('ipAddress');
|
||||
|
||||
if (! $request->getAttribute('bypassFloodgate')) {
|
||||
$this->floodgate->assertNotFlooding($actor);
|
||||
|
|
|
@ -29,6 +29,7 @@ use Flarum\Locale\LocaleManager;
|
|||
use Flarum\Settings\Event\Saved;
|
||||
use Flarum\Settings\Event\Saving;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Illuminate\Support\Arr;
|
||||
use Laminas\Stratigility\MiddlewarePipe;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
|
||||
|
@ -57,6 +58,7 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||
$this->app->singleton('flarum.forum.middleware', function () {
|
||||
return [
|
||||
'flarum.forum.error_handler',
|
||||
'flarum.forum.proxy_middleware',
|
||||
HttpMiddleware\ParseJsonBody::class,
|
||||
HttpMiddleware\CollectGarbage::class,
|
||||
HttpMiddleware\StartSession::class,
|
||||
|
@ -76,6 +78,15 @@ class ForumServiceProvider extends AbstractServiceProvider
|
|||
);
|
||||
});
|
||||
|
||||
$this->app->bind('flarum.forum.proxy_middleware', function () {
|
||||
$config = $this->app->make('flarum.config');
|
||||
|
||||
return new HttpMiddleware\ProxyAddress(
|
||||
Arr::get($config, 'reverse_proxy.enabled', false),
|
||||
Arr::get($config, 'reverse_proxy.allowed', ['127.0.0.1'])
|
||||
);
|
||||
});
|
||||
|
||||
$this->app->singleton('flarum.forum.handler', function () {
|
||||
$pipe = new MiddlewarePipe;
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Http\Exception;
|
||||
|
||||
use Exception;
|
||||
use Flarum\Foundation\KnownError;
|
||||
|
||||
class ProxyNotAllowedException extends Exception implements KnownError
|
||||
{
|
||||
public function getType(): string
|
||||
{
|
||||
return 'reverse_proxy_not_allowed';
|
||||
}
|
||||
}
|
72
framework/core/src/Http/Middleware/ProxyAddress.php
Normal file
72
framework/core/src/Http/Middleware/ProxyAddress.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Http\Middleware;
|
||||
|
||||
use Flarum\Http\Exception\ProxyNotAllowedException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface as Middleware;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
class ProxyAddress implements Middleware
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $allowedAddresses;
|
||||
|
||||
/**
|
||||
* @param bool $enabled
|
||||
* @param array $allowedAddresses
|
||||
*/
|
||||
public function __construct($enabled, $allowedAddresses)
|
||||
{
|
||||
$this->enabled = $enabled;
|
||||
$this->allowedAddresses = $allowedAddresses;
|
||||
}
|
||||
|
||||
private function wildcardMatch(string $ipAddress): bool
|
||||
{
|
||||
foreach ($this->allowedAddresses as $allowedAddress) {
|
||||
if (fnmatch($allowedAddress, $ipAddress)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$serverParams = $request->getServerParams();
|
||||
$ipAddress = Arr::get($serverParams, 'REMOTE_ADDR', '127.0.0.1');
|
||||
|
||||
if ($this->enabled) {
|
||||
if ($this->wildcardMatch($ipAddress)) {
|
||||
// standard header for proxies, see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
|
||||
$ipAddress = Arr::get($serverParams, 'X_FORWARDED_FOR', $ipAddress);
|
||||
$ipAddress = Arr::get($serverParams, 'HTTP_CLIENT_IP', $ipAddress);
|
||||
$ipAddress = Arr::get($serverParams, 'X_PROXYUSER_IP', $ipAddress);
|
||||
} else {
|
||||
throw new ProxyNotAllowedException();
|
||||
}
|
||||
}
|
||||
|
||||
$request = $request->withAttribute('ipAddress', $ipAddress);
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user