The GPG Renderer

Length: 00:10:09

Lesson Summary:

Although getting our passwords our of our Salt states and into Pillar is a step in the right direction with regards to securing Salt, we can take this one step further by encrypting our data using Salt's GPG renderer. This allows Salt to take our encrypted data, read it, and use it within our states.

Before we begin encrypting passwords, however, we need to prepare our master server to use this renderer.

Prepare GPG Renderer:

  1. Create a directory in which we can store our GPG keys:

     $ sudo mkdir /etc/salt/gpgkeys
    
  2. Set the permissions:

     $ chmod 0700 /etc/salt/gpgkeys
    
  3. Chances are that our Salt master does not have enough entropy to create our master key. So let's first generate some extra entropy:

     $ sudo apt-get install rng-tools
     $ sudo rngd -r /dev/urandom
    
  4. Let's now create our master key:

     $ sudo gpg --gen-key --homedir /etc/salt/gpgkeys
    

    Leave the kind of key, keysize, and expiration date as the default settings. Generally, when creating this key, you'll want to follow your company's existing policies regarding GPG keys and experation.

    Set the full name to Saltstack, and leave the email and comment blank. Do not input a password -- Salt will not be able to use this key if a password is used.

  5. To use this key to encrypt our files, we need to import it to our workstation. In this case, this is the master itself, although generally, it will be whatever environment you've set up to create your states.

    First, let's export the key:

     $ sudo gpg --homedir /etc/salt/gpgkeys --armor --export Saltsalt > exported_pubkey.gpg
    

    Then import it:

     $ gpg --import exported_pubkey.gpg
    

    We're now set to create "secrets" -- or encrypted words or phrases -- to use in our pillar. Let's work on encrypting that temppass password we use for our root MySQL user.

Encrypt Pillar Data

  1. We first want to encrypt our password:

     $ echo -n "temppass" | gpg --armor --trust-model always --encrypt -r Saltstack
     -----BEGIN PGP MESSAGE-----
     Version: GnuPG v1
    
     hQEMA+IrJEeFbLG0AQf/dahR/1jvoO4+OV9yIenHkFKHerTNwWiBXgEq3nVCI1w/
     9KgNLpi5bvD/kv3NN0BhPNHCaqR2Y71t5hjHFqR8Fy8X99HXfXuyY/hvvKkr9vN6
     76MKUPS4MCyldvcR1IXY+AZdvjM0eM3YkV5YnJpGry9m2ZXJXEEpIQFUq3hjFBk8
     v4StCGaWnSgXzHCyMWjJ7L3iQi3GfOfUFeQlkRr380j2/PaaH4qJYKJ5FUMZ+D5D
     csIOQmyCQQT/gQSkBODQecIlD+sScZKdP+vMyMZmYcBDVupW/W6uF/xsll1dPLGG
     CTdbcPg5UMl/uR6v8YWtKovwD1VuTJ1X+ZuKIlFEodJEAW7q6N4tTPeVhyaZblNW
     ElE7zBSjB1anAtxJ7sv7+fir+lhFYjwtpBn2O6aXZ4irGmOBv8kqcMOIB0s9rId4
     Pk3cyG0=
     =Brqj
     -----END PGP MESSAGE-----
    

    Make note of this output. This is what we'll be adding to our pillar file.

  2. Now we can open our mysql.sls pillar file:

     $ vim /srv/pillar/mysql.sls
    
  3. From here, we want to tell Salt that our file contains a cipher that Salt will need to decrypt. To do this, we add a hashbang at the top of our file, informing Salt which renderers it will need to use:

     #!yaml|gpg
    
  4. We can now add that PGP block to our password value. To do this, we use a pipe (|) to tell Salt to look one line down at the block of text provided:

    mysql:
      root:
        name: root
        password: |
          -----BEGIN PGP MESSAGE-----
          Version: GnuPG v1

          hQEMA+IrJEeFbLG0AQf/dahR/1jvoO4+OV9yIenHkFKHerTNwWiBXgEq3nVCI1w/
          9KgNLpi5bvD/kv3NN0BhPNHCaqR2Y71t5hjHFqR8Fy8X99HXfXuyY/hvvKkr9vN6
          76MKUPS4MCyldvcR1IXY+AZdvjM0eM3YkV5YnJpGry9m2ZXJXEEpIQFUq3hjFBk8
          v4StCGaWnSgXzHCyMWjJ7L3iQi3GfOfUFeQlkRr380j2/PaaH4qJYKJ5FUMZ+D5D
          csIOQmyCQQT/gQSkBODQecIlD+sScZKdP+vMyMZmYcBDVupW/W6uF/xsll1dPLGG
          CTdbcPg5UMl/uR6v8YWtKovwD1VuTJ1X+ZuKIlFEodJEAW7q6N4tTPeVhyaZblNW
          ElE7zBSjB1anAtxJ7sv7+fir+lhFYjwtpBn2O6aXZ4irGmOBv8kqcMOIB0s9rId4
          Pk3cyG0=
          =Brqj
          -----END PGP MESSAGE-----

Also notice that the message is spaced in, underneath the `password` key, not inline with it.
  1. Save and exit, then refresh the pillar data:

     $ sudo salt '*' saltutil.refresh_pillar
    
  2. Let's see what happens when we run our MySQL state now:

     $ sudo salt 'minion*' state.sls mysql
    

    Nothing! It looks exactly as we left it before, because we didn't actually change anything, just supplied the password in an encrypted form.

  3. We now want to take that stored password key and use it in our debconf states:

     $ vim /srv/salt/mysql/server.sls
    
     mysql_debconf_settings:
       debconf.set:
         - name: mysql-server
         - data:
             'mysql-server/root_password': {'type': 'password', 'value': '{{ pillar['mysql']['root']['password'] }}'}
             'mysql-server/root_password_again': {'type': 'password', 'value': '{{ pillar['mysql']['root']['password'] }}'}
         - require:
           - pkg: debconf
         - require_in:
           - mysql_server_install
    

    Save and exit.

  4. Let's reapply the formula to ensure no changes are made:

     $ sudo salt 'minion*' state.sls mysql
    
  5. We can also check that our password is rendered properly by viewing our pillar items:

     $ sudo salt '*' pillar.items
    

    Notice that the password is unencrypted when the results are output.

  6. Finally, with our passwords removed from our state, we can now push to GitHub:

    $ cd /srv/salt/mysql/
    $ git add .
    $ git commit -am "Added service, root, and python states; stripped passwords"
    $ git push origin master
    


This lesson is only available to Linux Academy members.

Sign Up To View This Lesson
Or Log In

Looking For Team Training?

Learn More