Use random passwords by default

It's easy to forget to override them, and you'll end up with a well known
password used in your keystone and database. Use the password module
to generate secure random passwords instead. Operators of production
environments are still expected to provide their own passwords.

The generated passwords are stored in /etc/bifrost and reused on the next
installation. A new task is provided for upgrading the bootstrap (admin)
user in keystone to the new password.

Change-Id: I6771015f2b062233eeff85704655c8e2ab64364d
This commit is contained in:
Dmitry Tantsur 2020-07-21 16:11:33 +02:00
parent 90ec3890fe
commit 2a6fc72559
12 changed files with 136 additions and 61 deletions

View File

@ -302,8 +302,9 @@ upon.
your local installation.
- Change ``network_interface`` to match the interface that will need
to service DHCP requests.
- Change the ``ironic_db_password`` which is set by ansible in MySQL
and in ironic's configuration file.
- Set ``service_password`` which is used for communication between services.
If unset, a random password is generated during the initial installation and
stored on the controller in ``~/.config/bifrost/service_password``.
The install process, when executed will either download, or build
disk images for the deployment of nodes, and be deployed to the nodes.

View File

@ -18,7 +18,21 @@ oneanother. Example::
ansible-playbook -vvvv -i inventory/target install.yaml -e enable_keystone=true -e noauth_mode=false
However, prior to installation, overriding credentials should be set
in order to customize the deployment to meet your needs.
in order to customize the deployment to meet your needs. At the very least,
the following parameters should be changed for a production environment:
``admin_password``
Password for the bootstrap user (called ``admin`` by default).
``default_password``
Password for the regular user (called ``bifrost_user`` by default).
``service_password``
Password for communication between services (never exposed to end users).
If any of these values is not set, a random password is generated during the
initial installation and stored on the controller in an accordingly named file
in the ``~/.config/bifrost`` directory (override using ``password_dir``).
See the following files for more settings that can be overridden:
* ``playbooks/roles/bifrost-ironic-install/defaults/main.yml``
* ``playbooks/roles/bifrost-keystone-install/defaults/main.yml``

View File

@ -7,8 +7,8 @@
# network_interface: "virbr0"
# ironic_db_password ironic user password for rabbit
ironic_db_password: aSecretPassword473z
# password to use between services
#service_password: aSecretPassword473z
# mysql_username: Default mysql admin username
mysql_username: root
# mysql_password: Default mysql admin user password

View File

@ -7,8 +7,8 @@
# network_interface: "virbr0"
# ironic_db_password ironic user password for rabbit
ironic_db_password: aSecretPassword473z
# password to use between services
#service_password: aSecretPassword473z
# mysql_username: Default mysql admin username
mysql_username: root
# mysql_password: Default mysql admin user password

View File

