Skip to content

Commit 167c1a1

Browse files
committed
Fixes REST-Api while running as NT Authority\NetworkService
1 parent 938d917 commit 167c1a1

File tree

5 files changed

+53
-14
lines changed

5 files changed

+53
-14
lines changed

doc/100-General/10-Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
1919

2020
* [#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
2121
* [#710](https://github.com/Icinga/icinga-powershell-framework/pull/710) Fixes various console errors while running Icinga for Windows outside of an administrative shell
22+
* [#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`
2223
* [#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
2324
* [#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
2425
* [#716](https://github.com/Icinga/icinga-powershell-framework/pull/716) Fixes Icinga for Windows certificate creation while using WinRM or SSH for remote connections

lib/daemon/Start-IcingaPowerShellDaemon.psm1

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ function Start-IcingaForWindowsDaemon()
2222
[string]$MainServicePidFile = (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'service.pid');
2323
[string]$JeaPidFile = (Join-Path -Path (Get-IcingaCacheDir) -ChildPath 'jea.pid');
2424
[string]$JeaProfile = Get-IcingaPowerShellConfig -Path 'Framework.JEAProfile';
25-
[Security.Cryptography.X509Certificates.X509Certificate2]$Certificate = Get-IcingaForWindowsCertificate;
2625
[string]$JeaPid = '';
2726

2827
if (Test-IcingaJEAServiceRunning) {
@@ -37,7 +36,14 @@ function Start-IcingaForWindowsDaemon()
3736

3837
# Todo: Add config for active background tasks. Set it to 20 for the moment
3938
Add-IcingaThreadPool -Name 'MainPool' -MaxInstances 20;
40-
$Global:Icinga.Public.Add('SSLCertificate', $Certificate);
39+
$Global:Icinga.Public.Add(
40+
'SSL',
41+
@{
42+
'Certificate' = $null;
43+
'CertFile' = $null;
44+
'CertThumbprint' = $null;
45+
}
46+
);
4147

4248
New-IcingaThreadInstance -Name "Main" -ThreadPool (Get-IcingaThreadPool -Name 'MainPool') -Command 'Add-IcingaForWindowsDaemon' -Start;
4349
} else {
@@ -47,13 +53,21 @@ function Start-IcingaForWindowsDaemon()
4753
try {
4854
Use-Icinga -Daemon;
4955

50-
Write-IcingaFileSecure -File ($args[1]) -Value $PID;
56+
Write-IcingaFileSecure -File ($args[0]) -Value $PID;
5157

5258
$Global:Icinga.Protected.JEAContext = $TRUE;
5359
$Global:Icinga.Protected.RunAsDaemon = $TRUE;
5460
# Todo: Add config for active background tasks. Set it to 20 for the moment
5561
Add-IcingaThreadPool -Name 'MainPool' -MaxInstances 20;
56-
$Global:Icinga.Public.Add('SSLCertificate', $args[0]);
62+
63+
$Global:Icinga.Public.Add(
64+
'SSL',
65+
@{
66+
'Certificate' = $null;
67+
'CertFile' = $null;
68+
'CertThumbprint' = $null;
69+
}
70+
);
5771

5872
New-IcingaThreadInstance -Name "Main" -ThreadPool (Get-IcingaThreadPool -Name 'MainPool') -Command 'Add-IcingaForWindowsDaemon' -Start;
5973

@@ -63,7 +77,7 @@ function Start-IcingaForWindowsDaemon()
6377
} catch {
6478
Write-IcingaEventMessage -EventId 1600 -Namespace 'Framework' -ExceptionObject $_;
6579
}
66-
} -Args $Certificate, $JeaPidFile;
80+
} -Args $JeaPidFile;
6781
}
6882

6983
if ($JEARestart) {

lib/daemons/RestAPI/daemon/New-IcingaForWindowsRESTApi.psm1

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,29 @@ function New-IcingaForWindowsRESTApi()
5454

5555
Write-IcingaDebugMessage -Message ($Global:Icinga.Public.Daemons.RESTApi.RegisteredEndpoints | Out-String);
5656

57+
$Global:Icinga.Public.SSL.CertFile = $CertFile;
58+
$Global:Icinga.Public.SSL.CertThumbprint = $CertThumbprint;
59+
5760
while ($TRUE) {
58-
if ($null -eq $Global:Icinga.Public.SSLCertificate) {
59-
$Global:Icinga.Public.SSLCertificate = (Get-IcingaForWindowsCertificate);
60-
} else {
61+
if ($null -eq $Global:Icinga.Public.SSL.Certificate) {
62+
# In case we are not inside a JEA context, use the SSLCertForSocket function to create the certificate file on the fly
63+
# while maintaining the new wait feature. This fix is required, as the NetworkService user has no permssion
64+
# to read the icingaforwindows.pfx file with the private key
65+
if ([string]::IsNullOrEmpty((Get-IcingaJEAContext))) {
66+
$Global:Icinga.Public.SSL.Certificate = Get-IcingaSSLCertForSocket `
67+
-CertFile $Global:Icinga.Public.SSL.CertFile `
68+
-CertThumbprint $Global:Icinga.Public.SSL.CertThumbprint;
69+
} else {
70+
$Global:Icinga.Public.SSL.Certificate = Get-IcingaForWindowsCertificate;
71+
}
72+
}
73+
74+
if ($null -ne $Global:Icinga.Public.SSL.Certificate) {
6175
break;
6276
}
6377

6478
# Wait 5 minutes and try again
65-
Write-IcingaEventMessage -EventId 2002 -Namespace 'RESTApi';
79+
Write-IcingaEventMessage -EventId 2002 -Namespace 'RESTApi' -Objects ($Global:Icinga.Public.SSL.Certificate | Out-String), $Global:Icinga.Public.SSL.CertFile, $Global:Icinga.Public.SSL.CertThumbprint;
6680
Start-Sleep -Seconds (60 * 5);
6781
}
6882

@@ -81,7 +95,7 @@ function New-IcingaForWindowsRESTApi()
8195

8296
$Connection = Open-IcingaTCPClientConnection `
8397
-Client (New-IcingaTCPClient -Socket $Socket) `
84-
-Certificate $Global:Icinga.Public.SSLCertificate;
98+
-Certificate $Global:Icinga.Public.SSL.Certificate;
8599

86100
if ($Connection.Client -eq $null -Or $Connection.Stream -eq $null) {
87101
Close-IcingaTCPConnection -Connection $Connection;

lib/daemons/RestAPI/eventlog/Register-IcingaEventLogMessagesRESTApi.psm1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function Register-IcingaEventLogMessagesRESTApi()
1717
2002 = @{
1818
'EntryType' = 'Warning';
1919
'Message' = 'Icinga for Windows certificate not ready';
20-
'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.';
20+
'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.';
2121
'EventId' = 2002;
2222
};
2323
2003 = @{

lib/daemons/RestAPI/threads/New-IcingaForWindowsCertificateThreadTaskInstance.psm1

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,24 @@ function New-IcingaForWindowsCertificateThreadTaskInstance()
55
while ($TRUE) {
66
# Check every 10 minutes if our certificate is present and update it in case it is
77
# missing or updates have happened
8-
$NewIcingaForWindowsCertificate = Get-IcingaForWindowsCertificate;
8+
9+
# In case we are not inside a JEA context, use the SSLCertForSocket function to create the certificate file on the fly
10+
# while maintaining the new wait feature. This fix is required, as the NetworkService user has no permssion
11+
# to read the icingaforwindows.pfx file with the private key
12+
if ([string]::IsNullOrEmpty((Get-IcingaJEAContext))) {
13+
$NewIcingaForWindowsCertificate = Get-IcingaSSLCertForSocket `
14+
-CertFile $Global:Icinga.Public.SSL.CertFile `
15+
-CertThumbprint $Global:Icinga.Public.SSL.CertThumbprint;
16+
} else {
17+
$NewIcingaForWindowsCertificate = Get-IcingaForWindowsCertificate;
18+
}
919

1020
if ($null -ne $NewIcingaForWindowsCertificate) {
1121
if ($NewIcingaForWindowsCertificate.Issuer.ToLower() -eq ([string]::Format('cn={0}', $IcingaHostname).ToLower())) {
1222
Write-IcingaEventMessage -EventId 1506 -Namespace 'Framework';
1323
} else {
14-
if ($Global:Icinga.Public.SSLCertificate.GetCertHashString() -ne $NewIcingaForWindowsCertificate.GetCertHashString()) {
15-
$Global:Icinga.Public.SSLCertificate = $NewIcingaForWindowsCertificate;
24+
if ($Global:Icinga.Public.SSL.Certificate.GetCertHashString() -ne $NewIcingaForWindowsCertificate.GetCertHashString()) {
25+
$Global:Icinga.Public.SSL.Certificate = $NewIcingaForWindowsCertificate;
1626
Write-IcingaEventMessage -EventId 2004 -Namespace 'RESTApi';
1727
}
1828
}

0 commit comments

Comments
 (0)