Skip to content
This repository was archived by the owner on Dec 26, 2020. It is now read-only.

Commit bfafa96

Browse files
authored
Merge pull request #116 from dev-sec/finish_94
Finish 94
2 parents 7f9245a + aeb61c7 commit bfafa96

File tree

6 files changed

+114
-24
lines changed

6 files changed

+114
-24
lines changed

.kitchen.yml

+1-4
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ driver:
99
transport:
1010
max_ssh_sessions: 5
1111

12-
transport:
13-
max_ssh_sessions: 5
14-
15-
1612
provisioner:
1713
name: ansible_playbook
1814
hosts: all
@@ -26,6 +22,7 @@ provisioner:
2622
http_proxy: <%= ENV['http_proxy'] || nil %>
2723
https_proxy: <%= ENV['https_proxy'] || nil %>
2824
playbook: default.yml
25+
ansible_diff: true
2926
ansible_extra_flags:
3027
- "--skip-tags=sysctl"
3128

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ Warning: This role disables root-login on the target server! Please make sure yo
4949
|`ssh_challengeresponseauthentication` | false | Specifies whether challenge-response authentication is allowed (e.g. via PAM) |
5050
|`ssh_client_password_login` | false | `true` to allow password-based authentication with the ssh client |
5151
|`ssh_server_password_login` | false | `true` to allow password-based authentication with the ssh server |
52+
|`ssh_banner` | `false` | `true` to print a banner on login |
53+
|`ssh_client_hardening` | `true` | `false` to stop harden the client |
54+
|`ssh_client_port` | `'22'` | Specifies the port number to connect on the remote host. |
55+
|`ssh_compression` | `false` | Specifies whether compression is enabled after the user has authenticated successfully. |
56+
|`ssh_max_auth_retries` | `2` | Specifies the maximum number of authentication attempts permitted per connection. |
57+
|`ssh_print_debian_banner` | `false` | `true` to print debian specific banner |
58+
|`ssh_server_enabled` | `true` | `false` to disable the opensshd server |
59+
|`ssh_server_hardening` | `true` | `false` to stop harden the server |
60+
|`ssh_server_match_group` | '' | Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file. |
61+
|`ssh_server_match_user` | '' | Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file. |
62+
|`ssh_server_permit_environment_vars` | `false` | `true` to specify that ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd |
63+
|`ssh_use_dns` | `false` | Specifies whether sshd should look up the remote host name, and to check that the resolved host name for the remote IP address maps back to the very same IP address. |
5264
|`ssh_server_revoked_keys` | [] | a list of revoked public keys that the ssh server will always reject, useful to revoke known weak or compromised keys.|
5365

5466
## Example Playbook

default.yml

+28-1
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,42 @@
1818
vars:
1919
network_ipv6_enable: true
2020
ssh_allow_root_with_key: true
21+
ssh_allow_tcp_forwarding: true
22+
ssh_allow_agent_forwarding: true
23+
ssh_server_permit_environment_vars: 'PWD'
24+
ssh_client_alive_interval: 100
25+
ssh_client_alive_count: 10
2126
ssh_client_password_login: true
2227
ssh_client_cbc_required: true
23-
ssh_server_weak_hmac: true
2428
ssh_client_weak_kex: true
29+
ssh_challengeresponseauthentication: true
30+
ssh_compression: true
31+
ssh_allow_users: 'root kitchen vagrant'
32+
ssh_allow_groups: 'root kitchen vagrant'
33+
ssh_deny_users: 'foo bar'
34+
ssh_deny_groups: 'foo bar'
35+
ssh_max_auth_retries: 10
36+
ssh_permit_tunnel: true
37+
ssh_print_motd: true
38+
ssh_print_last_log: true
39+
ssh_banner: true
40+
ssh_server_password_login: true
41+
ssh_server_enabled: false
42+
ssh_server_weak_hmac: true
43+
sftp_enabled: true
44+
ssh_server_match_group:
45+
- group: 'root'
46+
rules: 'AllowTcpForwarding yes'
47+
ssh_server_match_user:
48+
- user: 'root'
49+
rules: 'AllowTcpForwarding yes'
2550
ssh_remote_hosts:
2651
- names: ['example.com', 'example2.com']
2752
options: ['Port 2222', 'ForwardAgent yes']
2853
- names: ['example3.com']
2954
options: ['StrictHostKeyChecking no']
55+
ssh_use_dns: true
56+
ssh_use_pam: true
3057

3158
- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings
3259
hosts: localhost

