ansible-role-mysql icon indicating copy to clipboard operation
ansible-role-mysql copied to clipboard

Default insecure passwords seems bad

Open eythian opened this issue 8 years ago • 14 comments

I think that setting a default password of 'root' is dangerous. Instead, it might be worth considering:

  • aborting with an error if no password is defined
  • setting a large random one if none is defined

That should reduce the risk of people ending up with an insecure setup because they were in a hurry or something. Relatedly, it could be interesting to have a little aside in the docs on how to securely create a password file for when you drop this role in as a git submodule, and so want to avoid making changes to it if possible.

eythian avatar Jun 13 '17 18:06 eythian

I think that setting a default password of 'root' is dangerous.

At least it's more secure than MySQL's traditional default of having no password :)

I've considered doing something like this from time to time... but it's difficult to think of a way to randomize it (where it's random on first run, then consistent on future runs), and it's also just security-through-obscurity to simply set a more secure default.

Throwing a warning if it's root, I might be amenable to, since it would be the least invasive and most reliable way of highlighting insecure passwords.

But one thing to keep in mind is that many people (myself included) end up using the defaults for things like one-off database environments where we need to build something quick, run some commands, then tear it down. I usually either use 'root' or '' (no password) for that, just because it's fast and works quickly with defaults in many of the downstream tools I use with MySQL...

geerlingguy avatar Jun 13 '17 21:06 geerlingguy

Presumably the root password is only set if the .my.cnf exists (excluding that override option), so if a random one were generated, it would be set and written into that file the first time, and wouldn't change again?

But even a loud warning would be enough I think.

Thanks for the role btw, it's a very handy thing for me finally getting my wordpress installation ansibleised :)

eythian avatar Jun 13 '17 21:06 eythian

maybe optionally prompting for a password based on config parameter. this would not break it for people just needing an easy way to set a password and still allow for a bit more control over access to password.

llbbl avatar Jan 25 '19 00:01 llbbl

This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution!

Please read this blog post to see the reasons why I mark issues as stale.

stale[bot] avatar Mar 06 '20 02:03 stale[bot]

This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details.

stale[bot] avatar Apr 05 '20 03:04 stale[bot]

@geerlingguy wrote:

I've considered doing something like this from time to time... but it's difficult to think of a way to randomize it (where it's random on first run, then consistent on future runs), and it's also just security-through-obscurity to simply set a more secure default.

Agreed on those points. The solution here is to do the following:

  1. Set a random password on each run (unless there's already one there and there's no reason to change it).
  2. Place the generated password in /root/.my.cnf.

But one thing to keep in mind is that many people (myself included) end up using the defaults for things like one-off database environments where we need to build something quick, run some commands, then tear it down. I usually either use 'root' or '' (no password) for that, just because it's fast and works quickly with defaults in many of the downstream tools I use with MySQL...

As proven time and time again, with routers and other IoT devices for example, setting passwords to common defaults is a terrible idea.

For this particular use case, you don't need to know what the password is. It'll be in /root/.my.cnf, which can be accessed indirectly by running sudo -H mysql. That logs you in as root, with whatever root password is in the file. It can be used in scripts, etc.

Please have a look at my Matomo role for an example of how to do this, generating a random password and then sticking it in the file. Specifically, see how I set the default password securely:

matomo_superuser_password: "{{ lookup('password', '/dev/null length=20 chars=ascii_letters') }}"

I believe that this issue should be reopened (and ideally labelled as a security issue). I can't see a "Reopen" button so I can't do this myself.

colans avatar Apr 07 '20 16:04 colans

This issue is no longer marked for closure.

stale[bot] avatar Jan 11 '21 17:01 stale[bot]

This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution!

Please read this blog post to see the reasons why I mark issues as stale.

stale[bot] avatar Apr 12 '21 00:04 stale[bot]

@geerlingguy Any chance you could roadmap this one? Thanks.

colans avatar Apr 12 '21 13:04 colans

This issue is no longer marked for closure.

stale[bot] avatar Apr 12 '21 13:04 stale[bot]

Just adding how we currently randomly change the root password on the first run of our playbook in case if it is of any use:

- name: install openssl to make sure we can generate a random password
  apt: name=openssl update_cache=yes cache_valid_time=3600
  tags:
    - packages

- name: make a random password for mysql root user
  shell: openssl rand -base64 48 | tr -d "=+/" | cut -c1-40
  register: mysql_root_password

- name: set mysql root password to something random if it is still set as the default
  mysql_user:
    append_privs: yes
    login_password: root
    login_user: root
    name: root
    password: "{{ mysql_root_password.stdout }}"
  ignore_errors: yes
  register: mysql_root_pw_set

- name: update root .my.cnf with new password
  ini_file:
    dest: "~/.my.cnf"
    section: client
    option: "{{ item.option }}"
    value: "{{ item.value }}"
    mode: 0600
  with_items:
    - { option: user, value: root }
    - { option: password, value: "{{ mysql_root_password.stdout }}" }
  when: mysql_root_pw_set.changed

This makes sure we have a random secure password setup for every new MySQL server and the password is stored in the root .my.cnf file so we can ssh in to grab the password.

I'm sure there will be a way of generating a password without the requirement of openssl but I don't know of a good way yet.

l3rady avatar Sep 06 '21 13:09 l3rady

I'm sure there will be a way of generating a password without the requirement of openssl but I don't know of a good way yet.

As I stated in my earlier comment, you can do this in Ansible natively. There's no need to shell for openssl. Here's that same example again:

matomo_superuser_password: "{{ lookup('password', '/dev/null length=20 chars=ascii_letters') }}"

colans avatar Sep 06 '21 14:09 colans

@geerlingguy : I think this MR should do the trick. Thoughts?

colans avatar Oct 07 '21 15:10 colans

This was more complicated that I thought. See the new PR for details, #465 (I closed the original one.)

colans avatar Oct 07 '21 20:10 colans