📜 ⬆️ ⬇️

SaltStack: Pre-generation of passwords for use in services

What is the article about?

A short article on how to generate passwords needed for various services automatically set using SaltStack.


The difficulties of generating passwords.


Very often, it is necessary to automatically install services or applications that require specifying passwords for access to some of their parts (for example, to the web interface or to manage their API). It is also often necessary to configure database users, which will then be used in services using these databases, etc.

A typical problem is the generation of passwords for all such cases. There are several solutions to this problem:
')
1. Register passwords manually in the pillar file


pillar / passwords.sls
service1: web-access-password: '9KTE2aN11GYOJmZGOoqV' db-access-password: '2pGbSlSFkHPY22TwqUus' 

Well, then in any other pillar or in the stack use the specified passwords to generate accesses.
Everything seems to be normal and understandable - but there is one thing - if you spread the state using the specified pillar, the passwords will be stored in the same unchanged form. Moreover, even all single-type servers for which this state will be used will have the same password. Naturally, it makes no sense to explain how this may threaten from the point of view of information security.

2. Generate passwords with SaltStack.


There is one interesting function in SaltStack in the grains get_or_set_hash module, which can generate a password for later use of a particular grain. Passwords are quite complex (due to the default character set, which can be overridden when called), it is easy to use them in the states (just read the corresponding grain from the minion). The only thing worth remembering is that the password is generated only when you first call this function (and the password itself is placed in the / etc / salt / grains file), all subsequent ones will simply read this grain from the file as if the salt was called [ 'grains.get'] ('stored-password-grain-name') .
One of the most significant drawbacks of this method is the inability to read the passwords generated in this way in pillar files, which is often useful when using various formulas ( SaltStack Formulas ).

3. Prev password generation in pillar file

Another way that I use often enough is to pre-generate passwords with Jinja2.
In general, for the pre. generation is used minion installed on the same machine as Salt Master. If you do not want to connect such a minion to the master itself, you can use the masterless configuration, but I prefer to use the minion connected to the master, designating it as grains: roles: local-minion and creating a separate entry in the master configuration:
master / top.sls
 base: 'roles:local-minion': - match: grain - local-minion-state 


The essence of the method before. generating passwords is to create a jarja template for a pillar file with passwords (s) of the following form:
master / files / some-srv-password.sls.jinja2
 some-srv: password: '{{salt['random.get_str'](30)}}' 


The function get_str of the random module is used here.

The next step will be a description of the state for the local minion that generates the pillar password file.
master / local-minion-state.sls
 passwords-file: file.managed: - name: /srv/salt/pillar/some-srv-password.sls #   ,  pillar      - source: salt://files/some-srv-password.sls.jinja2 - template: jinja 


Thereafter, before applying the states, depending on the presence of the pre. generated passwords, run the described state:
 ~# salt-call --local state.sls local-minion-state # masterless or ~# salt -C 'G@roles:local-minion' state.sls local-minion-state 


After the execution of the state, we get a pillar file containing the generated password. To use it, execute include in another pillar file:
pillar / some-srv.sls
 include: - some-srv-password some-srv: username: Fred . . . 


As a result, when requesting salt 'minion-with-some-srv-pillar-connected' pillar.items we get something like this:
 pillar: . . . some-srv: . . . username: Fred password: AoEK8u4Uvo_r9MKtooSUxZV1Y_DLoy 


then you can access the password data by simply calling salt ['pillar.get'] ('some-srv: password') .

Conclusion


Due to the rather large flexibility of the SaltStack system, the solution to this problem is most likely not limited to only 3 methods described in the article - it is quite possible that you will come up with an equally productive and convenient method.
In any case - I hope the description in this article is useful for beginners and not only for SaltStack users. Good luck!

Source: https://habr.com/ru/post/254403/


All Articles