Skip to content

Instantly share code, notes, and snippets.

@darkpixel
Last active May 6, 2020 19:04
Show Gist options
  • Save darkpixel/51930435c27724d2b41daa8c6bded673 to your computer and use it in GitHub Desktop.
Save darkpixel/51930435c27724d2b41daa8c6bded673 to your computer and use it in GitHub Desktop.
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.
@darkpixel
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment