Salt through spiped
# Quick-and-dirty how-to for wrapping salt traffic in spiped. Critiques welcome. You'll probably need to adjust slightly if you aren't using FreeBSD. | |
# There's a great write-up with pictures here: https://hackacad.net/security/2020/05/06/how-to-secure-you-salstack-salt-master-using-spiped.html | |
## Master | |
# /usr/local/etc/salt/master needs to be bound to localhost, and it's better to be explicit than implicit with your ports. | |
interface: 127.0.0.1 | |
publish_port: 4505 | |
ret_port: 4506 | |
Start your salt master | |
# Install pwgen and spiped | |
# Generate a new key for spiped | |
pwgen 64 1 > /usr/local/etc/salt.key | |
# Launch spiped on the master for both ports (Remove the -F to daemonize. Automatically launch from your favorite init system.) | |
spiped -d -s 0.0.0.0:4505 -t 127.0.0.1:4505 -k /usr/local/etc/salt.key -F | |
spiped -d -s 0.0.0.0:4506 -t 127.0.0.1:4506 -k /usr/local/etc/salt.key -F | |
# Salt master setup is complete. | |
## Minions | |
# Distribute /usr/local/etc/salt.key from the master to minions (scp, copy/paste, etc...) | |
# Skip this if you are going to use salt to deploy to the minions | |
# Install spiped on the minions and launch spiped (Remove the -F to daemonize. Automatically launch from your favorite init system.) | |
spiped -e -s 127.0.0.1:4505 -t saltmaster.example.tld:4505 -k /usr/local/etc/spiped/salt.key -F | |
spiped -e -s 127.0.0.1:4506 -t saltmaster.example.tld:4506 -k /usr/local/etc/spiped/salt.key -F | |
# /usr/local/etc/salt/minion needs to be told to look for the master on 'localhost' | |
master: "localhost" | |
service salt_minion restart | |
# salt-call -l info test.ping | |
local: | |
True | |
## Kludgy state for installing spiped | |
# I manage FreeBSD and Debian systems, so I've tested with them more extensively than anything else. Your mileage may vary. | |
# Use the steps above to set up spiped on your master | |
# map.jinja | |
{% set spiped_settings = salt['grains.filter_by']({ | |
'Arch': { | |
'config_dir': '/etc/spiped', | |
'config_dir_group': 'root', | |
}, | |
'Debian': { | |
'config_dir': '/etc/spiped', | |
'config_dir_group': 'root', | |
}, | |
'FreeBSD': { | |
'config_dir': '/usr/local/etc/spiped', | |
'config_dir_group': 'wheel', | |
}, | |
'OpenBSD': { | |
'config_dir': '/etc/spiped', | |
'config_dir_group': 'root', | |
}, | |
'Gentoo': { | |
'config_dir': '/etc/spiped', | |
'config_dir_group': 'root', | |
}, | |
'RedHat': { | |
'config_dir': '/etc/spiped', | |
'config_dir_group': 'root', | |
}, | |
'Suse': { | |
'config_dir': '/etc/spiped', | |
'config_dir_group': 'root', | |
}, | |
} | |
, grain="os_family" | |
, merge=salt['pillar.get']('spiped_config')) | |
%} | |
# init.sls | |
{% from "minion_spiped/map.jinja" import spiped_settings %} | |
spiped_pkg: | |
pkg.installed: | |
- pkgs: | |
- spiped | |
{{ spiped_settings.config_dir }}: | |
file.directory: | |
- user: root | |
- group: {{ spiped_settings.config_dir_group }} | |
- dir_mode: 700 | |
spiped_salt_key: | |
file.managed: | |
- name: {{ spiped_settings.config_dir }}/salt.key | |
- contents: "YOUR-SPIPED-KEY-FROM-YOUR-MASTER" | |
- contents_newline: True # Some minions have a broken contents_newline when set to false preventing connectivity | |
- require: | |
- file: {{ spiped_settings.config_dir }} | |
- watch_in: | |
- spiped | |
{% if 'BSD' in grains.get('kernel', '') %} | |
spiped_enabled: | |
service.enabled: | |
- name: spiped | |
# service spiped restart WILL HANG on a lot of systems due to yet another salt bug relating to things writing to stdout | |
spiped: | |
cmd.wait: | |
- name: "killall -SIGKILL spiped > /dev/null 2>&1; exit 0" | |
spiped_stop: | |
cmd.wait: | |
- name: "service spiped stop > /dev/null 2>&1; exit 0" | |
- watch: | |
- spiped | |
spiped_start: | |
cmd.wait: | |
- name: "service spiped start > /dev/null 2>&1; exit 0" | |
- watch: | |
- spiped_stop | |
spiped_rc_enable: | |
sysrc.managed: | |
- name: "spiped_enable" | |
- value: "YES" | |
spiped_rc_enable_pipes: | |
sysrc.managed: | |
- name: "spiped_pipes" | |
- value: "saltmaster saltreturn" | |
- watch_in: | |
- spiped | |
spiped_rc_pipe_mode_saltmaster: | |
sysrc.managed: | |
- name: spiped_pipe_saltmaster_mode | |
- value: client | |
- watch_in: | |
- spiped | |
spiped_rc_pipe_source_saltmaster: | |
sysrc.managed: | |
- name: spiped_pipe_saltmaster_source | |
- value: 127.0.0.1:4505 | |
- watch_in: | |
- spiped | |
spiped_rc_pipe_target_saltmaster: | |
sysrc.managed: | |
- name: spiped_pipe_saltmaster_target | |
- value: DNS-NAME-OR-IP-OF-YOUR-SALT-MASTER:4505 | |
- watch_in: | |
- spiped | |
spiped_pipe_saltmaster_key: | |
sysrc.managed: | |
- name: spiped_pipe_saltmaster_key | |
- value: "{{ spiped_settings.config_dir }}/salt.key" | |
- watch_in: | |
- spiped | |
spiped_rc_pipe_key_saltmaster: | |
sysrc.managed: | |
- name: spiped_pipe_salt_key | |
- value: {{ spiped_settings.config_dir }}/salt.key | |
- watch_in: | |
- spiped | |
spiped_rc_pipe_mode_saltreturn: | |
sysrc.managed: | |
- name: spiped_pipe_saltreturn_mode | |
- value: client | |
- watch_in: | |
- spiped | |
spiped_rc_pipe_source_saltreturn: | |
sysrc.managed: | |
- name: spiped_pipe_saltreturn_source | |
- value: 127.0.0.1:4506 | |
- watch_in: | |
- spiped | |
spiped_rc_pipe_target_saltreturn: | |
sysrc.managed: | |
- name: spiped_pipe_saltreturn_target | |
- value: DNS-NAME-OR-IP-OF-YOUR-SALT-MASTER:4506 | |
- watch_in: | |
- spiped | |
spiped_pipe_saltreturn_key: | |
sysrc.managed: | |
- name: spiped_pipe_saltreturn_key | |
- value: "{{ spiped_settings.config_dir }}/salt.key" | |
- watch_in: | |
- spiped | |
spiped_rc_pipe_key_saltreturn: | |
sysrc.managed: | |
- name: spiped_pipe_salt_key | |
- value: {{ spiped_settings.config_dir }}/salt.key | |
- watch_in: | |
- spiped | |
{% else %} | |
fuck_systemd: | |
cmd.wait: | |
- name: systemctl daemon-reload | |
/etc/systemd/system/spiped-saltmaster.service: | |
file.managed: | |
- template: jinja | |
- source: salt:///spiped-saltmaster.service | |
- context: | |
- watch_in: | |
- fuck_systemd | |
/etc/systemd/system/spiped-saltreturn.service: | |
file.managed: | |
- template: jinja | |
- source: salt:///spiped-saltreturn.service | |
- context: | |
- watch_in: | |
- fuck_systemd | |
spiped-saltmaster: | |
service.running: | |
- enable: true | |
- require: | |
- /etc/systemd/system/spiped-saltmaster.service | |
spiped-saltreturn: | |
service.running: | |
- enable: true | |
- require: | |
- /etc/systemd/system/spiped-saltreturn.service | |
{% endif %} | |
# A few notes: | |
# I recommend spinning up a new salt master with a version of salt that isn't vulnerable to use. | |
# Once it is up and running, go to your 'old' salt master and make sure it has the bare-minimum states necessary to configure the salt minion, and deploy spiped. | |
# If something screws up, it will still talk to your old server. If it works, it will talk to your new master via spiped. | |
minion: | |
master: | |
- 127.0.0.1 | |
- old-server.example.tld | |
master_alive_interval: 60 | |
master_type: failover | |
retry_dns: 0 | |
# If you have questions, I'm happy to help. Leave a comment below. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
There's a great write-up here: https://hackacad.net/security/2020/05/06/how-to-secure-you-salstack-salt-master-using-spiped.html