From 8fbbdc7d3d11a9b23026e29b18048a44d349aeb1 Mon Sep 17 00:00:00 2001 From: Garrett Honeycutt Date: Sat, 25 Oct 2014 13:52:05 -0700 Subject: [PATCH] Add ability to specify ListenAddress in sshd_config --- README.md | 6 ++++ manifests/init.pp | 6 ++-- spec/classes/init_spec.rb | 73 ++++++++++++++++++++++++++++++++++++--- templates/sshd_config.erb | 6 ++-- 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index d86ae35..0edb4e9 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,12 @@ sshd_config's mode. The default is '0600' on Linux and '0644' on Solaris. - *Default*: 'USE_DEFAULTS' +sshd_listen_address +------------------- +String or Array to specify address(es) for which sshd will bind. Corresponds to ListenAddress in sshd_config. + +- *Default*: undef + sshd_config_port --------------------------- String to specify listen port for sshd. Port option in sshd_config. diff --git a/manifests/init.pp b/manifests/init.pp index 6830edc..da08605 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -65,7 +65,7 @@ class ssh ( $sshd_gssapicleanupcredentials = 'USE_DEFAULTS', $sshd_acceptenv = 'USE_DEFAULTS', $sshd_config_hostkey = 'USE_DEFAULTS', - $sshd_listen = undef, + $sshd_listen_address = undef, $service_ensure = 'running', $service_name = 'USE_DEFAULTS', $service_enable = 'true', @@ -349,8 +349,8 @@ class ssh ( $sshd_config_hostkey_real = $sshd_config_hostkey } - if $sshd_listen { - validate_array($sshd_listen) + if $sshd_listen_address { + validate_array($sshd_listen_address) } if $service_hasstatus == 'USE_DEFAULTS' { diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index 0977062..eebd65d 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -81,7 +81,7 @@ describe 'ssh' do it { should contain_file('sshd_config').with_content(/^GSSAPIAuthentication yes$/) } it { should contain_file('sshd_config').with_content(/^GSSAPICleanupCredentials yes$/) } it { should contain_file('sshd_config').with_content(/^HostKey \/etc\/ssh\/ssh_host_rsa_key$/) } - it { should contain_file('sshd_config').without_content(/^ListenAddress/) } + it { should contain_file('sshd_config').without_content(/^\s*ListenAddress/) } 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/) } @@ -212,6 +212,7 @@ describe 'ssh' do it { should contain_file('sshd_config').without_content(/^\s*DenyGroups/) } it { should contain_file('sshd_config').without_content(/^\s*AllowUsers/) } it { should contain_file('sshd_config').without_content(/^\s*AllowGroups/) } + it { should contain_file('sshd_config').without_content(/^\s*ListenAddress/) } it { should contain_service('sshd_service').with({ @@ -313,6 +314,7 @@ describe 'ssh' do it { should contain_file('sshd_config').without_content(/^\s*DenyGroups/) } it { should contain_file('sshd_config').without_content(/^\s*AllowUsers/) } it { should contain_file('sshd_config').without_content(/^\s*AllowGroups/) } + it { should contain_file('sshd_config').without_content(/^\s*ListenAddress/) } it { should contain_service('sshd_service').with({ @@ -413,6 +415,7 @@ describe 'ssh' do it { should contain_file('sshd_config').without_content(/^\s*DenyGroups/) } it { should contain_file('sshd_config').without_content(/^\s*AllowUsers/) } it { should contain_file('sshd_config').without_content(/^\s*AllowGroups/) } + it { should contain_file('sshd_config').without_content(/^\s*ListenAddress/) } it { should contain_service('sshd_service').with({ @@ -520,6 +523,7 @@ describe 'ssh' do it { should contain_file('sshd_config').without_content(/^\s*DenyGroups/) } it { should contain_file('sshd_config').without_content(/^\s*AllowUsers/) } it { should contain_file('sshd_config').without_content(/^\s*AllowGroups/) } + it { should contain_file('sshd_config').without_content(/^\s*ListenAddress/) } it { should contain_service('sshd_service').with({ @@ -627,6 +631,7 @@ describe 'ssh' do it { should contain_file('sshd_config').without_content(/^\s*DenyGroups/) } it { should contain_file('sshd_config').without_content(/^\s*AllowUsers/) } it { should contain_file('sshd_config').without_content(/^\s*AllowGroups/) } + it { should contain_file('sshd_config').without_content(/^\s*ListenAddress/) } it { should contain_service('sshd_service').with({ @@ -734,6 +739,7 @@ describe 'ssh' do it { should contain_file('sshd_config').without_content(/^\s*DenyGroups/) } it { should contain_file('sshd_config').without_content(/^\s*AllowUsers/) } it { should contain_file('sshd_config').without_content(/^\s*AllowGroups/) } + it { should contain_file('sshd_config').without_content(/^\s*ListenAddress/) } it { should contain_service('sshd_service').with({ @@ -883,7 +889,7 @@ describe 'ssh' do :sshd_config_allowgroups => [ 'ssh', 'security', ], - :sshd_listen => [ '192.168.1.1', + :sshd_listen_address => [ '192.168.1.1', '2001:db8::dead:f00d', ], } @@ -935,8 +941,7 @@ describe 'ssh' do it { should contain_file('sshd_config').with_content(/^\s*DenyGroups nossh wheel$/) } it { should contain_file('sshd_config').with_content(/^\s*AllowUsers foo bar$/) } it { should contain_file('sshd_config').with_content(/^\s*AllowGroups ssh security$/) } - it { should contain_file('sshd_config').with_content(/^ListenAddress 192.168.1.1$/) } - it { should contain_file('sshd_config').with_content(/^ListenAddress 2001:db8::dead:f00d$/) } + it { should contain_file('sshd_config').with_content(/^ListenAddress 192.168.1.1\nListenAddress 2001:db8::dead:f00d$/) } it { should contain_file('sshd_banner').with({ @@ -951,6 +956,66 @@ describe 'ssh' do } end + describe 'sshd_listen_address param' do + context 'when set to an array' do + let :facts do + { + :fqdn => 'monkey.example.com', + :osfamily => 'RedHat', + :root_home => '/root', + :sshrsakey => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ==' + } + end + let (:params) {{'sshd_listen_address' => ['192.168.1.1','2001:db8::dead:f00d'] }} + + it { should contain_file('sshd_config').with_content(/^ListenAddress 192.168.1.1\nListenAddress 2001:db8::dead:f00d$/) } + end + + context 'when set to a string' do + let :facts do + { + :fqdn => 'monkey.example.com', + :osfamily => 'RedHat', + :root_home => '/root', + :sshrsakey => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ==' + } + end + let (:params) {{'sshd_listen_address' => ['192.168.1.1'] }} + + it { should contain_file('sshd_config').with_content(/^ListenAddress 192.168.1.1$/) } + end + + context 'when not set' do + let :facts do + { + :fqdn => 'monkey.example.com', + :osfamily => 'RedHat', + :root_home => '/root', + :sshrsakey => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ==' + } + end + + it { should_not contain_file('sshd_config').with_content(/^\s*ListenAddress/) } + end + + + context 'when set to an invalid type (not string or array)' do + let :facts do + { + :fqdn => 'monkey.example.com', + :osfamily => 'RedHat', + :root_home => '/root', + :sshrsakey => 'AAAAB3NzaC1yc2EAAAABIwAAAQEArGElx46pD6NNnlxVaTbp0ZJMgBKCmbTCT3RaeCk0ZUJtQ8wkcwTtqIXmmiuFsynUT0DFSd8UIodnBOPqitimmooAVAiAi30TtJVzADfPScMiUnBJKZajIBkEMkwUcqsfh630jyBvLPE/kyQcxbEeGtbu1DG3monkeymanOBW1AKc5o+cJLXcInLnbowMG7NXzujT3BRYn/9s5vtT1V9cuZJs4XLRXQ50NluxJI7sVfRPVvQI9EMbTS4AFBXUej3yfgaLSV+nPZC/lmJ2gR4t/tKvMFF9m16f8IcZKK7o0rK7v81G/tREbOT5YhcKLK+0wBfR6RsmHzwy4EddZloyLQ==' + } + end + let (:params) {{'sshd_listen_address' => true }} + + it 'should fail' do + expect { subject }.to raise_error(Puppet::Error) + end + end + end + describe 'sshd_loglevel param' do context 'when set to an invalid value' do let :facts do diff --git a/templates/sshd_config.erb b/templates/sshd_config.erb index e6f9958..7e04039 100644 --- a/templates/sshd_config.erb +++ b/templates/sshd_config.erb @@ -18,10 +18,12 @@ Port <%= @sshd_config_port %> #Protocol 2,1 Protocol 2 #AddressFamily any -<% if @sshd_listen -%> -<% @sshd_listen.each do |val| -%> +<% if @sshd_listen_address.class == Array -%> +<% @sshd_listen_address.each do |val| -%> ListenAddress <%= val %> <% end -%> +<% elsif @sshd_listen_address.class == String -%> +ListenAddress <%= @sshd_listen_address %> <% end -%> # HostKey for protocol version 1