Quantum metadata handler now uses X-Forwarded-For
fixes bug 1097524 The guest IP address was not properly forwarded from the Quantum metadata proxy. This patch adds support in Nova for reading this X-Forwarded-For header. Previously, the internal proxy IP was mistakenly used exposing internal infrastructure details. Change-Id: I6d7d21e2aea4ca5debf1ca4ba6802012537f78a5
This commit is contained in:
parent
77dbed11a6
commit
2fc0097c5b
@ -142,7 +142,7 @@ class MetadataRequestHandler(wsgi.Application):
|
|||||||
def _handle_instance_id_request(self, req):
|
def _handle_instance_id_request(self, req):
|
||||||
instance_id = req.headers.get('X-Instance-ID')
|
instance_id = req.headers.get('X-Instance-ID')
|
||||||
signature = req.headers.get('X-Instance-ID-Signature')
|
signature = req.headers.get('X-Instance-ID-Signature')
|
||||||
remote_address = req.remote_addr
|
remote_address = req.headers.get('X-Forwarded-For')
|
||||||
|
|
||||||
# Ensure that only one header was passed
|
# Ensure that only one header was passed
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
import base64
|
import base64
|
||||||
import copy
|
import copy
|
||||||
|
import hashlib
|
||||||
|
import hmac
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -461,15 +463,19 @@ class MetadataHandlerTestCase(test.TestCase):
|
|||||||
expected_instance_id = 'a-b-c-d'
|
expected_instance_id = 'a-b-c-d'
|
||||||
|
|
||||||
def fake_get_metadata(instance_id, remote_address):
|
def fake_get_metadata(instance_id, remote_address):
|
||||||
if instance_id == expected_instance_id:
|
if remote_address is None:
|
||||||
|
raise Exception('Expected X-Forwared-For header')
|
||||||
|
elif instance_id == expected_instance_id:
|
||||||
return self.mdinst
|
return self.mdinst
|
||||||
else:
|
else:
|
||||||
# raise the exception to aid with 500 response code test
|
# raise the exception to aid with 500 response code test
|
||||||
raise Exception("Expected instance_id of %s, got %s" %
|
raise Exception("Expected instance_id of %s, got %s" %
|
||||||
(expected_instance_id, instance_id))
|
(expected_instance_id, instance_id))
|
||||||
|
|
||||||
signed = ('d98d0dd53b026a24df2c06b464ffa5da'
|
signed = hmac.new(
|
||||||
'db922ae41af7bd3ecc3cae75aef65771')
|
CONF.quantum_metadata_proxy_shared_secret,
|
||||||
|
expected_instance_id,
|
||||||
|
hashlib.sha256).hexdigest()
|
||||||
|
|
||||||
# try a request with service disabled
|
# try a request with service disabled
|
||||||
response = fake_request(
|
response = fake_request(
|
||||||
@ -481,8 +487,33 @@ class MetadataHandlerTestCase(test.TestCase):
|
|||||||
self.assertEqual(response.status_int, 200)
|
self.assertEqual(response.status_int, 200)
|
||||||
|
|
||||||
# now enable the service
|
# now enable the service
|
||||||
|
|
||||||
self.flags(service_quantum_metadata_proxy=True)
|
self.flags(service_quantum_metadata_proxy=True)
|
||||||
|
response = fake_request(
|
||||||
|
self.stubs, self.mdinst,
|
||||||
|
relpath="/2009-04-04/user-data",
|
||||||
|
address="192.192.192.2",
|
||||||
|
fake_get_metadata_by_instance_id=fake_get_metadata,
|
||||||
|
headers={'X-Forwarded-For': '192.192.192.2',
|
||||||
|
'X-Instance-ID': 'a-b-c-d',
|
||||||
|
'X-Instance-ID-Signature': signed})
|
||||||
|
|
||||||
|
self.assertEqual(response.status_int, 200)
|
||||||
|
self.assertEqual(response.body,
|
||||||
|
base64.b64decode(self.instance['user_data']))
|
||||||
|
|
||||||
|
# mismatched signature
|
||||||
|
response = fake_request(
|
||||||
|
self.stubs, self.mdinst,
|
||||||
|
relpath="/2009-04-04/user-data",
|
||||||
|
address="192.192.192.2",
|
||||||
|
fake_get_metadata_by_instance_id=fake_get_metadata,
|
||||||
|
headers={'X-Forwarded-For': '192.192.192.2',
|
||||||
|
'X-Instance-ID': 'a-b-c-d',
|
||||||
|
'X-Instance-ID-Signature': ''})
|
||||||
|
|
||||||
|
self.assertEqual(response.status_int, 403)
|
||||||
|
|
||||||
|
# without X-Forwarded-For
|
||||||
response = fake_request(
|
response = fake_request(
|
||||||
self.stubs, self.mdinst,
|
self.stubs, self.mdinst,
|
||||||
relpath="/2009-04-04/user-data",
|
relpath="/2009-04-04/user-data",
|
||||||
@ -491,29 +522,22 @@ class MetadataHandlerTestCase(test.TestCase):
|
|||||||
headers={'X-Instance-ID': 'a-b-c-d',
|
headers={'X-Instance-ID': 'a-b-c-d',
|
||||||
'X-Instance-ID-Signature': signed})
|
'X-Instance-ID-Signature': signed})
|
||||||
|
|
||||||
self.assertEqual(response.status_int, 200)
|
self.assertEqual(response.status_int, 500)
|
||||||
self.assertEqual(response.body,
|
|
||||||
base64.b64decode(self.instance['user_data']))
|
# unexpected Instance-ID
|
||||||
|
signed = hmac.new(
|
||||||
|
CONF.quantum_metadata_proxy_shared_secret,
|
||||||
|
'z-z-z-z',
|
||||||
|
hashlib.sha256).hexdigest()
|
||||||
|
|
||||||
response = fake_request(
|
response = fake_request(
|
||||||
self.stubs, self.mdinst,
|
self.stubs, self.mdinst,
|
||||||
relpath="/2009-04-04/user-data",
|
relpath="/2009-04-04/user-data",
|
||||||
address="192.192.192.2",
|
address="192.192.192.2",
|
||||||
fake_get_metadata_by_instance_id=fake_get_metadata,
|
fake_get_metadata_by_instance_id=fake_get_metadata,
|
||||||
headers={'X-Instance-ID': 'a-b-c-d',
|
headers={'X-Forwarded-For': '192.192.192.2',
|
||||||
'X-Instance-ID-Signature': ''})
|
'X-Instance-ID': 'z-z-z-z',
|
||||||
|
'X-Instance-ID-Signature': signed})
|
||||||
self.assertEqual(response.status_int, 403)
|
|
||||||
|
|
||||||
response = fake_request(
|
|
||||||
self.stubs, self.mdinst,
|
|
||||||
relpath="/2009-04-04/user-data",
|
|
||||||
address="192.192.192.2",
|
|
||||||
fake_get_metadata_by_instance_id=fake_get_metadata,
|
|
||||||
headers={'X-Instance-ID': 'z-z-z-z',
|
|
||||||
'X-Instance-ID-Signature': '81f42e3fc77ba3a3e8d83142746e0'
|
|
||||||
'8387b96cbc5bd2474665192d2ec28'
|
|
||||||
'8ffb67'})
|
|
||||||
self.assertEqual(response.status_int, 500)
|
self.assertEqual(response.status_int, 500)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user