Saltstack configuration

From wikinotes
Revision as of 14:37, 16 February 2020 by Will (talk | contribs) (→‎Locations)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Locations

file description
macos:     /usr/local/etc/saltstack/master  # NOT OFFICIALLY SUPPORTED
bsd:       /usr/local/etc/salt/master
linux:     /etc/salt/master
macos:     /opt/local/etc/salt/master
win:       None
configure the salt-master
macos:     /usr/local/etc/saltstack/minion
bsd:       /usr/local/etc/salt/minion
linux:     /etc/salt/minion
macos:     /opt/local/etc/salt/minion
win:       C:/salt/conf/minion
configure the salt-minion
macos:     /usr/local/etc/saltstack/gpgkeys/
bsd:       /usr/local/etc/salt/gpgkeys/
macos:     /opt/local/etc/salt/gpgkeys/
linux:     /etc/salt/gpgkeys/
win:       None
salt-master's gpg home-directory (to encrypt/decrypt pillar entries)
bsd:       /usr/local/etc/salt/grains
linux:     /etc/salt/grains
macos:     /opt/local/etc/salt/grains
win:       C:/salt/conf/grains
define custom grains for the managed server.
(4505-4506)
salt communication ports


SaltMaster

General

The saltmaster is a central server that you will communicate with to receive instructions. The master contains your statefiles, and your encrypted data (passwords, configurations, etc).

Salt lets you organize your statefiles and pillar into different environments. Generally they think of these in terms of base (production), dev (development) and anything else you may find you need. Since I'm working alone, I've been quite happy using simply base.

user: salt                 # user to run salt as

file_roots:                # root of salt-states and salt:// files
    base:
        - /srv/salt

pillar_roots:              # root of salt-pillar
    base:
        - /srv/pillar

Running as Non-Root

Saltmaster can be run as non-root, but make sure that all of it's files are accessible to the user it is configured to use:

/usr/local/etc/salt
/var/cache/salt
/var/log/salt
/var/run/salt

See: https://docs.saltstack.com/en/latest/ref/configuration/nonroot.html

Pillar Encryption

Generate GPGkey

Your pillar is designed to store secret information like passwords, keys, etc. If you have any advantage of taking advantage of this, you should setup a gpg key to allow your pillar to store encrypted info.

create saltmaster's gpgkey

gpg --expert --gen-key --homedir /usr/local/etc/salt/gpgkeys

add saltmaster's public-key to your login user, so that it is easy to encrypt information for the saltmaster. Note that unless you add the private key, your user will only be able to encrypt information, and not decrypt it.

# export saltmaster's gpgkey
gpg --armor --homedir /usr/local/etc/salt/gpgkeys  \
    --armor --export saltmaster  /usr/local/etc/salt/saltmaster.pub

# import gpgkey into your user
# (imports gpgkey into current user's ~/.gnupg)
gpg --import /usr/local/etc/salt/saltmaster.pub

# trust the key by issuing the following
# command, and then choosing the options
# that follow in the interactive prompt.
gpg --edit saltmaster
   # trust
   # 5
   # quit



Backup GPGKey

Export your saltmaster private-key, and back this up somewhere safe. Otherwise your pillar will be useless when you rebuild your machine.

gpg --armor --homedir /usr/local/etc/salt/gpgkeys \
    --armor --export-secret-keys \
    saltmaster > /usr/local/salt/gpgkeys/saltmaster.prv

You can add this key (public/private) to a user if you need to (although this generally isn't necessary).

# user you are importing keys into
gpg --allow-secret-key-import --import /usr/local/salt/gpgkeys/saltmaster.prv

# now clear the passphrase that was automatically set during import
gpg --edit-key saltmaster
    > <existing passphrase>
    > <enter>
    > <enter>
    > <quit>



Encrypt/Decrypt

Encrypt as your login-user

# encrypt the text 'mypassword', and write to 'encrypted_password.gpg'
echo -n "mypassword" \
    | gpg --armor --encrypt -r saltmaster \
    > encrypted_password.gpg

Decrypt using saltmaster

# decrypt the encrypted fake-password
cat encrypted_password.gpg \
    | gpg --homedir /usr/local/etc/salt/gpgkeys



Adding to Pillar

Make sure to add the shebang #!yaml|gpg. This indicates the order that the file should be parsed (first with yaml, then with gpg).

#!yaml|gpg
#### /usr/local/etc/salt/pillars/passwd/mysql/somehost.sls

mysql:
    root: |
        -----BEGIN PGP MESSAGE-----

        hQEMAw2B674HRhwSAQgAhTrN8NizwUv/VunVrqa4/X8t6EUulrnhKcSeb8sZS4th
        W1Qz3K2NjL4lkUHCQHKZVx/VoZY7zsddBIFvvoGGfj8+2wjkEDwFmFjGE4DEsS74
        ZLRFIFJC1iB/O0AiQ+oU745skQkU6OEKxqavmKMrKo3rvJ8ZCXDC470+i2/Hqrp7
        +KWGmaDOO422JaSKRm5D9bQZr9oX7KqnrPG9I1+UbJyQSJdsdtquPWmeIpamEVHb
        VMDNQRjSezZ1yKC4kCWm3YQbBF76qTHzG1VlLF5qOzuGI9VkyvlMaLfMibriqY73
        zBbPzf6Bkp2+Y9qyzuveYMmwS4sEOuZL/PetqisWe9JGAWD/O+slQ2KRu9hNww06
        KMDPJRdyj5bRuBVE4hHkkP23KrYr7SuhW2vpe7O/MvWEJ9uDNegpMLhTWruGngJh
        iFndxegN9w==
        =bAuo
        -----END PGP MESSAGE-----


    user: |
        -----BEGIN PGP MESSAGE-----
        
        hQEMAw2B674HRhwSAQf+Ne+IfsP2IcPDrUWct8sTJrga47jQvlPCmO+7zJjOVcqz
        ...
        -----END PGP MESSAGE-----

Verifying

After you've completed the above, you can check that the value is properly being retrieved by one of your salt-minions.

From a host with access to a pillar entry:

sudo salt-call   pillar.get   passwd:mysql:root   # where passwd:mysql:root is a YAML dictionary address.



System Passwords

FreeBSD/Linux

salted_password=$( python -c "import crypt,uuid; print( crypt.crypt( 'your-password',  '\$6\$;+ uuid.uuid4().hex ) )" )
echo -n "${salted_password}" | gpg --armor --encrypt -r saltmaster
# outputs encrypted, salted password

Windows

# simply use a plaintext password.

SaltMinion

The minion is the worker process. If your machine is targeted on the master, it communicates with the salt-minion. The salt-minion can also request an update from the master.

general

minion with master

id:     my-minion       # handle assigned to your machine. defaults to hostname
master: 192.168.1.100   # the ip-address of your salt-master.

masterless minion

file_client: local

file_roots:               # root-location of salt-states, and salt://
  base:
    - /srv/salt/states
pillar_roots:             # root-location of salt-pillar files
  base:
    - /srv/salt/pillars

You can now apply states using

salt-call --local state.highstate


pre-authenticated keys

If you are provisioning a server, you can generate and store pre-authenticated minion keys. This way, you never need to accept keys on the master.

references
https://docs.saltstack.com/en/latest/topics/tutorials/preseed_key.html

custom grains

Grains are facts about the system being managed by the salt-minion. Most of these are obtained automatically, but you can add your own custom grains to a minion if you find you need to.

/etc/salt/grains