@ -112,11 +112,6 @@ ipa_git_url: https://opendev.org/openstack/ironic-python-agent
ipa_builder_git_url: https://opendev.org/openstack/ironic-python-agent-builder
mysql_username: "root"
mysql_password: ""
# NOTE(TheJulia): While we have indicated we're going to deprecate ironic_db_password,
# we didn't properly notate it from what I can see at a glance, and we seem to have
# an odd variable expansion issue on fedora blocking migration to fedora-27 that this
# should fix....
ironic_db_password: aSecretPassword473z
disable_dnsmasq_dns: True
ironic_git_folder: /opt/stack/ironic
ironicclient_git_folder: /opt/stack/python-ironicclient
@ -266,47 +261,32 @@ enable_keystone: false
ironic_api_url: "http://localhost:6385"
ironic_inspector_api_url: "http://localhost:5050"
# NOTE: The keystone support in this role
# expects the keystone.bootstrap variables to
# either be loaded OR present from keystone
# installation. The keystone settings below
# should only be used if the role is utilized
# independently of the keystone installation
# role, such as leveraging a pre-existing
# keystone installation.
# WARNING: Using a pre-existing keystone has
# not been tested.
#
#keystone:
# debug: true
# bootstrap:
# enabled: true
# username: admin
# password: ChangeThisPa55w0rd
# project_name: admin
# admin_url: "http://127.0.0.1:35357/v3/"
# public_url: "http://127.0.0.1:5000/v3/"
# internal_url: "http://127.0.0.1:5000/v3/"
# region_name: "RegionOne"
# message_queue:
# username: keystone
# password: ChangeThisPa55w0rd
# host: 127.0.0.1
# database:
# name: keystone
# username: keystone
# password: ChangeThisPa55w0rd
# host: 127.0.0.1
# Directory (on the controller) to keep the passwords
password_dir: "{{ lookup('env', 'HOME') }}/.config/bifrost"
# Various credentials
default_username: bifrost_user
default_password: "{{ lookup('password', password_dir + '/default_password') }}"
admin_username: admin
admin_password: "{{ lookup('password', password_dir + '/admin_password') }}"
# NOTE(dtantsur): various URLs in configuration files don't like special
# symbols in passwords.
service_password: "{{ lookup('password', password_dir + '/service_password chars=ascii_letters,digits') }}"
# TODO(dtantsur): deprecate in favor of service_password
ironic_db_password: "{{ service_password }}"
ironic:
service_catalog:
username: "ironic"
password: "ChangeThisPa55w0rd"
password: "{{ service_password }}"
auth_url: "http://127.0.0.1:5000/v3"
project_name: "service"
keystone:
default_username: "bifrost_user"
default_password: "ChangeThisPa55w0rd"
default_username: "{{ default_username }}"
default_password: "{{ default_password }}"
database:
name: "ironic"
username: "ironic"
@ -316,19 +296,40 @@ ironic:
ironic_inspector:
service_catalog:
username: "ironic_inspector"
password: "ChangeThisPa55w0rd"
password: "{{ service_password }}"
auth_url: "http://127.0.0.1:5000/v3"
project_name: "service"
keystone:
default_username: "inspector_user"
default_password: "ChangeThisPa55w0rd"
default_username: "{{ default_username }}"
default_password: "{{ default_password }}"
database:
name: "inspector"
username: "inspector"
password: "{{ ironic_db_password }}"
host: "localhost"
# DEPRECATED(TheJulia): Inheritance of ironic_db_password params
# should be removed in Queens.
# NOTE(dtantsur): keep in sync with bifrost-keystone-install
keystone:
debug: true
bootstrap:
enabled: true
username: "{{ admin_username }}"
password: "{{ admin_password }}"
project_name: admin
admin_url: "http://127.0.0.1:35357/v3/"
public_url: "http://127.0.0.1:5000/v3/"
internal_url: "http://127.0.0.1:5000/v3/"
region_name: "RegionOne"
message_queue:
username: keystone
password: "{{ service_password }}"
host: localhost
port: 5672
database:
name: keystone
username: keystone
password: "{{ service_password }}"
host: localhost
pip_opts: "{{ lookup('env', 'PIP_OPTS') | default('') }}"

View File

@ -65,6 +65,7 @@
project_name: "{{ keystone.bootstrap.project_name | default('admin') }}"
project_domain_id: "default"
user_domain_id: "default"
update_password: always
wait: yes
environment: "{{ bifrost_venv_env if enable_venv else {} }}"
no_log: true

View File

@ -194,6 +194,7 @@
project_name: admin
project_domain_id: "default"
user_domain_id: "default"
update_password: always
wait: yes
environment: "{{ bifrost_venv_env if enable_venv else {} }}"
no_log: true

View File

@ -6,9 +6,9 @@ clouds:
auth_type: "password"
region_name: {{ cloud.1.config_region_name }}
auth:
username: {{ cloud.1.config_username }}
password: {{ cloud.1.config_password }}
project_name: {{ cloud.1.config_project_name }}
username: "{{ cloud.1.config_username }}"
password: "{{ cloud.1.config_password }}"
project_name: "{{ cloud.1.config_project_name }}"
auth_url: {{ cloud.1.config_auth_url }}
project_domain_id: "{{ cloud.1.config_project_domain_id | default('default') }}"
user_domain_id: "{{ cloud.1.config_user_domain_id | default('default') }}"

View File

