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. your local installation.
- Change ``network_interface`` to match the interface that will need - Change ``network_interface`` to match the interface that will need
to service DHCP requests. to service DHCP requests.
- Change the ``ironic_db_password`` which is set by ansible in MySQL - Set ``service_password`` which is used for communication between services.
and in ironic's configuration file. 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 The install process, when executed will either download, or build
disk images for the deployment of nodes, and be deployed to the nodes. 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 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 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-ironic-install/defaults/main.yml``
* ``playbooks/roles/bifrost-keystone-install/defaults/main.yml`` * ``playbooks/roles/bifrost-keystone-install/defaults/main.yml``

View File

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

View File

@ -7,8 +7,8 @@
# network_interface: "virbr0" # network_interface: "virbr0"
# ironic_db_password ironic user password for rabbit # password to use between services
ironic_db_password: aSecretPassword473z #service_password: aSecretPassword473z
# mysql_username: Default mysql admin username # mysql_username: Default mysql admin username
mysql_username: root mysql_username: root
# mysql_password: Default mysql admin user password # 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 ipa_builder_git_url: https://opendev.org/openstack/ironic-python-agent-builder
mysql_username: "root" mysql_username: "root"
mysql_password: "" 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 disable_dnsmasq_dns: True
ironic_git_folder: /opt/stack/ironic ironic_git_folder: /opt/stack/ironic
ironicclient_git_folder: /opt/stack/python-ironicclient ironicclient_git_folder: /opt/stack/python-ironicclient
@ -266,47 +261,32 @@ enable_keystone: false
ironic_api_url: "http://localhost:6385" ironic_api_url: "http://localhost:6385"
ironic_inspector_api_url: "http://localhost:5050" ironic_inspector_api_url: "http://localhost:5050"
# NOTE: The keystone support in this role # Directory (on the controller) to keep the passwords
# expects the keystone.bootstrap variables to password_dir: "{{ lookup('env', 'HOME') }}/.config/bifrost"
# either be loaded OR present from keystone
# installation. The keystone settings below # Various credentials
# should only be used if the role is utilized default_username: bifrost_user
# independently of the keystone installation default_password: "{{ lookup('password', password_dir + '/default_password') }}"
# role, such as leveraging a pre-existing
# keystone installation. admin_username: admin
# WARNING: Using a pre-existing keystone has admin_password: "{{ lookup('password', password_dir + '/admin_password') }}"
# not been tested.
# # NOTE(dtantsur): various URLs in configuration files don't like special
#keystone: # symbols in passwords.
# debug: true service_password: "{{ lookup('password', password_dir + '/service_password chars=ascii_letters,digits') }}"
# bootstrap:
# enabled: true # TODO(dtantsur): deprecate in favor of service_password
# username: admin ironic_db_password: "{{ service_password }}"
# 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
ironic: ironic:
service_catalog: service_catalog:
username: "ironic" username: "ironic"
password: "ChangeThisPa55w0rd" password: "{{ service_password }}"
auth_url: "http://127.0.0.1:5000/v3" auth_url: "http://127.0.0.1:5000/v3"
project_name: "service" project_name: "service"
keystone: keystone:
default_username: "bifrost_user" default_username: "{{ default_username }}"
default_password: "ChangeThisPa55w0rd" default_password: "{{ default_password }}"
database: database:
name: "ironic" name: "ironic"
username: "ironic" username: "ironic"
@ -316,19 +296,40 @@ ironic:
ironic_inspector: ironic_inspector:
service_catalog: service_catalog:
username: "ironic_inspector" username: "ironic_inspector"
password: "ChangeThisPa55w0rd" password: "{{ service_password }}"
auth_url: "http://127.0.0.1:5000/v3" auth_url: "http://127.0.0.1:5000/v3"
project_name: "service" project_name: "service"
keystone: keystone:
default_username: "inspector_user" default_username: "{{ default_username }}"
default_password: "ChangeThisPa55w0rd" default_password: "{{ default_password }}"
database: database:
name: "inspector" name: "inspector"
username: "inspector" username: "inspector"
password: "{{ ironic_db_password }}" password: "{{ ironic_db_password }}"
host: "localhost" 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('') }}" pip_opts: "{{ lookup('env', 'PIP_OPTS') | default('') }}"

