Secure OpenStack and Yuyu Billing with TLS
Many organizations run private clouds with OpenStack to manage infrastructure more flexibly and efficiently. In day-to-day operations, however, teams still need to control resource usage and reduce human error, especially when developers test in an environment that is too close to production. Separating development and production projects helps protect system stability and keeps resource usage predictable.
The organization also needs a measurable way to track and calculate resource usage. Yuyu provides usage reporting and billing for OpenStack resources, including volumes, flavors, images, and routers. With this data, the team can analyze consumption and identify opportunities to reduce operating costs.
- OpenStack - Antelope - v2023.1
- Kolla-Ansible - v2023.1
- Ansible - v2.14.18
- Horizon - v2023.1
- Yuyu - v2023.1
- Python - 3.10.12

-
Create an IP SAN file for the controller node, because Horizon and Yuyu run on the controller.
bashsudo nano /etc/ssl/IP_SANS.txtbashsubjectAltName=IP:<IP Server / Node> -
Create a directory for the certificates under
/etc/ssl/.bash~$ sudo mkdir -p /etc/ssl/ ~$ sudo mkdir -p /etc/ssl/ -
Create certificates for Horizon and Yuyu.
-
Horizon:
bashsudo openssl genrsa -out /etc/ssl/horizon/horizon.key 2048 sudo openssl req -sha512 -new \ -subj "/C=IN/ST=jateng/L=kendal/0=Horizon Najwan/OU=Horizon Najwan/CN=Horizon Najwan>" \ -key /etc/ssl/horizon/horizon.key \ -out /etc/ssl/horizon/horizon.csr sudo openssl x509 -req -sha512 -days 3650 \ -key /etc/ssl/horizon/horizon.key \ -extfile /etc/ssl/IP_SANS.txt \ -in /etc/ssl/horizon/horizon.csr\ -out /etc/ssl/horizon/horizon.crt -
Yuyu:
bashsudo openssl genrsa -out /etc/ssl/yuyu/yuyu.key 2048 sudo openssl req -sha512 -new \ -subj "/C=IN/ST=jateng/L=kendal/0=Yuyu Najwan/OU=Yuyu Najwan/CN=Yuyu Najwan>" \ -key /etc/ssl/yuyu/yuyu.key \ -out /etc/ssl/yuyu/yuyu.csr sudo openssl x509 -req -sha512 -days 3650 \ -key /etc/ssl/yuyu/yuyu.key \ -extfile /etc/ssl/IP_SANS.txt \ -in /etc/ssl/yuyu/yuyu.csr\ -out /etc/ssl/yuyu/yuyu.crt
-
-
Install the certificates into Ubuntu's trust store so they are trusted by the operating system and by Horizon's Django application.
bash~$ sudo apt-get install ca-certificates ~$ sudo cp /etc/ssl/horizon/horizon.crt /usr/local/share/ca-certificates ~$ sudo cp /etc/ssl/yuyu/yuyu.crt /usr/local/share/ca-certificates ~$ sudo update-ca-certificates
OpenStack includes several services that communicate through their respective APIs:
- Keystone provides identity and access verification.
- Neutron provides OpenStack networking.
- Nova provides compute services and creates instances.
- Glance stores the images used to create instances.
- Cinder provides volumes for instances.
- RabbitMQ is the message broker that distributes OpenStack events.
For the complete OpenStack installation procedure, see OpenStack and Kolla-Ansible. Apply the following adjustments before deployment because the cluster must be redeployed after internal TLS is enabled.
-
Update
globals.ymlto enable TLS for internal OpenStack services and copy the CA into the service containers. Replace{DIR_KOLLA}with{{ node_config }}and{DIR_KOLLA_CERT}with{{ kolla_certificates_dir }}.yamlopenstack_cacert: "/etc/ssl/certs/ca-certificates.crt" kolla_enable_tls_internal: "yes" kolla_certificates_dir: "{DIR_KOLLA}/certificates" kolla_admin_openrc_cacert: "/etc/kolla/certificates/ca/root.crt" kolla_copy_ca_into_containers: "yes" kolla_enable_tls_backend: "yes" kolla_verify_tls_backend: "no" kolla_tls_backend_cert: "{DIR_KOLLA_CERT}/backend-cert.pem" kolla_tls_backend_key: "{DIR_KOLLA_CERT}/backend-key.pem" -
Before deployment, generate the certificates with:
bash(kolla-venv) student@controller:~$ kolla-ansible -i ./multinode certificates
Horizon and Yuyu API are both implemented with Django. To enable TLS, configure Django with the certificate and private-key files. For the base Horizon and Yuyu installation, see Yuyu Billing in OpenStack Horizon.
The following additional steps enable TLS on both services.
A. Horizon
-
Update Horizon's
local_settings.py, located here in this example:/var/www/html/horizon/openstack_dashboard/local/.pythonWEBROOT = '/' YUYU_URL = 'https://{IP HOST}:8182' SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') CSRF_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True OPENSTACK_KEYSTONE_URL = 'https://{IP HOST}:5000/v3' OPENSTACK_KEYSTONE_DEFAULT_ROLE = 'member' OPENSTACK_SSL_NO_VERIFY = False OPENSTACK_SSL_CACERT = '/etc/ssl/certs/ca-certificates.crt' OPENSTACK_KEYSTONE_BACKEND = { 'name': 'native', 'can_edit_group': True, 'can_edit_user': True, 'can_edit_role': True, 'can_edit_project': True, 'can_edit_domain': True, } -
When generating the Apache configuration, add the SSL options below.
bash~# ./manage.py make_web_conf --apache \ --sslkey /etc/ssl/horizon/horizon.key \ --sslcert /etc/ssl/horizon/horizon.crt \ --cacert /etc/ssl/certs/ca-certificates.crt \ --ssl > /etc/apache2/sites-available/horizon.conf -
Restart Apache and Memcached.
bash~# systemctl restart apache2.service memcached
B. Yuyu API
-
Update Yuyu API's
local_settings.py, located here in this example:/var/yuyu/yuyu/.pythonALLOWED_HOSTS = ['*'] SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SECURE_SSL_HOST = True SECURE_SSL_REDIRECT = False SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True -
Update the Yuyu API service to enable TLS.
bash~# nano /etc/systemd/system/yuyu_api.service ExecStart=/var/yuyu/env/bin/gunicorn yuyu.wsgi \ --workers 2 \ --keyfile /etc/ssl/yuyu/yuyu.key \ --certfile /etc/ssl/yuyu/yuyu.crt \ --bind 10.18.18.10:8182 \ --log-file=logs/gunicorn.log -
Restart Yuyu API, Apache, and Memcached.
bash~# systemctl restart yuyu_api.service spache2.service memcached
-
CLI login fails when using the OpenStack
openrcfile.Update
export OS_CACERTin theopenrcfile. If it does not exist, add it with/etc/kolla/certificates/ca/root.crt. You can also use/etc/ssl/certs/ca-certificate.crtafter copying the root certificate to/usr/local/share/ca-certificatesand runningsudo update-ca-certificates. -
SSLError at /admin/billing_overview/appears in Horizon.Django does not trust the self-signed certificate. Add the Horizon and Yuyu certificates to
/usr/local/share/ca-certificates, then update the CA store using the Ubuntu root CA guide. -
AttributeError at /auth/logout/appears when signing out of Horizon.Use
python-memcachedversion 1.59. Newer versions may cause the logout flow to fail in this setup. -
Curl reports an
Invalid HTTP_HOST headererror.Add the host IP, such as
10.18.18.10, toALLOWED_HOSTSin Yuyu'slocal_settings.py. Use*only when every source IP should be allowed. -
The Horizon instance console shows
Did Not Connect: Potential Security Issue.This can happen when the certificate is not publicly trusted or when the instance image is invalid. Select "Click here to show only console" below the "Instance Console" heading to check whether the image is the cause.
Final Result
The final result is similar to the Yuyu Billing in OpenStack Horizon project, with Horizon, Yuyu Billing, and OpenStack services protected by TLS.
This project covers the complete workflow: generating certificates, configuring the services, and troubleshooting common issues. The topology and step-by-step commands are intended to make the implementation easier to follow, especially for engineers who are new to OpenStack security.