Skip to content

Commit 929237d

Browse files
committed
Adds renewal handling for Icinga for Windows certificate
1 parent 959fac6 commit 929237d

9 files changed

+68
-28
lines changed

lib/core/installer/Start-IcingaForWindowsInstallation.psm1

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,9 @@ function Start-IcingaForWindowsInstallation()
312312
};
313313
}
314314

315-
# Install Icinga for Windows certificate if both, JEA and REST is installed
316-
if ($InstallJEA -And $InstallRESTApi) {
317-
Install-IcingaForWindowsCertificate;
318-
Restart-IcingaWindowsService;
319-
}
315+
# Always install the Icinga for Windows certificate
316+
Install-IcingaForWindowsCertificate;
317+
Restart-IcingaWindowsService;
320318

321319
# Update configuration and clear swap
322320
$ConfigSwap = Get-IcingaPowerShellConfig -Path 'Framework.Config.Swap';

lib/core/installer/menu/manage/framework/ToogleFrameworkApiChecks.psm1

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ function Invoke-IcingaForWindowsManagementConsoleToggleFrameworkApiChecks()
77
Register-IcingaBackgroundDaemon -Command 'Start-IcingaWindowsRESTApi';
88
Add-IcingaRESTApiCommand -Command 'Invoke-IcingaCheck*' -Endpoint 'apichecks';
99
}
10-
if ([string]::IsNullOrEmpty((Get-IcingaJEAContext)) -eq $FALSE) {
11-
Install-IcingaForWindowsCertificate;
12-
}
1310

11+
Install-IcingaForWindowsCertificate;
1412
Enable-IcingaFrameworkApiChecks;
1513
}
1614

lib/core/jea/Install-IcingaJeaProfile.psm1

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ function Install-IcingaJEAProfile()
2626
Write-IcingaJEAProfile -RebuildFramework:$RebuildFramework -AllowScriptBlocks:$AllowScriptBlocks;
2727
Write-IcingaConsoleNotice 'Registering Icinga for Windows JEA profile'
2828
Register-IcingaJEAProfile -IcingaUser $IcingaUser -TestEnv:$TestEnv -ConstrainedLanguage:$ConstrainedLanguage;
29-
30-
if ((Get-IcingaBackgroundDaemons).ContainsKey('Start-IcingaWindowsRESTApi')) {
31-
Install-IcingaForWindowsCertificate;
32-
}
29+
Install-IcingaForWindowsCertificate;
3330
}
3431

3532
Set-Alias -Name 'Update-IcingaJEAProfile' -Value 'Install-IcingaJEAProfile';

lib/core/wintasks/daemon/Register-TaskRenewCertificate.psm1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function Register-IcingaWindowsScheduledTaskRenewCertificate()
2020
$TaskPrincipal = New-ScheduledTaskPrincipal -GroupId 'S-1-5-32-544' -RunLevel 'Highest';
2121
$TaskSettings = New-ScheduledTaskSettingsSet -DontStopIfGoingOnBatteries -AllowStartIfOnBatteries -StartWhenAvailable;
2222

23-
Register-ScheduledTask -TaskName $TaskName -TaskPath $TaskPath -Force -Principal $TaskPrincipal -Action $TaskAction -Trigger $TaskTrigger -Settings $TaskSettings;
23+
Register-ScheduledTask -TaskName $TaskName -TaskPath $TaskPath -Force -Principal $TaskPrincipal -Action $TaskAction -Trigger $TaskTrigger -Settings $TaskSettings | Out-Null;
2424

25-
Write-IcingaConsoleWarning -Message 'The task "{0}" has been successfully registered at location "{1}".' -Objects $TaskName, $TaskPath;
25+
Write-IcingaConsoleNotice -Message 'The task "{0}" has been successfully registered at location "{1}".' -Objects $TaskName, $TaskPath;
2626
}

lib/daemon/Start-IcingaPowerShellDaemon.psm1

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ function Start-IcingaForWindowsDaemon()
3939
Add-IcingaThreadPool -Name 'MainPool' -MaxInstances 20;
4040
$Global:Icinga.Public.Add('SSLCertificate', $Certificate);
4141

