Showing with 118 additions and 47 deletions.
  1. +13 −1 README.md
  2. +10 −0 manifests/init.pp
  3. +1 −1 metadata.json
  4. +87 −44 spec/classes/init_spec.rb
  5. +7 −1 templates/sshd_config.erb
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,18 @@ AllowTcpForwarding in sshd_config. Specifies whether TCP forwarding is permitted

- *Default*: 'yes'

sshd_authorized_keys_command
----------------------------
Fully qualified path to command for AuthorizedKeysCommand in sshd_config.

- *Default*: undef

sshd_authorized_keys_command_user
---------------------------------
String of user for AuthorizedKeysCommandUser in sshd_config.

- *Default*: undef

sshd_x11_forwarding
-------------------
X11Forwarding in sshd_config. Specifies whether X11 forwarding is permitted.
Expand Down Expand Up @@ -367,7 +379,7 @@ Array of users for the AllowUsers setting in sshd_config.

sshd_config_maxstartups
-----------------------
Specifies the maximum number of concurrent unauthenticated connections to the SSH daemon.
Specifies the maximum number of concurrent unauthenticated connections to the SSH daemon.

- *Default*: undef

Expand Down
10 changes: 10 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
$sshd_config_chrootdirectory = undef,
$sshd_config_forcecommand = undef,
$sshd_config_match = undef,
$sshd_authorized_keys_command = undef,
$sshd_authorized_keys_command_user = undef,
$sshd_banner_content = undef,
$sshd_banner_owner = 'root',
$sshd_banner_group = 'root',
Expand Down Expand Up @@ -463,6 +465,14 @@
validate_string($sshd_config_forcecommand)
}

if $sshd_authorized_keys_command != undef {
validate_absolute_path($sshd_authorized_keys_command)
}

if $sshd_authorized_keys_command_user != undef {
validate_string($sshd_authorized_keys_command_user)
}