defaults/main.yml

+17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
# true if IPv6 is needed
22
network_ipv6_enable: false # sshd + ssh
33

4+
# true if sshd should be started and enabled
5+
ssh_server_enabled: true # sshd
6+
7+
# true if DNS resolutions are needed, look up the remote host name, defaults to false from 6.8, see: http://www.openssh.com/txt/release-6.8
8+
ssh_use_dns: false # sshd
9+
10+
# true or value if compression is needed
11+
ssh_compression: false # sshd
12+
413
# For which components (client and server) to generate the configuration for. Can be useful when running against a client without an SSH server.
514
ssh_client_hardening: true # ssh
615
ssh_server_hardening: true # sshd
@@ -96,6 +105,14 @@ sftp_chroot_dir: /home/%u
96105
# enable experimental client roaming
97106
ssh_client_roaming: false
98107

108+
# list of hashes (containing user and rules) to generate Match User blocks for.
109+
ssh_server_match_user: false # sshd
110+
111+
# list of hashes (containing group and rules) to generate Match Group blocks for.
112+
ssh_server_match_group: false # sshd
113+
114+
ssh_server_permit_environment_vars: false
115+
99116

100117
ssh_ps53: 'yes'
101118
ssh_ps59: 'sandbox'

handlers/main.yml

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
- name: restart sshd
22
service: name={{ sshd_service_name }} state=restarted
3+
when: "(ssh_server_enabled|bool)"

templates/opensshd.conf.j2

+55-19
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
# ===================
88

99
# Either disable or only allowssh root login via certificates.
10-
PermitRootLogin {{ 'without-password' if ssh_allow_root_with_key else 'no' }}
10+
PermitRootLogin {{ 'without-password' if (ssh_allow_root_with_key|bool) else 'no' }}
1111

1212
# Define which port sshd should listen to. Default to `22`.
1313
{% for port in ssh_server_ports -%}
1414
Port {{port}}
1515
{% endfor %}
1616

1717
# Address family should always be limited to the active network configuration.
18-
AddressFamily {{ 'any' if network_ipv6_enable else 'inet' }}
18+
AddressFamily {{ 'any' if (network_ipv6_enable|bool) else 'inet' }}
1919

2020
# Define which addresses sshd should listen to. Default to `0.0.0.0`, ie make sure you put your desired address in here, since otherwise sshd will listen to everyone.
2121
{% for address in ssh_listen_to -%}
@@ -113,7 +113,6 @@ LogLevel VERBOSE
113113
UseLogin no
114114
UsePrivilegeSeparation {% if (ansible_distribution == 'Debian' and ansible_distribution_major_version <= '6') or (ansible_os_family in ['Oracle Linux', 'RedHat'] and ansible_distribution_major_version <= '6') -%}{{ssh_ps53}}{% else %}{{ssh_ps59}}{% endif %}
115115

116-
PermitUserEnvironment no
117116
LoginGraceTime 30s
118117
MaxAuthTries {{ssh_max_auth_retries}}
119118
MaxSessions 10
@@ -128,12 +127,12 @@ IgnoreUserKnownHosts yes
128127
HostbasedAuthentication no
129128

130129
# Enable PAM to enforce system wide rules
131-
UsePAM {{ 'yes' if ssh_use_pam else 'no' }}
130+
UsePAM {{ 'yes' if (ssh_use_pam|bool) else 'no' }}
132131

133132
# Disable password-based authentication, it can allow for potentially easier brute-force attacks.
134-
PasswordAuthentication {{ 'yes' if ssh_server_password_login else 'no' }}
133+
PasswordAuthentication {{ 'yes' if (ssh_server_password_login|bool) else 'no' }}
135134
PermitEmptyPasswords no
136-
ChallengeResponseAuthentication {{ 'yes' if ssh_challengeresponseauthentication else 'no' }}
135+
ChallengeResponseAuthentication {{ 'yes' if (ssh_challengeresponseauthentication|bool) else 'no' }}
137136

138137
# Only enable Kerberos authentication if it is configured.
139138
KerberosAuthentication no
@@ -173,15 +172,15 @@ ClientAliveInterval {{ssh_client_alive_interval}}
173172
ClientAliveCountMax {{ssh_client_alive_count}}
174173

175174
# Disable tunneling
176-
PermitTunnel {{ 'yes' if ssh_permit_tunnel else 'no' }}
175+
PermitTunnel {{ 'yes' if (ssh_permit_tunnel|bool) else 'no' }}
177176

