Saltstack Official OpenSSH Formula
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
8.1KB

  1. {#- present in sshd_config and known in actual file options -#}
  2. {%- set processed_options = [] -%}
  3. {#- generic renderer used for sshd matches, known options, -#}
  4. {#- and unknown options -#}
  5. {%- macro render_option(keyword, config_dict=sshd_config) -%}
  6. {%- set value = config_dict.get(keyword) -%}
  7. {%- if value is sameas true -%}
  8. {{ keyword }} yes
  9. {% elif value is sameas false -%}
  10. {{ keyword }} no
  11. {% elif value is string or value is number -%}
  12. {{ keyword }} {{ value }}
  13. {% else -%}
  14. {%- for single_value in value -%}
  15. {{ keyword }} {{ single_value }}
  16. {% endfor -%}
  17. {%- endif -%}
  18. {%- endmacro -%}
  19. {#- macros for render option if present -#}
  20. {%- macro option(keyword, present) -%}
  21. {%- if keyword in sshd_config -%}
  22. {%- do processed_options.append(keyword) -%}
  23. {{ render_option(keyword) }}
  24. {%- endif -%}
  25. {%- endmacro -%}
  26. {#- macro for collapsing a list into a string -#}
  27. {%- macro option_collapselist(keyword, sep, config_dict=None) -%}
  28. {%- if config_dict is sameas None -%}
  29. {%- do processed_options.append(keyword) -%}
  30. {%- set config_dict = sshd_config -%}
  31. {%- endif -%}
  32. {{ keyword }} {{ config_dict.get(keyword) | join(sep) }}
  33. {% endmacro -%}
  34. {#- macro for handling an option that can be specified as a list or a string -#}
  35. {%- macro option_string_or_list(keyword, sep=',') -%}
  36. {%- if sshd_config.get(keyword, '') is string -%}
  37. {{ option(keyword) }}
  38. {%- else -%}
  39. {{ option_collapselist(keyword, sep) }}
  40. {%- endif -%}
  41. {%- endmacro -%}
  42. {#- macro for conditionally joining a string, list or dict(keys) to just a string -#}
  43. {%- macro join_to_string(src, keyword, sep=',') -%}
  44. {%- set srcval = src.get(keyword, '') -%}
  45. {%- if srcval is string -%}
  46. {{ srcval }}
  47. {%- elif srcval is mapping -%}
  48. {{ srcval.keys() | sort | join(sep) }}
  49. {%- else -%}
  50. {{ srcval | join(sep) }}
  51. {%- endif -%}
  52. {%- endmacro -%}
  53. {%- if sshd_config.get('ConfigBanner', False) -%}
  54. {%- do processed_options.append('ConfigBanner') -%}
  55. {{ sshd_config['ConfigBanner'] }}
  56. {%- else -%}
  57. # This file is managed by salt. Manual changes risk being overwritten.
  58. {%- endif %}
  59. {%- set global_src_url = salt ['pillar.get']('__formulas:print_template_url', None) %}
  60. {%- set local_src_url = salt ['pillar.get']('openssh-formula:print_template_url', None) %}
  61. {%- if (global_src_url and local_src_url is none) or local_src_url %}
  62. #
  63. # Template used to generate this file:
  64. # {{ source }}
  65. #
  66. {%- endif %}
  67. # The contents of the original sshd_config are kept on the bottom for
  68. # quick reference.
  69. # See the sshd_config(5) manpage for details
  70. {# Specifies which address family should be used by sshd(8). -#}
  71. {#- Valid arguments are any, inet (use IPv4 only), or inet6 (use IPv6 only) -#}
  72. {{- option('AddressFamily') -}}
  73. {#- What ports, IPs and protocols we listen for -#}
  74. {{- option('Port') -}}
  75. {#- Use these options to restrict which interfaces/protocols sshd will bind to -#}
  76. {{- option('ListenAddress') -}}
  77. {{- option('Protocol') -}}
  78. {#- HostKeys for protocol version 2 -#}
  79. {{- option('HostKey') -}}
  80. {#- Privilege Separation is turned on for security -#}
  81. {{- option('UsePrivilegeSeparation') -}}
  82. {#- Logging -#}
  83. {{- option('SyslogFacility') -}}
  84. {{- option('LogLevel') -}}
  85. {#- Session idle time out -#}
  86. {{- option('ClientAliveInterval') -}}
  87. {{- option('ClientAliveCountMax') -}}
  88. {#- Authentication: -#}
  89. {{- option('LoginGraceTime') -}}
  90. {{- option('PermitRootLogin') -}}
  91. {{- option('StrictModes') -}}
  92. {{- option('MaxAuthTries') -}}
  93. {{- option('MaxSessions') -}}
  94. {{- option('PubkeyAuthentication') -}}
  95. {{- option('AuthorizedKeysFile') -}}
  96. {{- option('AuthorizedKeysCommand') -}}
  97. {{- option('AuthorizedKeysCommandUser') -}}
  98. {#- Don't read the user's ~/.rhosts and ~/.shosts files -#}
  99. {{- option('IgnoreRhosts') -}}
  100. {#- similar for protocol version 2 -#}
  101. {{- option('HostbasedAuthentication') -}}
  102. {#- Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication -#}
  103. {{- option('IgnoreUserKnownHosts') -}}
  104. {#- To enable empty passwords, change to yes (NOT RECOMMENDED) -#}
  105. {{- option('PermitEmptyPasswords') -}}
  106. {#- Change to yes to enable challenge-response passwords (beware issues with -#}
  107. {#- some PAM modules and threads) -#}
  108. {{- option('ChallengeResponseAuthentication') -}}
  109. {{- option('AuthenticationMethods') -}}
  110. {#- Change to no to disable tunnelled clear text passwords -#}
  111. {{- option('PasswordAuthentication') -}}
  112. {#- Kerberos options -#}
  113. {{- option('KerberosAuthentication') -}}
  114. {{- option('KerberosGetAFSToken') -}}
  115. {{- option('KerberosOrLocalPasswd') -}}
  116. {{- option('KerberosTicketCleanup') -}}
  117. {#- GSSAPI options -#}
  118. {{- option('GSSAPIAuthentication') -}}
  119. {{- option('GSSAPICleanupCredentials') -}}
  120. {{- option('X11Forwarding') -}}
  121. {{- option('AllowTcpForwarding') -}}
  122. {{- option('X11DisplayOffset') -}}
  123. {{- option('PrintMotd') -}}
  124. {#- Bug in FreeBSD 10.3 (?) See https://lists.freebsd.org/pipermail/freebsd-stable/2016-April/084501.html -#}
  125. {% if not (salt['grains.get']('os') == 'FreeBSD' and salt['grains.get']('osrelease')|float >= 10.3) -%}
  126. {{- option('PrintLastLog') -}}
  127. {% endif -%}
  128. {{- option('TCPKeepAlive') -}}
  129. {{- option('UseLogin') -}}
  130. {{- option('MaxStartups') -}}
  131. {{- option('Banner') -}}
  132. {#- Allow client to pass locale environment variables -#}
  133. {{- option('AcceptEnv') -}}
  134. {{- option('Subsystem') -}}
  135. {% if not salt['grains.get']('os') == 'OpenBSD' -%}
  136. {#- Set this to 'yes' to enable PAM authentication, account processing, -#}
  137. {#- and session processing. If this is enabled, PAM authentication will -#}
  138. {#- be allowed through the ChallengeResponseAuthentication and -#}
  139. {#- PasswordAuthentication. Depending on your PAM configuration, -#}
  140. {#- PAM authentication via ChallengeResponseAuthentication may bypass -#}
  141. {#- the setting of "PermitRootLogin without-password". -#}
  142. {#- If you just want the PAM account and session checks to run without -#}
  143. {#- PAM authentication, then enable this but set PasswordAuthentication -#}
  144. {#- and ChallengeResponseAuthentication to 'no'. -#}
  145. {{- option('UsePAM') -}}
  146. {%- endif %}
  147. {#- DNS resolve and map remote IP addresses -#}
  148. {{- option('UseDNS') -}}
  149. {#- Restricting Users and Hosts -#}
  150. {#- example: -#}
  151. {#- AllowUsers vader@10.0.0.1 maul@sproing.evil.com luke -#}
  152. {#- AllowGroups wheel staff -#}
  153. {#- Keep in mind that using AllowUsers or AllowGroups means that anyone -#}
  154. {#- not Matching one of the supplied patterns will be denied access by default. -#}
  155. {#- Also, in order for sshd to allow access based on full or partial hostnames it -#}
  156. {#- needs to to a DNS lookup -#}
  157. {# DenyUsers -#}
  158. {{- option_string_or_list('DenyUsers', sep=' ') -}}
  159. {# AllowUsers -#}
  160. {{- option_string_or_list('AllowUsers', sep=' ') -}}
  161. {# DenyGroups -#}
  162. {{- option_string_or_list('DenyGroups', sep=' ') -}}
  163. {# AllowGroups -#}
  164. {{- option_string_or_list('AllowGroups', sep=' ') -}}
  165. {#- Specifies the available KEX (Key Exchange) algorithms. -#}
  166. {{- option_string_or_list('KexAlgorithms') -}}
  167. {#- Specifies the ciphers allowed for protocol version 2. -#}
  168. {{- option_string_or_list('Ciphers') -}}
  169. {#- Specifies the available MAC (message authentication code) algorithms. -#}
  170. {{- option_string_or_list('MACs') -}}
  171. {#- Handling unknown in salt template options -#}
  172. {%- for keyword in sshd_config.keys() %}
  173. {#- Matches have to be at the bottom and should be handled differently -#}
  174. {%- if not keyword in processed_options and keyword != 'matches' -%}
  175. {{- render_option(keyword) -}}
  176. {% endif -%}
  177. {%- endfor %}
  178. {#- Handle matches last as they need to go at the bottom -#}
  179. {%- if 'matches' in sshd_config %}
  180. {%- for name, match in sshd_config['matches']|dictsort(true) %}
  181. Match
  182. {#- Set up the match criteria -#}
  183. {%- for criteria in match['type'].keys()|sort() -%}
  184. {{ ' ' -}}{{criteria }} {{ join_to_string(match['type'], criteria) }}
  185. {%- endfor %} #{{- name }}
  186. {# Set up the applied options -#}
  187. {%- for keyword in match['options'].keys()|sort() -%}
  188. {%- if keyword in ['AllowUsers', 'DenyUsers', 'AllowGroups', 'DenyGroups'] -%}
  189. {{ option_collapselist(keyword, ' ', config_dict=match['options']) | indent(4, true) }}
  190. {% else -%}
  191. {{ render_option(keyword, config_dict=match['options']) | indent(4, true) }}
  192. {% endif -%}
  193. {%- endfor %}
  194. {%- endfor %}
  195. {%- endif %}
  196. {#- vim: set ft=jinja : -#}