From 55d9ac75aae354b7560ca1cbdb22bf974ccc3d4a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 19 Mar 2022 09:49:48 +0100 Subject: [PATCH] Updates doc for better structure --- README.md | 110 +-------------------------- docs/00-General.md | 27 +++++++ docs/01-Installation.md | 70 ++++++++++++++++++ docs/02-WinRM_config.md | 160 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 258 insertions(+), 109 deletions(-) create mode 100644 docs/00-General.md create mode 100644 docs/01-Installation.md create mode 100644 docs/02-WinRM_config.md diff --git a/README.md b/README.md index 4f4f56a..215e9d7 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ For easier usage, the plugin is designed to work as replacement for the `PowerSh ## Usage -``` +```text Arguments: -C, -Command string The Icinga for Windows command being executed on the target machine -WindowsUser string Username of the remote host @@ -29,114 +29,6 @@ Arguments: | 'free_space_partition_s'=1855056000000B;;;0;1999841000000 'free_space_partition_i'=799003800000B;;;0;2199021000000 'free_space_partition_c'=442423800000B;;;0;478964400000 'free_space_partition_t'=102553700000B;;;0;107237900000 ``` -## Installing PowerShell on Linux - -You can find a guide on how to install PowerShell on Linux on the [Microsoft Documentation](https://docs.microsoft.com/de-de/powershell/scripting/install/installing-powershell-on-linux). - -## Troubleshooting - -On some systems you can run into the below errors, with guides on how to resolve them - -### Unspecified GSS failure - -Connecting to remote server windows.example.com failed with the following error message : acquiring creds with username only failed Unspecified GSS failure. Minor code may provide more information SPNEGO cannot find mechanisms to negotiate For more information, see the about_Remote_Troubleshooting Help topic. - -**Solution**: Install the package `gssntlmssp` for your distribution - -#### RedHat/CentOS/Fedora - -```bash -sudo yum install gssntlmssp -y -``` - -#### Debian/Ubuntu - -```bash -sudo apt install gss-ntlmssp -y -``` - -### WSMan client library was not found - -This parameter set requires WSMan, and no supported WSMan client library was found. WSMan is either not installed or unavailable for this system. - -**Solution**: Install WSMan by using PowerShell on Linux - -```powershell -pwsh -Command 'Install-Module -Name PSWSMan' -sudo pwsh -Command 'Install-WSMan' -``` - -### NTML authentication not working - -MI_RESULT_ACCESS_DENIED is returned while using the plugin - -**Solution**: Use `Negotiate` method (which the plugin defaults to) for authentication - -## Preparing the Windows machine - -By default, WinRM is not enabled, and if enabled, will only allow Kerberos authentication. WinRM can be configured in many ways, to allow connections by HTTP or HTTPs. - -Best practice would be to configure WinRM with a TLS certificate, signed by the PKI of the Active Directory domain, and using NTLM auth to access the systems. - -Anything you configure via cmd or powershell needs to be run from an administrative shell. - -We start with the minimal setup of enabling WinRM and raising the memory limit: - -```powershell -winrm quickconfig -winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}' -``` - -### Setting up a HTTPS / TLS listener - -Make sure to install the certificate in the local machine cert store. This example is using PowerShell. - -WinRM HTTPS requires a local computer "Server Authentication" certificate with a CN matching the hostname, that is not expired, revoked, or self-signed to be installed. - -```powershell -# Find the cert -Get-ChildItem -Path cert:\LocalMachine\My -Recurse; - -# Put the thumbprint here or script it otherwise -$CertThumbprint = 'cert_thumbprint'; - -# Allow PS-Remote configuration -Enable-PSRemoting -SkipNetworkProfileCheck -Force; - -# (optional) Disable HTTP transport for PS-Remoting to ensure encryption -Get-ChildItem WSMan:\Localhost\listener | Where-Object Keys -eq "Transport=HTTP" | Remove-Item -Recurse; - -# Set the HTTPS Transport with our provided Thumbprint for the SSL certificate -New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $CertThumbprint -Force; - -# Set Firewall Rule for allowing communication -New-NetFirewallRule -DisplayName "Windows Remote Management (HTTPS-In)" ` - -Name "Windows Remote Management (HTTPS-In)" -Profile Any -LocalPort 5986 -Protocol TCP; - -# Enable the HTTPS listener -Set-Item WSMan:\localhost\Service\EnableCompatibilityHttpsListener -Value true; - -# Disable possible old HTTP firewall rules (names language specific) -Disable-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)"; -Disable-NetFirewallRule -DisplayName "Windows-Remoteverwaltung (HTTP eingehend)"; - -# (optional) You can configure hosts that are allowed to connect to WinRM -winrm set winrm/config/client '@{TrustedHosts="*"}'; - -Restart-Service winrm; -``` - -If it's necessary to use a self-signed-certificate, you can follow the -[guide on visualstudiogeeks.com](https://www.visualstudiogeeks.com/devops/how-to-configure-winrm-for-https-manually). - -### Enabling Basic Auth - -Basic auth can be used as fallback for NTLM, but will require a local account on each machine. - -```powershell -winrm set winrm/config/service/Auth '@{Basic="true"}' -``` - ## Contributing The check_by_icingaforwindows plugin is an Open Source project and lives from your contributions. No matter whether these are feature requests, issues, translations, documentation or code. diff --git a/docs/00-General.md b/docs/00-General.md new file mode 100644 index 0000000..caf0cf6 --- /dev/null +++ b/docs/00-General.md @@ -0,0 +1,27 @@ +# General information for check_by_icingaforwindows + +This plugin is intended as Icinga for Windows remote execution connector from Linux based systems by using WinRM. WinRM (Windows Remote Management), allows for remote connections from different systems, to access the Windows command line. + +## Requirements + +* Installed [PowerShell for Linux](https://docs.microsoft.com/de-de/powershell/scripting/install/installing-powershell-on-linux) +* Configured WinRM service on the Windows machines +* [Icinga for Windows](https://icinga.com/docs/icinga-for-windows/latest/) >=1.8.0 installed on the Windows machines + +## Plugin Installation + +To install this plugin, you simply require to copy the `check_by_icingaforwindows.ps1` to your base plugin directory on your Icinga machine (e.g. `/usr/lib64/nagios/plugins/`). + +For detailed instructions, please follow the [Installation](01-Installation.md) guide. + +## WinRM Installation + +On some systems, WinRM might not be enabled by default. Please have a look on the [WinRM config](02-WinRM_config.md) section, in case you require to install it. + +## WinRM Security + +By default, WinRM will listen on a HTTP socket for incoming connections on port `5985`. Even though this is a HTTP connection, WinRM based connections are not plain text and always encrypted, unless explicitly specified to allow unencrypted connections *which you should never enable*. + +You can add more security to the encryption by using HTTPS instead of HTTP, which requires a trusted and signed TLS certificate. The [WinRM config](02-WinRM_config.md) section covers, on how to setup and install WinRM by using TLS. + +**Note:** On some Linux systems and depending on your environment, it might not be able to connect from Linux to WinRM by using TLS, as the authentication request is not properly passed through. Therefor, even while more secure, we would not advice to rely on WinRM over TLS connections and stick to the default behaviour by using HTTP sockets. diff --git a/docs/01-Installation.md b/docs/01-Installation.md new file mode 100644 index 0000000..70383ef --- /dev/null +++ b/docs/01-Installation.md @@ -0,0 +1,70 @@ +# Install check_by_icingaforwindows + +## Install the Plugin + +To install this plugin, you simply require to copy the `check_by_icingaforwindows.ps1` to your base plugin directory on your Icinga machine (e.g. `/usr/lib64/nagios/plugins/`). + +In addition to that, make the plugin executable + +```bash +chmod +x /usr/lib64/nagios/plugins/check_by_icingaforwindows.ps1 +``` + +## Installing PowerShell on Linux + +You can find a guide on how to install PowerShell on Linux on the [Microsoft Documentation](https://docs.microsoft.com/de-de/powershell/scripting/install/installing-powershell-on-linux). + +## Troubleshooting + +On some systems you can run into the below errors, with guides on how to resolve them + +### Unspecified GSS failure + +Connecting to remote server windows.example.com failed with the following error message : acquiring creds with username only failed Unspecified GSS failure. Minor code may provide more information SPNEGO cannot find mechanisms to negotiate For more information, see the about_Remote_Troubleshooting Help topic. + +**Solution**: Install the package `gssntlmssp` for your distribution + +#### RedHat/CentOS/Fedora + +```bash +sudo yum install epel-release -y +sudo yum install gssntlmssp -y +``` + +#### Debian/Ubuntu + +```bash +sudo apt install gss-ntlmssp -y +``` + +### WSMan client library was not found + +This parameter set requires WSMan, and no supported WSMan client library was found. WSMan is either not installed or unavailable for this system. + +**Solution**: Install WSMan by using PowerShell on Linux + +```powershell +pwsh -Command 'Install-Module -Name PSWSMan' +sudo pwsh -Command 'Install-WSMan' +``` + +### SSL Error on Authentication + +In some cases you will receive the following error: + +```bash +pwsh: symbol lookup error: /opt/microsoft/powershell/7/libmi.so: undefined symbol: SSL_library_init +``` + +**Solution**: Install WSMan + +```powershell +pwsh -Command 'Install-Module -Name PSWSMan' +sudo pwsh -Command 'Install-WSMan' +``` + +### NTML authentication not working + +MI_RESULT_ACCESS_DENIED is returned while using the plugin + +**Solution**: Use `Negotiate` method (which the plugin defaults to) for authentication diff --git a/docs/02-WinRM_config.md b/docs/02-WinRM_config.md new file mode 100644 index 0000000..1c39ffd --- /dev/null +++ b/docs/02-WinRM_config.md @@ -0,0 +1,160 @@ +# Configuring WinRM on Windows + +In order to be able to execute plugins by using `check_by_icingaforwindows`, we have to enable PowerShell remote by configuring `WinRM` (Windows Remote-Management). + +## Preparing the Windows machine + +By default, WinRM is most likely not enabled, and if enabled, will only allow Kerberos authentication. WinRM can be configured in many ways, to allow connections by HTTP or HTTPS. + +Even by using HTTP as connection protocol, your communication is encrypted and **not** transmitted plain text. For more security, you can enable the HTTPS listener, by using a TLS certificate. More details on how to setup this, are listed below. + +**Note:** On some Linux systems and depending on your environment, it might not be able to connect from Linux to WinRM by using TLS, as the authentication request is not properly passed through. Therefor, even while more secure, we would not advice to rely on WinRM over TLS connections and stick to the default behaviour by using HTTP sockets. + +Anything you configure via cmd or powershell needs to be run from an administrative shell. + +## WinRM quickconfig + +If you have not yet configured `WinRM` on the system, you can use the `quickconfig` setting to get the basic configuration done: + +```powershell +winrm quickconfig +winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="2048"}' +``` + +`MaxMemoryPerShellMB` ensures that we will not run out of memory for executing our commands. For Icinga for Windows, we recommend at least `2GB` of memory per shell. + +## Enable PowerShell Remoting + +Even though `winrm quickconfig` should be enough, it can sometimes be required to explicitly enable PowerShell remote: + +```powershell +Enable-PSRemoting -SkipNetworkProfileCheck -Force; +``` + +**Note:** On newer Windows machines, WinRM and PowerShell remote might already be enabled + +## Allow Specific Hosts only (optional) + +We can limit the access to our machine by adding a list of hosts that are allowed to connect. To allow every host, we can use `*`: + +```powershell +# (optional) You can configure hosts that are allowed to connect to WinRM +winrm set winrm/config/client '@{TrustedHosts="*"}'; +``` + +## Enabling Basic Auth (optional) + +Basic auth can be enabled and used as fallback for NTLM, but will require a local account on each machine. You can enable it with: + +```powershell +winrm set winrm/config/service/Auth '@{Basic="true"}' +``` + +## Setting up HTTPS Listener + +While PowerShell remote might be enabled by default, it is most likely that it only listens on HTTP. Therefor we could setup a HTTPS listener with a TLS certificate, for increased encryption and security. + +We can either use a certificate provided by our domain or use the local host certificate used by `Remote Desktop`. + +WinRM HTTPS requires a local computer `Server Authentication` certificate with a CN matching the hostname, that is not expired, revoked, or self-signed to be installed. + +**Note:** On some Linux systems and depending on your environment, it might not be able to connect from Linux to WinRM by using TLS, as the authentication request is not properly passed through. Therefor, even while more secure, we would not advice to rely on WinRM over TLS connections and stick to the default behaviour by using HTTP sockets. + +### Own Certificate + +To use an own certificate, you have to install it inside the `Cert:\LocalMachine\My` location of the `Cert Store`. You then have to note the `thumbprint` of the certificate for later use. + +You can write it into a variable as follows + +```powershell +$CertThumbprint = 'cert_thumbprint'; +``` + +For creating self signed certificates, please have a look on the [guide on visualstudiogeeks.com](https://www.visualstudiogeeks.com/devops/how-to-configure-winrm-for-https-manually). + +### Remote Desktop Certificate + +In case you are using the `Remote Desktop` certificate, you can try to auto fetch the certificate from path `Cert:\LocalMachine\Remote Desktop` by using the hostname and the dns alias of the domain and install it inside the `Cert:\LocalMachine\My` location: + +```powershell +$Certificate = Get-ChildItem ` + -Path 'Cert:\LocalMachine\Remote Desktop\' | + ForEach-Object { + if ($_.Subject -like ([string]::Format('CN={0}.{1}', $env:COMPUTERNAME, $env:USERDNSDOMAIN ))) { + return $_; + } + }; + +$MyCertStore = New-Object 'System.Security.Cryptography.X509Certificates.X509Store' 'My', 'LocalMachine' +$MyCertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite); +$MyCertStore.Add($Certificate); + +$MyCertStore.Close(); + +$CertThumbprint = $Certificate.ThumbPrint; +``` + +Otherwise you can manually lookup the `Thumbprint` at `Cert:\LocalMachine\Remote Desktop` by using the `mmc` or changing the filter to print all certificates: + +```powershell +Get-ChildItem -Path 'Cert:\LocalMachine\Remote Desktop\' +``` + +## Disabling HTTP Listener (optional) + +Now as we found our `Thumbprint` for the certificate to use, we can remove the HTTP listener to prevent connections for this: + +```powershell +# (optional) Disable HTTP transport listener +Get-ChildItem WSMan:\Localhost\listener | Where-Object Keys -eq "Transport=HTTP" | Remove-Item -Recurse; +``` + +In addition, we can also disable the firewall rule for HTTP WinRM requests. This is language specific and has to be updated to your language. Both examples will cover German and English: + +```powershell +# Disable possible old HTTP firewall rules (names language specific) +Disable-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)"; +Disable-NetFirewallRule -DisplayName "Windows-Remoteverwaltung (HTTP eingehend)"; +``` + +Make sure to install the certificate in the local machine cert store. This example is using PowerShell. + +**Note:** Please be aware, that disabling HTTP listener might break other remote execution tools, which rely on the HTTP listener and/or do not support the HTTPS listener. We would recommend leaving the HTTP listener enabled. + +## Install HTTPS Listener + +To install the HTTPS listener, we have to provide the `Thumbprint` of our certificate we provided and installed into `Cert:\LocalMachine\My` or use the `Remote Desktop` one we copied into the `Cert:\LocalMachine\My` space. The listen address can either be specified to a specific address or use `*` to listen everywhere: + +```powershell +New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $CertThumbprint -Force; +``` + +Last but not least we have to open the Windows firewall to accept connections to our HTTPS listener: + +```powershell +# Create a new firewall rule to allow incoming HTTPS connection on port 5986 +New-NetFirewallRule ` + -DisplayName "Windows Remote Management (HTTPS-In)" ` + -Name "Windows Remote Management (HTTPS-In)" ` + -Profile 'Any' ` + -LocalPort 5986 ` + -Protocol 'TCP'; +``` + +## Connecting by using HTTPS listener + +In order to connect to the Windows host by using the HTTPS listener, we have to use the `-UseSSL` flag for the `Enter-PSSession` and `Invoke-Command` Cmdlet: + +```powershell +Enter-PSSession -ComputerName 'windowstest.example.com' -UseSSL; +``` + +In case you are running self-signed certificates and receive an error that the validation failed, you can skip it by using `New-PSSessionOption`: + +```powershell +Enter-PSSession -ComputerName 'windowstest.example.com' -UseSSL -SessionOption (New-PSSessionOption -SkipCNCheck -SkipCACheck) +``` + +## Important Notice + +If you disable the `HTTP` listener or block the firewall rule, a connection to this specific Windows host is no longer possible without the `-UseSSL` flag for remote Cmdlets.