178177
# Disable forwarding tcp connections.
179178
# no real advantage without denied shell access
180-
AllowTcpForwarding {{ 'yes' if ssh_allow_tcp_forwarding else 'no' }}
179+
AllowTcpForwarding {{ 'yes' if (ssh_allow_tcp_forwarding|bool) else 'no' }}
181180

182181
# Disable agent formwarding, since local agent could be accessed through forwarded connection.
183182
# no real advantage without denied shell access
184-
AllowAgentForwarding {{ 'yes' if ssh_allow_agent_forwarding else 'no' }}
183+
AllowAgentForwarding {{ 'yes' if (ssh_allow_agent_forwarding|bool) else 'no' }}
185184

186185
# Do not allow remote port forwardings to bind to non-loopback addresses.
187186
GatewayPorts no
@@ -190,34 +189,50 @@ GatewayPorts no
190189
X11Forwarding no
191190
X11UseLocalhost yes
192191

193-
# Look up the remote host name, defaults to false from 6.8, see: http://www.openssh.com/txt/release-6.8
194-
UseDNS {{ 'yes' if ssh_use_dns else 'no' }}
192+
# User environment configuration
193+
# ==============================
194+
195+
{% if ssh_server_permit_environment_vars %}
196+
PermitUserEnvironment yes
197+
{% for item in ssh_server_permit_environment_vars %}
198+
AcceptEnv {{ item }}
199+
{% endfor %}
200+
{% else %}
201+
PermitUserEnvironment no
202+
{% endif %}
195203

196204
# Misc. configuration
197205
# ===================
198206

199-
PrintMotd {{ 'yes' if ssh_print_motd else 'no' }}
207+
Compression {{ 'yes' if (ssh_compression|bool) else 'no' }}
208+
209+
UseDNS {{ 'yes' if (ssh_use_dns|bool) else 'no' }}
210+
211+
PrintMotd {{ 'yes' if (ssh_print_motd|bool) else 'no' }}
200212

201213
{% if ansible_os_family != 'FreeBSD' %}
202-
PrintLastLog {{ 'yes' if ssh_print_last_log else 'no' }}
214+
PrintLastLog {{ 'yes' if (ssh_print_last_log|bool) else 'no' }}
203215
{% endif %}
204216

205-
Banner {{ '/etc/ssh/banner.txt' if ssh_banner else 'none' }}
217+
Banner {{ '/etc/ssh/banner.txt' if (ssh_banner|bool) else 'none' }}
206218

207219
{% if ansible_os_family == 'Debian' %}
208-
DebianBanner {{ 'yes' if ssh_print_debian_banner else 'no' }}
220+
DebianBanner {{ 'yes' if (ssh_print_debian_banner|bool) else 'no' }}
209221
{% endif %}
210222

211223
# Reject keys that are explicitly blacklisted
212224
RevokedKeys /etc/ssh/revoked_keys
213225

214226
{% if sftp_enabled %}
227+
# SFTP matching configuration
228+
# ===========================
215229
# Configuration, in case SFTP is used
216-
## override default of no subsystems
217-
## Subsystem sftp /opt/app/openssh5/libexec/sftp-server
230+
# override default of no subsystems
231+
# Subsystem sftp /opt/app/openssh5/libexec/sftp-server
232+
218233
Subsystem sftp internal-sftp -l INFO -f LOCAL6
219-
#
220-
## These lines must appear at the *end* of sshd_config
234+
235+
# These lines must appear at the *end* of sshd_config
221236
Match Group sftponly
222237
ForceCommand internal-sftp -l INFO -f LOCAL6
223238
ChrootDirectory {{ sftp_chroot_dir }}
@@ -227,3 +242,24 @@ PasswordAuthentication no
227242
PermitRootLogin no
228243
X11Forwarding no
229244
{% endif %}
245+
246+
{% if ssh_server_match_group %}
247+
# Group matching configuration
248+
# ============================
249+
250+
{% for item in ssh_server_match_group %}
251+
Match Group {{ item.group }}
252+
{{ item.rules | indent(4) }}
253+
{% endfor %}
254+
{% endif %}
255+
256+
257+
{% if ssh_server_match_user %}
258+
# User matching configuration
259+
# ===========================
260+
261+
{% for item in ssh_server_match_user %}
262+
Match User {{ item.user }}
263+
{{ item.rules | indent(4) }}
264+
{% endfor %}
265+
{% endif %}

0 commit comments

Comments
 (0)