diff --git a/README.md b/README.md index 897cd8ee..e0fb0058 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ Source: https://github.com/saz/puppet-ssh * puppetlabs/stdlib * puppetlabs/concat +For Windows: +* puppetlabs/chocolatey (configured externally) +* At least Puppet 5.5.1 (due to a bug with templates in earlier versions) + ## Usage Since version 2.0.0 only non-default values are written to both, @@ -369,3 +373,16 @@ ssh_server_version_full => 6.6.1p1 ssh_server_version_major => 6.6 ssh_server_version_release => 6.6.1 ``` + +## Special note about Windows support + +Support for Windows is semi experimental at present. There are definite possibilities +that some options do not currently work correctly. + +It is based on the following project: + +This product is installed via Chocolatey and the package definition +can be found here: + +SSHD server support is assumed, so this module installs the server features regardless +of whether you intend to only use the client. diff --git a/lib/puppet/functions/ssh/ipaddresses.rb b/lib/puppet/functions/ssh/ipaddresses.rb index 466647a3..fb33a709 100644 --- a/lib/puppet/functions/ssh/ipaddresses.rb +++ b/lib/puppet/functions/ssh/ipaddresses.rb @@ -15,7 +15,7 @@ def ipaddresses(excluded_interfaces = []) facts = closure_scope['facts'] # always exclude loopback interface - excluded_interfaces += ['lo'] + excluded_interfaces += %w[lo lo0] result = [] facts['networking']['interfaces'].each do |iface, data| @@ -26,7 +26,10 @@ def ipaddresses(excluded_interfaces = []) next unless data.key?(binding_type) data[binding_type].each do |binding| next unless binding.key?('address') - result << binding['address'] + result << binding['address'].sub(%r{%.*$}, '') + # Note: This sub is a workaround for Facter under Windows doing this: + # facter -p ipaddress6 + # fe80::18fa:a970:c261:1cd8%3 end end end diff --git a/manifests/client/config.pp b/manifests/client/config.pp index 5aa1f0fb..4707f700 100644 --- a/manifests/client/config.pp +++ b/manifests/client/config.pp @@ -8,9 +8,9 @@ } else { file { $ssh::params::ssh_config: ensure => present, - owner => '0', - group => '0', - mode => '0644', + owner => $ssh::params::cfg_file_owner, + group => $ssh::params::cfg_file_group, + mode => $ssh::params::cfg_file_mode, content => template("${module_name}/ssh_config.erb"), require => Class['ssh::client::install'], } diff --git a/manifests/client/config/user.pp b/manifests/client/config/user.pp index 04c1f814..a01db756 100644 --- a/manifests/client/config/user.pp +++ b/manifests/client/config/user.pp @@ -20,8 +20,9 @@ $_target = $target } else { if ($user_home_dir == undef) { - $_user_home_dir = "/home/${user}" - } else { + $_user_home_dir = "${::ssh::params::home_dir_path}/${name}" + } + else { $_user_home_dir = $user_home_dir } diff --git a/manifests/client/install.pp b/manifests/client/install.pp index 11f0d2bd..9c412248 100644 --- a/manifests/client/install.pp +++ b/manifests/client/install.pp @@ -1,5 +1,10 @@ class ssh::client::install { if $ssh::params::client_package_name { - ensure_packages([$ssh::params::client_package_name], {'ensure' => $ssh::client::ensure}) + ensure_packages([$ssh::params::client_package_name], { + 'ensure' => $ssh::client::ensure, + 'provider' => $ssh::params::package_provider, + 'install_options' => $ssh::params::package_install_options, + 'uninstall_options' => $ssh::params::package_uninstall_options, + }) } } diff --git a/manifests/knownhosts.pp b/manifests/knownhosts.pp index cd7cf583..505ad1a8 100644 --- a/manifests/knownhosts.pp +++ b/manifests/knownhosts.pp @@ -13,9 +13,13 @@ ) inherits ssh::params { if ($collect_enabled) { if $storeconfigs_group { - Sshkey <<| tag == "hostkey_${storeconfigs_group}" |>> + Sshkey <<| tag == "hostkey_${storeconfigs_group}" |>> { + target => $ssh::params::ssh_known_hosts, + } } else { - Sshkey <<| |>> + Sshkey <<| |>> { + target => $ssh::params::ssh_known_hosts, + } } } } diff --git a/manifests/params.pp b/manifests/params.pp index 5b4b6c17..08731c50 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -7,82 +7,204 @@ case $::osfamily { 'Debian': { $server_package_name = 'openssh-server' + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = 'openssh-client' - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'ssh' $sftp_server_path = '/usr/lib/openssh/sftp-server' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' } 'RedHat': { $server_package_name = 'openssh-server' + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = 'openssh-clients' - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'sshd' $sftp_server_path = '/usr/libexec/openssh/sftp-server' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' if versioncmp($::operatingsystemmajrelease, '7') >= 0 { $host_priv_key_group = 'ssh_keys' } else { $host_priv_key_group = 0 } + $host_priv_key_mode = '0600' } 'FreeBSD', 'DragonFly': { $server_package_name = undef + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = undef - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'sshd' $sftp_server_path = '/usr/libexec/sftp-server' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' } 'OpenBSD': { $server_package_name = undef + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = undef - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'sshd' $sftp_server_path = '/usr/libexec/sftp-server' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' } 'Darwin': { $server_package_name = undef + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = undef - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'com.openssh.sshd' $sftp_server_path = '/usr/libexec/sftp-server' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' + } + 'windows': { + $server_package_name = 'openssh' + $client_package_name = 'openssh' + $package_install_options = ['-params', '""/SSHServerFeature""'] + $package_uninstall_options = ['-params','""/SSHServerFeature""'] + $package_provider = 'chocolatey' + $home_dir_path = 'C:/Users' + if $::architecture == 'x64' { + $sshd_exe_dir = 'C:/Program Files/OpenSSH-Win64' + } + else { + $sshd_exe_dir = 'C:/Program Files/OpenSSH-Win32' + } + $sshd_path = "${sshd_exe_dir}/sshd.exe" + $ssh_cfg_dir = 'C:/ProgramData/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" + $service_name = 'sshd' + $sftp_server_path = 'sftp-server.exe' + $cfg_file_owner = 'Administrators' + $cfg_file_group = 'Users' + $cfg_file_mode = '0755' + $cfg_priv_file_mode = '0750' + $host_key_owner = 'Administrators' + $host_key_group = 'NT SERVICE\SSHD' + $host_key_mode = '0755' + $host_priv_key_group = 'NT SERVICE\SSHD' + $host_priv_key_mode = '0750' + } 'ArchLinux': { $server_package_name = 'openssh' + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = 'openssh' - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'sshd.service' $sftp_server_path = '/usr/lib/ssh/sftp-server' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' } 'Suse': { $server_package_name = 'openssh' + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = 'openssh' - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' case $::operatingsystem { 'SLES': { $service_name = 'sshd' @@ -113,23 +235,49 @@ case $::operatingsystem { 'SmartOS': { $server_package_name = undef + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = undef - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'svc:/network/ssh:default' $sftp_server_path = 'internal-sftp' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' } default: { - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'svc:/network/ssh:default' $sftp_server_path = 'internal-sftp' + $package_install_options = undef + $package_uninstall_options = undef + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' case versioncmp($::kernelrelease, '5.10') { 1: { # Solaris 11 and later @@ -153,25 +301,51 @@ case $::operatingsystem { 'Gentoo': { $server_package_name = 'openssh' + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = 'openssh' - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'sshd' $sftp_server_path = '/usr/lib/misc/sftp-server' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' } 'Amazon': { $server_package_name = 'openssh-server' + $package_install_options = undef + $package_uninstall_options = undef $client_package_name = 'openssh-clients' - $sshd_dir = '/etc/ssh' - $sshd_config = '/etc/ssh/sshd_config' - $ssh_config = '/etc/ssh/ssh_config' - $ssh_known_hosts = '/etc/ssh/ssh_known_hosts' + $package_provider = undef + $home_dir_path = '/home' + $sshd_path = '/usr/sbin/sshd' + $ssh_cfg_dir = '/etc/ssh' + $sshd_config = "${ssh_cfg_dir}/sshd_config" + $ssh_config = "${ssh_cfg_dir}/ssh_config" + $ssh_known_hosts = "${ssh_cfg_dir}/ssh_known_hosts" $service_name = 'sshd' $sftp_server_path = '/usr/libexec/openssh/sftp-server' + $cfg_file_owner = 0 + $cfg_file_group = 0 + $cfg_file_mode = '0644' + $cfg_priv_file_mode = '0600' + $host_key_owner = 0 + $host_key_group = 0 + $host_key_mode = '0644' $host_priv_key_group = 0 + $host_priv_key_mode = '0600' } default: { fail("Unsupported platform: ${::osfamily}/${::operatingsystem}") @@ -183,6 +357,7 @@ # ssh & sshd default options: # - OpenBSD doesn't know about UsePAM # - Sun_SSH doesn't know about UsePAM & AcceptEnv; SendEnv & HashKnownHosts + # - Windows doesn't know about UsePAM & override host key paths case $::osfamily { 'OpenBSD': { $sshd_default_options = { @@ -206,12 +381,21 @@ 'PrintMotd' => 'no', 'Subsystem' => "sftp ${sftp_server_path}", 'HostKey' => [ - "${sshd_dir}/ssh_host_rsa_key", - "${sshd_dir}/ssh_host_dsa_key", + "${ssh_cfg_dir}/ssh_host_rsa_key", + "${ssh_cfg_dir}/ssh_host_dsa_key", ], } $ssh_default_options = { } } + 'windows': { + $sshd_default_options = { + 'AuthorizedKeysFile' => '.ssh/authorized_keys', + 'LogLevel' => 'QUIET', + 'Subsystem' => "sftp ${sftp_server_path}", + 'hostkeyagent' => '\\\\.\pipe\openssh-ssh-agent', + } + $ssh_default_options = { } + } default: { $sshd_default_options = { 'ChallengeResponseAuthentication' => 'no', diff --git a/manifests/server/config.pp b/manifests/server/config.pp index 97dc5ce3..3ffcf777 100644 --- a/manifests/server/config.pp +++ b/manifests/server/config.pp @@ -8,7 +8,7 @@ case $ssh::server::validate_sshd_file { true: { - $sshd_validate_cmd = '/usr/sbin/sshd -tf %' + $sshd_validate_cmd = "${ssh::params::sshd_path} -tf %" } default: { $sshd_validate_cmd = undef @@ -20,9 +20,9 @@ } else { concat { $ssh::params::sshd_config: ensure => present, - owner => 0, - group => 0, - mode => '0600', + owner => $ssh::params::cfg_file_owner, + group => $ssh::params::cfg_file_group, + mode => $ssh::params::cfg_priv_file_mode, validate_cmd => $sshd_validate_cmd, notify => Service[$ssh::params::service_name], } @@ -37,9 +37,9 @@ if $::ssh::server::use_issue_net { file { $ssh::params::issue_net: ensure => present, - owner => 0, - group => 0, - mode => '0644', + owner => $ssh::params::cfg_file_owner, + group => $ssh::params::cfg_file_group, + mode => $ssh::params::cfg_file_mode, content => template("${module_name}/issue.net.erb"), notify => Service[$ssh::params::service_name], } diff --git a/manifests/server/host_key.pp b/manifests/server/host_key.pp index 45a4d857..c5bc0437 100644 --- a/manifests/server/host_key.pp +++ b/manifests/server/host_key.pp @@ -86,10 +86,10 @@ if $ensure == 'present' { file {"${name}_pub": ensure => $ensure, - owner => 0, - group => 0, - mode => '0644', - path => "${::ssh::params::sshd_dir}/${name}.pub", + owner => $::ssh::params::host_key_owner, + group => $::ssh::params::host_key_group, + mode => $::ssh::params::host_key_mode, + path => "${::ssh::params::ssh_cfg_dir}/${name}.pub", source => $manage_pub_key_source, content => $manage_pub_key_content, notify => Class['ssh::server::service'], @@ -97,10 +97,10 @@ file {"${name}_priv": ensure => $ensure, - owner => 0, + owner => $::ssh::params::host_key_owner, group => $::ssh::params::host_priv_key_group, - mode => '0600', - path => "${::ssh::params::sshd_dir}/${name}", + mode => $::ssh::params::host_priv_key_mode, + path => "${::ssh::params::ssh_cfg_dir}/${name}", source => $manage_priv_key_source, content => $manage_priv_key_content, show_diff => false, @@ -109,19 +109,19 @@ } else { file {"${name}_pub": ensure => $ensure, - owner => 0, - group => 0, - mode => '0644', - path => "${::ssh::params::sshd_dir}/${name}.pub", + owner => $::ssh::params::host_key_owner, + group => $::ssh::params::host_key_group, + mode => $::ssh::params::host_key_mode, + path => "${::ssh::params::ssh_cfg_dir}/${name}.pub", notify => Class['ssh::server::service'], } file {"${name}_priv": ensure => $ensure, - owner => 0, + owner => $::ssh::params::host_key_owner, group => $::ssh::params::host_priv_key_group, - mode => '0600', - path => "${::ssh::params::sshd_dir}/${name}", + mode => $::ssh::params::host_priv_key_mode, + path => "${::ssh::params::ssh_cfg_dir}/${name}", show_diff => false, notify => Class['ssh::server::service'], } @@ -131,10 +131,10 @@ if $ensure == 'present' { file {"${name}_cert": ensure => $ensure, - owner => 0, - group => 0, - mode => '0644', - path => "${::ssh::params::sshd_dir}/${name}-cert.pub", + owner => $::ssh::params::host_key_owner, + group => $::ssh::params::host_key_group, + mode => $::ssh::params::host_key_mode, + path => "${::ssh::params::ssh_cfg_dir}/${name}-cert.pub", source => $manage_cert_source, content => $manage_cert_content, notify => Class['ssh::server::service'], @@ -142,10 +142,10 @@ } else { file {"${name}_cert": ensure => $ensure, - owner => 0, - group => 0, - mode => '0644', - path => "${::ssh::params::sshd_dir}/${name}-cert.pub", + owner => $::ssh::params::host_key_owner, + group => $::ssh::params::host_key_group, + mode => $::ssh::params::host_key_mode, + path => "${::ssh::params::ssh_cfg_dir}/${name}-cert.pub", notify => Class['ssh::server::service'], } } diff --git a/manifests/server/install.pp b/manifests/server/install.pp index 5ab1e83c..cdf15174 100644 --- a/manifests/server/install.pp +++ b/manifests/server/install.pp @@ -6,9 +6,11 @@ class ssh::server::install { include ::ssh::params if $ssh::params::server_package_name { - ensure_packages( - [$ssh::params::server_package_name], - { 'ensure' => $ssh::server::ensure } - ) + ensure_packages([$ssh::params::server_package_name], { + 'ensure' => $ssh::server::ensure, + 'provider' => $ssh::params::package_provider, + 'install_options' => $ssh::params::package_install_options, + 'uninstall_options' => $ssh::params::package_uninstall_options, + }) } }