diff --git a/README.md b/README.md index 92ccfd2..bdd9cc7 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,12 @@ Specify location of authorized_keys file. Default is to not specify. - *Default*: undef +sshd_config_strictmodes +---------------------------- +Specifies whether sshd should check file modes and ownership of the user's files and home directory before accepting login. Valid values are yes and no. + +- *Default*: undef + sshd_config_banner ------------------ Banner option in sshd_config. diff --git a/manifests/init.pp b/manifests/init.pp index 4ac9ba0..194b4a4 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -32,6 +32,7 @@ class ssh ( $sshd_config_print_motd = 'yes', $sshd_config_use_dns = 'USE_DEFAULTS', $sshd_config_authkey_location = undef, + $sshd_config_strictmodes = undef, $sshd_config_banner = 'none', $sshd_banner_content = undef, $sshd_banner_owner = 'root', @@ -353,6 +354,10 @@ class ssh ( validate_string($sshd_config_authkey_location) } + if $sshd_config_strictmodes != undef { + validate_re($sshd_config_strictmodes, '^(yes|no)$', "ssh::sshd_config_strictmodes may be either 'yes' or 'no' and is set to <${sshd_config_strictmodes}>.") + } + case type($hiera_merge) { 'string': { validate_re($hiera_merge, '^(true|false)$', "ssh::hiera_merge may be either 'true' or 'false' and is set to <${hiera_merge}>.") diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index 61541b6..2dd1fea 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -77,6 +77,7 @@ describe 'ssh' do it { should_not contain_file('sshd_config').with_content(/^\s*PAMAuthenticationViaKBDInt yes$/) } it { should_not contain_file('sshd_config').with_content(/^\s*GSSAPIKeyExchange no$/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } + it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } it { @@ -186,6 +187,7 @@ describe 'ssh' do it { should contain_file('sshd_config').with_content(/^GSSAPIKeyExchange yes$/) } it { should_not contain_file('sshd_config').with_content(/^\s*AcceptEnv L.*$/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } + it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should contain_service('sshd_service').with({ @@ -276,6 +278,7 @@ describe 'ssh' do it { should contain_file('sshd_config').with_content(/^GSSAPIKeyExchange yes$/) } it { should_not contain_file('sshd_config').with_content(/^\s*AcceptEnv L.*$/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } + it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should contain_service('sshd_service').with({ @@ -365,6 +368,7 @@ describe 'ssh' do it { should contain_file('sshd_config').with_content(/^GSSAPIKeyExchange yes$/) } it { should_not contain_file('sshd_config').with_content(/^\s*AcceptEnv L.*$/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } + it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should contain_service('sshd_service').with({ @@ -461,6 +465,7 @@ describe 'ssh' do it { should_not contain_file('sshd_config').with_content(/^\s*GSSAPIKeyExchange yes$/) } it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } + it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should contain_service('sshd_service').with({ @@ -557,6 +562,7 @@ describe 'ssh' do it { should_not contain_file('sshd_config').with_content(/^\s*GSSAPIKeyExchange yes$/) } it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } + it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should contain_service('sshd_service').with({ @@ -653,6 +659,7 @@ describe 'ssh' do it { should_not contain_file('sshd_config').with_content(/^\s*GSSAPIKeyExchange yes$/) } it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } + it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should contain_service('sshd_service').with({ @@ -761,6 +768,7 @@ describe 'ssh' do :sshd_client_alive_interval => '242', :sshd_client_alive_count_max => '0', :sshd_config_authkey_location => '.ssh/authorized_keys', + :sshd_config_strictmodes => 'yes', } end @@ -800,6 +808,7 @@ describe 'ssh' do it { should_not contain_file('sshd_config').with_content(/^\s*GSSAPIKeyExchange yes$/) } it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } it { should contain_file('sshd_config').with_content(/^AuthorizedKeysFile .ssh\/authorized_keys/) } + it { should contain_file('sshd_config').with_content(/^StrictModes yes$/) } it { should contain_file('sshd_banner').with({ @@ -1058,7 +1067,26 @@ describe 'ssh' do }.to raise_error(Puppet::Error,/is not a string/) end end + + context 'with sshd_config_strictmodes set to invalid value on valid osfamily' do + let :facts do + { + :fqdn => 'monkey.example.com', + :osfamily => 'RedHat', + :sshrsakey => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ==' + } + end + let :params do + { :sshd_config_strictmodes => 'invalid' } + end + it 'should fail' do + expect { + should contain_class('ssh') + }.to raise_error(Puppet::Error,/^ssh::sshd_config_strictmodes may be either \'yes\' or \'no\' and is set to \./) + 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 diff --git a/templates/sshd_config.erb b/templates/sshd_config.erb index 010374e..0bc1817 100644 --- a/templates/sshd_config.erb +++ b/templates/sshd_config.erb @@ -44,6 +44,9 @@ LoginGraceTime <%= @sshd_config_login_grace_time %> #PermitRootLogin yes PermitRootLogin <%= @permit_root_login %> #StrictModes yes +<% if @sshd_config_strictmodes -%> +StrictModes <%= @sshd_config_strictmodes %> +<% end -%> #MaxAuthTries 6 #RSAAuthentication yes