Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,128 @@ ssh::hostkeys::exclude_ipaddresses:
- 10.42.24.242
```

## Windows

This module also has support for the Windows Capability ("Optional Feature") `OpenSSH.Server`. Other ways regarding the installation and configuration of sshd on windows might just work (e.g. chocholatey), but have not been tested so far and could thus require modifications.

`data/osfamily/windows.yaml` could look like follows:

```yaml
---
ssh::server::server_package_name: null
ssh::client::client_package_name: null
ssh::server::sshd_dir: 'C:\ProgramData\ssh'
ssh::server::sshd_binary: 'C:\Windows\System32\OpenSSH\sshd.exe'
ssh::server::sshd_config: 'C:\ProgramData\ssh\sshd_config'
ssh::server::sshd_config_mode: '0700'
ssh::server::sshd_environments_file: null
ssh::client::ssh_config: 'C:\ProgramData\ssh\ssh_config'
ssh::server::service_name: 'sshd'
ssh::sftp_server_path: 'C:\Windows\System32\OpenSSH\sftp-server.exe'
ssh::client::config_user: 'BUILTIN\Administrators'
ssh::client::config_group: 'Administrator'
ssh::server::config_user: null
ssh::server::config_group: null
Comment on lines +404 to +405
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my original proposition, I had the additional option ssh::server::manage_config_permissions which allowed me to skip setting owner and group properties for the file and concat resources. @saz, are you able to tell me, whether it is possible to use null here instead? As far as I remember, the Microsoft OpenSSH Feature sets the required permissions itself, and overwriting them caused issues.

I might be able to test it next week, but I can't guarantee, because I'm currently working on other things. I'd also have to find out how to use puppet environments I guess.

  $config_file_ownership = $ssh::server::manage_config_permissions ? {
    false   => {},
    default => {
      owner => $ssh::server::config_user,
      group => $ssh::server::config_group,
    }
  }
    file { $ssh::server::include_dir:
      ensure  => directory,
      *       => $config_file_ownership,
      mode    => $ssh::server::include_dir_mode,
      purge   => $ssh::server::include_dir_purge,
      recurse => $ssh::server::include_dir_purge,
    }

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've intentionally left this part out, as it wouldn't be required by any supported OS right now.

I suggest that this should be part of your PR.

For the testing part: I'm not able to help here, as I don't run Windows, but take your time to validate, that things are working properly.

ssh::server::host_priv_key_user: 'BUILTIN\Administrators'
ssh::server::host_priv_key_group: 'NT AUTHORITY\SYSTEM'
```

To correctly set the file permissions, the [`puppetlabs-acl`-puppet module](https://forge.puppetlabs.com/modules/puppetlabs/acl) is required. Remove the unsupported `UsePAM`-sshd config option.

One can optionally set the default shell when connecting through ssh, e.g. to powershell. For this, the [`puppetlabs-registry`-puppet module](https://forge.puppet.com/modules/puppetlabs/registry) is required.

```puppet
$sshd_dir = lookup('ssh::server::sshd_dir')
$sshd_config = lookup('ssh::server::sshd_config')
$config_user = lookup('ssh::server::config_user')
$config_group = lookup('ssh::server::config_group')

$os_family = $facts['os']['family']

$os_specific_path_separator = $os_family ? {
'windows' => '\\',
default => '/',
}

$host_key_paths = [
"${sshd_dir}${os_specific_path_separator}ssh_host_ed25519_key",
"${sshd_dir}${os_specific_path_separator}ssh_host_rsa_key",
"${sshd_dir}${os_specific_path_separator}ssh_host_ecdsa_key",
]

if $os_family == 'windows' {
exec { 'install_openssh_server':
command => 'Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0',
provider => powershell,
unless => 'if ((Get-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0).State -eq "Installed") { echo 0 } else { exit 1 }',
logoutput => true,
before => Class['ssh::server'],
}

$initialize_sshd_command = @(EOT)
Write-Output "Initializing SSHD service..."
Start-Service -Name 'sshd'
Start-Sleep -Seconds 5
$status = Get-Service -Name 'sshd'
Write-Output "Service status: $($status.Status)"
Stop-Service -Name 'sshd'
Write-Output "SSHD service initialization completed"
| EOT

# this is required, so that sshd creates all directories and files by itself and sets the appropriate permissions
exec { 'initialize_sshd':
command => $initialize_sshd_command,
provider => powershell,
creates => $host_key_paths,
logoutput => true,
require => Exec['install_openssh_server'],
before => Class['ssh::server'],
}

acl { $sshd_config:
permissions => [
{
identity => $config_group,
rights => ['full'],
perm_type => 'allow',
},
{
identity => $config_user,
rights => ['full'],
perm_type => 'allow',
},
],
inherit_parent_permissions => false,
purge => true,
require => Class['ssh::server::config'],
before => Class['ssh::server::service'],
}

registry::value { 'set_powershell_as_default_ssh_shell':
key => 'HKLM:\SOFTWARE\OpenSSH',
name => 'DefaultShell',
type => 'string',
data => 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe',
require => Exec['install_openssh_server'],
}
}

$os_specific_ssh_options = $os_family ? {
'windows' => {
'UsePAM' => undef,
},
default => {},
}

class { 'ssh::server':
storeconfigs_enabled => false,
validate_sshd_file => true,
options => {
# ...
} + $os_specific_ssh_options,
}
```

## Facts

This module provides facts detailing the available SSH client and server
Expand Down
6 changes: 3 additions & 3 deletions lib/facter/ssh_server_version.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

Facter.add('ssh_server_version_full') do
confine kernel: %w[Linux SunOS FreeBSD DragonFly Darwin]
confine kernel: %w[Linux SunOS FreeBSD DragonFly Darwin windows]

setcode do
if Facter::Util::Resolution.which('sshd')
Expand All @@ -15,13 +15,13 @@
first.
rstrip

version&.gsub(%r{^(OpenSSH_|Sun_SSH_)([^ ,]+).*$}, '\2')
version&.gsub(%r{^(OpenSSH_for_Windows_|OpenSSH_|Sun_SSH_)([^ ,]+).*$}, '\2')
end
end
end

Facter.add('ssh_server_version_major') do
confine kernel: %w[Linux SunOS FreeBSD DragonFly DragonFly Darwin]
confine kernel: %w[Linux SunOS FreeBSD DragonFly DragonFly Darwin windows]
confine ssh_server_version_full: %r{\d+}
setcode do
version = Facter.value('ssh_server_version_full')
Expand Down
3 changes: 3 additions & 0 deletions metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
},
{
"operatingsystem": "AIX"
},
{
"operatingsystem": "Windows"
}
],
"requirements": [
Expand Down