Browse Source

Use iteritems() instead of items().

Signed-off-by: René Jochum <rene@jochums.at>
master
René Jochum 9 years ago
parent
commit
c27f9a81f3
9 changed files with 241 additions and 46 deletions
  1. +44
    -0
      README.rst
  2. +14
    -0
      openssh/config.sls
  3. +8
    -0
      openssh/defaults.yaml
  4. +38
    -0
      openssh/files/ssh_known_hosts
  5. +10
    -1
      openssh/files/sshd_config
  6. +16
    -0
      openssh/known_hosts.sls
  7. +50
    -39
      openssh/map.jinja
  8. +8
    -0
      openssh/moduli.sls
  9. +53
    -6
      pillar.example

+ 44
- 0
README.rst View File

@@ -41,3 +41,47 @@ Installs the ssh daemon configuration file included in this formula
by values from pillar. ``pillar.example`` results in the generation
of the default ``sshd_config`` file on Debian Wheezy.

``openssh.known_hosts``
-----------------------

Manages the site-wide ssh_known_hosts file and fills it with the
public SSH host keys of all minions. You can restrict the set of minions
whose keys are listed by using the pillar data ``openssh:known_hosts:target``
and ``openssh:known_hosts:expr_form`` (those fields map directly to the
corresponding attributes of the ``mine.get`` function).

The Salt mine is used to share the public SSH host keys, you must thus
configure it accordingly on all hosts that must export their keys. Two
mine functions are required, one that exports the keys (one key per line,
as they are stored in ``/etc/ssh/ssh_host_*_key.pub``) and one that defines
the public hostname that the keys are associated to. Here's the way to
setup those functions through pillar::

# Required for openssh.known_hosts
mine_functions:
public_ssh_host_keys:
mine_function: cmd.run
cmd: cat /etc/ssh/ssh_host_*_key.pub
public_ssh_hostname:
mine_function: grains.get
key: id

The above example assumes that the minion identifier is a valid DNS name
that can be used to connect to the host. If that's not the case, you might
want to use the ``fqdn`` grain instead of the ``id`` one. The above example
also uses the default mine function names used by this formula. If you have to
use other names, then you should indicate the names to use in pillar keys
``openssh:known_hosts:mine_keys_function`` and
``openssh:known_hosts:mine_hostname_function``.

You can also integrate alternate DNS names of the various hosts in the
ssh_known_hosts files. You just have to list all the alternate DNS names as a
list in the ``openssh:known_hosts:aliases`` pillar key. Whenever the IPv4 or
IPv6 behind one of those DNS entries matches an IPv4 or IPv6 behind the
official hostname of a minion, the alternate DNS name will be associated to the
minion's public SSH host key.

``openssh.moduli``
-----------------------

Manages the system wide ``/etc/ssh/moduli`` file.

+ 14
- 0
openssh/config.sls View File

@@ -17,10 +17,24 @@ sshd_config:
{% if salt['pillar.get']('openssh:generate_' ~ keyType ~ '_keys', False) %}
ssh_generate_host_{{ keyType }}_key:
cmd.run:
{%- if salt['pillar.get']('openssh:generate_' ~ keyType ~ '_size', False) %}
{%- set keySize = salt['pillar.get']('openssh:generate_' ~ keyType ~ '_size', 4096) %}
- name: ssh-keygen -t {{ keyType }} -b {{ keySize }} -N '' -f /etc/ssh/ssh_host_{{ keyType }}_key
{%- else %}
- name: ssh-keygen -t {{ keyType }} -N '' -f /etc/ssh/ssh_host_{{ keyType }}_key
{%- endif %}
- creates: /etc/ssh/ssh_host_{{ keyType }}_key
- user: root

{% elif salt['pillar.get']('openssh:absent_' ~ keyType ~ '_keys', False) %}
ssh_host_{{ keyType }}_key:
file.absent:
- name: /etc/ssh/ssh_host_{{ keyType }}_key

ssh_host_{{ keyType }}_key.pub:
file.absent:
- name: /etc/ssh/ssh_host_{{ keyType }}_key.pub

{% elif salt['pillar.get']('openssh:provide_' ~ keyType ~ '_keys', False) %}
ssh_host_{{ keyType }}_key:
file.managed:

+ 8
- 0
openssh/defaults.yaml View File

@@ -0,0 +1,8 @@
openssh:
sshd_config: /etc/ssh/sshd_config
sshd_config_src: salt://openssh/files/sshd_config
banner: /etc/ssh/banner
banner_src: salt://openssh/files/banner
ssh_known_hosts: /etc/ssh/ssh_known_hosts
dig_pkg: dnsutils
ssh_moduli: /etc/ssh/moduli

