From e9059616d240016812cfc0a7ae11fa839edf8775 Mon Sep 17 00:00:00 2001 From: Markus Frosch Date: Mon, 7 Sep 2020 14:56:10 +0200 Subject: [PATCH] Improve README --- README.md | 187 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index ea954b5..5765811 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,21 @@ # check_by_winrm -check_by_winrm is a check plugin for Icinga 2 written in GO. It's build on the go-library [winrm](https://github.com/masterzen/winrm), which can execute remote commands on Windows machines through -the use of WinRM/WinRS. +Icinga check plugin to run checks and other commands directly on any Windows system using WinRM (Windows Remote Management). -## Preparing the remote Windows machine for Basic authentication -This project supports only basic authentication for local accounts (domain users are not supported). The remote windows system must be prepared for winrm: +Main use case would be to call one of the [plugins](https://github.com/Icinga/icinga-powershell-plugins) +from the [Icinga Powershell Framework](https://github.com/Icinga/icinga-powershell-framework). This will avoid the +requirement of installing an Icinga 2 agent on every Windows system. -### HTTP - winrm quickconfig - winrm set winrm/config/service/Auth '@{Basic="true"}' - winrm set winrm/config/service '@{AllowUnencrypted="true"}' - winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}' +The plugin will require WinRM to be preconfigured for access with a HTTPs or HTTP connection. -### HTTPS -By default WinRM uses Kerberos for authentication so Windows never sends the password to the system requesting validation. -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. -On the remote host, a PowerShell prompt, using the __Run as Administrator__ : +Supported authentication methods: - $CertThumbprint = 'cert_thumbprint'; +* Basic with local users +* NTLM with local or AD accounts +* TLS client certificate +* (SSH connection) - $certificate = Get-ChildItem -Path cert:\ -Recurse | Where-Object Thumbprint -eq $CertThumbprint; - - if ($null -eq $certificate) { - throw 'The provided thumbprint was not found in any certificate stores'; - } - - # Allow PS-Remote configuration - Enable-PSRemoting -SkipNetworkProfileCheck -Force; - - # 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 lisener - Set-Item WSMan:\localhost\Service\EnableCompatibilityHttpsListener -Value true; - - # Disable possible old HTTP firewall rules - Disable-NetFirewallRule -DisplayName "Windows Remote Management (HTTP-In)"; - Disable-NetFirewallRule -DisplayName "Windows-Remoteverwaltung (HTTP eingehend)"; - - winrm set winrm/config/service/auth '@{Basic="true"}'; - winrm set winrm/config/client '@{TrustedHosts="*"}'; - - Restart-Service winrm; - -If it's necessary to use a self-signed-certificate, you can follow this [guide](https://www.visualstudiogeeks.com/devops/how-to-configure-winrm-for-https-manually) - -## GO build example -To compile for a specific platform, you have to set the GOOS and GOARCH environment variables. For more [information](https://golang.org/pkg/go/build/) - -| **Platform** | **GOOS** | **GOARCH** | -| ------------- |:-------------:| -----:| -| Mac | darwin | amd64 | -| Linux | linux | amd64 | -| Windows | windows | amd64 | - -### Example - Linux - GOOS=linux GOARCH=amd64 go build -o check_by_winrm main.go +Not supported at the moment is Kerberos. ## Usage @@ -88,16 +42,123 @@ Arguments: -V, --version Print version and exit ``` -### Execute a script over http - ./check_by_winrm -H 192.168.172.217 -p 5985 --cmd "cscript.exe /T:30 /NoLogo C:\Windows\system32\check_time.vbs 1.de.pool.ntp.org 20 240" --user "windowsuser" --password 'secret!pw' +Also, see the Icinga 2 examples in the [icinga2/ directory](icinga2/). - OK - NTP OK: Offset +0.0556797 secs|'offset'=+0.0556797s;20;240; +## Examples -It is necessary that the PowerShell script exits with an exitcode like *exit 2*, otherwise the plugin could exit with an unexpected exitcode. +Calling a PowerShell plugin from the framework is easy: -### Execute a Icinga PowerShell Framework Commandlet over https - ./check_by_winrm -H "example.local.de" --icingacmd "Invoke-IcingaCheckCPU" --user "windowsuser" --password '!secret!pw' --tls --unsecure -t 30 + ./check_by_winrm -H example.local.de --user 'ad\user' --password '!secret!pw' \ + --icingacmd 'Invoke-IcingaCheckCPU -Warning 80 -Critical 90' [OK] Check package "CPU Load" | 'core_23_10'=2.31%;;;0;100 'core_23_3'=2.54%;;;0;100 'core_23_15'=2.12%;;;0;100 'core_23_5'=2.39%;;;0;100 'core_23_1'=2.04%;;;0;100 'core_23'=1.93%;;;0;100 'core_2_15'=2.78%;;;0;100 'core_2_10'=2.89%;;;0;100 [...] + +Notes: +* You can use `--insecure` to skip CA trust and certificate checks - be careful! +* You can use `--no-tls` to use a HTTP connection + +Executing any other Windows program or script, could be another Icinga plugin: + + ./check_by_winrm -H 192.168.172.217 \ + --user 'windowsuser' --password 'secret!pw' \ + --cmd "cscript.exe /T:30 /NoLogo C:\Windows\system32\check_time.vbs 1.de.pool.ntp.org 20 240" + + OK - NTP OK: Offset +0.0556797 secs|'offset'=+0.0556797s;20;240; + +If you run a program or script like this, you need to make sure to exit the script with a proper exit code, to reflect +the correct status for Icinga. + +## 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: + +``` +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 lisener +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. + +``` +winrm set winrm/config/service/Auth '@{Basic="true"}' +``` + +### Enabling unencrypted HTTP or basic auth + +**Warning:** This is insecure, and should only be done during testing! + +This will allow credentials and data transmitted over an **unencrypted** connection like HTTP. + +``` +winrm set winrm/config/service '@{AllowUnencrypted="true"}' +``` + +## Manually building the program + +The plugin is written in Golang and can easily be compiled from source, see the [documentation](https://golang.org/doc/) +for further details. + +``` +GOOS=linux GOARCH=amd64 go build -o check_by_winrm . +GOOS=windows GOARCH=amd64 go build -o check_by_winrm.exe . +``` + +## Acknowledgements + +To Brice Figureau [@masterzen](https://github.com/masterzen), who built a +[WinRM client for golang](https://github.com/masterzen/winrm).