Integration with Apache2
Pages 59
- Home
- Application Programming Interface
- Architecture
- Auditing
- Barbican debugging with IDE
- Barbican Contributions: dataflow
- Barbican Contributions: design
- Barbican Contributions: prerequisite reading
- Barbican Contributions: project structure
- Barbican Developer Guide
- Barbican Getting Started Guide
- Barbican Options: authentication with Keystone
- Barbican Options: distributed task queue
- Barbican Quick Start Guide
- Barbican Setup: insecure development environment
- Barbican Setup: project environment using oslo incubator
- Barbican Setup: virtual environment using pyenv
- Barbican Testing
- Barbican Troubleshooting
- Blueprint: Add Metadatda to Secrets
- Blueprint: Add Verification API
- Blueprint: Auditing
- Blueprint: Create Secret Store
- Blueprint: Events
- Blueprint: Implement KMIP Secret Store
- Blueprint: Initial Approach to Keystone Interaction
- Blueprint: KDS Service
- Blueprint: MIME Type Revamp
- Blueprint: Plug in Encryption
- Blueprint: Statistics
- Blueprint: Support KMIP
- Blueprint: Technical Approach
- Chef Usage
- Database Migrations
- Deploy OpenStack Barbican with Nginx web server
- Developer Guide
- Developer Guide for CloudCafe
- Developer Guide for Contributors
- Developer Guide for Keystone
- Gerrit Review Process
- GPG Signing Key
- High Level API Proposal
- Integration Environment
- Integration with Apache2
- Integration with Keystone V3 API
- Launchpad Release Process
- Middleware
- New Relic App and Infrastructure Metrics
- Performance Considerations
- Policies
- Project Management Backlog
- Project Management Sprint Information
- Release Notes
- Research Spike:MySQL with Percona XtraDB for Multi Master Replication
- Role Based Access Control
- Running Barbican in DevStack
- Secrets
- Testing Process
- Vagrant Usage
- Show 44 more pages…
Clone this wiki locally
Securing Barbican behind Apache2 HTTPS
Apache2 is a mature web server that has the capability to launch services directly using the Web Service Gateway Interface (WSGI). When a secure connection to Barbican is required, using Apache2 as the front end offloads HTTPS processing onto Apache2. Combining HTTPS and WSGI, the Apache2 server handles the secure incoming network traffic and passes the API request parameters directly to the Barbican service via Barbican's WSGI. The Apache2 server also handles the secure HTTPS outgoing network traffic by placing the returned API response onto the network for Barbican. Using this methodology, the Barbican API requests are never exposed to the network in an insecure format!
How to do it Example (using Ubuntu 12.04)
Make sure Barbican is installed as detailed in the Barbican Quick Start Guide, then install Apache2 and mod_wsgi:
sudo apt-get install apache2 libapache2-mod-wsgi
sudo a2enmod ssl
Create a server certificate for testing:
mkdir /etc/barbican/ssl_keys
cd /etc/barbican/ssl_keys
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Create the two Barbican API vhost files
Create the barbican-api.conf vhost file:
cd /etc/apache2/sites-available/
vi barbican-api.conf
and add the following content to the file:
Listen *:9311
<VirtualHost *:9311>
WSGIScriptAlias / /usr/lib/cgi-bin/barbican/barbican-api
WSGIDaemonProcess barbican-api user=barbican group=barbican processes=3 threads=10 python-path=/home/ubuntu/barbican/barbican:/usr/lib/python2.7
WSGIProcessGroup barbican-api
SetEnv nokeepalive ssl-unclean-shutdown
# SSL Config
SSLEngine on
SSLCertificateFile /etc/barbican/ssl_keys/server.crt
SSLCertificateKeyFile /etc/barbican/ssl_keys/server.key
SSLProtocol all -SSLv2
SSLVerifyClient none
ErrorLog /var/log/barbican/barbican-api.log
LogLevel debug
CustomLog /var/log/barbican/barbican-api.log combined
</VirtualHost>
Now create the barbican-admin.conf vhost file:
vi barbican-admin.conf
and add the following content:
Listen *:9312
<VirtualHost *:9312>
WSGIScriptAlias / /usr/lib/cgi-bin/barbican/barbican-admin
WSGIDaemonProcess barbican-admin user=barbican group=barbican processes=3 threads=10 python-path=/home/ubuntu/barbican/barbican:/usr/lib/python2.7
WSGIProcessGroup barbican-admin
SetEnv nokeepalive ssl-unclean-shutdown
# SSL Config
SSLEngine on
SSLCertificateFile /etc/barbican/ssl_keys/server.crt
SSLCertificateKeyFile /etc/barbican/ssl_keys/server.key
SSLProtocol all -SSLv2
SSLVerifyClient none
ErrorLog /var/log/barbican/barbican-admin.log
LogLevel debug
CustomLog /var/log/barbican/barbican-admin.log combined
</VirtualHost>
Now link the vhost files you just created from the sites-available directory to the sites-enabled directory and also create the log file directory:
ln -s /etc/apache2/sites-available/barbican-api.conf /etc/apache2/sites-enabled/barbican-api.conf
ln -s /etc/apache2/sites-available/barbican-admin.conf /etc/apache2/sites-enabled/barbican-admin.conf
mkdir /var/log/barbican
Create the corresponding Barbican WSGI Python scripts
Create file barbican-api:
mkdir /usr/lib/cgi-bin/barbican
vi /usr/lib/cgi-bin/barbican/barbican-api
and add the following content to the file:
from barbican.common import config
from paste import deploy
config_files = ['/etc/barbican/barbican-api-paste.ini', '/etc/barbican/barbican-api.conf']
config.parse_args(default_config_files=config_files)
conf = '/etc/barbican/barbican-api-paste.ini'
name = "apiapp"
application = deploy.loadapp('config:%s' % conf, name=name)
Now create file barbican-admin
vi /usr/lib/cgi-bin/barbican/barbican-admin
and add the following content:
from barbican.common import config
from paste import deploy
config_files = ['/etc/barbican/barbican-admin-paste.ini', '/etc/barbican/barbican-api.conf']
config.parse_args(default_config_files=config_files)
conf = '/etc/barbican/barbican-admin-paste.ini'
name = "adminapp"
application = deploy.loadapp('config:%s' % conf, name=name)
I also moved the following file due to a common error that occurs with init.py files that do not contain any executable statements (ImportError: cannot import name normalize):
mv /home/ubuntu/barbican/barbican/locale/_init.py /home/ubuntu/barbican/barbican/locale/init_.py.bak
Lastly create user "barbican" and restart Apache2 which will also start both the barbican-api and barbican-admin services:
useradd -r -s /bin/false barbican
service apache2 restart
One last connection issue; you may need to use the "Common Name" of the server in the URL that you entered when you created the test certificate. For example:
https://ubuntubarbican.mycompany.net:9311/v1/12345/orders/b755f76b-5866-4a03-8c0e-3368d5e5074f
I also added an entry into my local "/etc/hosts" file for the server on my client computer.
15.253.59.114 ubuntubarbican.mycompany.net
Adding secure HTTPS Keystone Authentication
Keystone Modifications
NOTE: This set of instructions assumes that you first have Keystone installed and running and configured to use UUID token format.
Edit file /etc/keystone/keystone.conf and enable SSL by setting the following directives (NOTE: Set the "cert_subject" directive to match your local server).
[ssl]
# Toggle for SSL support on the keystone eventlet servers.
# (boolean value)
enable=true
# Path of the certfile for SSL. (string value)
certfile=/etc/keystone/ssl/certs/keystone.pem
# Path of the keyfile for SSL. (string value)
keyfile=/etc/keystone/ssl/private/keystonekey.pem
# Path of the ca cert file for SSL. (string value)
ca_certs=/etc/keystone/ssl/certs/ca.pem
# Path of the CA key file for SSL (string value)
ca_key=/etc/keystone/ssl/private/cakey.pem
# (boolean value)
cert_required=false
# SSL Key Length (in bits) (auto generated certificate)
# (integer value)
key_size=2048
# Days the certificate is valid for once signed (auto
# generated certificate) (integer value)
valid_days=3650
# SSL Certificate Subject (auto generated certificate) (string value)
cert_subject="/C=US/ST=Oregon/L=Corvallis/O=Cloud/CN=ubuntubarbican.mycompany.net"
Now generate sample SSL certificates using the keystone tool (NOTE: If you already have sample Keystone certificates, then you will need to rename directory /etc/keystone/ssl in order to generate new certificates).
keystone-manage ssl_setup
Restart Keystone for these changes to take effect
service keystone restart
Add the following elements to your Keystone server:
- user "barbican" with password "secret" (I changed the password from "orange" to make sure that we are now authenticating from Keystone).
- role "admin"
- project "service"
- add the "admin" role to user "barbican" for project "service"
Barbican Modifications
To simplify certificate handling, recreate your local Barbican server certificate using the Keystone Certificate Authority file. This way both Keystone and Barbican will accept each others certificates. Enter all of the options below on one continuous line.
openssl ca
-in /etc/barbican/ssl_keys/server.csr
-out /etc/barbican/ssl_keys/server.crt -config /etc/keystone/ssl/certs/openssl.conf
-days 365
-cert /etc/keystone/ssl/certs/ca.pem
-keyfile /etc/keystone/ssl/private/cakey.pem
Change the "admin_password" in files /etc/barbican/barbican-api-paste.ini and /etc/barbican/barbican-admin-paste.ini to match the password for the barbican user that you entered into Keystone.
admin_password = secret
Edit WSGI file barbican-api:
vi /usr/lib/cgi-bin/barbican/barbican-api
and change the "name" variable from "apiapp" to "barbican-api-keystone" to have it reference the "barbican-api-keystone" pipeline in the "barbican-api-paste.ini" configuration file.
from barbican.common import configfrom barbican.common import config
from paste import deploy
config_files = ['/etc/barbican/barbican-api-paste.ini', '/etc/barbican/barbican-api.conf']
config.parse_args(default_config_files=config_files)
conf = '/etc/barbican/barbican-api-paste.ini'
name = "barbican-api-keystone"
#name = "apiapp"
application = deploy.loadapp('config:%s' % conf, name=name)
Also edit WSGI file barbican-admin:
vi /usr/lib/cgi-bin/barbican/barbican-admin
and change the "name" variable from "adminapp" to "barbican-admin-keystone" to have it reference the "barbican-admin-keystone" pipeline in the "barbican-admin-paste.ini" configuration file.
from barbican.common import config
from paste import deploy
config_files = ['/etc/barbican/barbican-admin-paste.ini', '/etc/barbican/barbican-api.conf']
config.parse_args(default_config_files=config_files)
conf = '/etc/barbican/barbican-admin-paste.ini'
name = "barbican-admin-keystone"
#name = "adminapp"
application = deploy.loadapp('config:%s' % conf, name=name)
Barbican Config File Changes/Examples
I cannot recall all of the changes I made to the three main Barican configuration files so I am including my local/working Barbican config files below. Pay special attention to the "[pipeline:barbican-api-keystone]", "[pipeline:barbican-admin-keystone]", and "[filter:keystone_v3_authtoken]" sections. One directive I found missing from the "keystone_v3_authtoken" filter was the "cafile" directive that the keystoneclient needs for the secure connection from Barbican to Keystone.
File /etc/barbican/barbican-api.conf
[DEFAULT]
# Show more verbose log output (sets INFO log level output)
verbose = True
# Show debugging output in logs (sets DEBUG log level output)
debug = True
# Address to bind the API server
bind_host = 0.0.0.0
# Port to bind the API server to
bind_port = 9311
# Host name, for use in HATEOS-style references
# Note: Typically this would be the load balanced endpoint that clients would use
# communicate back with this service.
host_href = https://15.253.59.114:9311
# Log to this file. Make sure you do not set the same log
# file for both the API and registry servers!
#log_file = /var/log/barbican/api.log
# Backlog requests when creating socket
backlog = 4096
# TCP_KEEPIDLE value in seconds when creating socket.
# Not supported on OS X.
#tcp_keepidle = 600
# SQLAlchemy connection string for the reference implementation
# registry server. Any valid SQLAlchemy connection string is fine.
# See: http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/connections.html#sqlalchemy.create_engine
# Uncomment this for local dev, putting db in project directory:
#sql_connection = sqlite:///barbican.sqlite
# Note: For absolute addresses, use '////' slashes after 'sqlite:'
# Uncomment for a more global development environment
sql_connection = sqlite:////var/lib/barbican/barbican.sqlite
# Period in seconds after which SQLAlchemy should reestablish its connection
# to the database.
#
# MySQL uses a default `wait_timeout` of 8 hours, after which it will drop
# idle connections. This can result in 'MySQL Gone Away' exceptions. If you
# notice this, you can lower this value to ensure that SQLAlchemy reconnects
# before MySQL can drop the connection.
sql_idle_timeout = 3600
# Default page size for the 'limit' paging URL parameter.
default_limit_paging = 10
# Maximum page size for the 'limit' paging URL parameter.
max_limit_paging = 100
# Number of Barbican API worker processes to start.
# On machines with more than one CPU increasing this value
# may improve performance (especially if using SSL with
# compression turned on). It is typically recommended to set
# this value to the number of CPUs present on your machine.
workers = 1
# Role used to identify an authenticated user as administrator
#admin_role = admin
# Allow unauthenticated users to access the API with read-only
# privileges. This only applies when using ContextMiddleware.
allow_anonymous_access = False
# Allow access to version 1 of barbican api
#enable_v1_api = True
# Allow access to version 2 of barbican api
#enable_v2_api = True
# ================= SSL Options ===============================
# Certificate file to use when starting API server securely
# cert_file = /etc/keystone/ssl/certs/keystone.pem
# Private key file to use when starting API server securely
# key_file = /etc/keystone/ssl/private/keystonekey.pem
# CA certificate file to use to verify connecting clients
# ca_file = /etc/keystone/ssl/certs/ca.pem
# ================= Security Options ==========================
# AES key for encrypting store 'location' metadata, including
# -- if used -- Swift or S3 credentials
# Should be set to a random string of length 16, 24 or 32 bytes
metadata_encryption_key = 12345678901234567890123456789012
# ============ Delayed Delete Options =============================
# Turn on/off delayed delete
delayed_delete = False
# Delayed delete time in seconds
scrub_time = 43200
# Directory that the scrubber will use to remind itself of what to delete
# Make sure this is also set in glance-scrubber.conf
scrubber_datadir = /var/lib/barbican/scrubber
# ======== OpenStack policy integration
# JSON file representing policy (string value)
policy_file=/etc/barbican/policy.json
# Rule checked when requested rule is not found (string value)
policy_default_rule=default
# ================= Queue Options - oslo.messaging ==========================
# Rabbit and HA configuration:
ampq_durable_queues = True
rabbit_userid=guest
rabbit_password=guest
rabbit_ha_queues = True
rabbit_port=5672
# For HA, specify queue nodes in cluster, comma delimited:
# For example: rabbit_hosts=192.168.50.8:5672, 192.168.50.9:5672
rabbit_hosts=localhost:5672
# For HA, specify queue nodes in cluster as 'user@host:5672', comma delimited, ending with '/offset':
# For example: transport_url = rabbit://guest@192.168.50.8:5672,guest@192.168.50.9:5672/
# DO NOT USE THIS, due to '# FIXME(markmc): support multiple hosts' in oslo/messaging/_drivers/amqpdriver.py
# transport_url = rabbit://guest@localhost:5672/
# ================= Queue Options - Application ==========================
[queue]
# Enable queuing asynchronous messaging.
# Set false to invoke worker tasks synchronously (i.e. no-queue standalone mode)
enable = False
# Namespace for the queue
namespace = 'barbican'
# Topic for the queue
topic = 'barbican.workers'
# Version for the task API
version = '1.1'
# Server name for RPC service
server_name = 'barbican.queue'
File /etc/barbican/barbican-api-paste.ini
[pipeline:main]
#pipeline = unauthenticated-context apiapp
pipeline = keystone_v3_authtoken context apiapp
####pipeline = simple apiapp
#Use this pipeline to activate a repoze.profile middleware and HTTP port,
# to provide profiling information for the REST API processing.
[pipeline:barbican-profile]
pipeline = unauthenticated-context egg:Paste#cgitb egg:Paste#httpexceptions profile apiapp
#Use this pipeline for keystone auth
[pipeline:barbican-api-keystone]
pipeline = keystone_v3_authtoken context apiapp
[app:apiapp]
paste.app_factory = barbican.api.app:create_main_app
[filter:simple]
paste.filter_factory = barbican.api.middleware.simple:SimpleFilter.factory
[filter:unauthenticated-context]
paste.filter_factory = barbican.api.middleware.context:UnauthenticatedContextMiddleware.factory
[filter:context]
paste.filter_factory = barbican.api.middleware.context:ContextMiddleware.factory
[filter:keystone_authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
signing_dir = /tmp/barbican/cache
auth_host = ubuntubarbican.mycompany.net
#need ability to re-auth a token, thus admin url
auth_port = 35357
auth_protocol = https
admin_tenant_name = service
admin_user = barbican
admin_password = secret
#admin_password = orange
auth_version = v2.0
#delay failing perhaps to log the unauthorized request in barbican ..
#delay_auth_decision = true
[filter:keystone_v3_authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
signing_dir = /tmp/barbican/cache
auth_host = ubuntubarbican.mycompany.net
#need ability to re-auth a token, thus admin url
auth_port = 35357
auth_protocol = https
admin_tenant_name = service
admin_user = barbican
admin_password = secret
#admin_password = orange
auth_version = v3
#auth_version = v3.0
#delay failing perhaps to log the unauthorized request in barbican ..
#delay_auth_decision = true
cafile = /etc/keystone/ssl/certs/ca.pem
[filter:profile]
use = egg:repoze.profile
log_filename = myapp.profile
cachegrind_filename = cachegrind.out.myapp
discard_first_request = true
path = /__profile__
flush_at_shutdown = true
unwind = false
File /etc/barbican/barbican-admin-paste.ini
[pipeline:main]
#pipeline = unauthenticated-context admin
pipeline = keystone_v3_authtoken context adminapp
[pipeline:barbican-admin-keystone]
pipeline = keystone_v3_authtoken context adminapp
[app:adminapp]
paste.app_factory = barbican.api.app:create_admin_app
#[filter:unauthenticated-context]
#paste.filter_factory = barbican.api.middleware.context:UnauthenticatedContextMiddleware.factory
[filter:keystone_v3_authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
signing_dir = /tmp/barbican/cache
auth_host = ubuntubarbican.mycompany.net
#need ability to re-auth a token, thus admin url
auth_port = 35357
auth_protocol = https
admin_tenant_name = service
admin_user = barbican
admin_password = secret
#admin_password = orange
auth_version = v3
#delay failing perhaps to log the unauthorized request in barbican ..
#delay_auth_decision = true
cafile = /etc/keystone/ssl/certs/ca.pem
[filter:simple]
paste.filter_factory = barbican.api.middleware.simple:SimpleFilter.factory
[filter:context]
paste.filter_factory = barbican.api.middleware.context:ContextMiddleware.factory
[filter:profile]
use = egg:repoze.profile
log_filename = myapp.profile
cachegrind_filename = cachegrind.out.myapp
discard_first_request = true
path = /__profile__
flush_at_shutdown = true
unwind = false
##########################
[filter:unauthenticated-context]
paste.filter_factory = barbican.api.middleware.context:UnauthenticatedContextMiddleware.factory
[filter:keystone_authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
signing_dir = /tmp/barbican/cache
auth_host = ubuntubarbican.mycompany.net
#need ability to re-auth a token, thus admin url
auth_port = 35357
auth_protocol = https
admin_tenant_name = service
admin_user = barbican
admin_password = secret
#admin_password = orange
auth_version = v2.0
#delay failing perhaps to log the unauthorized request in barbican ..
#delay_auth_decision = true
[filter:profile]
use = egg:repoze.profile
log_filename = myapp.profile
cachegrind_filename = cachegrind.out.myapp
discard_first_request = true
path = /__profile__
flush_at_shutdown = true
unwind = false
Lastly restart apache2 for all of your changes to take effect.
service apache2 restart