From 5e2b5d658680cea02fba37df8848fc7db30aac19 Mon Sep 17 00:00:00 2001 From: Anthony Garratt Date: Tue, 24 Jun 2025 14:54:01 +0200 Subject: [PATCH] windows compatibility (#414) windows-compatibility - remove mentions of `ssh::server::manage_config_permissions` windows compatibility - fix tests windows compatibility - review suggestions - update `REFERENCE.md` windows compatibility - review suggestions - fix "selector inside resource block" windows compatibility - review suggestions - fix "selector inside resource block"; proper indentation windows compatibility - review suggestions - proper indentation windows compatibility - review suggestions - inline variable where it's only used once Co-authored-by: Steffen Zieger windows compatibility - review suggestions - demand string content Co-authored-by: Steffen Zieger windows compatibility - review suggestions - remove unnecessary check Co-authored-by: Steffen Zieger windows compatibility - apply review suggestions Co-authored-by: Steffen Zieger windows compatibility - remove same-value copy-pasta from hiera data files windows compatibility - update `REFERENCE.md` windows compatibility - parameter docs windows compatibility - fix permissions according to fresh install windows compatibility - clean up windows compatibility - fix `ssh::server::manage_config_permissions` windows compatibility - update windows example windows compatibility - make file ownership configurable windows compatibility - let fact also parse on windows windows compatibility - add compability support-statement to metadata.json windows compatibility - make file ownership configurable; provide example for setup on windows --- README.md | 122 +++++++++++++++++++++++++++++++ lib/facter/ssh_server_version.rb | 6 +- metadata.json | 3 + 3 files changed, 128 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2f012953..f4db734f 100644 --- a/README.md +++ b/README.md @@ -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 +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 diff --git a/lib/facter/ssh_server_version.rb b/lib/facter/ssh_server_version.rb index e18327c4..cd2fa293 100644 --- a/lib/facter/ssh_server_version.rb +++ b/lib/facter/ssh_server_version.rb @@ -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') @@ -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') diff --git a/metadata.json b/metadata.json index a9338916..09c49f33 100644 --- a/metadata.json +++ b/metadata.json @@ -101,6 +101,9 @@ }, { "operatingsystem": "AIX" + }, + { + "operatingsystem": "Windows" } ], "requirements": [