42-
4342
New-IcingaThreadInstance -Name "Main" -ThreadPool (Get-IcingaThreadPool -Name 'MainPool') -Command 'Add-IcingaForWindowsDaemon' -Start;
4443
} else {
4544
Write-IcingaDebugMessage -Message 'Starting Icinga for Windows service inside JEA context' -Objects $RunAsService, $JEARestart, $JeaProfile;

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

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,20 @@ function New-IcingaForWindowsRESTApi()
5454

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

57-
if ($Global:Icinga.Protected.JEAContext) {
58-
if ($Global:Icinga.Public.ContainsKey('SSLCertificate') -eq $FALSE -Or $null -eq $Global:Icinga.Public.SSLCertificate) {
59-
Write-IcingaEventMessage -EventId 2001 -Namespace 'RESTApi';
60-
return;
57+
while ($TRUE) {
58+
if ($null -eq $Global:Icinga.Public.SSLCertificate) {
59+
$Global:Icinga.Public.SSLCertificate = (Get-IcingaForWindowsCertificate);
60+
} else {
61+
break;
6162
}
6263

63-
$Certificate = $Global:Icinga.Public.SSLCertificate;
64-
} else {
65-
$Certificate = Get-IcingaSSLCertForSocket -CertFile $CertFile -CertThumbprint $CertThumbprint;
64+
# Wait 5 minutes and try again
65+
Write-IcingaEventMessage -EventId 2002 -Namespace 'RESTApi';
66+
Start-Sleep -Seconds (60 * 5);
6667
}
6768

68-
if ($null -eq $Certificate) {
69-
Write-IcingaEventMessage -EventId 2000 -Namespace 'RESTApi';
70-
return;
71-
}
69+
# Create a background thread to renew the certificate on a regular basis
70+
Start-IcingaForWindowsCertificateThreadTask;
7271

7372
$Socket = New-IcingaTCPSocket -Address $Address -Port $Port -Start;
7473

@@ -82,7 +81,7 @@ function New-IcingaForWindowsRESTApi()
8281

8382
$Connection = Open-IcingaTCPClientConnection `
8483
-Client (New-IcingaTCPClient -Socket $Socket) `
85-
-Certificate $Certificate;
84+
-Certificate $Global:Icinga.Public.SSLCertificate;
8685

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

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,27 @@ function Register-IcingaEventLogMessagesRESTApi()
1111
2001 = @{
1212
'EntryType' = 'Error';
1313
'Message' = 'Failed to start REST-Api daemon in JEA context';
14-
'Details' = 'Icinga for Windows is being used inside a JEA context as service with the REST-Api daemon. To establish a secure TLS socket, it is required to create certificates in advance for the socket to bind on with "Install-IcingaForWindowsCertificate". The REST-Api daemon will now exit.';
14+
'Details' = 'Icinga for Windows is being used inside a JEA context as service with the REST-Api daemon. To establish a secure TLS socket, it is required to create certificates in advance for the socket to bind on with "Start-IcingaWindowsScheduledTaskRenewCertificate". The REST-Api daemon will now exit.';
1515
'EventId' = 2001;
1616
};
17+
2002 = @{
18+
'EntryType' = 'Warning';
19+
'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.';
21+
'EventId' = 2002;
22+
};
23+
2003 = @{
24+
'EntryType' = 'Warning';
25+
'Message' = 'Icinga for Windows certificate was not found';
26+
'Details' = 'The Icinga for Windows "icingaforwindows.pfx" file was not found on the system while the REST-Api is running. Please ensure the certificate is created shortly, as the daemon will no longer work once it will be restarted or the certificate is due for renewal. Please run "Start-IcingaWindowsScheduledTaskRenewCertificate" to re-create the certificate on your machine.'
27+
'EventId' = 2003;
28+
};
29+
2004 = @{
30+
'EntryType' = 'Information';
31+
'Message' = 'Icinga for Windows certificate was renewed';
32+
'Details' = 'The Icinga for Windows certificate has been modified and was updated inside the Icinga for Windows REST-Api daemon.'
33+
'EventId' = 2004;
34+
};
1735
2050 = @{
1836
'EntryType' = 'Error';
1937
'Message' = 'Failed to parse received REST-Api call';
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function New-IcingaForWindowsCertificateThreadTaskInstance()
2+
{
3+
$IcingaHostname = Get-IcingaHostname -ReadConstants;
4+
5+
while ($TRUE) {
6+
# Check every 10 minutes if our certificate is present and update it in case it is
7+
# missing or updates have happened
8+
$NewIcingaForWindowsCertificate = Get-IcingaForWindowsCertificate;
9+
10+
if ($null -ne $NewIcingaForWindowsCertificate) {
11+
if ($NewIcingaForWindowsCertificate.Issuer.ToLower() -eq ([string]::Format('cn={0}', $IcingaHostname).ToLower())) {
12+
Write-IcingaEventMessage -EventId 1506 -Namespace 'Framework';
13+
} else {
14+
if ($Global:Icinga.Public.SSLCertificate.GetCertHashString() -ne $NewIcingaForWindowsCertificate.GetCertHashString()) {
15+
$Global:Icinga.Public.SSLCertificate = $NewIcingaForWindowsCertificate;
16+
Write-IcingaEventMessage -EventId 2004 -Namespace 'RESTApi';
17+
}
18+
}
19+
}
20+
21+
Start-Sleep -Seconds (60 * 10);
22+
}
23+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function Start-IcingaForWindowsCertificateThreadTask()
2+
{
3+
New-IcingaThreadInstance `
4+
-Name 'CertificateRenewThread' `
5+
-ThreadPool (New-IcingaThreadPool -MaxInstances 1) `
6+
-Command 'New-IcingaForWindowsCertificateThreadTaskInstance' `
7+
-Start;
8+
}

0 commit comments

Comments
 (0)