+ 38
- 0
openssh/files/ssh_known_hosts View File

@@ -0,0 +1,38 @@
{#
# vi:syntax=jinja
#}

{%- set target = salt['pillar.get']('openssh:known_hosts:target', '*') -%}
{%- set expr_form = salt['pillar.get']('openssh:known_hosts:expr_form', 'glob') -%}
{%- set keys_function = salt['pillar.get']('openssh:known_hosts:mine_keys_function', 'public_ssh_host_keys') -%}
{%- set hostname_function = salt['pillar.get']('openssh:known_hosts:mine_hostname_function', 'public_ssh_hostname') -%}
{#- Lookup IP of all aliases so that when we have a matching IP, we inject the alias name
in the SSH known_hosts entry -#}
{%- set aliases = salt['pillar.get']('openssh:known_hosts:aliases', []) -%}
{%- set aliases_ips = {} -%}
{%- for alias in aliases -%}
{%- for ip in salt['dig.A'](alias) + salt['dig.AAAA'](alias) -%}
{%- do aliases_ips.setdefault(ip, []).append(alias) -%}
{%- endfor -%}
{%- endfor -%}
{#- Loop over targetted minions -#}
{%- set host_keys = salt['mine.get'](target, keys_function, expr_form=expr_form) -%}
{%- set host_names = salt['mine.get'](target, hostname_function, expr_form=expr_form) -%}
{%- for host, keys in host_keys|dictsort -%}
{%- set ip4 = salt['dig.A'](host) -%}
{%- set ip6 = salt['dig.AAAA'](host) -%}
{%- set names = [host_names.get(host, host)] -%}
{%- for ip in ip4 + ip6 -%}
{%- do names.append(ip) -%}
{%- for alias in aliases_ips.get(ip, []) -%}
{%- if alias not in names -%}
{%- do names.append(alias) -%}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
{%- for line in keys.split('\n') -%}
{%- if line -%}
{{ ','.join(names) }} {{ line }}
{% endif -%}
{%- endfor -%}
{%- endfor -%}

+ 10
- 1
openssh/files/sshd_config View File

@@ -139,7 +139,7 @@

# Restricting Users and Hosts
# example:
# AllowUsers vader@10.0.0.1 maul@sproing.evil.com luke
# AllowUsers vader@10.0.0.1 maul@sproing.evil.com luke
# AllowGroups wheel staff
#
# Keep in mind that using AllowUsers or AllowGroups means that anyone
@@ -156,6 +156,15 @@
# AllowGroups
{{ option('AllowGroups', '') }}

# Specifies the available KEX (Key Exchange) algorithms.
{{ option('KexAlgorithms', 'ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1') }}

# Specifies the ciphers allowed for protocol version 2.
{{ option('Ciphers', 'aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se') }}

# Specifies the available MAC (message authentication code) algorithms.
{{ option('MACs', 'hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-256-96,hmac-sha2-512,hmac-sha2-512-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96') }}

{# Handling unknown in salt template options #}
{%- for keyword in sshd_config.keys() %}
{#- Matches have to be at the bottem and should be handled differently -#}

+ 16
- 0
openssh/known_hosts.sls View File

@@ -0,0 +1,16 @@
{% from "openssh/map.jinja" import openssh with context %}

ensure dig is available:
pkg.installed:
- name: {{ openssh.dig_pkg }}

manage ssh_known_hosts file:
file.managed:
- name: {{ openssh.ssh_known_hosts }}
- source: salt://openssh/files/ssh_known_hosts
- template: jinja
- user: root
- group: root
- mode: 644
- require:
- pkg: ensure dig is available

+ 50
- 39
openssh/map.jinja View File

@@ -1,45 +1,56 @@
{% set openssh = salt['grains.filter_by']({
{## Start with defaults from defaults.yaml ##}
{% import_yaml "openssh/defaults.yaml" as default_settings %}

{##
Setup variable using grains['os_family'] based logic, only add key:values here
that differ from whats in defaults.yaml
##}
{% set os_family_map = salt['grains.filter_by']({
'Arch': {
'server': 'openssh',
'client': 'openssh',
'service': 'sshd',
},
'Debian': {
'server': 'openssh-server',
'client': 'openssh-client',
'service': 'ssh',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'server': 'openssh-server',
'client': 'openssh-client',
'service': 'ssh',
},
'FreeBSD': {
'service': 'sshd',
'dig_pkg': 'bind-tools',
},
'Gentoo': {
'server': 'net-misc/openssh',
'client': 'net-misc/openssh',
'service': 'sshd',
'dig_pkg': 'net-dns/bind-tools',
},
'RedHat': {
'server': 'openssh-server',
'client': 'openssh',
'service': 'sshd',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'server': 'openssh-server',
'client': 'openssh',
'service': 'sshd',
'dig_pkg': 'bind-utils',
},
'Suse': {
'server': 'openssh',
'client': 'openssh',
'service': 'sshd',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
},
'FreeBSD': {
'service': 'sshd',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
'server': 'openssh',
'client': 'openssh',
'service': 'sshd',
'dig_pkg': 'bind-utils',
},
'Arch': {
'server': 'openssh',
'client': 'openssh',
'service': 'sshd.socket',
'sshd_config': '/etc/ssh/sshd_config',
'sshd_config_src': 'salt://openssh/files/sshd_config',
'banner': '/etc/ssh/banner',
'banner_src': 'salt://openssh/files/banner',
},
}, merge=salt['pillar.get']('openssh:lookup')) %}
}
, grain="os_family"
, merge=salt['pillar.get']('openssh:lookup'))
%}

{## Merge the flavor_map to the default settings ##}
{% do default_settings.openssh.update(os_family_map) %}

{## Merge in openssh:lookup pillar ##}
{% set openssh = salt['pillar.get'](
'openssh',
default=default_settings.openssh,
merge=True
)
%}


+ 8
- 0
openssh/moduli.sls View File

@@ -0,0 +1,8 @@
{% from "openssh/map.jinja" import openssh with context %}

{% if salt['pillar.get']('openssh:moduli', False) %}
ssh_moduli:
file.managed:
- name: {{ openssh.ssh_moduli }}
- contents_pillar: openssh:moduli
{% endif %}

+ 53
- 6
pillar.example View File

@@ -22,7 +22,7 @@ sshd_config:
HostbasedAuthentication: 'no'
PermitEmptyPasswords: 'no'
ChallengeResponseAuthentication: 'no'
AuthenticationMethods 'publickey,keyboard-interactive'
AuthenticationMethods: 'publickey,keyboard-interactive'
X11Forwarding: 'yes'
X11DisplayOffset: 10
PrintMotd: 'no'
@@ -36,7 +36,6 @@ sshd_config:
DenyUsers: 'yoda chewbaca@112.10.21.1'
AllowGroups: 'wheel staff imperial'
DenyGroups: 'rebel'
Deny
matches:
sftp_chroot:
type:
@@ -46,20 +45,31 @@ sshd_config:
X11Forwarding: no
AllowTcpForwarding: no
ForceCommand: internal-sftp
# Check `man sshd_config` for supported KexAlgorithms, Ciphers and MACs first.
KexAlgorithms: 'diffie-hellman-group14-sha1,diffie-hellman-group1-sha1'
Ciphers: 'aes128-ctr,aes256-ctr'
MACs: 'hmac-sha1'

openssh:
auth:
joe:
- name: JOE_VALID_SSH_PUBLIC_KEY
joe-valid-ssh-key-desktop:
- user: joe
present: True
enc: ssh-rsa
comment: main key
- name: JOE_NON_VALID_SSH_PUBLIC_KEY
comment: main key - desktop
joe-valid-ssh-key-notebook:
- user: joe
present: True
enc: ssh-rsa
comment: main key - notebook
joe-non-valid-ssh-key:
- user: joe
present: False
enc: ssh-rsa
comment: obsolete key - removed

generate_dsa_keys: False
absent_dsa_keys: False
provide_dsa_keys: False
dsa:
private_key: |
@@ -70,6 +80,7 @@ openssh:
ssh-dss NOT_DEFINED

generate_ecdsa_keys: False
absent_ecdsa_keys: False
provide_ecdsa_keys: False
ecdsa:
private_key: |
@@ -80,6 +91,8 @@ openssh:
ecdsa-sha2-nistp256 NOT_DEFINED

generate_rsa_keys: False
generate_rsa_size: 4096
absent_rsa_keys: False
provide_rsa_keys: False
rsa:
private_key: |
@@ -90,6 +103,7 @@ openssh:
ssh-rsa NOT_DEFINED

generate_ed25519_keys: False
absent_ed25519_keys: False
provide_ed25519_keys: False
ed25519:
private_key: |
@@ -98,3 +112,36 @@ openssh:
-----END OPENSSH PRIVATE KEY-----
public_key: |
ssh-ed25519 NOT_DEFINED

known_hosts:
# The next 2 settings restrict the set of minions that will be added in
# the generated ssh_known_hosts files (the default is to match all minions)
target: '*'
expr_form: 'glob'
# Name of mining functions used to gather public keys and hostnames
# (the default values are shown here)
mine_keys_function: public_ssh_host_keys
mine_hostname_function: public_ssh_hostname
# List of DNS entries also pointing to our managed machines and that we want
# to inject in our generated ssh_known_hosts file
aliases:
- cname-to-minion.example.org
- alias.example.org

# specify DH parameters (see /etc/ssh/moduli)
moduli: |
# Time Type Tests Tries Size Generator Modulus
20120821045639 2 6 100 2047 2 DD2047CBDBB6F8E919BC63DE885B34D0FD6E3DB2887D8B46FE249886ACED6B46DFCD5553168185FD376122171CD8927E60120FA8D01F01D03E58281FEA9A1ABE97631C828E41815F34FDCDF787419FE13A3137649AA93D2584230DF5F24B5C00C88B7D7DE4367693428C730376F218A53E853B0851BAB7C53C15DA7839CBE1285DB63F6FA45C1BB59FE1C5BB918F0F8459D7EF60ACFF5C0FA0F3FCAD1C5F4CE4416D4F4B36B05CDCEBE4FB879E95847EFBC6449CD190248843BC7EDB145FBFC4EDBB1A3C959298F08F3BA2CFBE231BBE204BE6F906209D28BD4820AB3E7BE96C26AE8A809ADD8D1A5A0B008E9570FA4C4697E116B8119892C604293680B09D63
20120821045830 2 6 100 2047 2 DD2047CBDBB6F8E919BC63DE885B34D0FD6E3DB2887D8B46FE249886ACED6B46DFCD5553168185FD376122171CD8927E60120FA8D01F01D03E58281FEA9A1ABE97631C828E41815F34FDCDF787419FE13A3137649AA93D2584230DF5F24B5C00C88B7D7DE4367693428C730376F218A53E853B0851BAB7C53C15DA7839CBE1285DB63F6FA45C1BB59FE1C5BB918F0F8459D7EF60ACFF5C0FA0F3FCAD1C5F4CE4416D4F4B36B05CDCEBE4FB879E95847EFBC6449CD190248843BC7EDB145FBFC4EDBB1A3C959298F08F3BA2CFBE231BBE204BE6F906209D28BD4820AB3E7BE96C26AE8A809ADD8D1A5A0B008E9570FA4C4697E116B8119892C6042936814C2FFB
20120821050046 2 6 100 2047 2 DD2047CBDBB6F8E919BC63DE885B34D0FD6E3DB2887D8B46FE249886ACED6B46DFCD5553168185FD376122171CD8927E60120FA8D01F01D03E58281FEA9A1ABE97631C828E41815F34FDCDF787419FE13A3137649AA93D2584230DF5F24B5C00C88B7D7DE4367693428C730376F218A53E853B0851BAB7C53C15DA7839CBE1285DB63F6FA45C1BB59FE1C5BB918F0F8459D7EF60ACFF5C0FA0F3FCAD1C5F4CE4416D4F4B36B05CDCEBE4FB879E95847EFBC6449CD190248843BC7EDB145FBFC4EDBB1A3C959298F08F3BA2CFBE231BBE204BE6F906209D28BD4820AB3E7BE96C26AE8A809ADD8D1A5A0B008E9570FA4C4697E116B8119892C60429368214FC53
20120821050054 2 6 100 2047 5 DD2047CBDBB6F8E919BC63DE885B34D0FD6E3DB2887D8B46FE249886ACED6B46DFCD5553168185FD376122171CD8927E60120FA8D01F01D03E58281FEA9A1ABE97631C828E41815F34FDCDF787419FE13A3137649AA93D2584230DF5F24B5C00C88B7D7DE4367693428C730376F218A53E853B0851BAB7C53C15DA7839CBE1285DB63F6FA45C1BB59FE1C5BB918F0F8459D7EF60ACFF5C0FA0F3FCAD1C5F4CE4416D4F4B36B05CDCEBE4FB879E95847EFBC6449CD190248843BC7EDB145FBFC4EDBB1A3C959298F08F3BA2CFBE231BBE204BE6F906209D28BD4820AB3E7BE96C26AE8A809ADD8D1A5A0B008E9570FA4C4697E116B8119892C60429368218E83F

# Required for openssh.known_hosts
mine_functions:
public_ssh_host_keys:
mine_function: cmd.run
cmd: cat /etc/ssh/ssh_host_*_key.pub
python_shell: True
public_ssh_hostname:
mine_function: grains.get
key: id

Loading…
Cancel
Save