Allow server-side validation of client ssl certs
This adds a 'ca_file' config option that points to a local CA cert that will be used to verify certs provided by connecting clients. The 'ca_file' option is only used if the server is already properly configured to to use SSL - that means having a valid 'cert_file' and 'key_file'. If no 'ca_file' is provided, the behavior will remain the same - the server will still provide its cert to clients, but it will ignore certs sent back from those clients. Fixes bug 1032451 Change-Id: Ie48646b0fc5398ba7cda2fb627b820f533482e00
This commit is contained in:
parent
4ac0f4f0a4
commit
006254c505
@ -187,6 +187,14 @@ SSL-wrapped socket.
|
||||
|
||||
Optional. Default: not enabled.
|
||||
|
||||
* ``ca_file=PATH``
|
||||
|
||||
Path to the CA certificate file the server should use to validate client
|
||||
certificates provided during an SSL handshake. This is ignored if
|
||||
``cert_file`` and ''key_file`` are not set.
|
||||
|
||||
Optional. Default: not enabled.
|
||||
|
||||
* ``registry_client_protocol=PROTOCOL``
|
||||
|
||||
If you run a secure Registry server, you need to set this value to ``https``
|
||||
|
@ -81,6 +81,9 @@ use_syslog = False
|
||||
# Private key file to use when starting API server securely
|
||||
# key_file = /path/to/keyfile
|
||||
|
||||
# CA certificate file to use to verify connecting clients
|
||||
# ca_file = /path/to/cafile
|
||||
|
||||
# ================= Security Options ==========================
|
||||
|
||||
# AES key for encrypting store 'location' metadata, including
|
||||
|
@ -63,3 +63,6 @@ use_syslog = False
|
||||
|
||||
# Private key file to use when starting registry server securely
|
||||
# key_file = /path/to/keyfile
|
||||
|
||||
# CA certificate file to use to verify connecting clients
|
||||
# ca_file = /path/to/cafile
|
||||
|
@ -53,6 +53,7 @@ bind_opts = [
|
||||
socket_opts = [
|
||||
cfg.IntOpt('backlog', default=4096),
|
||||
cfg.IntOpt('tcp_keepidle', default=600),
|
||||
cfg.StrOpt('ca_file'),
|
||||
cfg.StrOpt('cert_file'),
|
||||
cfg.StrOpt('key_file'),
|
||||
]
|
||||
@ -109,15 +110,30 @@ def get_socket(default_port):
|
||||
"specify both a cert_file and key_file "
|
||||
"option value in your configuration file"))
|
||||
|
||||
def wrap_ssl(sock):
|
||||
ssl_kwargs = {
|
||||
'server_side': True,
|
||||
'certfile': cert_file,
|
||||
'keyfile': key_file,
|
||||
'cert_reqs': ssl.CERT_NONE,
|
||||
}
|
||||
|
||||
if CONF.ca_file:
|
||||
ssl_kwargs['ca_certs'] = CONF.ca_file
|
||||
ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED
|
||||
|
||||
return ssl.wrap_socket(sock, **ssl_kwargs)
|
||||
|
||||
sock = None
|
||||
retry_until = time.time() + 30
|
||||
while not sock and time.time() < retry_until:
|
||||
try:
|
||||
sock = eventlet.listen(bind_addr, backlog=CONF.backlog,
|
||||
sock = eventlet.listen(bind_addr,
|
||||
backlog=CONF.backlog,
|
||||
family=address_family)
|
||||
if use_ssl:
|
||||
sock = ssl.wrap_socket(sock, certfile=cert_file,
|
||||
keyfile=key_file)
|
||||
sock = wrap_ssl(sock)
|
||||
|
||||
except socket.error, err:
|
||||
if err.args[0] != errno.EADDRINUSE:
|
||||
raise
|
||||
|
Loading…
Reference in New Issue
Block a user