New -k/--insecure command line option
Fix for bug 929591. Change glance to require server certificate validation by default when using https. The standard system CA file will be used if available (and an alternative was not provided). The --insecure option can be used by clients to skip server certificate validation if appropriate. * This change will impact Nova clients accessing glance over https. If the standard CA file is not suitable they will need to provide a CA file or else create an 'insecure' glance client. * Accesses to a https registry server must now perform server certificate validation. * If the package which provides the standard system CA file is installed then that file will be used by default. It probably makes sense for the glance package to have a dependency on whichever package provides the default CA bundle. (In Ubuntu this is 'ca-certificates') Change-Id: I7c83361ba0881559ec77d4baf10dfeb5b8e32185
This commit is contained in:
parent
56efd271ac
commit
0f0fe2ba1b
10
bin/glance
10
bin/glance
@ -754,7 +754,7 @@ def get_client(options):
|
||||
use_ssl=use_ssl,
|
||||
auth_tok=options.auth_token or \
|
||||
os.getenv('OS_TOKEN'),
|
||||
creds=creds)
|
||||
creds=creds, insecure=options.insecure)
|
||||
|
||||
|
||||
def create_options(parser):
|
||||
@ -781,6 +781,12 @@ def create_options(parser):
|
||||
"(http/https) of the glance server, for example "
|
||||
"-U https://localhost:" + str(DEFAULT_PORT) +
|
||||
"/v1 Default: None")
|
||||
parser.add_option('-k', '--insecure', dest="insecure",
|
||||
default=False, action="store_true",
|
||||
help="Explicitly allow glance to perform \"insecure\" "
|
||||
"SSL (https) requests. The server's certificate will "
|
||||
"not be verified against any certificate authorities. "
|
||||
"This option should be used with caution.")
|
||||
parser.add_option('-A', '--auth_token', dest="auth_token",
|
||||
metavar="TOKEN", default=None,
|
||||
help="Authentication token to use to identify the "
|
||||
@ -810,7 +816,7 @@ def create_options(parser):
|
||||
help="Sort results by this image attribute.")
|
||||
parser.add_option('--sort_dir', dest="sort_dir", metavar="[desc|asc]",
|
||||
help="Sort results in this direction.")
|
||||
parser.add_option('-f', '--force', dest="force", metavar="FORCE",
|
||||
parser.add_option('-f', '--force', dest="force",
|
||||
default=False, action="store_true",
|
||||
help="Prevent select actions from requesting "
|
||||
"user confirmation")
|
||||
|
@ -100,6 +100,10 @@ a brief help message, like so::
|
||||
specify the hostname, port and protocol (http/https)
|
||||
of the glance server, for example -U
|
||||
https://localhost:9292/v1 Default: None
|
||||
-k, --insecure Explicitly allow glance to perform insecure SSL
|
||||
requests. The server certificate will not be
|
||||
verified against any certificate authorities.
|
||||
This option should be used with caution.
|
||||
--limit=LIMIT Page size to use while requesting image metadata
|
||||
--marker=MARKER Image index after which to begin pagination
|
||||
--sort_key=KEY Sort results by this image attribute.
|
||||
@ -153,7 +157,7 @@ Important Information about Uploading Images
|
||||
Before we go over the commands for adding an image to Glance, it is
|
||||
important to understand that Glance **does not currently inspect** the image
|
||||
files you add to it. In other words, **Glance only understands what you tell it,
|
||||
via attributes and custom properties**.
|
||||
via attributes and custom properties**.
|
||||
|
||||
If the file extension of the file you upload to Glance ends in '.vhd', Glance
|
||||
**does not** know that the image you are uploading has a disk format of ``vhd``.
|
||||
|
@ -78,10 +78,10 @@ OPTIONS
|
||||
|
||||
**-v, --verbose**
|
||||
Print more verbose output
|
||||
|
||||
|
||||
**-d, --debug**
|
||||
Print more verbose output
|
||||
|
||||
|
||||
**-H ADDRESS, --host=ADDRESS**
|
||||
Address of Glance API host. Default: 0.0.0.0
|
||||
|
||||
@ -90,10 +90,15 @@ OPTIONS
|
||||
|
||||
**-U URL, --url=URL**
|
||||
URL of Glance service. This option can be used to specify the hostname,
|
||||
port and protocol (http/https) of the glance server, for example
|
||||
-U https://localhost:9292/v1
|
||||
port and protocol (http/https) of the glance server, for example
|
||||
-U https://localhost:9292/v1
|
||||
Default: None
|
||||
|
||||
**-k, --insecure**
|
||||
Explicitly allow glance to perform insecure SSL (https) requests.
|
||||
The server certificate will not be verified against any certificate
|
||||
authorities. This option should be used with caution.
|
||||
|
||||
**-A TOKEN, --auth_token=TOKEN**
|
||||
Authentication token to use to identify the client to the glance server
|
||||
|
||||
|
@ -148,13 +148,14 @@ class HTTPSClientAuthConnection(httplib.HTTPSConnection):
|
||||
"""
|
||||
|
||||
def __init__(self, host, port, key_file, cert_file,
|
||||
ca_file, timeout=None):
|
||||
ca_file, timeout=None, insecure=False):
|
||||
httplib.HTTPSConnection.__init__(self, host, port, key_file=key_file,
|
||||
cert_file=cert_file)
|
||||
self.key_file = key_file
|
||||
self.cert_file = cert_file
|
||||
self.ca_file = ca_file
|
||||
self.timeout = timeout
|
||||
self.insecure = insecure
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
@ -170,14 +171,14 @@ class HTTPSClientAuthConnection(httplib.HTTPSConnection):
|
||||
if self._tunnel_host:
|
||||
self.sock = sock
|
||||
self._tunnel()
|
||||
# If there's no CA File, don't force Server Certificate Check
|
||||
if self.ca_file:
|
||||
# Check CA file unless 'insecure' is specificed
|
||||
if self.insecure is True:
|
||||
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
|
||||
cert_reqs=ssl.CERT_NONE)
|
||||
else:
|
||||
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
|
||||
ca_certs=self.ca_file,
|
||||
cert_reqs=ssl.CERT_REQUIRED)
|
||||
else:
|
||||
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file,
|
||||
cert_reqs=ssl.CERT_NONE)
|
||||
|
||||
|
||||
class BaseClient(object):
|
||||
@ -186,6 +187,12 @@ class BaseClient(object):
|
||||
|
||||
DEFAULT_PORT = 80
|
||||
DEFAULT_DOC_ROOT = None
|
||||
# Standard CA file locations for Debian/Ubuntu, RedHat/Fedora,
|
||||
# Suse, FreeBSD/OpenBSD
|
||||
DEFAULT_CA_FILE_PATH = '/etc/ssl/certs/ca-certificates.crt:'\
|
||||
'/etc/pki/tls/certs/ca-bundle.crt:'\
|
||||
'/etc/ssl/ca-bundle.pem:'\
|
||||
'/etc/ssl/cert.pem'
|
||||
|
||||
OK_RESPONSE_CODES = (
|
||||
httplib.OK,
|
||||
@ -203,8 +210,8 @@ class BaseClient(object):
|
||||
)
|
||||
|
||||
def __init__(self, host, port=None, use_ssl=False, auth_tok=None,
|
||||
creds=None, doc_root=None,
|
||||
key_file=None, cert_file=None, ca_file=None):
|
||||
creds=None, doc_root=None, key_file=None,
|
||||
cert_file=None, ca_file=None, insecure=False):
|
||||
"""
|
||||
Creates a new client to some service.
|
||||
|
||||
@ -231,6 +238,8 @@ class BaseClient(object):
|
||||
If use_ssl is True, and this param is None (the
|
||||
default), then an environ variable
|
||||
GLANCE_CLIENT_CA_FILE is looked for.
|
||||
:param insecure: Optional. If set then the server's certificate
|
||||
will not be verified.
|
||||
"""
|
||||
self.host = host
|
||||
self.port = port or self.DEFAULT_PORT
|
||||
@ -286,7 +295,15 @@ class BaseClient(object):
|
||||
msg = _("The CA file you specified %s does not "
|
||||
"exist") % ca_file
|
||||
raise exception.ClientConnectionError(msg)
|
||||
|
||||
if ca_file is None:
|
||||
for ca in self.DEFAULT_CA_FILE_PATH.split(":"):
|
||||
if os.path.exists(ca):
|
||||
ca_file = ca
|
||||
break
|
||||
|
||||
self.connect_kwargs['ca_file'] = ca_file
|
||||
self.connect_kwargs['insecure'] = insecure
|
||||
|
||||
def set_auth_token(self, auth_tok):
|
||||
"""
|
||||
|
@ -40,6 +40,8 @@ import os
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from glance import client as glance_client
|
||||
from glance.common import exception
|
||||
from glance.common import utils
|
||||
from glance.store.location import get_location_from_uri
|
||||
from glance.tests import functional
|
||||
@ -62,6 +64,12 @@ class TestSSL(functional.FunctionalTest):
|
||||
self.inited = False
|
||||
self.disabled = True
|
||||
|
||||
# Test key/cert/CA file created as per:
|
||||
# http://blog.didierstevens.com/2008/12/30/
|
||||
# howto-make-your-own-cert-with-openssl/
|
||||
# Note that for these tests certificate.crt had to
|
||||
# be created with 'Common Name' set to 0.0.0.0
|
||||
|
||||
self.key_file = os.path.join(TEST_VAR_DIR, 'privatekey.key')
|
||||
if not os.path.exists(self.key_file):
|
||||
self.disabled_message = "Could not find private key file"
|
||||
@ -69,11 +77,17 @@ class TestSSL(functional.FunctionalTest):
|
||||
return
|
||||
|
||||
self.cert_file = os.path.join(TEST_VAR_DIR, 'certificate.crt')
|
||||
if not os.path.exists(self.key_file):
|
||||
if not os.path.exists(self.cert_file):
|
||||
self.disabled_message = "Could not find certificate file"
|
||||
self.inited = True
|
||||
return
|
||||
|
||||
self.ca_file = os.path.join(TEST_VAR_DIR, 'ca.crt')
|
||||
if not os.path.exists(self.ca_file):
|
||||
self.disabled_message = "Could not find CA file"
|
||||
self.inited = True
|
||||
return
|
||||
|
||||
self.inited = True
|
||||
self.disabled = False
|
||||
|
||||
@ -1230,3 +1244,94 @@ class TestSSL(functional.FunctionalTest):
|
||||
self.assertEqual(response.status, 404)
|
||||
|
||||
self.stop_servers()
|
||||
|
||||
@skip_if_disabled
|
||||
def test_certificate_validation(self):
|
||||
"""
|
||||
Check SSL client cerificate verification
|
||||
"""
|
||||
self.cleanup()
|
||||
self.start_servers(**self.__dict__.copy())
|
||||
|
||||
# 0. GET /images
|
||||
# Verify no public images
|
||||
path = "https://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
https = httplib2.Http(disable_ssl_certificate_validation=True)
|
||||
response, content = https.request(path, 'GET')
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertEqual(content, '{"images": []}')
|
||||
|
||||
# 1. POST /images with public image named Image1
|
||||
headers = {'Content-Type': 'application/octet-stream',
|
||||
'X-Image-Meta-Name': 'Image1',
|
||||
'X-Image-Meta-Status': 'active',
|
||||
'X-Image-Meta-Container-Format': 'ovf',
|
||||
'X-Image-Meta-Disk-Format': 'vdi',
|
||||
'X-Image-Meta-Size': '19',
|
||||
'X-Image-Meta-Is-Public': 'True'}
|
||||
path = "https://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
https = httplib2.Http(disable_ssl_certificate_validation=True)
|
||||
response, content = https.request(path, 'POST', headers=headers)
|
||||
self.assertEqual(response.status, 201)
|
||||
data = json.loads(content)
|
||||
|
||||
image_id = data['image']['id']
|
||||
|
||||
# 2. Attempt to delete the image *without* CA file
|
||||
path = "https://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
secure_cli = glance_client.Client(host="0.0.0.0", port=self.api_port,
|
||||
use_ssl=True, insecure=False)
|
||||
try:
|
||||
secure_cli.delete_image(image_id)
|
||||
self.fail("Client with no CA file deleted image %s" % image_id)
|
||||
except exception.ClientConnectionError, e:
|
||||
pass
|
||||
|
||||
# 3. Delete the image with a secure client *with* CA file
|
||||
secure_cli2 = glance_client.Client(host="0.0.0.0", port=self.api_port,
|
||||
use_ssl=True, ca_file=self.ca_file,
|
||||
insecure=False)
|
||||
try:
|
||||
secure_cli2.delete_image(image_id)
|
||||
except exception.ClientConnectionError, e:
|
||||
self.fail("Secure client failed to delete image %s" % image_id)
|
||||
|
||||
# Verify image is deleted
|
||||
path = "https://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
https = httplib2.Http(disable_ssl_certificate_validation=True)
|
||||
response, content = https.request(path, 'GET')
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertEqual(content, '{"images": []}')
|
||||
|
||||
# 4. POST another image
|
||||
headers = {'Content-Type': 'application/octet-stream',
|
||||
'X-Image-Meta-Name': 'Image1',
|
||||
'X-Image-Meta-Status': 'active',
|
||||
'X-Image-Meta-Container-Format': 'ovf',
|
||||
'X-Image-Meta-Disk-Format': 'vdi',
|
||||
'X-Image-Meta-Size': '19',
|
||||
'X-Image-Meta-Is-Public': 'True'}
|
||||
path = "https://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
https = httplib2.Http(disable_ssl_certificate_validation=True)
|
||||
response, content = https.request(path, 'POST', headers=headers)
|
||||
self.assertEqual(response.status, 201)
|
||||
data = json.loads(content)
|
||||
|
||||
image_id = data['image']['id']
|
||||
|
||||
# 5. Delete the image with an insecure client
|
||||
insecure_cli = glance_client.Client(host="0.0.0.0", port=self.api_port,
|
||||
use_ssl=True, insecure=True)
|
||||
try:
|
||||
insecure_cli.delete_image(image_id)
|
||||
except exception.ClientConnectionError, e:
|
||||
self.fail("Insecure client failed to delete image")
|
||||
|
||||
# Verify image is deleted
|
||||
path = "https://%s:%d/v1/images" % ("0.0.0.0", self.api_port)
|
||||
https = httplib2.Http(disable_ssl_certificate_validation=True)
|
||||
response, content = https.request(path, 'GET')
|
||||
self.assertEqual(response.status, 200)
|
||||
self.assertEqual(content, '{"images": []}')
|
||||
|
||||
self.stop_servers()
|
||||
|
35
glance/tests/var/ca.crt
Normal file
35
glance/tests/var/ca.crt
Normal file
@ -0,0 +1,35 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
WoRMgEwjGJWqzhJZUYpUAQ==
|
||||
-----END CERTIFICATE-----
|
@ -1,18 +1,30 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC4DCCAcigAwIBAgIBATANBgkqhkiG9w0BAQUFADATMREwDwYDVQQDEwhNeVRl
|
||||
c3RDQTAeFw0xMTA3MjExNTA1NDZaFw0xMjA3MjAxNTA1NDZaMCMxEDAOBgNVBAMT
|
||||
B2FobWFkcGMxDzANBgNVBAoTBnNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAO9zpczf+W4DoK2z8oFbsZfbvz1y/yQOnrQYvb1zv1IieT+QA+Ti
|
||||
N64N/sgR/cR7YEIXDnhij8yE1JTWMk1W6g4m7TGacUMXD/WAcsTM7kRol/FVksdn
|
||||
F51qxCYqWUPQ3xiTfBg2SJWvJCUGowvz06xh8JeOEXLbALC5xrzrM3hclpdbrKYE
|
||||
oe8kikI/K0TKpu52VJJrTBGPHMsw+eIqL2Ix5pWHh7DPfjBiiG7khsJxN7xSqLbX
|
||||
LrhDi24nTM9pndaqABkmPYQ9qd11SoAUB82QAAGj8A7iR/DnAzAfJl1usvQp+Me6
|
||||
sR3TPY27zifBbD04tiROi1swM/1xRH7qOpkCAwEAAaMvMC0wCQYDVR0TBAIwADAL
|
||||
BgNVHQ8EBAMCBSAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQAD
|
||||
ggEBAIJvnQjkEDFvLT7NiyFrO938BuxdQH2mX2N7Fz86myZLcGpr5NCdLvT9tD9f
|
||||
6KqrR8e839pYVPZY80cBpGTmRmzW3xLsmGCFHPHt4p1tkqSP1R5iLzKDe8jawHhD
|
||||
sch8P9URRhW9ZgBzA4xiv9FnIxZ70uDr04uX/sR/j41HGBS8YW6dJvr9Y2SpGqSS
|
||||
rR2btnNZ945dau6CPLRNd9Fls3Qjx03PnsmZ5ikSuV0pT1sPQmhhw7rBYV/b2ff+
|
||||
z/4cRtZrR00NVc74IEXLoujIjUUpFC83in10PKQmAvKYTeTdXns48eC4Cwqe8eaM
|
||||
N0YtxqQvSTsUo6vPM28NR99Fbow=
|
||||
MIIFLjCCAxYCAQEwDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCQVUxEzARBgNV
|
||||
BAgTClNvbWUtU3RhdGUxFTATBgNVBAoTDE9wZW5zdGFjayBDQTESMBAGA1UECxMJ
|
||||
R2xhbmNlIENBMRIwEAYDVQQDEwlHbGFuY2UgQ0EwHhcNMTIwMjA5MTcxMDUzWhcN
|
||||
MjIwMjA2MTcxMDUzWjBZMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0
|
||||
ZTESMBAGA1UEChMJT3BlbnN0YWNrMQ8wDQYDVQQLEwZHbGFuY2UxEDAOBgNVBAMT
|
||||
BzAuMC4wLjAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXpUkQN6pu
|
||||
avo+gz3o1K4krVdPl1m7NjNJDyD/+ZH0EGNcEN7iag1qPE7JsjqGPNZsQK1dMoXb
|
||||
Sz+OSi9qvNeJnBcfwUx5qTAtwyAb9AxGkwuMafIU+lWbsclo+dPGsja01ywbXTCZ
|
||||
bF32iqnpOMYhfxWUdoQYiBkhxxhW9eMPKLS/KkP8/bx+Vaa2XJiAebqkd9nrksAA
|
||||
BeGc9mlafYBEmiChPdJEPw+1ePA4QVq9aPepDsqAKtGN8JLpmoC3BdxQQTbbwL3Q
|
||||
8fTXK4tCNUaVk4AbDy/McFq6y0ocQoBPJjihOY35mWG/OLtcI99yPOpWGnps/5aG
|
||||
/64DDJ2D67Fnaj6gKHV+6TXFO8KZxlnxtgtiZDJBZkneTBt9ArSOv+l6NBsumRz0
|
||||
iEJ4o4H1S2TSMnprAvX7WnGtc6Xi9gXahYcDHEelwwYzqAiTBv6hxSp4MZ2dNXa+
|
||||
KzOitC7ZbV2qsg0au0wjfE/oSQ3NvsvUr8nOmfutJTvHRAwbC1v4G/tuAsO7O0w2
|
||||
0u2B3u+pG06m5+rnEqp+rB9hmukRYTfgEFRRsVIvpFl/cwvPXKRcX03UIMx+lLr9
|
||||
Ft+ep7YooBhY3wY2kwCxD4lRYNmbwsCIVywZt40f/4ad98TkufR9NhsfycxGeqbr
|
||||
mTMFlZ8TTlmP82iohekKCOvoyEuTIWL2+wIDAQABMA0GCSqGSIb3DQEBBQUAA4IC
|
||||
AQBMUBgV0R+Qltf4Du7u/8IFmGAoKR/mktB7R1gRRAqsvecUt7kIwBexGdavGg1y
|
||||
0pU0+lgUZjJ20N1SlPD8gkNHfXE1fL6fmMjWz4dtYJjzRVhpufHPeBW4tl8DgHPN
|
||||
rBGAYQ+drDSXaEjiPQifuzKx8WS+DGA3ki4co5mPjVnVH1xvLIdFsk89z3b3YD1k
|
||||
yCJ/a9K36x6Z/c67JK7s6MWtrdRF9+MVnRKJ2PK4xznd1kBz16V+RA466wBDdARY
|
||||
vFbtkafbEqOb96QTonIZB7+fAldKDPZYnwPqasreLmaGOaM8sxtlPYAJ5bjDONbc
|
||||
AaXG8BMRQyO4FyH237otDKlxPyHOFV66BaffF5S8OlwIMiZoIvq+IcTZOdtDUSW2
|
||||
KHNLfe5QEDZdKjWCBrfqAfvNuG13m03WqfmcMHl3o/KiPJlx8l9Z4QEzZ9xcyQGL
|
||||
cncgeHM9wJtzi2cD/rTDNFsx/gxvoyutRmno7I3NRbKmpsXF4StZioU3USRspB07
|
||||
hYXOVnG3pS+PjVby7ThT3gvFHSocguOsxClx1epdUJAmJUbmM7NmOp5WVBVtMtC2
|
||||
Su4NG/xJciXitKzw+btb7C7RjO6OEqv/1X/oBDzKBWQAwxUC+lqmnM7W6oqWJFEM
|
||||
YfTLnrjs7Hj6ThMGcEnfvc46dWK3dz0RjsQzUxugPuEkLA==
|
||||
-----END CERTIFICATE-----
|
||||
|
@ -1,27 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
Loading…
x
Reference in New Issue
Block a user