barbican/devstack/lib/barbican
Kaitlin Farr 10e7a5491a Fix KMIP gate
Switches KMIP server configuration and KMIP plugin to use TLSv1.2
by default. This is the most secure option. In case the system is
older and does not have TLSv1.2, an error message is printed out.

Removes the behavior of switching to TLSv1.2 despite
the user's configuration that was added with
I7018262cb74a95dfa24d6b94d49f1ebd62bdeebd. This behavior was
confusing -- it is much clearer to have the user-configurable options
default to TLSv1.2.

Sets KMIP_PLUGIN_ENABLED before running the tests, so that the
tests that won't work for KMIP will be skipped.
See Id908bf57233af84bff56d90c75d175b04ccd4373 for more details.

Cleans up the quotes around the paths to the log files and server
conf files when they are passed to the pykmip server.

Depends-On: I9fe7b156c4a825c8bfe94a3c48ce686ce0dee01e
Change-Id: I64e27a26dfe02d794b725763c55d0197bc2c46bd
2017-03-15 17:43:01 -04:00

555 lines
17 KiB
Bash

#!/usr/bin/env bash
# Install and start **Barbican** service
# To enable a minimal set of Barbican features, add the following to localrc:
# enable_service barbican-svc barbican-retry
#
# Dependencies:
# - functions
# - OS_AUTH_URL for auth in api
# - DEST set to the destination directory
# - SERVICE_PASSWORD, SERVICE_PROJECT_NAME for auth in api
# - STACK_USER service user
# stack.sh
# ---------
# install_barbican
# configure_barbican
# init_barbican
# start_barbican
# stop_barbican
# cleanup_barbican
# Save trace setting
XTRACE=$(set +o | grep xtrace)
set +o xtrace
# PyKMIP configuration
PYKMIP_SERVER_KEY=${PYKMIP_SERVER_KEY:-$INT_CA_DIR/private/pykmip-server.key}
PYKMIP_SERVER_CERT=${PYKMIP_SERVER_CERT:-$INT_CA_DIR/pykmip-server.crt}
PYKMIP_CLIENT_KEY=${PYKMIP_CLIENT_KEY:-$INT_CA_DIR/private/pykmip-client.key}
PYKMIP_CLIENT_CERT=${PYKMIP_CLIENT_CERT:-$INT_CA_DIR/pykmip-client.crt}
PYKMIP_CA_PATH=${PYKMIP_CA_PATH:-$INT_CA_DIR/ca-chain.pem}
# Functions
# ---------
# TODO(john-wood-w) These 'magic' functions are called by devstack to enable
# a given service (so the name between 'is_' and '_enabled'). Currently the
# Zuul infra gate configuration (at https://github.com/openstack-infra/project-config/blob/master/jenkins/jobs/barbican.yaml)
# only enables the 'barbican' service. So the two functions below, for the two
# services we wish to run, have to key off of that lone 'barbican' selection.
# Once the Zuul config is updated to add these two services properly, then
# these functions should be replaced by the single method below.
# !!!! Special thanks to rm_work for figuring this out !!!!
function is_barbican-retry_enabled {
[[ ,${ENABLED_SERVICES} =~ ,"barbican" ]] && return 0
}
function is_barbican-svc_enabled {
[[ ,${ENABLED_SERVICES} =~ ,"barbican" ]] && return 0
}
# TODO(john-wood-w) Replace the above two functions with the one below once
# Zuul is update per above.
## Test if any Barbican services are enabled
## is_barbican_enabled
#function is_barbican_enabled {
# [[ ,${ENABLED_SERVICES} =~ ,"barbican-" ]] && return 0
# return 1
#}
# cleanup_barbican - Remove residual data files, anything left over from previous
# runs that a clean run would need to clean up
function cleanup_barbican {
:
}
# configure_barbicanclient - Set config files, create data dirs, etc
function configure_barbicanclient {
setup_develop $BARBICANCLIENT_DIR
}
# configure_dogtag_plugin - Change config to use dogtag plugin
function configure_dogtag_plugin {
sudo openssl pkcs12 -in /root/.dogtag/pki-tomcat/ca_admin_cert.p12 -passin pass:PASSWORD -out $BARBICAN_CONF_DIR/kra_admin_cert.pem -nodes
sudo chown $USER $BARBICAN_CONF_DIR/kra_admin_cert.pem
iniset $BARBICAN_CONF dogtag_plugin dogtag_port 8373
iniset $BARBICAN_CONF secretstore enabled_secretstore_plugins dogtag_crypto
iniset $BARBICAN_CONF certificate enabled_certificate_plugins dogtag
}
# configure_barbican - Set config files, create data dirs, etc
function configure_barbican {
setup_develop $BARBICAN_DIR
[ ! -d $BARBICAN_CONF_DIR ] && sudo mkdir -m 755 -p $BARBICAN_CONF_DIR
sudo chown $USER $BARBICAN_CONF_DIR
[ ! -d $BARBICAN_API_LOG_DIR ] && sudo mkdir -m 755 -p $BARBICAN_API_LOG_DIR
sudo chown $USER $BARBICAN_API_LOG_DIR
[ ! -d $BARBICAN_CONF_DIR ] && sudo mkdir -m 755 -p $BARBICAN_CONF_DIR
sudo chown $USER $BARBICAN_CONF_DIR
# Copy the barbican config files to the config dir
cp $BARBICAN_DIR/etc/barbican/barbican.conf $BARBICAN_CONF_DIR
cp $BARBICAN_DIR/etc/barbican/barbican-api-paste.ini $BARBICAN_CONF_DIR
cp -R $BARBICAN_DIR/etc/barbican/vassals $BARBICAN_CONF_DIR
# Copy functional test config
cp $BARBICAN_DIR/etc/barbican/barbican-functional.conf $BARBICAN_CONF_DIR
# Enable DEBUG
iniset $BARBICAN_CONF DEFAULT debug True
# Set the host_href
iniset $BARBICAN_CONF DEFAULT host_href "$BARBICAN_HOST_HREF"
# Set the log file location
iniset $BARBICAN_CONF DEFAULT log_file "$BARBICAN_API_LOG_DIR/barbican.log"
# Enable logging to stderr to have log also in the screen window
iniset $BARBICAN_CONF DEFAULT use_stderr True
# Format logging
if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
setup_colorized_logging $BARBICAN_CONF DEFAULT project user
fi
# Install the policy file for the API server
cp $BARBICAN_DIR/etc/barbican/policy.json $BARBICAN_CONF_DIR
iniset $BARBICAN_CONF DEFAULT policy_file $BARBICAN_CONF_DIR/policy.json
# Set the database connection url
iniset $BARBICAN_CONF DEFAULT sql_connection `database_connection_url barbican`
# Disable auto-migration when deploying Barbican
iniset $BARBICAN_CONF DEFAULT db_auto_create False
# Increase default request buffer size, keystone auth PKI tokens can be very long
iniset $BARBICAN_CONF_DIR/vassals/barbican-api.ini uwsgi buffer-size 65535
# Rabbit settings
if is_service_enabled rabbit; then
iniset $BARBICAN_CONF 'secrets' broker rabbit://guest:$RABBIT_PASSWORD@$RABBIT_HOST
else
echo_summary "Barbican requires that the RabbitMQ service is enabled"
fi
## Set up keystone
# Turn on the middleware
iniset $BARBICAN_PASTE_CONF 'pipeline:barbican_api' pipeline 'barbican-api-keystone'
# Set the keystone parameters
configure_auth_token_middleware $BARBICAN_CONF barbican $BARBICAN_AUTH_CACHE_DIR
}
# init_barbican - Initialize etc.
function init_barbican {
# Create cache dir
sudo mkdir -p $BARBICAN_AUTH_CACHE_DIR
sudo chown $STACK_USER $BARBICAN_AUTH_CACHE_DIR
rm -f $BARBICAN_AUTH_CACHE_DIR/*
recreate_database barbican utf8
$BARBICAN_BIN_DIR/barbican-manage db upgrade -v head
}
# install_barbican - Collect source and prepare
function install_barbican {
# Install package requirements
if is_fedora; then
install_package sqlite-devel openldap-devel
fi
# TODO(ravips): We need this until barbican gets into devstack
setup_develop $BARBICAN_DIR
pip_install 'uwsgi'
}
# install_barbicanclient - Collect source and prepare
function install_barbicanclient {
git_clone $BARBICANCLIENT_REPO $BARBICANCLIENT_DIR $BARBICANCLIENT_BRANCH
setup_develop $BARBICANCLIENT_DIR
}
# start_barbican - Start running processes, including screen
function start_barbican {
# Start the Barbican service up.
run_process barbican-svc "uwsgi --master --emperor $BARBICAN_CONF_DIR/vassals"
# Pause while the barbican-svc populates the database, otherwise the retry
# service below might try to do this at the same time, leading to race
# conditions.
sleep 10
# Start the retry scheduler server up.
run_process barbican-retry "$BARBICAN_BIN_DIR/barbican-retry --config-file=$BARBICAN_CONF_DIR/barbican-api.conf"
}
# stop_barbican - Stop running processes
function stop_barbican {
# This will eventually be refactored to work like
# Solum and Manila (script to kick off a wsgiref server)
# For now, this will stop uWSGI rather than have it hang
killall -9 uwsgi
# This cleans up the PID file, but uses pkill so Barbican
# uWSGI emperor process doesn't actually stop
stop_process barbican-svc
stop_process barbican-retry
}
function get_id {
echo `"$@" | awk '/ id / { print $4 }'`
}
function create_barbican_accounts {
#
# Setup Default Admin User
#
SERVICE_PROJECT=$(openstack project list | awk "/ $SERVICE_PROJECT_NAME / { print \$2 }")
ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
BARBICAN_USER=$(openstack user create \
--password "$SERVICE_PASSWORD" \
--project $SERVICE_PROJECT \
--email "barbican@example.com" \
barbican \
| grep " id " | get_field 2)
openstack role add --project $SERVICE_PROJECT \
--user $BARBICAN_USER \
$ADMIN_ROLE
#
# Setup Default service-admin User
#
SERVICE_ADMIN=$(get_id openstack user create \
--password "$SERVICE_PASSWORD" \
--email "service-admin@example.com" \
"service-admin")
SERVICE_ADMIN_ROLE=$(get_id openstack role create \
"key-manager:service-admin")
openstack role add \
--user "$SERVICE_ADMIN" \
--project "$SERVICE_PROJECT" \
"$SERVICE_ADMIN_ROLE"
#
# Setup RBAC User Projects and Roles
#
PASSWORD="barbican"
PROJECT_A_ID=$(get_id openstack project create "project_a")
PROJECT_B_ID=$(get_id openstack project create "project_b")
ROLE_ADMIN_ID=$(get_id openstack role show admin)
ROLE_CREATOR_ID=$(get_id openstack role create "creator")
ROLE_OBSERVER_ID=$(get_id openstack role create "observer")
ROLE_AUDIT_ID=$(get_id openstack role create "audit")
#
# Setup RBAC Admin of Project A
#
USER_ID=$(get_id openstack user create \
--password "$PASSWORD" \
--email "admin_a@example.net" \
"project_a_admin")
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_A_ID" \
"$ROLE_ADMIN_ID"
#
# Setup RBAC Creator of Project A
#
USER_ID=$(get_id openstack user create \
--password "$PASSWORD" \
--email "creator_a@example.net" \
"project_a_creator")
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_A_ID" \
"$ROLE_CREATOR_ID"
# Adding second creator user in project_a
USER_ID=$(openstack user create \
--password "$PASSWORD" \
--email "creator2_a@example.net" \
"project_a_creator_2" -f value -c id)
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_A_ID" \
"$ROLE_CREATOR_ID"
#
# Setup RBAC Observer of Project A
#
USER_ID=$(get_id openstack user create \
--password "$PASSWORD" \
--email "observer_a@example.net" \
"project_a_observer")
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_A_ID" \
"$ROLE_OBSERVER_ID"
#
# Setup RBAC Auditor of Project A
#
USER_ID=$(get_id openstack user create \
--password "$PASSWORD" \
--email "auditor_a@example.net" \
"project_a_auditor")
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_A_ID" \
"$ROLE_AUDIT_ID"
#
# Setup RBAC Admin of Project B
#
USER_ID=$(get_id openstack user create \
--password "$PASSWORD" \
--email "admin_b@example.net" \
"project_b_admin")
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_B_ID" \
"$ROLE_ADMIN_ID"
#
# Setup RBAC Creator of Project B
#
USER_ID=$(get_id openstack user create \
--password "$PASSWORD" \
--email "creator_b@example.net" \
"project_b_creator")
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_B_ID" \
"$ROLE_CREATOR_ID"
#
# Setup RBAC Observer of Project B
#
USER_ID=$(get_id openstack user create \
--password "$PASSWORD" \
--email "observer_b@example.net" \
"project_b_observer")
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_B_ID" \
"$ROLE_OBSERVER_ID"
#
# Setup RBAC auditor of Project B
#
USER_ID=$(get_id openstack user create \
--password "$PASSWORD" \
--email "auditor_b@example.net" \
"project_b_auditor")
openstack role add \
--user "$USER_ID" \
--project "$PROJECT_B_ID" \
"$ROLE_AUDIT_ID"
#
# Setup Barbican Endpoint
#
BARBICAN_SERVICE=$(openstack service create \
--name barbican \
--description "Barbican Service" \
'key-manager' \
| grep " id " | get_field 2)
openstack endpoint create \
--os-identity-api-version 3 \
--region RegionOne \
$BARBICAN_SERVICE \
public "http://$SERVICE_HOST:9311"
openstack endpoint create \
--os-identity-api-version 3 \
--region RegionOne \
$BARBICAN_SERVICE \
internal "http://$SERVICE_HOST:9311"
}
# PyKMIP functions
# ----------------
# install_pykmip - install the PyKMIP python module
# create keys and certificate for server
function install_pykmip {
pip_install 'pykmip'
if is_service_enabled pykmip-server; then
[ ! -d ${PYKMIP_CONF_DIR} ] && sudo mkdir -p ${PYKMIP_CONF_DIR}
sudo chown ${USER} ${PYKMIP_CONF_DIR}
[ ! -d ${PYKMIP_LOG_DIR} ] && sudo mkdir -p ${PYKMIP_LOG_DIR}
sudo chown ${USER} ${PYKMIP_LOG_DIR}
init_CA
if [ ! -e ${PYKMIP_SERVER_KEY} ]; then
make_cert ${INT_CA_DIR} 'pykmip-server' 'pykmip-server'
chmod 400 ${PYKMIP_SERVER_KEY}
fi
if [ ! -e ${PYKMIP_CLIENT_KEY} ]; then
make_cert ${INT_CA_DIR} 'pykmip-client' 'pykmip-client'
chmod 400 ${PYKMIP_CLIENT_KEY}
fi
if [ ! -e ${PYKMIP_CONF} ]; then
cat > ${PYKMIP_CONF} <<EOF
[server]
hostname=127.0.0.1
port=5696
certificate_path=${PYKMIP_SERVER_CERT}
key_path=${PYKMIP_SERVER_KEY}
ca_path=${PYKMIP_CA_PATH}
auth_suite=TLS1.2
EOF
fi
fi
}
# configure_pykmip - enable KMIP plugin and configure
function configure_pykmip {
iniset $BARBICAN_CONF secretstore enabled_secretstore_plugins kmip_plugin
iniset $BARBICAN_CONF kmip_plugin username demo
iniset $BARBICAN_CONF kmip_plugin password secretpassword
iniset $BARBICAN_CONF kmip_plugin keyfile ${PYKMIP_CLIENT_KEY}
iniset $BARBICAN_CONF kmip_plugin certfile ${PYKMIP_CLIENT_CERT}
iniset $BARBICAN_CONF kmip_plugin ca_certs ${PYKMIP_CA_PATH}
}
# start_pykmip - start the PyKMIP server
function start_pykmip {
run_process pykmip-server "pykmip-server -f ${PYKMIP_CONF} -l ${PYKMIP_LOG_DIR}/pykmip-devstack.log"
}
# Dogtag functions
# ----------------
function install_389_directory_server {
# Make sure that 127.0.0.1 resolves to localhost.localdomain (fqdn)
sudo sed -i 's/127.0.0.1[ \t]*localhost localhost.localdomain/127.0.0.1\tlocalhost.localdomain localhost/' /etc/hosts
sudo mkdir -p /etc/389-ds
# Instead of spawning a sub-shell to cat this whole chunk into the desired
# file. I just cat it into a temporary file that this user will have access
# to, and subsequently use elevated privileges to move the already made
# file where we need it to be.
cat > .tmp.setup.inf <<EOF
[General]
FullMachineName= localhost.localdomain
SuiteSpotUserID= nobody
SuiteSpotGroup= nobody
[slapd]
ServerPort= 389
ServerIdentifier= pki-tomcat
Suffix= dc=example,dc=com
RootDN= cn=Directory Manager
RootDNPwd= PASSWORD
EOF
sudo mv .tmp.setup.inf /etc/389-ds/setup.inf
sudo setup-ds.pl --silent --file=/etc/389-ds/setup.inf
}
function install_dogtag_ca {
sudo mkdir -p /etc/dogtag
cat > .tmp.ca.cfg <<EOF
[CA]
pki_admin_email=caadmin@example.com
pki_admin_name=caadmin
pki_admin_nickname=caadmin
pki_admin_password=PASSWORD
pki_admin_uid=caadmin
pki_backup_password=PASSWORD
pki_client_database_password=PASSWORD
pki_client_database_purge=False
pki_client_pkcs12_password=PASSWORD
pki_clone_pkcs12_password=PASSWORD
pki_ds_base_dn=dc=ca,dc=example,dc=com
pki_ds_database=ca
pki_ds_password=PASSWORD
pki_hostname=localhost
pki_security_domain_name=EXAMPLE
pki_token_password=PASSWORD
pki_https_port=8373
pki_http_port=8370
pki_ajp_port=8379
pki_tomcat_server_port=8375
EOF
sudo mv .tmp.ca.cfg /etc/dogtag/ca.cfg
sudo pkispawn -v -f /etc/dogtag/ca.cfg -s CA
}
function wait_for_ca {
while true; do
# If the sleep command is executed "as-is", the subprocess that it
# executes will trigger the "exit_trap" and will cause this script to
# fail. To avoid this, we run the sleep command inside this sub-shell,
# so the signal will not be caught in this process.
ca_running=$(sleep 2 && curl -s -k https://localhost:8373/ca/admin/ca/getStatus | grep -c running)
if [[ $ca_running == 1 ]]; then
break
fi
done
}
function install_dogtag_kra {
sudo mkdir -p /etc/dogtag
# Even though we are using localhost.localdomain, the server certificate by
# default will get the real host name for the server. So we need to
# properly configure the KRA to try to communicate with the real host name
# instead of the localhost.
cat > .tmp.kra.cfg <<EOF
[KRA]
pki_admin_cert_file=/root/.dogtag/pki-tomcat/ca_admin.cert
pki_admin_email=kraadmin@example.com
pki_admin_name=kraadmin
pki_admin_nickname=kraadmin
pki_admin_password=PASSWORD
pki_admin_uid=kraadmin
pki_backup_password=PASSWORD
pki_client_database_password=PASSWORD
pki_client_database_purge=False
pki_client_pkcs12_password=PASSWORD
pki_clone_pkcs12_password=PASSWORD
pki_ds_base_dn=dc=kra,dc=example,dc=com
pki_ds_database=kra
pki_ds_password=PASSWORD
pki_hostname=localhost
pki_security_domain_name=EXAMPLE
pki_security_domain_user=caadmin
pki_security_domain_password=PASSWORD
pki_token_password=PASSWORD
pki_https_port=8373
pki_http_port=8370
pki_ajp_port=8379
pki_tomcat_server_port=8375
pki_security_domain_hostname=localhost
pki_security_domain_https_port=8373
EOF
sudo mv .tmp.kra.cfg /etc/dogtag/kra.cfg
sudo pkispawn -v -f /etc/dogtag/kra.cfg -s KRA
}
function install_dogtag_plugin_dependencies {
install_package nss-devel 389-ds-base pki-ca pki-kra
}
function install_dogtag_components {
install_dogtag_plugin_dependencies
install_389_directory_server
install_dogtag_ca
wait_for_ca
install_dogtag_kra
}
# Restore xtrace
$XTRACE