Fixes REST-Api while running as NT Authority\NetworkService

This commit is contained in:
Lord Hepipud 2024-04-02 20:12:56 +02:00
parent d0b53e3877
commit 9d47bf1bec
5 changed files with 55 additions and 14 deletions

View file

@ -13,10 +13,13 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
## 1.12.1 (tbd)
[Issues and PRs](https://github.com/Icinga/icinga-powershell-framework/milestone/33)
### Bugfixes
* [#707](https://github.com/Icinga/icinga-powershell-framework/pull/707) Fixes size of the `Icinga for Windows` eventlog by setting it to `20MiB`, allowing to store more events before they are overwritten
* [#710](https://github.com/Icinga/icinga-powershell-framework/pull/710) Fixes various console errors while running Icinga for Windows outside of an administrative shell
* [#713](https://github.com/Icinga/icinga-powershell-framework/pull/713) Fixes Icinga for Windows REST-Api which fails during certificate auth handling while running as `NT Authority\NetworkService`
* [#714](https://github.com/Icinga/icinga-powershell-framework/pull/714) Fixes missing service environment information during initial setup of Icinga for Windows v1.12 on some systems
* [#715](https://github.com/Icinga/icinga-powershell-framework/pull/715) Fixes internal scheduled task handling and certificate renewal task by setting the user to `LocalSystem` instead of any administrative user or group, ensuring compatibility with all Windows versions as well as managing by using WinRM and SSH
* [#716](https://github.com/Icinga/icinga-powershell-framework/pull/716) Fixes Icinga for Windows certificate creation while using WinRM or SSH for remote connections

View file

@ -22,7 +22,6 @@ function Start-IcingaForWindowsDaemon()
[string]$MainServicePidFile = (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'service.pid');
[string]$JeaPidFile = (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'jea.pid');
[string]$JeaProfile = Get-IcingaPowerShellConfig -Path 'Framework.JEAProfile';
[Security.Cryptography.X509Certificates.X509Certificate2]$Certificate = Get-IcingaForWindowsCertificate;
[string]$JeaPid = '';
if (Test-IcingaJEAServiceRunning) {
@ -37,7 +36,14 @@ function Start-IcingaForWindowsDaemon()
# Todo: Add config for active background tasks. Set it to 20 for the moment
Add-IcingaThreadPool -Name 'MainPool' -MaxInstances 20;
$Global:Icinga.Public.Add('SSLCertificate', $Certificate);
$Global:Icinga.Public.Add(
'SSL',
@{
'Certificate' = $null;
'CertFile' = $null;
'CertThumbprint' = $null;
}
);
New-IcingaThreadInstance -Name "Main" -ThreadPool (Get-IcingaThreadPool -Name 'MainPool') -Command 'Add-IcingaForWindowsDaemon' -Start;
} else {
@ -47,13 +53,21 @@ function Start-IcingaForWindowsDaemon()
try {
Use-Icinga -Daemon;
Write-IcingaFileSecure -File ($args[1]) -Value $PID;
Write-IcingaFileSecure -File ($args[0]) -Value $PID;
$Global:Icinga.Protected.JEAContext = $TRUE;
$Global:Icinga.Protected.RunAsDaemon = $TRUE;
# Todo: Add config for active background tasks. Set it to 20 for the moment
Add-IcingaThreadPool -Name 'MainPool' -MaxInstances 20;
$Global:Icinga.Public.Add('SSLCertificate', $args[0]);
$Global:Icinga.Public.Add(
'SSL',
@{
'Certificate' = $null;
'CertFile' = $null;
'CertThumbprint' = $null;
}
);
New-IcingaThreadInstance -Name "Main" -ThreadPool (Get-IcingaThreadPool -Name 'MainPool') -Command 'Add-IcingaForWindowsDaemon' -Start;
@ -63,7 +77,7 @@ function Start-IcingaForWindowsDaemon()
} catch {
Write-IcingaEventMessage -EventId 1600 -Namespace 'Framework' -ExceptionObject $_;
}
} -Args $Certificate, $JeaPidFile;
} -Args $JeaPidFile;
}
if ($JEARestart) {

View file

@ -54,15 +54,29 @@ function New-IcingaForWindowsRESTApi()
Write-IcingaDebugMessage -Message ($Global:Icinga.Public.Daemons.RESTApi.RegisteredEndpoints | Out-String);
$Global:Icinga.Public.SSL.CertFile = $CertFile;
$Global:Icinga.Public.SSL.CertThumbprint = $CertThumbprint;
while ($TRUE) {
if ($null -eq $Global:Icinga.Public.SSLCertificate) {
$Global:Icinga.Public.SSLCertificate = (Get-IcingaForWindowsCertificate);
} else {
if ($null -eq $Global:Icinga.Public.SSL.Certificate) {
# In case we are not inside a JEA context, use the SSLCertForSocket function to create the certificate file on the fly
# while maintaining the new wait feature. This fix is required, as the NetworkService user has no permssion
# to read the icingaforwindows.pfx file with the private key
if ([string]::IsNullOrEmpty((Get-IcingaJEAContext))) {
$Global:Icinga.Public.SSL.Certificate = Get-IcingaSSLCertForSocket `
-CertFile $Global:Icinga.Public.SSL.CertFile `
-CertThumbprint $Global:Icinga.Public.SSL.CertThumbprint;
} else {
$Global:Icinga.Public.SSL.Certificate = Get-IcingaForWindowsCertificate;
}
}
if ($null -ne $Global:Icinga.Public.SSL.Certificate) {
break;
}
# Wait 5 minutes and try again
Write-IcingaEventMessage -EventId 2002 -Namespace 'RESTApi';
Write-IcingaEventMessage -EventId 2002 -Namespace 'RESTApi' -Objects ($Global:Icinga.Public.SSL.Certificate | Out-String), $Global:Icinga.Public.SSL.CertFile, $Global:Icinga.Public.SSL.CertThumbprint;
Start-Sleep -Seconds (60 * 5);
}
@ -81,7 +95,7 @@ function New-IcingaForWindowsRESTApi()
$Connection = Open-IcingaTCPClientConnection `
-Client (New-IcingaTCPClient -Socket $Socket) `
-Certificate $Global:Icinga.Public.SSLCertificate;
-Certificate $Global:Icinga.Public.SSL.Certificate;
if ($Connection.Client -eq $null -Or $Connection.Stream -eq $null) {
Close-IcingaTCPConnection -Connection $Connection;

View file

@ -17,7 +17,7 @@ function Register-IcingaEventLogMessagesRESTApi()
2002 = @{
'EntryType' = 'Warning';
'Message' = 'Icinga for Windows certificate not ready';
'Details' = 'The Icinga for Windows REST-Api was not able to fetch the icingaforwindows.pfx certificate file. You can manually enforce the certificate creation by using the command "Start-IcingaWindowsScheduledTaskRenewCertificate". Once successful, this message should disappear and the REST-Api start. If the error persist, ensure your Icinga Agent certificate is configured properly and signed by your Icinga CA. This check is queued every 5 minutes and should vanish once everything works fine.';
'Details' = 'The Icinga for Windows REST-Api was not able to fetch the Icinga Agent or icingaforwindows.pfx certificate file. You can manually enforce the certificate creation of the icingaforwindows.pfx by using the command "Start-IcingaWindowsScheduledTaskRenewCertificate". Once successful, this message should disappear and the REST-Api start in case you are running inside a JEA-Context. If you are not using JEA, the Icinga Agent certificate has to be present and signed by the Icinga CA. You can test if a certificate is present by using "Get-IcingaSSLCertForSocket". This should return a certificate object with the subject "CN=<hostname>", while "<hostname>" should match your hostname or object name in Icinga. This check is queued every 5 minutes and should vanish once everything works fine.';
'EventId' = 2002;
};
2003 = @{

View file

@ -5,14 +5,24 @@ function New-IcingaForWindowsCertificateThreadTaskInstance()
while ($TRUE) {
# Check every 10 minutes if our certificate is present and update it in case it is
# missing or updates have happened
$NewIcingaForWindowsCertificate = Get-IcingaForWindowsCertificate;
# In case we are not inside a JEA context, use the SSLCertForSocket function to create the certificate file on the fly
# while maintaining the new wait feature. This fix is required, as the NetworkService user has no permssion
# to read the icingaforwindows.pfx file with the private key
if ([string]::IsNullOrEmpty((Get-IcingaJEAContext))) {
$NewIcingaForWindowsCertificate = Get-IcingaSSLCertForSocket `
-CertFile $Global:Icinga.Public.SSL.CertFile `
-CertThumbprint $Global:Icinga.Public.SSL.CertThumbprint;
} else {
$NewIcingaForWindowsCertificate = Get-IcingaForWindowsCertificate;
}
if ($null -ne $NewIcingaForWindowsCertificate) {
if ($NewIcingaForWindowsCertificate.Issuer.ToLower() -eq ([string]::Format('cn={0}', $IcingaHostname).ToLower())) {
Write-IcingaEventMessage -EventId 1506 -Namespace 'Framework';
} else {
if ($Global:Icinga.Public.SSLCertificate.GetCertHashString() -ne $NewIcingaForWindowsCertificate.GetCertHashString()) {
$Global:Icinga.Public.SSLCertificate = $NewIcingaForWindowsCertificate;
if ($Global:Icinga.Public.SSL.Certificate.GetCertHashString() -ne $NewIcingaForWindowsCertificate.GetCertHashString()) {
$Global:Icinga.Public.SSL.Certificate = $NewIcingaForWindowsCertificate;
Write-IcingaEventMessage -EventId 2004 -Namespace 'RESTApi';
}
}