Merge "healthcheck: Ignore proxied requests"
This commit is contained in:
commit
531f39e63c
@ -395,6 +395,8 @@ Reason
|
|||||||
self._source_ranges = [
|
self._source_ranges = [
|
||||||
ipaddress.ip_network(r)
|
ipaddress.ip_network(r)
|
||||||
for r in self._conf_get('allowed_source_ranges')]
|
for r in self._conf_get('allowed_source_ranges')]
|
||||||
|
self._ignore_proxied_requests = self._conf_get(
|
||||||
|
'ignore_proxied_requests')
|
||||||
self._backends = stevedore.NamedExtensionManager(
|
self._backends = stevedore.NamedExtensionManager(
|
||||||
self.NAMESPACE, self._conf_get('backends'),
|
self.NAMESPACE, self._conf_get('backends'),
|
||||||
name_order=True, invoke_on_load=True,
|
name_order=True, invoke_on_load=True,
|
||||||
@ -565,6 +567,13 @@ Reason
|
|||||||
# the request in this middleware.
|
# the request in this middleware.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
if self._ignore_proxied_requests:
|
||||||
|
for hdr in [
|
||||||
|
'FORWARDED', 'FORWARDED_PROTO', 'FORWARDED_HOST',
|
||||||
|
'FORWARDED_FOR', 'FORWARDED_PREFIX']:
|
||||||
|
if req.environ.get("HTTP_X_%s" % hdr):
|
||||||
|
return None
|
||||||
|
|
||||||
results = [ext.obj.healthcheck(req.server_port)
|
results = [ext.obj.healthcheck(req.server_port)
|
||||||
for ext in self._backends]
|
for ext in self._backends]
|
||||||
healthy = self._are_results_healthy(results)
|
healthy = self._are_results_healthy(results)
|
||||||
|
@ -34,6 +34,9 @@ HEALTHCHECK_OPTS = [
|
|||||||
help='A list of network addresses to limit source ip allowed '
|
help='A list of network addresses to limit source ip allowed '
|
||||||
'to access healthcheck information. Any request from ip '
|
'to access healthcheck information. Any request from ip '
|
||||||
'outside of these network addresses are ignored.'),
|
'outside of these network addresses are ignored.'),
|
||||||
|
cfg.BoolOpt('ignore_proxied_requests',
|
||||||
|
default=False,
|
||||||
|
help='Ignore requests with proxy headers.')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,10 +63,13 @@ class HealthcheckTests(test_base.BaseTestCase):
|
|||||||
|
|
||||||
def _do_test_request(self, conf={}, path='/healthcheck',
|
def _do_test_request(self, conf={}, path='/healthcheck',
|
||||||
accept='text/plain', method='GET',
|
accept='text/plain', method='GET',
|
||||||
server_port=80, remote_addr='127.0.0.1'):
|
server_port=80, headers=None,
|
||||||
|
remote_addr='127.0.0.1'):
|
||||||
self.app = healthcheck.Healthcheck(self.application, conf)
|
self.app = healthcheck.Healthcheck(self.application, conf)
|
||||||
req = webob.Request.blank(path, accept=accept, method=method)
|
req = webob.Request.blank(path, accept=accept, method=method)
|
||||||
req.server_port = server_port
|
req.server_port = server_port
|
||||||
|
if headers:
|
||||||
|
req.headers = headers
|
||||||
req.remote_addr = remote_addr
|
req.remote_addr = remote_addr
|
||||||
res = req.get_response(self.app)
|
res = req.get_response(self.app)
|
||||||
return res
|
return res
|
||||||
@ -74,10 +77,12 @@ class HealthcheckTests(test_base.BaseTestCase):
|
|||||||
def _do_test(self, conf={}, path='/healthcheck',
|
def _do_test(self, conf={}, path='/healthcheck',
|
||||||
expected_code=webob.exc.HTTPOk.code,
|
expected_code=webob.exc.HTTPOk.code,
|
||||||
expected_body=b'', accept='text/plain',
|
expected_body=b'', accept='text/plain',
|
||||||
method='GET', server_port=80, remote_addr='127.0.0.1'):
|
method='GET', server_port=80, headers=None,
|
||||||
|
remote_addr='127.0.0.1'):
|
||||||
res = self._do_test_request(conf=conf, path=path,
|
res = self._do_test_request(conf=conf, path=path,
|
||||||
accept=accept, method=method,
|
accept=accept, method=method,
|
||||||
server_port=server_port,
|
server_port=server_port,
|
||||||
|
headers=headers,
|
||||||
remote_addr=remote_addr)
|
remote_addr=remote_addr)
|
||||||
self.assertEqual(expected_code, res.status_int)
|
self.assertEqual(expected_code, res.status_int)
|
||||||
self.assertEqual(expected_body, res.body)
|
self.assertEqual(expected_body, res.body)
|
||||||
@ -215,3 +220,28 @@ class HealthcheckTests(test_base.BaseTestCase):
|
|||||||
expected_code=webob.exc.HTTPOk.code,
|
expected_code=webob.exc.HTTPOk.code,
|
||||||
expected_body=b'Hello, World!!!',
|
expected_body=b'Hello, World!!!',
|
||||||
remote_addr='192.168.3.1')
|
remote_addr='192.168.3.1')
|
||||||
|
|
||||||
|
def test_proxied_not_ignored(self):
|
||||||
|
conf = {}
|
||||||
|
self._do_test(conf,
|
||||||
|
expected_code=webob.exc.HTTPOk.code,
|
||||||
|
headers={'Forwarded-For': 'http://localhost'})
|
||||||
|
|
||||||
|
def test_proxied_ignored(self):
|
||||||
|
conf = {'ignore_proxied_requests': True}
|
||||||
|
modern_headers = {
|
||||||
|
'x-forwarded': 'https://localhost'
|
||||||
|
}
|
||||||
|
self._do_test(conf,
|
||||||
|
expected_code=webob.exc.HTTPOk.code,
|
||||||
|
expected_body=b'Hello, World!!!',
|
||||||
|
headers=modern_headers)
|
||||||
|
legacy_headers = {
|
||||||
|
'x-forwarded-proto': 'https',
|
||||||
|
'x-forwarded-host': 'localhost',
|
||||||
|
'x-forwarded-for': '192.0.2.11',
|
||||||
|
}
|
||||||
|
self._do_test(conf,
|
||||||
|
expected_code=webob.exc.HTTPOk.code,
|
||||||
|
expected_body=b'Hello, World!!!',
|
||||||
|
headers=legacy_headers)
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The new ``[healthcheck] ignore_proxied_requests`` option has been added.
|
||||||
|
When this option is set to true, the healthcheck middleware ignores
|
||||||
|
requests with any of the following headers, which indicates that
|
||||||
|
the requests came through a reverse proxy or a load balancer.
|
||||||
|
|
||||||
|
- ``x-forwarded``
|
||||||
|
- ``x-forwarded-proto``
|
||||||
|
- ``x-forwarded-host``
|
||||||
|
- ``x-forwarded-for``
|
||||||
|
- ``x-forwarded-prefix``
|
Loading…
Reference in New Issue
Block a user