Merge pull request #240 from dhollinger/sshca

Add more SSH CA related fixes and paramaters
This commit is contained in:
Garrett Honeycutt 2017-07-24 16:21:25 -04:00 committed by GitHub
commit a9be160560
5 changed files with 181 additions and 131 deletions

View File

@ -33,6 +33,6 @@ gem 'puppetlabs_spec_helper', '2.0.2', :require => false if RUBY_VERSION >= '
gem 'puppetlabs_spec_helper', '>= 2.0.0', :require => false if RUBY_VERSION >= '1.9' gem 'puppetlabs_spec_helper', '>= 2.0.0', :require => false if RUBY_VERSION >= '1.9'
gem 'parallel_tests', '<= 2.9.0', :require => false if RUBY_VERSION < '2.0.0' gem 'parallel_tests', '<= 2.9.0', :require => false if RUBY_VERSION < '2.0.0'
if puppetversion < '5.0' if puppetversion && puppetversion < '5.0'
gem 'semantic_puppet', :require => false gem 'semantic_puppet', :require => false
end end

View File

@ -598,7 +598,7 @@ ssh::sshd_config_match:
sshd_config_hostcertificate sshd_config_hostcertificate
--------------------------- ---------------------------
Absolute path to the OpenSSH Host CA Certificate (HostCertificate) for use with SSH CA validation for Host Certificates. An Absolute Path or Array of Absolute Paths to the Host CA Public Key. Each entry *MUST* be tied 1:1 to a Host CA Private Key (see [sshd_config_hostkey](#sshd_config_hostkey))
- *Default*: undefined - *Default*: undefined
@ -608,6 +608,14 @@ Absolute path to the OpenSSH User CA Certificate (TrustedUserCAKeys) for use wit
- *Default*: undefined - *Default*: undefined
sshd_config_authorized_principals_file
--------------------------------------
String path (relative or absolute) to the `authorized_principals` file. Sets the `AuthorizedPrincipalsFile` setting in `sshd_config`
See `sshd_config(5)` for more details
- *Default*: undefined
keys keys
---- ----
Hash of keys for user's ~/.ssh/authorized_keys Hash of keys for user's ~/.ssh/authorized_keys

View File

@ -3,120 +3,121 @@
# Manage ssh client and server # Manage ssh client and server
# #
class ssh ( class ssh (
$hiera_merge = false, $hiera_merge = false,
$packages = 'USE_DEFAULTS', $packages = 'USE_DEFAULTS',
$permit_root_login = 'yes', $permit_root_login = 'yes',
$purge_keys = true, $purge_keys = true,
$manage_firewall = false, $manage_firewall = false,
$ssh_package_source = 'USE_DEFAULTS', $ssh_package_source = 'USE_DEFAULTS',
$ssh_package_adminfile = 'USE_DEFAULTS', $ssh_package_adminfile = 'USE_DEFAULTS',
$ssh_config_hash_known_hosts = 'USE_DEFAULTS', $ssh_config_hash_known_hosts = 'USE_DEFAULTS',
$ssh_config_path = '/etc/ssh/ssh_config', $ssh_config_path = '/etc/ssh/ssh_config',
$ssh_config_owner = 'root', $ssh_config_owner = 'root',
$ssh_config_group = 'root', $ssh_config_group = 'root',
$ssh_config_mode = '0644', $ssh_config_mode = '0644',
$ssh_config_forward_x11 = undef, $ssh_config_forward_x11 = undef,
$ssh_config_forward_x11_trusted = 'USE_DEFAULTS', $ssh_config_forward_x11_trusted = 'USE_DEFAULTS',
$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_hostbasedauthentication = undef, $ssh_hostbasedauthentication = undef,
$ssh_config_proxy_command = undef, $ssh_config_proxy_command = undef,
$ssh_strict_host_key_checking = undef, $ssh_strict_host_key_checking = undef,
$ssh_config_ciphers = undef, $ssh_config_ciphers = undef,
$ssh_config_kexalgorithms = undef, $ssh_config_kexalgorithms = undef,
$ssh_config_macs = undef, $ssh_config_macs = undef,
$ssh_config_use_roaming = 'USE_DEFAULTS', $ssh_config_use_roaming = 'USE_DEFAULTS',
$ssh_config_template = 'ssh/ssh_config.erb', $ssh_config_template = 'ssh/ssh_config.erb',
$ssh_sendenv = 'USE_DEFAULTS', $ssh_sendenv = 'USE_DEFAULTS',
$ssh_gssapiauthentication = 'yes', $ssh_gssapiauthentication = 'yes',
$ssh_gssapidelegatecredentials = undef, $ssh_gssapidelegatecredentials = undef,
$sshd_config_path = '/etc/ssh/sshd_config', $sshd_config_path = '/etc/ssh/sshd_config',
$sshd_config_owner = 'root', $sshd_config_owner = 'root',
$sshd_config_group = 'root', $sshd_config_group = 'root',
$sshd_config_loglevel = 'INFO', $sshd_config_loglevel = 'INFO',
$sshd_config_mode = 'USE_DEFAULTS', $sshd_config_mode = 'USE_DEFAULTS',
$sshd_config_permitemptypasswords = undef, $sshd_config_permitemptypasswords = undef,
$sshd_config_permituserenvironment = undef, $sshd_config_permituserenvironment = undef,
$sshd_config_compression = undef, $sshd_config_compression = undef,
$sshd_config_port = '22', $sshd_config_port = '22',
$sshd_config_syslog_facility = 'AUTH', $sshd_config_syslog_facility = 'AUTH',
$sshd_config_template = 'ssh/sshd_config.erb', $sshd_config_template = 'ssh/sshd_config.erb',
$sshd_config_login_grace_time = '120', $sshd_config_login_grace_time = '120',
$sshd_config_challenge_resp_auth = 'yes', $sshd_config_challenge_resp_auth = 'yes',
$sshd_config_print_motd = 'yes', $sshd_config_print_motd = 'yes',
$sshd_config_print_last_log = undef, $sshd_config_print_last_log = undef,
$sshd_config_use_dns = 'USE_DEFAULTS', $sshd_config_use_dns = 'USE_DEFAULTS',
$sshd_config_authkey_location = undef, $sshd_config_authkey_location = undef,
$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_config_ciphers = undef,
$sshd_config_kexalgorithms = undef, $sshd_config_kexalgorithms = undef,
$sshd_config_macs = undef, $sshd_config_macs = undef,
$ssh_enable_ssh_keysign = undef, $ssh_enable_ssh_keysign = undef,
$sshd_config_allowgroups = [], $sshd_config_allowgroups = [],
$sshd_config_allowusers = [], $sshd_config_allowusers = [],
$sshd_config_denygroups = [], $sshd_config_denygroups = [],
$sshd_config_denyusers = [], $sshd_config_denyusers = [],
$sshd_config_maxauthtries = undef, $sshd_config_maxauthtries = undef,
$sshd_config_maxstartups = undef, $sshd_config_maxstartups = undef,
$sshd_config_maxsessions = undef, $sshd_config_maxsessions = undef,
$sshd_config_chrootdirectory = undef, $sshd_config_chrootdirectory = undef,
$sshd_config_forcecommand = undef, $sshd_config_forcecommand = undef,
$sshd_config_match = undef, $sshd_config_match = undef,
$sshd_authorized_keys_command = undef, $sshd_authorized_keys_command = undef,
$sshd_authorized_keys_command_user = undef, $sshd_authorized_keys_command_user = 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',
$sshd_banner_mode = '0644', $sshd_banner_mode = '0644',
$sshd_config_xauth_location = 'USE_DEFAULTS', $sshd_config_xauth_location = 'USE_DEFAULTS',
$sshd_config_subsystem_sftp = 'USE_DEFAULTS', $sshd_config_subsystem_sftp = 'USE_DEFAULTS',
$sshd_kerberos_authentication = undef, $sshd_kerberos_authentication = undef,
$sshd_password_authentication = 'yes', $sshd_password_authentication = 'yes',
$sshd_allow_tcp_forwarding = 'yes', $sshd_allow_tcp_forwarding = 'yes',
$sshd_x11_forwarding = 'yes', $sshd_x11_forwarding = 'yes',
$sshd_x11_use_localhost = 'yes', $sshd_x11_use_localhost = 'yes',
$sshd_use_pam = 'USE_DEFAULTS', $sshd_use_pam = 'USE_DEFAULTS',
$sshd_client_alive_count_max = '3', $sshd_client_alive_count_max = '3',
$sshd_client_alive_interval = '0', $sshd_client_alive_interval = '0',
$sshd_gssapiauthentication = 'yes', $sshd_gssapiauthentication = 'yes',
$sshd_gssapikeyexchange = 'USE_DEFAULTS', $sshd_gssapikeyexchange = 'USE_DEFAULTS',
$sshd_pamauthenticationviakbdint = 'USE_DEFAULTS', $sshd_pamauthenticationviakbdint = 'USE_DEFAULTS',
$sshd_gssapicleanupcredentials = 'USE_DEFAULTS', $sshd_gssapicleanupcredentials = 'USE_DEFAULTS',
$sshd_acceptenv = 'USE_DEFAULTS', $sshd_acceptenv = 'USE_DEFAULTS',
$sshd_config_hostkey = 'USE_DEFAULTS', $sshd_config_hostkey = 'USE_DEFAULTS',
$sshd_listen_address = undef, $sshd_listen_address = undef,
$sshd_hostbasedauthentication = 'no', $sshd_hostbasedauthentication = 'no',
$sshd_pubkeyacceptedkeytypes = undef, $sshd_pubkeyacceptedkeytypes = undef,
$sshd_pubkeyauthentication = 'yes', $sshd_pubkeyauthentication = 'yes',
$sshd_ignoreuserknownhosts = 'no', $sshd_ignoreuserknownhosts = 'no',
$sshd_ignorerhosts = 'yes', $sshd_ignorerhosts = 'yes',
$manage_service = true, $manage_service = true,
$sshd_addressfamily = 'USE_DEFAULTS', $sshd_addressfamily = 'USE_DEFAULTS',
$service_ensure = 'running', $service_ensure = 'running',
$service_name = 'USE_DEFAULTS', $service_name = 'USE_DEFAULTS',
$service_enable = true, $service_enable = true,
$service_hasrestart = true, $service_hasrestart = true,
$service_hasstatus = 'USE_DEFAULTS', $service_hasstatus = 'USE_DEFAULTS',
$ssh_key_ensure = 'present', $ssh_key_ensure = 'present',
$ssh_key_import = true, $ssh_key_import = true,
$ssh_key_type = 'ssh-rsa', $ssh_key_type = 'ssh-rsa',
$ssh_config_global_known_hosts_file = '/etc/ssh/ssh_known_hosts', $ssh_config_global_known_hosts_file = '/etc/ssh/ssh_known_hosts',
$ssh_config_global_known_hosts_list = undef, $ssh_config_global_known_hosts_list = undef,
$ssh_config_global_known_hosts_owner = 'root', $ssh_config_global_known_hosts_owner = 'root',
$ssh_config_global_known_hosts_group = 'root', $ssh_config_global_known_hosts_group = 'root',
$ssh_config_global_known_hosts_mode = '0644', $ssh_config_global_known_hosts_mode = '0644',
$ssh_config_user_known_hosts_file = undef, $ssh_config_user_known_hosts_file = undef,
$keys = undef, $keys = undef,
$manage_root_ssh_config = false, $manage_root_ssh_config = false,
$root_ssh_config_content = "# This file is being maintained by Puppet.\n# DO NOT EDIT\n", $root_ssh_config_content = "# This file is being maintained by Puppet.\n# DO NOT EDIT\n",
$sshd_config_tcp_keepalive = undef, $sshd_config_tcp_keepalive = undef,
$sshd_config_use_privilege_separation = undef, $sshd_config_use_privilege_separation = undef,
$sshd_config_permittunnel = undef, $sshd_config_permittunnel = undef,
$sshd_config_hostcertificate = undef, $sshd_config_hostcertificate = undef,
$sshd_config_trustedusercakeys = undef, $sshd_config_trustedusercakeys = undef,
$sshd_config_authorized_principals_file = undef,
) { ) {
case $::osfamily { case $::osfamily {
@ -500,6 +501,11 @@ class ssh (
default: { $sshd_config_trustedusercakeys_real = $sshd_config_trustedusercakeys } default: { $sshd_config_trustedusercakeys_real = $sshd_config_trustedusercakeys }
} }
case $sshd_config_authorized_principals_file {
'unset', undef: { $sshd_config_authorized_principals_file_real = undef }
default: { $sshd_config_authorized_principals_file_real = $sshd_config_authorized_principals_file }
}
# validate params # validate params
if $ssh_config_ciphers != undef { if $ssh_config_ciphers != undef {
validate_array($ssh_config_ciphers) validate_array($ssh_config_ciphers)
@ -839,6 +845,9 @@ class ssh (
} }
if $sshd_config_hostcertificate_real != undef { if $sshd_config_hostcertificate_real != undef {
if is_array($sshd_config_hostcertificate_real) {
validate_array($sshd_config_hostcertificate_real)
}
validate_absolute_path($sshd_config_hostcertificate_real) validate_absolute_path($sshd_config_hostcertificate_real)
} }
@ -849,6 +858,10 @@ class ssh (
} }
} }
if $sshd_config_authorized_principals_file_real != undef {
validate_string($sshd_config_authorized_principals_file_real)
}
package { $packages_real: package { $packages_real:
ensure => installed, ensure => installed,
source => $ssh_package_source_real, source => $ssh_package_source_real,

View File

@ -1068,26 +1068,48 @@ describe 'sshd_config_print_last_log param' do
end end
describe 'sshd_config_hostcertificate param' do describe 'sshd_config_hostcertificate param' do
['unset', '/etc/ssh/ssh_host_key-cert.pub'].each do |value| context 'unset value' do
context "set to #{value}" do let(:params) { { :sshd_config_hostcertificate => 'unset' } }
let (:params) { { :sshd_config_hostcertificate => value } }
if value == 'unset' it { should contain_file('sshd_config').without_content(/^\s*HostCertificate/) }
it { should contain_file('sshd_config').without_content(/^\s*HostCertificate/) } end
else
it { should contain_file('sshd_config').with_content(/^HostCertificate #{value}/) } context 'with a certificate' do
end let(:params) { { :sshd_config_hostcertificate => '/etc/ssh/ssh_host_key-cert.pub' } }
end
it { should contain_file('sshd_config').with_content(/^HostCertificate \/etc\/ssh\/ssh_host_key-cert\.pub/) }
end
context 'with multiple certs' do
let(:params) { { :sshd_config_hostcertificate => [ '/etc/ssh/ssh_host_key-cert.pub', '/etc/ssh/ssh_host_key-cert2.pub'] } }
it { should contain_file('sshd_config').with_content(/^HostCertificate \/etc\/ssh\/ssh_host_key-cert\.pub\nHostCertificate \/etc\/ssh\/ssh_host_key-cert2\.pub/)}
end end
end end
context 'with sshd_config_hostcertificate set to invalid value on valid osfamily' do context 'with sshd_config_hostcertificate set to invalid value on valid osfamily' do
let(:params) { { :sshd_config_hostcertificate => 'invalid' } } context 'with string' do
let(:params) { { :sshd_config_hostcertificate => 'invalid' } }
it 'should fail' do it 'should fail' do
expect { expect {
should contain_class('ssh') should contain_class('ssh')
}.to raise_error(Puppet::Error,/"invalid" is not an absolute path/) }.to raise_error(Puppet::Error,/"invalid" is not an absolute path/)
end
end
end
context 'with sshd_config_authorized_principals_file param' do
['unset', '.ssh/authorized_principals'].each do |value|
context "set to #{value}" do
let (:params) { { :sshd_config_authorized_principals_file => value } }
if value == 'unset'
it { should contain_file('sshd_config').without_content(/^\s*AuthorizedPrincipalsFile/)}
else
it { should contain_file('sshd_config').with_content(/^AuthorizedPrincipalsFile \.ssh\/authorized_principals/)}
end
end
end end
end end

View File

@ -263,9 +263,16 @@ Match <%= key %>
<% end -%> <% end -%>
<% end -%> <% end -%>
<% end -%> <% end -%>
<% if @sshd_config_hostcertificate_real -%> <% if @sshd_config_hostcertificate_real.class == Array -%>
<% @sshd_config_hostcertificate_real.each do |cert| -%>
HostCertificate <%= cert %>
<% end -%>
<% elsif @sshd_config_hostcertificate_real.class == String -%>
HostCertificate <%= @sshd_config_hostcertificate_real %> HostCertificate <%= @sshd_config_hostcertificate_real %>
<% end -%> <% end -%>
<% if @sshd_config_trustedusercakeys_real -%> <% if @sshd_config_trustedusercakeys_real -%>
TrustedUserCAKeys <%= @sshd_config_trustedusercakeys_real %> TrustedUserCAKeys <%= @sshd_config_trustedusercakeys_real %>
<% end -%> <% end -%>
<% if @sshd_config_authorized_principals_file_real -%>
AuthorizedPrincipalsFile <%= @sshd_config_authorized_principals_file_real %>
<% end -%>