diff --git a/README.rst b/README.rst index 86a551e..559e6fb 100644 --- a/README.rst +++ b/README.rst @@ -51,13 +51,23 @@ of the default ``sshd_config`` file on Debian Wheezy. It is highly recommended ``PermitRootLogin`` is added to pillar so root login will be disabled. +``openssh.config_ini`` +---------------------- + +Version of managing ``sshd_config`` that uses the +`ini_managed.option_present `_ +state module, so it enables to override only one or +multiple values and keeping the defaults shipped by your +distribution. + + ``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 +and ``openssh:known_hosts:tgt_type`` (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 diff --git a/openssh/auth_map.sls b/openssh/auth_map.sls index 2cd5870..86851ce 100644 --- a/openssh/auth_map.sls +++ b/openssh/auth_map.sls @@ -5,11 +5,11 @@ include: {%- set openssh_pillar = salt["pillar.get"]("openssh", {}) -%} {%- set authorized_keys_file = salt["pillar.get"]("sshd_config:AuthorizedKeysFile", None) %} -{%- for store, config in salt["pillar.get"]("openssh:auth_map", {}).iteritems() %} +{%- for store, config in salt["pillar.get"]("openssh:auth_map", {}).items() %} {%- set store_base = config["source"] %} # SSH store openssh:auth_map:{{ store }} -{%- for user, keys in config.get("users", {}).iteritems() %} -{%- for key, key_cfg in keys.iteritems() %} +{%- for user, keys in config.get("users", {}).items() %} +{%- for key, key_cfg in keys.items() %} "ssh_auth--{{ store }}--{{ user }}--{{ key }}": {%- set present = key_cfg.get("present", True) %} {%- set options = key_cfg.get("options", []) %} diff --git a/openssh/config.sls b/openssh/config.sls index 96d420c..dd5ac2f 100644 --- a/openssh/config.sls +++ b/openssh/config.sls @@ -67,7 +67,7 @@ ssh_generate_host_{{ keyType }}_key: {%- set keySizePart = "-b {}".format(keySize) if keySize else "" %} - name: "rm {{ keyFile }}*; ssh-keygen -t {{ keyType }} {{ keySizePart }} -N '' -f {{ keyFile }}" - unless: "test -s {{ keyFile }}" - - user: root + - runas: root - require_in: - file: sshd_config - watch_in: diff --git a/openssh/config_ini.sls b/openssh/config_ini.sls new file mode 100644 index 0000000..80f9061 --- /dev/null +++ b/openssh/config_ini.sls @@ -0,0 +1,17 @@ +{% from "openssh/map.jinja" import openssh with context %} + +include: + - openssh + +{% if salt['pillar.get']('sshd_config', False) %} +sshd_config-with-ini: + ini.options_present: + - name: {{ openssh.sshd_config }} + - separator: ' ' + - watch_in: + - service: {{ openssh.service }} + - sections: + {%- for k,v in salt['pillar.get']('sshd_config',{}).items() %} + {{ k }}: '{{ v }}' + {%- endfor %} +{% endif %} diff --git a/openssh/files/ssh_known_hosts b/openssh/files/ssh_known_hosts index ff448bd..9229fd3 100644 --- a/openssh/files/ssh_known_hosts +++ b/openssh/files/ssh_known_hosts @@ -16,7 +16,7 @@ {#- Extract the hostname from the FQDN and add it to the names. #} {%- if use_hostnames is iterable -%} {%- for name in names | sort -%} -{%- if salt["match.{}".format(hostnames_expr_form)](hostnames_target, minion_id=name) -%} +{%- if salt["match.{}".format(hostnames_tgt_type)](hostnames_target, minion_id=name) -%} {%- set hostname = name.split('.')|first -%} {%- if hostname not in names -%} {%- do names.append(hostname) -%} @@ -45,13 +45,13 @@ {#- Pre-fetch pillar data #} {%- set target = salt['pillar.get']('openssh:known_hosts:target', '*') -%} -{%- set expr_form = salt['pillar.get']('openssh:known_hosts:expr_form', 'glob') -%} +{%- set tgt_type = salt['pillar.get']('openssh:known_hosts:tgt_type', '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') -%} {%- set use_hostnames = salt['pillar.get']('openssh:known_hosts:hostnames', False) -%} {%- set hostnames_target_default = '*' if grains['domain'] == '' else "*.{}".format(grains['domain']) -%} {%- set hostnames_target = salt['pillar.get']('openssh:known_hosts:hostnames:target', hostnames_target_default) -%} -{%- set hostnames_expr_form = salt['pillar.get']('openssh:known_hosts:hostnames:expr_form', 'glob') -%} +{%- set hostnames_tgt_type = salt['pillar.get']('openssh:known_hosts:hostnames:tgt_type', 'glob') -%} {#- Lookup IP of all aliases so that when we have a matching IP, we inject the alias name in the SSH known_hosts entry -#} @@ -64,8 +64,8 @@ {%- 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) -%} +{%- set host_keys = salt['mine.get'](target, keys_function, tgt_type=tgt_type) -%} +{%- set host_names = salt['mine.get'](target, hostname_function, tgt_type=tgt_type) -%} {%- for host, keys in host_keys|dictsort -%} {{ known_host_entry(host, host_names, keys) }} {%- endfor -%} diff --git a/openssh/files/sshd_config b/openssh/files/sshd_config index ffa8e57..ead560f 100644 --- a/openssh/files/sshd_config +++ b/openssh/files/sshd_config @@ -4,80 +4,64 @@ {#- generic renderer used for sshd matches, known options, -#} {#- and unknown options -#} -{%- macro render_option(keyword, default, config_dict=sshd_config) -%} - {%- set value = config_dict.get(keyword, default) -%} - {%- if value is sameas true -%} -{{ keyword }} yes - {%- elif value is sameas false -%} -{{ keyword }} no - {%- elif value is string or value is number -%} -{{ keyword }} {{ value }} - {%- else -%} -{%- for single_value in value -%} +{%- macro render_option(keyword, config_dict=sshd_config) -%} +{%- set value = config_dict.get(keyword) -%} +{%- if value is sameas true -%} + {{ keyword }} yes +{% elif value is sameas false -%} + {{ keyword }} no +{% elif value is string or value is number -%} + {{ keyword }} {{ value }} +{% else -%} +{%- for single_value in value -%} {{ keyword }} {{ single_value }} -{% endfor -%} - {%- endif -%} +{% endfor -%} +{%- endif -%} {%- endmacro -%} -{#- macros for render option according to present -#} -{%- macro option_impl(keyword, default, present) -%} - {%- if present -%} - {%- do processed_options.append(keyword) -%} - {%- set prefix='' -%} - {%- else -%} - {%- set prefix='#' -%} - {%- endif -%} - {#- add prefix to keyword -#} - {%- set keyword = prefix ~ keyword -%} -{{ render_option(keyword, default) }} -{%- endmacro -%} - -{#- macros for render option commented by default -#} -{%- macro option(keyword, default, present) -%} -{{ option_impl(keyword, default, keyword in sshd_config) }} -{%- endmacro -%} - -{#- macros for render option uncommented by default -#} -{%- macro option_default_uncommented(keyword, default, present) -%} -{{ option_impl(keyword, default, True) }} +{#- macros for render option if present -#} +{%- macro option(keyword, present) -%} +{%- if keyword in sshd_config -%} +{%- do processed_options.append(keyword) -%} + {{ render_option(keyword) }} +{%- endif -%} {%- endmacro -%} {#- macro for collapsing a list into a string -#} -{%- macro option_collapselist(keyword, sep) -%} -{%- do processed_options.append(keyword) -%} -{{keyword}} {{sshd_config.get(keyword)|join(sep)}} -{%- endmacro -%} +{%- macro option_collapselist(keyword, sep, config_dict=None) -%} +{%- if config_dict is sameas None -%} +{%- do processed_options.append(keyword) -%} +{%- set config_dict = sshd_config -%} +{%- endif -%} + {{ keyword }} {{ config_dict.get(keyword) | join(sep) }} +{% endmacro -%} {#- macro for handling an option that can be specified as a list or a string -#} -{%- macro option_string_or_list(keyword, default, default_commented, sep=',') -%} -{%- if sshd_config.get(keyword, '') is string -%} - {%- if default_commented -%} -{{ option(keyword, default) }} - {%- else -%} -{{ option_default_uncommented(keyword, default) }} - {%- endif -%} -{%- else -%} -{{ option_collapselist(keyword, sep) }} -{%- endif -%} +{%- macro option_string_or_list(keyword, sep=',') -%} +{%- if sshd_config.get(keyword, '') is string -%} + {{ option(keyword) }} +{%- else -%} + {{ option_collapselist(keyword, sep) }} +{%- endif -%} {%- endmacro -%} {#- macro for conditionally joining a string, list or dict(keys) to just a string -#} {%- macro join_to_string(src, keyword, sep=',') -%} -{%- set srcval = src.get(keyword, '') -%} -{%- if srcval is string -%} - {{ srcval }} -{%- elif srcval is mapping -%} - {{ srcval.keys()|sort|join(sep) }} -{%- else -%} - {{ srcval|join(sep) }} -{%- endif -%} +{%- set srcval = src.get(keyword, '') -%} +{%- if srcval is string -%} + {{ srcval }} +{%- elif srcval is mapping -%} + {{ srcval.keys() | sort | join(sep) }} +{%- else -%} + {{ srcval | join(sep) }} +{%- endif -%} {%- endmacro -%} {%- if sshd_config.get('ConfigBanner', False) -%} - {%- do processed_options.append('ConfigBanner') -%} - {{ sshd_config['ConfigBanner'] }} +{%- do processed_options.append('ConfigBanner') -%} + {{ sshd_config['ConfigBanner'] }} {%- else -%} - # This file is managed by salt. Manual changes risk being overwritten. +# This file is managed by salt. Manual changes risk being overwritten. {%- endif %} {%- set global_src_url = salt ['pillar.get']('__formulas:print_template_url', None) %} {%- set local_src_url = salt ['pillar.get']('openssh-formula:print_template_url', None) %} @@ -91,163 +75,166 @@ # quick reference. # See the sshd_config(5) manpage for details -# Specifies which address family should be used by sshd(8). -# Valid arguments are any, inet (use IPv4 only), or inet6 (use IPv6 only) -{{ option('AddressFamily', 'any') }} +{# Specifies which address family should be used by sshd(8). -#} +{#- Valid arguments are any, inet (use IPv4 only), or inet6 (use IPv6 only) -#} +{{- option('AddressFamily') -}} -# What ports, IPs and protocols we listen for -{{ option('Port', 22) }} -# Use these options to restrict which interfaces/protocols sshd will bind to -{{ option('ListenAddress', ['::', '0.0.0.0']) }} -{{ option_default_uncommented('Protocol', 2) }} -# HostKeys for protocol version 2 -{{ option_default_uncommented('HostKey', ['/etc/ssh/ssh_host_rsa_key', '/etc/ssh/ssh_host_dsa_key', '/etc/ssh/ssh_host_ecdsa_key', '/etc/ssh/ssh_host_ed25519_key']) -}} +{#- What ports, IPs and protocols we listen for -#} +{{- option('Port') -}} +{#- Use these options to restrict which interfaces/protocols sshd will bind to -#} +{{- option('ListenAddress') -}} +{{- option('Protocol') -}} +{#- HostKeys for protocol version 2 -#} +{{- option('HostKey') -}} -#Privilege Separation is turned on for security -{{ option_default_uncommented('UsePrivilegeSeparation', 'sandbox') }} +{#- Privilege Separation is turned on for security -#} +{{- option('UsePrivilegeSeparation') -}} -# Lifetime and size of ephemeral version 1 server key -{{ option_default_uncommented('KeyRegenerationInterval', 3600) }} -{{ option_default_uncommented('ServerKeyBits', 1024) }} +{#- Lifetime and size of ephemeral version 1 server key -#} +{{- option('KeyRegenerationInterval') -}} +{{- option('ServerKeyBits') -}} -# Logging -{{ option_default_uncommented('SyslogFacility', 'AUTH') }} -{{ option_default_uncommented('LogLevel', 'INFO') }} +{#- Logging -#} +{{- option('SyslogFacility') -}} +{{- option('LogLevel') -}} -# Session idle time out -{{ option_default_uncommented('ClientAliveInterval', 0) }} -{{ option_default_uncommented('ClientAliveCountMax', 3) }} +{#- Session idle time out -#} +{{- option('ClientAliveInterval') -}} +{{- option('ClientAliveCountMax') -}} -# Authentication: -{{ option_default_uncommented('LoginGraceTime', 120) }} -{{ option_default_uncommented('PermitRootLogin', 'yes') }} -{{ option_default_uncommented('StrictModes', 'yes') }} -{{ option_default_uncommented('MaxAuthTries', '6') }} -{{ option_default_uncommented('MaxSessions', '10') }} +{#- Authentication: -#} +{{- option('LoginGraceTime') -}} +{{- option('PermitRootLogin') -}} +{{- option('StrictModes') -}} +{{- option('MaxAuthTries') -}} +{{- option('MaxSessions') -}} -{{ option('DSAAuthentication', 'yes') }} -{{ option_default_uncommented('RSAAuthentication', 'yes') }} -{{ option_default_uncommented('PubkeyAuthentication', 'yes') }} -{{ option('AuthorizedKeysFile', '%h/.ssh/authorized_keys') }} -{{ option('AuthorizedKeysCommand', 'none') }} -{{ option('AuthorizedKeysCommandUser', 'nobody') }} +{{- option('DSAAuthentication') -}} +{{- option('RSAAuthentication') -}} +{{- option('PubkeyAuthentication') -}} +{{- option('AuthorizedKeysFile') -}} +{{- option('AuthorizedKeysCommand') -}} +{{- option('AuthorizedKeysCommandUser') -}} -# Don't read the user's ~/.rhosts and ~/.shosts files -{{ option_default_uncommented('IgnoreRhosts', 'yes') }} -# For this to work you will also need host keys in /etc/ssh_known_hosts -{{ option_default_uncommented('RhostsRSAAuthentication', 'no') }} -# similar for protocol version 2 -{{ option_default_uncommented('HostbasedAuthentication', 'no') }} -# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication -{{ option('IgnoreUserKnownHosts', 'yes') }} +{#- Don't read the user's ~/.rhosts and ~/.shosts files -#} +{{- option('IgnoreRhosts') -}} +{#- For this to work you will also need host keys in /etc/ssh_known_hosts -#} +{{- option('RhostsRSAAuthentication') -}} +{#- similar for protocol version 2 -#} +{{- option('HostbasedAuthentication') -}} +{#- Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication -#} +{{- option('IgnoreUserKnownHosts') -}} -# To enable empty passwords, change to yes (NOT RECOMMENDED) -{{ option_default_uncommented('PermitEmptyPasswords', 'no') }} +{#- To enable empty passwords, change to yes (NOT RECOMMENDED) -#} +{{- option('PermitEmptyPasswords') -}} -# Change to yes to enable challenge-response passwords (beware issues with -# some PAM modules and threads) -{{ option_default_uncommented('ChallengeResponseAuthentication', 'no') }} -{{ option('AuthenticationMethods', 'publickey,keyboard-interactive') }} +{#- Change to yes to enable challenge-response passwords (beware issues with -#} +{#- some PAM modules and threads) -#} +{{- option('ChallengeResponseAuthentication') -}} +{{- option('AuthenticationMethods') -}} -# Change to no to disable tunnelled clear text passwords -{{ option('PasswordAuthentication', 'yes') }} +{#- Change to no to disable tunnelled clear text passwords -#} +{{- option('PasswordAuthentication') -}} -# Kerberos options -{{ option('KerberosAuthentication', 'no') }} -{{ option('KerberosGetAFSToken', 'no') }} -{{ option('KerberosOrLocalPasswd', 'yes') }} -{{ option('KerberosTicketCleanup', 'yes') }} +{#- Kerberos options -#} +{{- option('KerberosAuthentication') -}} +{{- option('KerberosGetAFSToken') -}} +{{- option('KerberosOrLocalPasswd') -}} +{{- option('KerberosTicketCleanup') -}} -# GSSAPI options -{{ option('GSSAPIAuthentication', 'no') }} -{{ option('GSSAPICleanupCredentials', 'yes') }} +{#- GSSAPI options -#} +{{- option('GSSAPIAuthentication') -}} +{{- option('GSSAPICleanupCredentials') -}} -{{ option_default_uncommented('X11Forwarding', 'yes') }} -{{ option('AllowTcpForwarding', 'yes') }} -{{ option_default_uncommented('X11DisplayOffset', '10') }} -{{ option_default_uncommented('PrintMotd', 'no') }} -{# Bug in FreeBSD 10.3 (?) See https://lists.freebsd.org/pipermail/freebsd-stable/2016-April/084501.html #} +{{- option('X11Forwarding') -}} +{{- option('AllowTcpForwarding') -}} +{{- option('X11DisplayOffset') -}} +{{- option('PrintMotd') -}} +{#- Bug in FreeBSD 10.3 (?) See https://lists.freebsd.org/pipermail/freebsd-stable/2016-April/084501.html -#} {% if not (salt['grains.get']('os') == 'FreeBSD' and salt['grains.get']('osrelease')|float >= 10.3) -%} -{{ option_default_uncommented('PrintLastLog', 'yes') }} +{{- option('PrintLastLog') -}} {% endif -%} -{{ option_default_uncommented('TCPKeepAlive', 'yes') }} -{{ option('UseLogin', 'no') }} +{{- option('TCPKeepAlive') -}} +{{- option('UseLogin') -}} -{{ option('MaxStartups', '10:30:60') }} -{{ option('Banner', '/etc/issue.net') }} +{{- option('MaxStartups') -}} +{{- option('Banner') -}} -# Allow client to pass locale environment variables -{{ option_default_uncommented('AcceptEnv', 'LANG LC_*') }} +{#- Allow client to pass locale environment variables -#} +{{- option('AcceptEnv') -}} -{{ option_default_uncommented('Subsystem', 'sftp /usr/lib/openssh/sftp-server') }} +{{- option('Subsystem') -}} {% if not salt['grains.get']('os') == 'OpenBSD' -%} -# Set this to 'yes' to enable PAM authentication, account processing, -# and session processing. If this is enabled, PAM authentication will -# be allowed through the ChallengeResponseAuthentication and -# PasswordAuthentication. Depending on your PAM configuration, -# PAM authentication via ChallengeResponseAuthentication may bypass -# the setting of "PermitRootLogin without-password". -# If you just want the PAM account and session checks to run without -# PAM authentication, then enable this but set PasswordAuthentication -# and ChallengeResponseAuthentication to 'no'. -{{ option_default_uncommented('UsePAM', 'yes') }} +{#- Set this to 'yes' to enable PAM authentication, account processing, -#} +{#- and session processing. If this is enabled, PAM authentication will -#} +{#- be allowed through the ChallengeResponseAuthentication and -#} +{#- PasswordAuthentication. Depending on your PAM configuration, -#} +{#- PAM authentication via ChallengeResponseAuthentication may bypass -#} +{#- the setting of "PermitRootLogin without-password". -#} +{#- If you just want the PAM account and session checks to run without -#} +{#- PAM authentication, then enable this but set PasswordAuthentication -#} +{#- and ChallengeResponseAuthentication to 'no'. -#} +{{- option('UsePAM') -}} {%- endif %} -# DNS resolve and map remote IP addresses -{{ option('UseDNS', 'yes') }} +{#- DNS resolve and map remote IP addresses -#} +{{- option('UseDNS') -}} -# Restricting Users and Hosts -# example: -# 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 -# not Matching one of the supplied patterns will be denied access by default. -# Also, in order for sshd to allow access based on full or partial hostnames it -# needs to to a DNS lookup -# -# DenyUsers -{{ option_string_or_list('DenyUsers', '', True , sep=' ')}} -# AllowUsers -{{ option_string_or_list('AllowUsers', '', True , sep=' ')}} -# DenyGroups -{{ option_string_or_list('DenyGroups', '', True , sep=' ')}} -# AllowGroups -{{ option_string_or_list('AllowGroups', '', True , sep=' ')}} +{#- Restricting Users and Hosts -#} +{#- example: -#} +{#- 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 -#} +{#- not Matching one of the supplied patterns will be denied access by default. -#} +{#- Also, in order for sshd to allow access based on full or partial hostnames it -#} +{#- needs to to a DNS lookup -#} + +{# DenyUsers -#} +{{- option_string_or_list('DenyUsers', sep=' ') }} +{# AllowUsers -#} +{{- option_string_or_list('AllowUsers', sep=' ') }} +{# DenyGroups -#} +{{- option_string_or_list('DenyGroups', sep=' ') }} +{# AllowGroups -#} +{{- option_string_or_list('AllowGroups', sep=' ') }}{{ "\n" -}} -# Specifies the available KEX (Key Exchange) algorithms. -{{ option_string_or_list('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', True) }} +{#- Specifies the available KEX (Key Exchange) algorithms. -#} +{{- option_string_or_list('KexAlgorithms') -}} -# Specifies the ciphers allowed for protocol version 2. -{{ option_string_or_list('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', True) }} +{#- Specifies the ciphers allowed for protocol version 2. -#} +{{- option_string_or_list('Ciphers') -}} -# Specifies the available MAC (message authentication code) algorithms. -{{ option_string_or_list('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', True) }} +{#- Specifies the available MAC (message authentication code) algorithms. -#} +{{- option_string_or_list('MACs') -}} -{# Handling unknown in salt template options #} +{#- Handling unknown in salt template options -#} {%- for keyword in sshd_config.keys() %} - {#- Matches have to be at the bottom and should be handled differently -#} - {%- if not keyword in processed_options and keyword != 'matches' -%} -{#- send a blank default as it doesn't matter #} -{{ render_option(keyword, '') }} - {%- endif -%} +{#- Matches have to be at the bottom and should be handled differently -#} +{%- if not keyword in processed_options and keyword != 'matches' -%} +{{- render_option(keyword) -}} +{% endif -%} {%- endfor %} -{# Handle matches last as they need to go at the bottom #} +{#- Handle matches last as they need to go at the bottom -#} {%- if 'matches' in sshd_config %} {%- for name, match in sshd_config['matches']|dictsort(true) %} Match {#- Set up the match criteria -#} {%- for criteria in match['type'].keys()|sort() -%} - {{- ' ' }}{{criteria }} {{ join_to_string(match['type'], criteria) -}} - {%- endfor %} #{{ name }} - {#- Set up the applied options -#} - {%- for keyword in match['options'].keys()|sort() %} - {{ render_option(keyword, '', config_dict=match['options']) }} - {%- endfor %} + {{ ' ' -}}{{criteria }} {{ join_to_string(match['type'], criteria) }} + {%- endfor %} #{{- name }} +{# Set up the applied options -#} + {%- for keyword in match['options'].keys()|sort() -%} + {%- if keyword in ['AllowUsers', 'DenyUsers', 'AllowGroups', 'DenyGroups'] -%} + {{ option_collapselist(keyword, ' ', config_dict=match['options']) | indent(4, true) }} +{% else -%} + {{ render_option(keyword, config_dict=match['options']) | indent(4, true) }} +{% endif -%} +{%- endfor %} {%- endfor %} {%- endif %} -{#- vim: set ft=jinja : #} +{#- vim: set ft=jinja : -#} diff --git a/openssh/map.jinja b/openssh/map.jinja index e9945a3..dd3f941 100644 --- a/openssh/map.jinja +++ b/openssh/map.jinja @@ -86,7 +86,6 @@ that differ from whats in defaults.yaml {% set os_finger_map = salt['grains.filter_by']({ 'CentOS-6': { - 'UsePrivilegeSeparation': 'yes', }, 'default': {} } diff --git a/pillar.example b/pillar.example index 935fb57..5708859 100644 --- a/pillar.example +++ b/pillar.example @@ -47,12 +47,12 @@ sshd_config: # set as string AllowUsers: 'vader@10.0.0.1 maul@evil.com sidious luke' # or set as list - AllowUsers: - - vader@10.0.0.1 - - maul@evil.com - - sidious + AllowUsers: + - vader@10.0.0.1 + - maul@evil.com + - sidious - luke - # set as string + # set as string DenyUsers: 'yoda chewbaca@112.10.21.1' # or set as list DenyUsers: @@ -118,7 +118,7 @@ sshd_config: # https://stribika.github.io/2015/01/04/secure-secure-shell.html #KexAlgorithms: 'curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256' #Ciphers: 'chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr' - #MACs: 'hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com' + #MACs: 'hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com' KexAlgorithms: - 'curve25519-sha256@libssh.org' - 'diffie-hellman-group-exchange-sha256' @@ -132,11 +132,9 @@ sshd_config: MACs: - 'hmac-sha2-512-etm@openssh.com' - 'hmac-sha2-256-etm@openssh.com' - - 'hmac-ripemd160-etm@openssh.com' - 'umac-128-etm@openssh.com' - 'hmac-sha2-512' - 'hmac-sha2-256' - - 'hmac-ripemd160' - 'umac-128@openssh.com' # Warning! You should generally NOT NEED to set ssh_config. Setting ssh_config @@ -175,7 +173,7 @@ ssh_config: # You can specify KexAlgorithms, Ciphers and MACs as both key or a list. #KexAlgorithms: 'curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1' #Ciphers: 'chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr' - #MACs: 'hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com' + #MACs: 'hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com' KexAlgorithms: - 'curve25519-sha256@libssh.org' - 'diffie-hellman-group-exchange-sha256' @@ -191,11 +189,9 @@ ssh_config: MACs: - 'hmac-sha2-512-etm@openssh.com' - 'hmac-sha2-256-etm@openssh.com' - - 'hmac-ripemd160-etm@openssh.com' - 'umac-128-etm@openssh.com' - 'hmac-sha2-512' - 'hmac-sha2-256' - - 'hmac-ripemd160' - 'umac-128@openssh.com' @@ -290,7 +286,7 @@ openssh: # 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' + tgt_type: '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 @@ -308,7 +304,7 @@ openssh: # Restrict wich hosts you want to use via their hostname # (i.e. ssh user@host instead of ssh user@host.example.com) # target: '*' # Defaults to "*.{}".format(grains['domain']) with a fallback to '*' - # expr_form: 'glob' + # tgt_type: 'glob' # To activate the defaults you can just set an empty dict. #hostnames: {}