if $sshd_config_match != undef {
validate_hash($sshd_config_match)
}
Expand Down
2 changes: 1 addition & 1 deletion metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ghoneycutt-ssh",
"version": "3.25.0",
"version": "3.26.0",
"author": "ghoneycutt",
"summary": "Manages SSH",
"license": "Apache-2.0",
Expand Down
131 changes: 87 additions & 44 deletions spec/classes/init_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
it { should_not contain_file('sshd_config').with_content(/^\s*AuthorizedKeysCommand/) }
it { should contain_file('sshd_config').with_content(/^#ChrootDirectory none/) }
it { should contain_file('sshd_config').without_content(/^ForceCommand/) }
it { should contain_file('sshd_config').without_content(/^Match/) }
Expand Down Expand Up @@ -233,6 +234,7 @@
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
it { should_not contain_file('sshd_config').with_content(/^\s*AuthorizedKeysCommand/) }
it { should contain_file('sshd_config').with_content(/^#ChrootDirectory none/) }
it { should contain_file('sshd_config').without_content(/^ForceCommand/) }
it { should contain_file('sshd_config').without_content(/^Match/) }
Expand Down Expand Up @@ -350,6 +352,7 @@
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
it { should_not contain_file('sshd_config').with_content(/^\s*AuthorizedKeysCommand/) }
it { should contain_file('sshd_config').with_content(/^#ChrootDirectory none/) }
it { should contain_file('sshd_config').without_content(/^ForceCommand/) }
it { should contain_file('sshd_config').without_content(/^Match/) }
Expand Down Expand Up @@ -466,6 +469,7 @@
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
it { should_not contain_file('sshd_config').with_content(/^\s*AuthorizedKeysCommand/) }
it { should contain_file('sshd_config').with_content(/^#ChrootDirectory none/) }
it { should contain_file('sshd_config').without_content(/^ForceCommand/) }
it { should contain_file('sshd_config').without_content(/^Match/) }
Expand Down Expand Up @@ -590,6 +594,7 @@
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
it { should_not contain_file('sshd_config').with_content(/^\s*AuthorizedKeysCommand/) }
it { should contain_file('sshd_config').with_content(/^#ChrootDirectory none/) }
it { should contain_file('sshd_config').without_content(/^ForceCommand/) }
it { should contain_file('sshd_config').without_content(/^Match/) }
Expand Down Expand Up @@ -713,6 +718,7 @@
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
it { should_not contain_file('sshd_config').with_content(/^\s*AuthorizedKeysCommand/) }
it { should contain_file('sshd_config').with_content(/^#ChrootDirectory none/) }
it { should contain_file('sshd_config').without_content(/^ForceCommand/) }
it { should contain_file('sshd_config').without_content(/^Match/) }
Expand Down Expand Up @@ -836,6 +842,7 @@
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
it { should_not contain_file('sshd_config').with_content(/^\s*AuthorizedKeysCommand/) }
it { should contain_file('sshd_config').with_content(/^#ChrootDirectory none/) }
it { should contain_file('sshd_config').without_content(/^ForceCommand/) }
it { should contain_file('sshd_config').without_content(/^Match/) }
Expand Down Expand Up @@ -951,57 +958,59 @@
end
let :params do
{
:sshd_config_port => '22222',
:sshd_config_syslog_facility => 'DAEMON',
:sshd_config_login_grace_time => '60',
:permit_root_login => 'no',
:sshd_config_chrootdirectory => '/chrootdir',
:sshd_config_forcecommand => '/force/command --with-parameter 242',
:sshd_config_match => { 'User JohnDoe' => [ 'AllowTcpForwarding yes', ], },
:sshd_config_challenge_resp_auth => 'no',
:sshd_config_print_motd => 'no',
:sshd_config_use_dns => 'no',
:sshd_config_banner => '/etc/sshd_banner',
:sshd_banner_content => 'textinbanner',
:sshd_config_xauth_location => '/opt/ssh/bin/xauth',
:sshd_config_subsystem_sftp => '/opt/ssh/bin/sftp',
:sshd_password_authentication => 'no',
:sshd_allow_tcp_forwarding => 'no',
:sshd_x11_forwarding => 'no',
:sshd_use_pam => 'no',
:sshd_client_alive_interval => '242',
:sshd_config_serverkeybits => '1024',
:sshd_client_alive_count_max => '0',
:sshd_config_authkey_location => '.ssh/authorized_keys',
:sshd_config_hostkey => [ '/etc/ssh/ssh_host_rsa_key',
'/etc/ssh/ssh_host_dsa_key',
:sshd_config_port => '22222',
:sshd_config_syslog_facility => 'DAEMON',
:sshd_config_login_grace_time => '60',
:permit_root_login => 'no',
:sshd_config_chrootdirectory => '/chrootdir',
:sshd_config_forcecommand => '/force/command --with-parameter 242',
:sshd_config_match => { 'User JohnDoe' => [ 'AllowTcpForwarding yes', ], },
:sshd_config_challenge_resp_auth => 'no',
:sshd_config_print_motd => 'no',
:sshd_config_use_dns => 'no',
:sshd_config_banner => '/etc/sshd_banner',
:sshd_authorized_keys_command => '/path/to/command',
:sshd_authorized_keys_command_user => 'asdf',
:sshd_banner_content => 'textinbanner',
:sshd_config_xauth_location => '/opt/ssh/bin/xauth',
:sshd_config_subsystem_sftp => '/opt/ssh/bin/sftp',
:sshd_password_authentication => 'no',
:sshd_allow_tcp_forwarding => 'no',
:sshd_x11_forwarding => 'no',
:sshd_use_pam => 'no',
:sshd_client_alive_interval => '242',
:sshd_config_serverkeybits => '1024',
:sshd_client_alive_count_max => '0',
:sshd_config_authkey_location => '.ssh/authorized_keys',
:sshd_config_hostkey => [ '/etc/ssh/ssh_host_rsa_key',
'/etc/ssh/ssh_host_dsa_key',
],
:sshd_config_strictmodes => 'yes',
:sshd_config_ciphers => [ 'aes128-cbc',
'3des-cbc',
'blowfish-cbc',
'cast128-cbc',
'arcfour',
'aes192-cbc',
'aes256-cbc',
:sshd_config_strictmodes => 'yes',
:sshd_config_ciphers => [ 'aes128-cbc',
'3des-cbc',
'blowfish-cbc',
'cast128-cbc',
'arcfour',
'aes192-cbc',
'aes256-cbc',
],
:sshd_config_macs => [ 'hmac-md5-etm@openssh.com',
'hmac-sha1-etm@openssh.com',
:sshd_config_macs => [ 'hmac-md5-etm@openssh.com',
'hmac-sha1-etm@openssh.com',
],
:sshd_config_denyusers => [ 'root',
'lusers',
:sshd_config_denyusers => [ 'root',
'lusers',
],
:sshd_config_denygroups => [ 'nossh',
'wheel',
:sshd_config_denygroups => [ 'nossh',
'wheel',
],
:sshd_config_allowusers => [ 'foo',
'bar',
:sshd_config_allowusers => [ 'foo',
'bar',
],
:sshd_config_allowgroups => [ 'ssh',
'security',
:sshd_config_allowgroups => [ 'ssh',
'security',
],
:sshd_listen_address => [ '192.168.1.1',
'2001:db8::dead:f00d',
:sshd_listen_address => [ '192.168.1.1',
'2001:db8::dead:f00d',
],
}
end
Expand Down Expand Up @@ -1048,6 +1057,8 @@
it { should contain_file('sshd_config').with_content(/^StrictModes yes$/) }
it { should_not contain_file('sshd_config').with_content(/^MaxStartups/) }
it { should_not contain_file('sshd_config').with_content(/^MaxSessions/) }
it { should contain_file('sshd_config').with_content(/^AuthorizedKeysCommand \/path\/to\/command$/) }
it { should contain_file('sshd_config').with_content(/^AuthorizedKeysCommandUser asdf$/) }
it { should contain_file('sshd_config').with_content(/^ChrootDirectory \/chrootdir$/) }
it { should contain_file('sshd_config').with_content(/^ForceCommand \/force\/command --with-parameter 242$/) }
it { should contain_file('sshd_config').with_content(/^Match User JohnDoe\n AllowTcpForwarding yes\Z/) }
Expand Down Expand Up @@ -1800,6 +1811,38 @@
end
end

context 'with sshd_authorized_keys_command specified with an invalid path' do
let(:params) { { :sshd_authorized_keys_command => 'invalid/path' } }
let :facts do
{ :fqdn => 'monkey.example.com',
:osfamily => 'RedHat',
:sshrsakey => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ=='
}
end

it 'should fail' do
expect {
should contain_class('ssh')
}.to raise_error(Puppet::Error,/^"invalid\/path" is not an absolute path/)
end
end

context 'with sshd_authorized_keys_command_user specified with an invalid type (non-string)' do
let(:params) { { :sshd_authorized_keys_command_user => ['invalid','type'] } }
let :facts do
{ :fqdn => 'monkey.example.com',
:osfamily => 'RedHat',
:sshrsakey => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ=='
}
end

it 'should fail' do
expect {
should contain_class('ssh')
}.to raise_error(Puppet::Error,/^\["invalid", "type"\] is not a string/)
end
end

context 'with sshd_banner_content set and with default value on sshd_config_banner on valid osfamily' do
let(:params) { { :sshd_banner_content => 'textinbanner' } }
let :facts do
Expand Down
8 changes: 7 additions & 1 deletion templates/sshd_config.erb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ StrictModes <%= @sshd_config_strictmodes %>
<% if @sshd_config_authkey_location -%>
AuthorizedKeysFile <%= @sshd_config_authkey_location %>
<% end -%>
<% if @sshd_authorized_keys_command -%>
AuthorizedKeysCommand <%= @sshd_authorized_keys_command %>
<% end -%>
<% if @sshd_authorized_keys_command_user -%>
AuthorizedKeysCommandUser <%= @sshd_authorized_keys_command_user %>
<% end -%>

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
Expand Down Expand Up @@ -203,8 +209,8 @@ AllowUsers <%= @sshd_config_allowusers_real.join(' ') %>
<% if @sshd_config_allowgroups -%>
AllowGroups <%= @sshd_config_allowgroups_real.join(' ') %>
<% end -%>
<% if @sshd_config_match -%>
<% @sshd_config_match.sort.each do |key, hash| -%>
Match <%= key %>
<% hash.sort.each do |values| -%>
Expand Down