@ -8,9 +8,9 @@ case "$1" in
"{{ cloud.0 }}")
export OS_PROJECT_DOMAIN_NAME="{{ cloud.1.config_project_domain_id | default('default') }}"
export OS_USER_DOMAIN_NAME="{{ cloud.1.config_user_domain_id | default('default') }}"
export OS_PROJECT_NAME={{ cloud.1.config_project_name }}
export OS_USERNAME={{ cloud.1.config_username }}
export OS_PASSWORD={{ cloud.1.config_password }}
export OS_PROJECT_NAME="{{ cloud.1.config_project_name }}"
export OS_USERNAME="{{ cloud.1.config_username }}"
export OS_PASSWORD="{{ cloud.1.config_password }}"
export OS_AUTH_URL={{ cloud.1.config_auth_url }}
export OS_IDENTITY_API_VERSION=3
;;

View File

@ -1,4 +1,6 @@
---
enable_keystone: false
keystone_source_install: true
# *_git_url can be overridden by local clones for offline installs
keystone_git_url: https://opendev.org/openstack/keystone
@ -47,12 +49,23 @@ bifrost_venv_env:
pydoc: "python -m pydoc"
ansible_python_interpreter: "{{ bifrost_venv_dir + '/bin/python3' if enable_venv | bool else '/usr/bin/python3' }}"
# Directory (on the controller) to keep the passwords
password_dir: "{{ lookup('env', 'HOME') }}/.config/bifrost"
admin_username: admin
admin_password: "{{ lookup('password', password_dir + '/admin_password') }}"
# NOTE(dtantsur): various URLs in configuration files don't like special
# symbols in passwords.
service_password: "{{ lookup('password', password_dir + '/service_password chars=ascii_letters,digits') }}"
keystone:
debug: true
bootstrap:
enabled: true
username: admin
password: ChangeThisPa55w0rd
username: "{{ admin_username }}"
password: "{{ admin_password }}"
project_name: admin
admin_url: "http://127.0.0.1:35357/v3/"
public_url: "http://127.0.0.1:5000/v3/"
@ -60,13 +73,13 @@ keystone:
region_name: "RegionOne"
message_queue:
username: keystone
password: ChangeThisPa55w0rd
password: "{{ service_password }}"
host: localhost
port: 5672
database:
name: keystone
username: keystone
password: ChangeThisPa55w0rd
password: "{{ service_password }}"
host: localhost
pip_opts: "{{ lookup('env', 'PIP_OPTS') | default('') }}"

View File

@ -44,3 +44,29 @@
- name: "Start Keystone services"
include: start.yml
when: enable_keystone is defined and enable_keystone |bool == True and skip_start | bool != True
- name: "Change the bootstrap password from the static value on upgrade"
os_user:
name: "{{ keystone.bootstrap.username }}"
password: "{{ keystone.bootstrap.password }}"
update_password: always
state: present
domain: "default"
default_project: "{{ keystone.bootstrap.project_name }}"
auth:
auth_url: "{{ ironic.service_catalog.auth_url | default('http://127.0.0.1:5000/') }}"
username: "{{ keystone.bootstrap.username }}"
password: "ChangeThisPa55w0rd"
project_name: "{{ keystone.bootstrap.project_name | default('admin') }}"
project_domain_id: "default"
user_domain_id: "default"
wait: yes
environment: "{{ bifrost_venv_env if enable_venv else {} }}"
no_log: true
ignore_errors: true
when:
- enable_keystone | bool
- not skip_bootstrap | bool
- test_created_keystone_db is undefined or not test_created_keystone_db.changed | bool
- keystone.bootstrap.enabled | bool
- keystone.database.host == 'localhost'

View File

@ -0,0 +1,18 @@
---
upgrade:
- |
The ``inspector_user`` user is not created by default any more. Use
``bifrost_user`` instead.
- |
If you're relying on default passwords (e.g. for the database or keystone
passwords), they will be changed on upgrade. Please use explicit values
if you want to avoid it.
security:
- |
Random passwords are now generated by default instead of using a constant.
The same parameters as before can be used to override them.
deprecations:
- |
The ``ironic_db_password`` parameter is deprecated, please use
``service_password`` to set a password to use between services or
override the whole ``ironic`` and ``keystone`` objects.