GPG Encrypt Pillar Data¶
/etc/salt/gpgkeys
is a required hard-coded directory. Ensure only the
salt-master user has access to this.
Note
salt-master requires no password for GPG decryption to work. Secure your certs. You may want to enforce expiration on certs as well.
If entropy generation is slow (typical on VM’s), install haveged to speed up entropy collection.
mkdir -p /etc/salt/gpgkeys
chmod 0700 /etc/salt/gpgkeys
gpg --gen-key --homedir /etc/salt/gpgkeys
Important
Default option (
RSA and RSA
).4096
bit key.0
(cert does not expire).salty (salt@example.com)
.NO password.
gpg --homedir /etc/salt/gpgkeys --armor --export > salty_public_key.gpg
salt_public_key.gpg
is used by anyone on any system to create encrypted data
that only the server can read.
gpg --import salt_public_key.gpg
Encrypting Data¶
Note
The entire PGP block should be added to Pillar; the blank vertical space can
be removed. salty
is the name of the recipient of the data.
echo -n "super_secret_server_stuff" | gpg --armor --batch --trust-model always --encrypt --recipient salty
gpg --armor --batch --trust-model always --encrypt --recipient salty {FILE}
Note
The contents of this file should be what is placed in Pillar. It will be
written as {FILE}.asc
. salty
is the name of the recipient of the data
(see Generate GPG keys for salt-master encryption/decryption.).
Warning
Binary data cannot be stored GPG encrypted in pillar for Python 3 versions of saltstack due to Python 3 strict handling of text vs. binary data type. This results in a binary data render error for GPG on salt. Binary support is being explicitly added.
Encrypt Shadow Passwords¶
The salt user state documentation recommends using openssl passwd -1
to
generate a bash passwd hash. This only hashes MD5; modern distributuions of
linux hash sha512. Use either the mkpasswd
tool or the python script
below to generate a salted, sha512 hash in the correct format for consumption
in /etc/shadow
. Then GPG encrypt the password when storing in Pillar.
apt install whois
mkpasswd -m sha-512
python3 -c "import crypt, getpass; print(crypt.crypt(getpass.getpass('password to hash: '), crypt.mksalt(crypt.METHOD_SHA512)))"
Add to Pillar¶
Prefix any Pillar file using GPG encryped data with #!yaml|gpg
and insert
the GPG message block as the value for a key. Use a pipe (|
) to denote a GPG
message. Blank lines between the begin/version and body can be removed. Standard
YAML indentation rules for long text blocks apply.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #!yaml|gpg
secret-stuff: |
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2.0.22 (GNU/Linux)
hQEMA4Pr9QJhL3umAQgAnZtS7lTyDR3kjr+VjCIADutmxyjrxbyaNnPEs3eJRi9G
N6LtiFlUt24Jgdgupu/CG2IS815V0Vx3EbBknpNNwq0Yrs2joMnm92ZRv4AI6ZTo
yQqGICetmBOS+vGk4jS8mj9qRjLamvPDOBPyNpKiRCFqu1TPKYw0a8xssO/j/pzW
TJ39WsHXjtOWLkfYOaf7SKffYL9EsdU5tqXASe5UvjR1Gbj7wdjPl+vMZxRhzfOn
YQ3fq3wNrGkuz2PpE7n77mmvYGVlXemw4o6tITZMa3MIFZqGTPbCCnh4OubqWGqd
MtMNgPD2EeZ6wfEWkf1LGrrFy9POmdpssiU92J5dsNJQAdTAZVP4gtoyjWRtHJQB
3FNarZY210P1o16s1n05ZbkVnz2FeZW/ClB6FqiewDe2EoXcVbXT5WgSZTHFi3mJ
dFXQZGtReJL4vt8Iq8jSwRI=
=wJ+K
-----END PGP MESSAGE-----
|
Refresh Pillar and Push Data¶
Regenerate cached Pillar data and push new values (e.g. updated GPG data) to minions if automatic refresh isn’t fast enough. Minions that have been given access to the specific pillar will be able to see the decrypted data.
salt '*' saltutil.refresh_pillar
salt pillar.items