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
110 changes: 1 addition & 109 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
27 changes: 27 additions & 0 deletions docs/00-General.md
Original file line number Diff line number Diff line change
@@ -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.
70 changes: 70 additions & 0 deletions docs/01-Installation.md
Original file line number Diff line number Diff line change
@@ -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
160 changes: 160 additions & 0 deletions docs/02-WinRM_config.md
Original file line number Diff line number Diff line change
@@ -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.