View File

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

View File

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

View File

@ -6,9 +6,9 @@ clouds:
auth_type: "password" auth_type: "password"
region_name: {{ cloud.1.config_region_name }} region_name: {{ cloud.1.config_region_name }}
auth: auth:
username: {{ cloud.1.config_username }} username: "{{ cloud.1.config_username }}"
password: {{ cloud.1.config_password }} password: "{{ cloud.1.config_password }}"
project_name: {{ cloud.1.config_project_name }} project_name: "{{ cloud.1.config_project_name }}"
auth_url: {{ cloud.1.config_auth_url }} auth_url: {{ cloud.1.config_auth_url }}
project_domain_id: "{{ cloud.1.config_project_domain_id | default('default') }}" project_domain_id: "{{ cloud.1.config_project_domain_id | default('default') }}"
user_domain_id: "{{ cloud.1.config_user_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 }}") "{{ cloud.0 }}")
export OS_PROJECT_DOMAIN_NAME="{{ cloud.1.config_project_domain_id | default('default') }}" 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_USER_DOMAIN_NAME="{{ cloud.1.config_user_domain_id | default('default') }}"
export OS_PROJECT_NAME={{ cloud.1.config_project_name }} export OS_PROJECT_NAME="{{ cloud.1.config_project_name }}"
export OS_USERNAME={{ cloud.1.config_username }} export OS_USERNAME="{{ cloud.1.config_username }}"
export OS_PASSWORD={{ cloud.1.config_password }} export OS_PASSWORD="{{ cloud.1.config_password }}"
export OS_AUTH_URL={{ cloud.1.config_auth_url }} export OS_AUTH_URL={{ cloud.1.config_auth_url }}
export OS_IDENTITY_API_VERSION=3 export OS_IDENTITY_API_VERSION=3
;; ;;

View File

@ -1,4 +1,6 @@
--- ---
enable_keystone: false
keystone_source_install: true keystone_source_install: true
# *_git_url can be overridden by local clones for offline installs # *_git_url can be overridden by local clones for offline installs
keystone_git_url: https://opendev.org/openstack/keystone keystone_git_url: https://opendev.org/openstack/keystone
@ -47,12 +49,23 @@ bifrost_venv_env:
pydoc: "python -m pydoc" pydoc: "python -m pydoc"
ansible_python_interpreter: "{{ bifrost_venv_dir + '/bin/python3' if enable_venv | bool else '/usr/bin/python3' }}" 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: keystone:
debug: true debug: true
bootstrap: bootstrap:
enabled: true enabled: true
username: admin username: "{{ admin_username }}"
password: ChangeThisPa55w0rd password: "{{ admin_password }}"
project_name: admin project_name: admin
admin_url: "http://127.0.0.1:35357/v3/" admin_url: "http://127.0.0.1:35357/v3/"
public_url: "http://127.0.0.1:5000/v3/" public_url: "http://127.0.0.1:5000/v3/"
@ -60,13 +73,13 @@ keystone:
region_name: "RegionOne" region_name: "RegionOne"
message_queue: message_queue:
username: keystone username: keystone
password: ChangeThisPa55w0rd password: "{{ service_password }}"
host: localhost host: localhost
port: 5672 port: 5672
database: database:
name: keystone name: keystone
username: keystone username: keystone
password: ChangeThisPa55w0rd password: "{{ service_password }}"
host: localhost host: localhost
pip_opts: "{{ lookup('env', 'PIP_OPTS') | default('') }}" pip_opts: "{{ lookup('env', 'PIP_OPTS') | default('') }}"

View File

@ -44,3 +44,29 @@
- name: "Start Keystone services" - name: "Start Keystone services"
include: start.yml include: start.yml
when: enable_keystone is defined and enable_keystone |bool == True and skip_start | bool != True 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.