/
opensshd.conf.j2
323 lines (258 loc) · 10.6 KB
/
opensshd.conf.j2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#jinja2: trim_blocks: "true", lstrip_blocks: "true"
{{ ansible_managed | comment }}
# Generated by Ansible role {{ ansible_role_name }}
# This is the sshd server system-wide configuration file.
# See sshd_config(5) for more information.
{% if sshd_custom_options %}
# Custom configuration that overwrites default configuration
# ==========================================================
{% for line in sshd_custom_options %}
{{ line }}
{% endfor %}
{% endif %}
# Basic configuration
# ===================
# Either disable or only allow root login via certificates.
PermitRootLogin {{ ssh_permit_root_login }}
# TCP port sshd should listen on. Default is 22.
{% for port in ssh_server_ports %}
Port {{ port }}
{% endfor %}
# Address family should always be limited to the active network configuration.
AddressFamily {{ 'any' if (network_ipv6_enable|bool) else 'inet' }}
# Addresses sshd listens on. Default is 0.0.0.0.
# Specify desired address here if you don't want sshd to listen on all available addresses.
{% for address in ssh_listen_to %}
ListenAddress {{ address }}
{% endfor %}
# HostKeys are listed here.
{% for key in ssh_host_key_files %}
HostKey {{ key }}
{% endfor %}
# HostCertificates are listed here.
{% for certificate in ssh_host_certificates -%}
HostCertificate {{ certificate }}
{% endfor %}
# Host key algorithms that the server offers.
{% if sshd_version is version('5.8', '>=') %}
{{ "HostKeyAlgorithms " ~ ssh_host_key_algorithms|join(',') if ssh_host_key_algorithms else "HostKeyAlgorithms"|comment }}
{% endif %}
# Security configuration
# ======================
{# Support for legacy SSHv1 has been completely removed from OpenSSH in version 7.6 -#}
{% if sshd_version is version('7.6', '<') %}
# Set the protocol version explicitly to 2. Version 1 is obsolete and should not be used.
Protocol 2
{% endif %}
# Make sure sshd checks file modes and ownership before accepting logins. This prevents accidental misconfiguration.
StrictModes {{ 'yes' if (sshd_strict_modes|bool) else 'no' }}
# Logging, obsoletes QuietMode and FascistLogging
SyslogFacility {{ sshd_syslog_facility }}
LogLevel {{ sshd_log_level }}
# Cryptography
# ------------
# **Ciphers** -- If your clients don't support CTR (eg older versions), cbc will be added
# CBC: is true if you want to connect with OpenSSL-base libraries
# eg ruby Net::SSH::Transport::CipherFactory requires cbc-versions of the given openssh ciphers to work
# -- see: (http://net-ssh.github.com/net-ssh/classes/Net/SSH/Transport/CipherFactory.html)
#
{# This outputs 'Ciphers <list-of-ciphers>' if ssh_ciphers is defined or '#Ciphers' if ssh_ciphers is undefined -#}
{{ 'Ciphers ' ~ ssh_ciphers|join(',') if ssh_ciphers else 'Ciphers'|comment }}
# **Hash algorithms** -- SHA-1 is formally deprecated by NIST in 2011 because of security issues.
# Weak HMAC is sometimes required if older package versions are used
# eg Ruby's Net::SSH at around 2.2.* doesn't support sha2 for hmac, so this will have to be set true in this case.
#
{# This outputs 'MACs <list-of-macs>' if ssh_macs is defined or '#MACs' if ssh_macs is undefined -#}
{{ 'MACs ' ~ ssh_macs|join(',') if ssh_macs else 'MACs'|comment }}
{% if sshd_version is version('5.9', '<') %}
# Alternative setting, if OpenSSH version is below v5.9
#MACs hmac-ripemd160
{% endif %}
# **Key Exchange Algorithms** -- SHA-1 is formally deprecated by NIST in 2011 because of security issues.
# Weak kex is sometimes required if older package versions are used
# eg ruby's Net::SSH at around 2.2.* doesn't support sha2 for kex, so this will have to be set true in this case.
# based on: https://bettercrypto.org/static/applied-crypto-hardening.pdf
#
{# This outputs 'KexAlgorithms <list-of-algos>' if ssh_kex is defined or '#KexAlgorithms' if ssh_kex is undefined #}
{{ 'KexAlgorithms ' ~ ssh_kex|join(',') if ssh_kex else 'KexAlgorithms'|comment }}
# Authentication
# --------------
# Secure Login directives.
{% if sshd_version is version('7.4', '<') %}
UseLogin no
{% endif %}
{% if sshd_version is version('7.5', '<') %}
UsePrivilegeSeparation {{ ssh_ps59 }}
{% endif %}
LoginGraceTime {{ ssh_login_grace_time }}
MaxAuthTries {{ ssh_max_auth_retries }}
MaxSessions {{ ssh_max_sessions }}
MaxStartups {{ ssh_max_startups }}
# Enable public key authentication
PubkeyAuthentication yes
# Never use host-based authentication. It can be exploited.
IgnoreRhosts yes
IgnoreUserKnownHosts yes
HostbasedAuthentication no
{% if ssh_pam_support %}
# Enable PAM to enforce system wide rules.
UsePAM {{ 'yes' if (ssh_use_pam|bool) else 'no' }}
{% endif %}
{# Set AuthenticationMethods per default to publickey -#}
{# AuthenticationMethods was introduced in OpenSSH 6.2 - https://www.openssh.com/txt/release-6.2 -#}
{% if sshd_version is version('6.2', '>=') %}
AuthenticationMethods {{ sshd_authenticationmethods }}
{% endif %}
# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
PasswordAuthentication {{ 'yes' if (ssh_server_password_login|bool) else 'no' }}
PermitEmptyPasswords no
ChallengeResponseAuthentication {{ 'yes' if (ssh_challengeresponseauthentication|bool) else 'no' }}
{% if ssh_kerberos_support %}
# Only enable Kerberos authentication if it is configured.
KerberosAuthentication no
KerberosOrLocalPasswd no
KerberosTicketCleanup yes
#KerberosGetAFSToken no
{% endif %}
{# OpenBSD does not support GSSAPIAuthentication, so leave this out if on OpenBSD #}
{% if ansible_facts.os_family != 'OpenBSD' -%}
# Only enable GSSAPI authentication if it is configured.
GSSAPIAuthentication {{ 'yes' if ssh_gssapi_support else 'no' }}
GSSAPICleanupCredentials yes
{% endif %}
{% if ssh_deny_users %}
# In case you don't use PAM (`UsePAM no`), you can alternatively restrict users and groups here.
# For key-based authentication this is not necessary, since all keys must be explicitly enabled.
DenyUsers {{ ssh_deny_users }}
{% endif %}
{% if ssh_allow_users %}
AllowUsers {{ ssh_allow_users }}
{% endif %}
{% if ssh_deny_groups %}
DenyGroups {{ ssh_deny_groups }}
{% endif %}
{% if ssh_allow_groups %}
AllowGroups {{ ssh_allow_groups }}
{% endif %}
{% if ssh_authorized_keys_file %}
AuthorizedKeysFile {{ ssh_authorized_keys_file }}
{% endif %}
{% if ssh_trusted_user_ca_keys_file %}
TrustedUserCAKeys {{ ssh_trusted_user_ca_keys_file }}
{% if ssh_authorized_principals_file %}
AuthorizedPrincipalsFile {{ ssh_authorized_principals_file }}
{% endif %}
{% endif %}
# Network
# -------
# Disable TCP keep alive since it is spoofable. Use ClientAlive messages instead, they use the encrypted channel
TCPKeepAlive no
# Manage `ClientAlive..` signals via interval and maximum count.
# This will periodically check up to a `..CountMax` number of times within `..Interval` timeframe,
# and abort the connection once these fail.
ClientAliveInterval {{ ssh_client_alive_interval }}
ClientAliveCountMax {{ ssh_client_alive_count }}
# Disable tunneling
PermitTunnel {{ ssh_permit_tunnel }}
# Disable forwarding tcp connections.
# no real advantage without denied shell access
{% if sshd_version is version('6.2', '>=') %}
AllowTcpForwarding {{ ssh_allow_tcp_forwarding if (ssh_allow_tcp_forwarding in ('yes', 'no', 'local', 'all', 'remote')) else ('yes' if (ssh_allow_tcp_forwarding|bool) else 'no') }}
{% else %}
AllowTcpForwarding {{ ssh_allow_tcp_forwarding if (ssh_allow_tcp_forwarding in ('yes', 'no')) else ('yes' if (ssh_allow_tcp_forwarding|bool) else 'no') }}
{% endif %}
# Disable agent forwarding, since local agent could be accessed through forwarded connection.
# no real advantage without denied shell access
AllowAgentForwarding {{ 'yes' if (ssh_allow_agent_forwarding|bool) else 'no' }}
{% if ssh_gateway_ports|bool %}
# Port forwardings are forced to bind to the wildcard address
GatewayPorts yes
{% elif ssh_gateway_ports == 'clientspecified' %}
# Clients allowed to specify which address to bind port forwardings to
GatewayPorts clientspecified
{% else %}
# Do not allow remote port forwardings to bind to non-loopback addresses.
GatewayPorts no
{% endif %}
# Disable X11 forwarding, since local X11 display could be accessed through forwarded connection.
X11Forwarding {{ 'yes' if (ssh_x11_forwarding|bool) else 'no' }}
X11UseLocalhost yes
# User environment configuration
# ==============================
PermitUserEnvironment {{ ssh_server_permit_environment_vars }}
{% if ssh_server_accept_env_vars %}
AcceptEnv {{ ssh_server_accept_env_vars }}
{% endif %}
# Misc. configuration
# ===================
Compression {{ 'yes' if (ssh_compression|bool) else 'no' }}
UseDNS {{ 'yes' if (ssh_use_dns|bool) else 'no' }}
PrintMotd {{ 'yes' if (ssh_print_motd|bool) else 'no' }}
{% if ansible_facts.os_family != 'FreeBSD' %}
PrintLastLog {{ 'yes' if (ssh_print_last_log|bool) else 'no' }}
{% endif %}
Banner {{ ssh_banner_path if (ssh_banner|bool) else 'none' }}
{% if ansible_facts.os_family == 'Debian' %}
DebianBanner {{ 'yes' if (ssh_print_debian_banner|bool) else 'no' }}
{% endif %}
# Reject keys that are explicitly blacklisted
RevokedKeys /etc/ssh/revoked_keys
{% if sftp_enabled %}
# SFTP matching configuration
# ===========================
# Configuration, in case SFTP is used
# override default of no subsystems
# Subsystem sftp /opt/app/openssh5/libexec/sftp-server
Subsystem sftp internal-sftp -l INFO -f LOCAL6 -u {{ sftp_umask }}
# These lines must appear at the *end* of sshd_config
Match Group sftponly
ForceCommand internal-sftp -l INFO -f LOCAL6 -u {{ sftp_umask }}
{% if sftp_chroot %}
ChrootDirectory {{ sftp_chroot_dir }}
{% endif %}
AllowTcpForwarding no
AllowAgentForwarding no
PasswordAuthentication {{ 'yes' if (ssh_server_password_login|bool) else 'no' }}
PermitRootLogin no
X11Forwarding no
{% endif %}
{% if ssh_server_match_address %}
# Address matching configuration
# ============================
{% for item in ssh_server_match_address %}
Match Address {{ item.address }}
{% for rule in item.rules %}
{{ rule | indent(4) }}
{% endfor %}
{% endfor %}
{% endif %}
{% if ssh_server_match_group %}
# Group matching configuration
# ============================
{% for item in ssh_server_match_group %}
Match Group {{ item.group }}
{% for rule in item.rules %}
{{ rule | indent(4) }}
{% endfor %}
{% endfor %}
{% endif %}
{% if ssh_server_match_user %}
# User matching configuration
# ===========================
{% for item in ssh_server_match_user %}
Match User {{ item.user }}
{% for rule in item.rules %}
{{ rule | indent(4) }}
{% endfor %}
{% endfor %}
{% endif %}
{% if ssh_server_match_local_port %}
# LocalPort matching configuration
# ================================
{% for item in ssh_server_match_local_port %}
Match LocalPort {{ item.port }}
{% for rule in item.rules %}
{{ rule | indent(4) }}
{% endfor %}
{% endfor %}
{% endif %}