--- /dev/null
+openssh:
+ sshd_config: /etc/ssh/sshd_config
+ sshd_config_src: salt://openssh/files/sshd_config
+ ssh_config: /etc/ssh/ssh_config
+ ssh_config_src: salt://openssh/files/ssh_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
+ssh_config:
+ Hosts:
+ '*':
+ AddressFamily: any
+ BatchMode: no
+ CheckHostIP: yes
+ Cipher: 3des
+ ConnectTimeout: 0
+ EscapeChar: '~'
+ ForwardAgent: yes
+ ForwardX11: no
+ HashKnownHosts: no
+ HostbasedAuthentication: no
+ GSSAPIAuthentication: no
+ GSSAPIDelegateCredentials: no
+ IdentityFile: ['~/.ssh/identity', "~/.ssh/id_rsa", '~/.ssh/id_dsa']
+ PasswordAuthentication: no
+ PermitLocalCommand: no
+ Port: 22
+ Protocol: 2
+ RhostsRSAAuthentication: no
+ RSAAuthentication: yes
+ SendEnv: 'LANG LC_*'
+ StrictHostKeyChecking: ask
+ Tunnel: no
+ TunnelDevice: "any:any"
+ VisualHostKey: no
+
--- /dev/null
+{%- import_yaml "openssh/files/defaults.yaml" as default_settings -%}
+{%- set ssh_config = salt['pillar.get']('ssh_config', default=default_settings.ssh_config, merge=True) -%}
+{#- present in ssh_config and known in actual file options -#}
+{%- set processed_options = [] -%}
+
+{%- macro render_raw_option(keyword, value) -%}
+ {%- 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 -%}
+{%- endmacro -%}
+
+{#- generic renderer used for ssh matches, known options, -#}
+{#- and unknown options -#}
+{%- macro render_option(keyword, default, config_dict=ssh_config) -%}
+ {%- set value = config_dict.get(keyword, default) -%}
+{{ render_raw_option(keyword, value) }}
+{%- 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 ssh_config) }}
+{%- endmacro -%}
+
+{#- macros for render option uncommented by default -#}
+{%- macro option_default_uncommented(keyword, default, present) -%}
+{{ option_impl(keyword, default, True) }}
+{%- endmacro -%}
+
+# This is the ssh client system-wide configuration file. See
+# ssh_config(5) for more information. This file provides defaults for
+# users, and the values can be changed in per-user configuration files
+# or on the command line.
+
+# Configuration data is parsed as follows:
+# 1. command line options
+# 2. user-specific file
+# 3. system-wide file
+# Any configuration value is only changed the first time it is set.
+# Thus, host-specific definitions should be at the beginning of the
+# configuration file, and defaults at the end.
+
+# Site-wide defaults for some commonly used options. For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
+
+# Do not edit this file manually!
+# It will be overwritten by salt!
+
+{%- if 'Hosts' in ssh_config %}
+{%- do processed_options.append('Hosts') %}
+{% for host, conf in ssh_config['Hosts'].items() %}
+Host {{ host }}
+ {%- for key, val in conf.items() %}
+ {{ render_raw_option(key, val) }}
+ {%- endfor %}
+{%- endfor %}
+{%- endif %}
+
+{# Handling unknown in salt template options #}
+{%- for keyword in ssh_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 -%}
+{%- endfor %}
+
+{# Handle matches last as they need to go at the bottom #}
+{%- if 'matches' in ssh_config %}
+ {%- for match in ssh_config['matches'].values() %}
+Match {{ match['type'].keys()[0] }} {{ match['type'].values()[0] }}
+ {%- for keyword in match['options'].keys() %}
+ {{ render_option(keyword, '', config_dict=match['options']) }}
+ {%- endfor %}
+ {%- endfor %}
+{%- endif %}
+
--- /dev/null
+{## Start with defaults from defaults.yaml ##}
+{% import_yaml "openssh/files/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',
+ },
+ 'FreeBSD': {
+ 'service': 'sshd',
+ 'dig_pkg': 'bind-tools',
+ 'Subsystem': 'sftp /usr/libexec/sftp-server',
+ },
+ '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',
+ 'dig_pkg': 'bind-utils',
+ },
+ 'Suse': {
+ 'server': 'openssh',
+ 'client': 'openssh',
+ 'service': 'sshd',
+ 'dig_pkg': 'bind-utils',
+ },
+ }
+ , 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
+ )
+%}
+
+