Allow deploying keystone with SSL certificates

Allow providing certificates through environment variables to be used
for keystone, and provide the basis for doing this for other services.
It cannot be used in conjunction with tls-proxy as the service provides
it's own encrypted endpoint.

Impletmenting: blueprint devstack-https
Change-Id: I8cf4c9c8c8a6911ae56ebcd14600a9d24cca99a0
This commit is contained in:
Jamie Lennox 2013-09-20 16:26:42 +10:00 committed by Gerrit Code Review
parent 99da4af55e
commit bd24a8d0f8
12 changed files with 111 additions and 8 deletions

View File

@ -209,6 +209,7 @@ function configure_cinder() {
inicomment $CINDER_API_PASTE_INI filter:authtoken auth_host
inicomment $CINDER_API_PASTE_INI filter:authtoken auth_port
inicomment $CINDER_API_PASTE_INI filter:authtoken auth_protocol
inicomment $CINDER_API_PASTE_INI filter:authtoken cafile
inicomment $CINDER_API_PASTE_INI filter:authtoken admin_tenant_name
inicomment $CINDER_API_PASTE_INI filter:authtoken admin_user
inicomment $CINDER_API_PASTE_INI filter:authtoken admin_password
@ -219,6 +220,7 @@ function configure_cinder() {
iniset $CINDER_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $CINDER_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $CINDER_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset $CINDER_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $CINDER_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $CINDER_CONF keystone_authtoken admin_user cinder
iniset $CINDER_CONF keystone_authtoken admin_password $SERVICE_PASSWORD

View File

@ -82,6 +82,7 @@ function configure_glance() {
iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset $GLANCE_REGISTRY_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
iniset $GLANCE_REGISTRY_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $GLANCE_REGISTRY_CONF keystone_authtoken admin_user glance
@ -99,6 +100,7 @@ function configure_glance() {
iniset $GLANCE_API_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $GLANCE_API_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $GLANCE_API_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset $GLANCE_API_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $GLANCE_API_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
iniset $GLANCE_API_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $GLANCE_API_CONF keystone_authtoken admin_user glance

View File

@ -96,6 +96,7 @@ function configure_heat() {
iniset $HEAT_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $HEAT_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset $HEAT_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
iniset $HEAT_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $HEAT_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $HEAT_CONF keystone_authtoken admin_user heat
iniset $HEAT_CONF keystone_authtoken admin_password $SERVICE_PASSWORD

View File

@ -98,6 +98,7 @@ function configure_ironic_api() {
iniset $IRONIC_CONF_FILE keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $IRONIC_CONF_FILE keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
iniset $IRONIC_CONF_FILE keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset $IRONIC_CONF_FILE keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $IRONIC_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
iniset $IRONIC_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $IRONIC_CONF_FILE keystone_authtoken admin_user ironic

View File

@ -4,6 +4,7 @@
# Dependencies:
#
# - ``functions`` file
# - ``tls`` file
# - ``DEST``, ``STACK_USER``
# - ``IDENTITY_API_VERSION``
# - ``BASE_SQL_CONN``
@ -79,6 +80,13 @@ KEYSTONE_VALID_IDENTITY_BACKENDS=kvs,ldap,pam,sql
# valid assignment backends as per dir keystone/identity/backends
KEYSTONE_VALID_ASSIGNMENT_BACKENDS=kvs,ldap,sql
# if we are running with SSL use https protocols
if is_ssl_enabled_service "key"; then
KEYSTONE_AUTH_PROTOCOL="https"
KEYSTONE_SERVICE_PROTOCOL="https"
fi
# Functions
# ---------
# cleanup_keystone() - Remove residual data files, anything left over from previous
@ -172,6 +180,15 @@ function configure_keystone() {
iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(public_port)s/"
iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(admin_port)s/"
# Register SSL certificates if provided
if is_ssl_enabled_service key; then
ensure_certificates KEYSTONE
iniset $KEYSTONE_CONF ssl enable True
iniset $KEYSTONE_CONF ssl certfile $KEYSTONE_SSL_CERT
iniset $KEYSTONE_CONF ssl keyfile $KEYSTONE_SSL_KEY
fi
if is_service_enabled tls-proxy; then
# Set the service ports for a proxy to take the originals
iniset $KEYSTONE_CONF DEFAULT public_port $KEYSTONE_SERVICE_PORT_INT
@ -373,7 +390,7 @@ function start_keystone() {
fi
echo "Waiting for keystone to start..."
if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -s http://$SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -s $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
die $LINENO "keystone did not start"
fi

View File

@ -225,6 +225,7 @@ function configure_nova() {
inicomment $NOVA_API_PASTE_INI filter:authtoken auth_host
inicomment $NOVA_API_PASTE_INI filter:authtoken auth_protocol
inicomment $NOVA_API_PASTE_INI filter:authtoken admin_tenant_name
inicomment $NOVA_API_PASTE_INI filter:authtoken cafile
inicomment $NOVA_API_PASTE_INI filter:authtoken admin_user
inicomment $NOVA_API_PASTE_INI filter:authtoken admin_password
fi
@ -399,6 +400,7 @@ function create_nova_conf() {
iniset $NOVA_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
iniset $NOVA_CONF keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset $NOVA_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset $NOVA_CONF keystone_authtoken cafile $KEYSTONE_SSL_CA
iniset $NOVA_CONF keystone_authtoken admin_user nova
iniset $NOVA_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
fi

View File

@ -306,6 +306,7 @@ function configure_swift() {
iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_host $KEYSTONE_AUTH_HOST
iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_port $KEYSTONE_AUTH_PORT
iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken cafile $KEYSTONE_SSL_CA
iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_tenant_name $SERVICE_TENANT_NAME
iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_user swift
@ -325,6 +326,7 @@ paste.filter_factory = keystone.middleware.s3_token:filter_factory
auth_port = ${KEYSTONE_AUTH_PORT}
auth_host = ${KEYSTONE_AUTH_HOST}
auth_protocol = ${KEYSTONE_AUTH_PROTOCOL}
cafile = ${KEYSTONE_SSL_CA}
auth_token = ${SERVICE_TOKEN}
admin_token = ${SERVICE_TOKEN}

50
lib/tls
View File

@ -22,7 +22,8 @@
# - make_int_ca
# - new_cert $INT_CA_DIR int-server "abc"
# - start_tls_proxy HOST_IP 5000 localhost 5000
# - ensure_certificates
# - is_ssl_enabled_service
# Defaults
# --------
@ -309,6 +310,53 @@ function make_root_CA() {
}
# Certificate Input Configuration
# ===============================
# check to see if the service(s) specified are to be SSL enabled.
#
# Multiple services specified as arguments are ``OR``'ed together; the test
# is a short-circuit boolean, i.e it returns on the first match.
#
# Uses global ``SSL_ENABLED_SERVICES``
function is_ssl_enabled_service() {
services=$@
for service in ${services}; do
[[ ,${SSL_ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
done
return 1
}
# Ensure that the certificates for a service are in place. This function does
# not check that a service is SSL enabled, this should already have been
# completed.
#
# The function expects to find a certificate, key and CA certificate in the
# variables {service}_SSL_CERT, {service}_SSL_KEY and {service}_SSL_CA. For
# example for keystone this would be KEYSTONE_SSL_CERT, KEYSTONE_SSL_KEY and
# KEYSTONE_SSL_CA. If it does not find these certificates the program will
# quit.
function ensure_certificates() {
local service=$1
local cert_var="${service}_SSL_CERT"
local key_var="${service}_SSL_KEY"
local ca_var="${service}_SSL_CA"
local cert=${!cert_var}
local key=${!key_var}
local ca=${!ca_var}
if [[ !($cert && $key && $ca) ]]; then
die $LINENO "Missing either the ${cert_var} ${key_var} or ${ca_var}" \
"variable to enable SSL for ${service}"
fi
cat $ca >> $SSL_BUNDLE_FILE
}
# Proxy Functions
# ===============

View File

@ -29,7 +29,6 @@ TROVE_DIR=$DEST/trove
TROVECLIENT_DIR=$DEST/python-troveclient
TROVE_CONF_DIR=/etc/trove
TROVE_LOCAL_CONF_DIR=$TROVE_DIR/etc/trove
TROVE_AUTH_ENDPOINT=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT//v$IDENTITY_API_VERSION
TROVE_AUTH_CACHE_DIR=${TROVE_AUTH_CACHE_DIR:-/var/cache/trove}
TROVE_BIN_DIR=/usr/local/bin
@ -102,6 +101,7 @@ function configure_trove() {
iniset $TROVE_API_PASTE_INI filter:tokenauth auth_host $KEYSTONE_AUTH_HOST
iniset $TROVE_API_PASTE_INI filter:tokenauth auth_port $KEYSTONE_AUTH_PORT
iniset $TROVE_API_PASTE_INI filter:tokenauth auth_protocol $KEYSTONE_AUTH_PROTOCOL
iniset $TROVE_API_PASTE_INI filter:tokenauth cafile $KEYSTONE_SSL_CA
iniset $TROVE_API_PASTE_INI filter:tokenauth admin_tenant_name $SERVICE_TENANT_NAME
iniset $TROVE_API_PASTE_INI filter:tokenauth admin_user trove
iniset $TROVE_API_PASTE_INI filter:tokenauth admin_password $SERVICE_PASSWORD
@ -123,6 +123,8 @@ function configure_trove() {
# (Re)create trove taskmanager conf file if needed
if is_service_enabled tr-tmgr; then
TROVE_AUTH_ENDPOINT=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT//v$IDENTITY_API_VERSION
iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT rabbit_password $RABBIT_PASSWORD
iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT sql_connection `database_connection_url trove`
iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT taskmanager_manager trove.taskmanager.manager.Manager

5
openrc
View File

@ -58,6 +58,7 @@ export OS_NO_CACHE=${OS_NO_CACHE:-1}
HOST_IP=${HOST_IP:-127.0.0.1}
SERVICE_HOST=${SERVICE_HOST:-$HOST_IP}
SERVICE_PROTOCOL=${SERVICE_PROTOCOL:-http}
KEYSTONE_AUTH_PROTOCOL=${KEYSTONE_AUTH_PROTOCOL:-$SERVICE_PROTOCOL}
# Some exercises call glance directly. On a single-node installation, Glance
# should be listening on HOST_IP. If its running elsewhere, it can be set here
@ -71,10 +72,10 @@ export OS_IDENTITY_API_VERSION=${IDENTITY_API_VERSION:-2.0}
# the user/tenant has access to - including nova, glance, keystone, swift, ...
# We currently recommend using the 2.0 *identity api*.
#
export OS_AUTH_URL=$SERVICE_PROTOCOL://$SERVICE_HOST:5000/v${OS_IDENTITY_API_VERSION}
export OS_AUTH_URL=$KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:5000/v${OS_IDENTITY_API_VERSION}
# Set the pointer to our CA certificate chain. Harmless if TLS is not used.
export OS_CACERT=$INT_CA_DIR/ca-chain.pem
export OS_CACERT=${OS_CACERT:-$INT_CA_DIR/ca-chain.pem}
# Currently novaclient needs you to specify the *compute api* version. This
# needs to match the config of your catalog returned by Keystone.

View File

@ -290,6 +290,10 @@ LOG_COLOR=`trueorfalse True $LOG_COLOR`
# Service startup timeout
SERVICE_TIMEOUT=${SERVICE_TIMEOUT:-60}
# Reset the bundle of CA certificates
SSL_BUNDLE_FILE="$DATA_DIR/ca-bundle.pem"
rm -f $SSL_BUNDLE_FILE
# Configure Projects
# ==================
@ -798,6 +802,17 @@ fi
restart_rpc_backend
# Export Certicate Authority Bundle
# ---------------------------------
# If certificates were used and written to the SSL bundle file then these
# should be exported so clients can validate their connections.
if [ -f $SSL_BUNDLE_FILE ]; then
export OS_CACERT=$SSL_BUNDLE_FILE
fi
# Configure database
# ------------------
@ -1145,6 +1160,7 @@ if is_service_enabled trove; then
start_trove
fi
# Create account rc files
# =======================
@ -1153,7 +1169,13 @@ fi
# which is helpful in image bundle steps.
if is_service_enabled nova && is_service_enabled key; then
$TOP_DIR/tools/create_userrc.sh -PA --target-dir $TOP_DIR/accrc
USERRC_PARAMS="-PA --target-dir $TOP_DIR/accrc"
if [ -f $SSL_BUNDLE_FILE ]; then
USERRC_PARAMS="$USERRC_PARAMS --os-cacert $SSL_BUNDLE_FILE"
fi
$TOP_DIR/tools/create_userrc.sh $USERRC_PARAMS
fi
@ -1229,7 +1251,7 @@ fi
CURRENT_RUN_TIME=$(date "+$TIMESTAMP_FORMAT")
echo "# $CURRENT_RUN_TIME" >$TOP_DIR/.stackenv
for i in BASE_SQL_CONN ENABLED_SERVICES HOST_IP LOGFILE \
SERVICE_HOST SERVICE_PROTOCOL STACK_USER TLS_IP; do
SERVICE_HOST SERVICE_PROTOCOL STACK_USER TLS_IP KEYSTONE_AUTH_PROTOCOL OS_CACERT; do
echo $i=${!i} >>$TOP_DIR/.stackenv
done

View File

@ -43,6 +43,7 @@ Optional Arguments
--os-tenant-name <tenant_name>
--os-tenant-id <tenant_id>
--os-auth-url <auth_url>
--os-cacert <cert file>
--target-dir <target_directory>
--skip-tenant <tenant-name>
--debug
@ -53,7 +54,7 @@ $0 -P -C mytenant -u myuser -p mypass
EOF
}
if ! options=$(getopt -o hPAp:u:r:C: -l os-username:,os-password:,os-tenant-name:,os-tenant-id:,os-auth-url:,target-dir:,skip-tenant:,help,debug -- "$@")
if ! options=$(getopt -o hPAp:u:r:C: -l os-username:,os-password:,os-tenant-name:,os-tenant-id:,os-auth-url:,target-dir:,skip-tenant:,os-cacert:,help,debug -- "$@")
then
#parse error
display_help
@ -80,6 +81,7 @@ do
--os-tenant-id) export OS_TENANT_ID=$2; shift ;;
--skip-tenant) SKIP_TENANT="$SKIP_TENANT$2,"; shift ;;
--os-auth-url) export OS_AUTH_URL=$2; shift ;;
--os-cacert) export OS_CACERT=$2; shift ;;
--target-dir) ACCOUNT_DIR=$2; shift ;;
--debug) set -o xtrace ;;
-u) MODE=${MODE:-one}; USER_NAME=$2; shift ;;
@ -201,6 +203,7 @@ export OS_USERNAME="$user_name"
# Openstack Tenant ID = $tenant_id
export OS_TENANT_NAME="$tenant_name"
export OS_AUTH_URL="$OS_AUTH_URL"
export OS_CACERT="$OS_CACERT"
export EC2_CERT="$ec2_cert"
export EC2_PRIVATE_KEY="$ec2_private_key"
export EC2_USER_ID=42 #not checked by nova (can be a 12-digit id)