Add ability to specify Ciphers option in ssh_config and sshd_config

This commit is contained in:
Garrett Honeycutt 2014-05-28 14:12:44 -04:00
parent b264bb97c6
commit dbf2d6c138
5 changed files with 101 additions and 0 deletions

View File

@ -95,6 +95,12 @@ Boolean to set 'SendEnv XMODIFIERS' in ssh_config. This option is only valid on
- *Default*: false - *Default*: false
ssh_config_ciphers
------------------
Array of ciphers to be used with the Ciphers option in ssh_config.
- *Default*: undef
ssh_sendenv ssh_sendenv
------------- -------------
Boolean to enable SendEnv options for specifying environment variables. Default is set to true on Linux. Boolean to enable SendEnv options for specifying environment variables. Default is set to true on Linux.
@ -276,6 +282,12 @@ after approximately 45 seconds. This option applies to protocol version 2 only.
- *Default*: '3' - *Default*: '3'
sshd_config_ciphers
-------------------
Array of ciphers for the Ciphers setting in sshd_config.
- *Default*: undef
keys keys
---- ----
Hash of keys for user's ~/.ssh/authorized_keys Hash of keys for user's ~/.ssh/authorized_keys

View File

@ -20,6 +20,7 @@ class ssh (
$ssh_config_forward_agent = undef, $ssh_config_forward_agent = undef,
$ssh_config_server_alive_interval = undef, $ssh_config_server_alive_interval = undef,
$ssh_config_sendenv_xmodifiers = false, $ssh_config_sendenv_xmodifiers = false,
$ssh_config_ciphers = undef,
$ssh_sendenv = 'USE_DEFAULTS', $ssh_sendenv = 'USE_DEFAULTS',
$sshd_config_path = '/etc/ssh/sshd_config', $sshd_config_path = '/etc/ssh/sshd_config',
$sshd_config_owner = 'root', $sshd_config_owner = 'root',
@ -35,6 +36,7 @@ class ssh (
$sshd_config_strictmodes = undef, $sshd_config_strictmodes = undef,
$sshd_config_serverkeybits = 'USE_DEFAULTS', $sshd_config_serverkeybits = 'USE_DEFAULTS',
$sshd_config_banner = 'none', $sshd_config_banner = 'none',
$sshd_config_ciphers = undef,
$sshd_banner_content = undef, $sshd_banner_content = undef,
$sshd_banner_owner = 'root', $sshd_banner_owner = 'root',
$sshd_banner_group = 'root', $sshd_banner_group = 'root',
@ -327,6 +329,14 @@ class ssh (
} }
# validate params # validate params
if $ssh_config_ciphers != undef {
validate_array($ssh_config_ciphers)
}
if $sshd_config_ciphers != undef {
validate_array($sshd_config_ciphers)
}
if $ssh_config_hash_known_hosts_real != undef { if $ssh_config_hash_known_hosts_real != undef {
validate_re($ssh_config_hash_known_hosts_real, '^(yes|no)$', "ssh::ssh_config_hash_known_hosts may be either 'yes' or 'no' and is set to <${ssh_config_hash_known_hosts_real}>.") validate_re($ssh_config_hash_known_hosts_real, '^(yes|no)$', "ssh::ssh_config_hash_known_hosts may be either 'yes' or 'no' and is set to <${ssh_config_hash_known_hosts_real}>.")
} }

View File

@ -39,6 +39,7 @@ describe 'ssh' do
it { should contain_file('ssh_config').with_content(/^\s*HashKnownHosts no$/) } it { should contain_file('ssh_config').with_content(/^\s*HashKnownHosts no$/) }
it { should contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) } it { should contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) }
it { should contain_file('ssh_config').with_content(/^\s*ForwardX11Trusted yes$/) } it { should contain_file('ssh_config').with_content(/^\s*ForwardX11Trusted yes$/) }
it { should contain_file('ssh_config').without_content(/^\s*Ciphers/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardAgent$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardAgent$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) }
@ -80,6 +81,7 @@ describe 'ssh' do
it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) }
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) }
it { should contain_file('sshd_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_service('sshd_service').with({ should contain_service('sshd_service').with({
@ -161,6 +163,7 @@ describe 'ssh' do
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) } it { should_not contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) }
it { should contain_file('ssh_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_file('sshd_config').with({ should contain_file('sshd_config').with({
@ -190,6 +193,7 @@ describe 'ssh' do
it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) }
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should contain_file('sshd_config').with_content(/^ServerKeyBits 768$/) } it { should contain_file('sshd_config').with_content(/^ServerKeyBits 768$/) }
it { should contain_file('sshd_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_service('sshd_service').with({ should contain_service('sshd_service').with({
@ -253,6 +257,7 @@ describe 'ssh' do
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) } it { should_not contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) }
it { should contain_file('ssh_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_file('sshd_config').with({ should contain_file('sshd_config').with({
@ -282,6 +287,7 @@ describe 'ssh' do
it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) }
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should contain_file('sshd_config').with_content(/^ServerKeyBits 768$/) } it { should contain_file('sshd_config').with_content(/^ServerKeyBits 768$/) }
it { should contain_file('sshd_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_service('sshd_service').with({ should contain_service('sshd_service').with({
@ -344,6 +350,7 @@ describe 'ssh' do
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) } it { should_not contain_file('ssh_config').with_content(/^\s*SendEnv L.*$/) }
it { should contain_file('ssh_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_file('sshd_config').with({ should contain_file('sshd_config').with({
@ -373,6 +380,7 @@ describe 'ssh' do
it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) } it { should_not contain_file('sshd_config').with_content(/^AuthorizedKeysFile/) }
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should contain_file('sshd_config').with_content(/^ServerKeyBits 768$/) } it { should contain_file('sshd_config').with_content(/^ServerKeyBits 768$/) }
it { should contain_file('sshd_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_service('sshd_service').with({ should contain_service('sshd_service').with({
@ -434,6 +442,7 @@ describe 'ssh' do
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardAgent$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardAgent$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) }
it { should contain_file('ssh_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_file('sshd_config').with({ should contain_file('sshd_config').with({
@ -471,6 +480,7 @@ describe 'ssh' do
it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } 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(/^AuthorizedKeysFile/) }
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should contain_file('ssh_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_service('sshd_service').with({ should contain_service('sshd_service').with({
@ -532,6 +542,7 @@ describe 'ssh' do
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardAgent$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardAgent$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) }
it { should contain_file('ssh_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_file('sshd_config').with({ should contain_file('sshd_config').with({
@ -569,6 +580,7 @@ describe 'ssh' do
it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } 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(/^AuthorizedKeysFile/) }
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should contain_file('sshd_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_service('sshd_service').with({ should contain_service('sshd_service').with({
@ -630,6 +642,7 @@ describe 'ssh' do
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardAgent$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardAgent$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ForwardX11$/) }
it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) } it { should_not contain_file('ssh_config').with_content(/^\s*ServerAliveInterval$/) }
it { should contain_file('ssh_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_file('sshd_config').with({ should contain_file('sshd_config').with({
@ -667,6 +680,7 @@ describe 'ssh' do
it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } 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(/^AuthorizedKeysFile/) }
it { should_not contain_file('sshd_config').with_content(/^StrictModes/) } it { should_not contain_file('sshd_config').with_content(/^StrictModes/) }
it { should contain_file('sshd_config').without_content(/^\s*Ciphers/) }
it { it {
should contain_service('sshd_service').with({ should contain_service('sshd_service').with({
@ -721,6 +735,14 @@ describe 'ssh' do
:ssh_config_forward_x11 => 'yes', :ssh_config_forward_x11 => 'yes',
:ssh_config_server_alive_interval => '300', :ssh_config_server_alive_interval => '300',
:ssh_config_sendenv_xmodifiers => true, :ssh_config_sendenv_xmodifiers => true,
:ssh_config_ciphers => [ 'aes128-cbc',
'3des-cbc',
'blowfish-cbc',
'cast128-cbc',
'arcfour',
'aes192-cbc',
'aes256-cbc',
],
} }
end end
@ -745,6 +767,7 @@ describe 'ssh' do
it { should contain_file('ssh_config').with_content(/^ ForwardX11 yes$/) } it { should contain_file('ssh_config').with_content(/^ ForwardX11 yes$/) }
it { should contain_file('ssh_config').with_content(/^ ServerAliveInterval 300$/) } it { should contain_file('ssh_config').with_content(/^ ServerAliveInterval 300$/) }
it { should contain_file('ssh_config').with_content(/^ SendEnv XMODIFIERS$/) } it { should contain_file('ssh_config').with_content(/^ SendEnv XMODIFIERS$/) }
it { should contain_file('ssh_config').with_content(/^\s*Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc$/) }
end end
context 'with params used in sshd_config set on valid osfamily' do context 'with params used in sshd_config set on valid osfamily' do
@ -777,6 +800,14 @@ describe 'ssh' do
:sshd_client_alive_count_max => '0', :sshd_client_alive_count_max => '0',
:sshd_config_authkey_location => '.ssh/authorized_keys', :sshd_config_authkey_location => '.ssh/authorized_keys',
:sshd_config_strictmodes => 'yes', :sshd_config_strictmodes => 'yes',
:sshd_config_ciphers => [ 'aes128-cbc',
'3des-cbc',
'blowfish-cbc',
'cast128-cbc',
'arcfour',
'aes192-cbc',
'aes256-cbc',
],
} }
end end
@ -818,6 +849,7 @@ describe 'ssh' do
it { should contain_file('sshd_config').with_content(/^AcceptEnv L.*$/) } 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(/^AuthorizedKeysFile .ssh\/authorized_keys/) }
it { should contain_file('sshd_config').with_content(/^StrictModes yes$/) } it { should contain_file('sshd_config').with_content(/^StrictModes yes$/) }
it { should contain_file('sshd_config').with_content(/^\s*Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc$/) }
it { it {
should contain_file('sshd_banner').with({ should contain_file('sshd_banner').with({
@ -873,6 +905,26 @@ describe 'ssh' do
} }
end end
[true,'invalid'].each do |ciphers|
context "with ssh_config_ciphers set to invalid value #{ciphers}" do
let(:params) { { :ssh_config_ciphers => ciphers } }
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)
end
end
end
context 'with ssh_config_hash_known_hosts set to invalid value on valid osfamily' do context 'with ssh_config_hash_known_hosts set to invalid value on valid osfamily' do
let :facts do let :facts do
{ {
@ -892,6 +944,26 @@ describe 'ssh' do
end end
end end
[true,'invalid'].each do |ciphers|
context "with sshd_config_ciphers set to invalid value #{ciphers}" do
let(:params) { { :sshd_config_ciphers => ciphers } }
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)
end
end
end
context 'with sshd_config_port not being a valid number' do context 'with sshd_config_port not being a valid number' do
let :facts do let :facts do
{ {

View File

@ -40,6 +40,9 @@
Protocol 2 Protocol 2
# Cipher 3des # Cipher 3des
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc # Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
<% if @ssh_config_ciphers -%>
Ciphers <%= @ssh_config_ciphers.join(',') %>
<% end -%>
# EscapeChar ~ # EscapeChar ~
# Tunnel no # Tunnel no
# TunnelDevice any:any # TunnelDevice any:any

View File

@ -158,3 +158,7 @@ XAuthLocation <%= @sshd_config_xauth_location_real %>
# override default of no subsystems # override default of no subsystems
Subsystem sftp <%= @sshd_config_subsystem_sftp_real %> Subsystem sftp <%= @sshd_config_subsystem_sftp_real %>
<% if @sshd_config_ciphers -%>
Ciphers <%= @sshd_config_ciphers.join(',') %>
<% end -%>