mirror of
https://github.com/Icinga/icinga-powershell-framework.git
synced 2025-12-20 23:00:35 -05:00
237 lines
9.5 KiB
PowerShell
237 lines
9.5 KiB
PowerShell
function Install-IcingaAgentCertificates()
|
|
{
|
|
param(
|
|
[string]$Hostname,
|
|
[string]$Endpoint,
|
|
[int]$Port = 5665,
|
|
[string]$CACert,
|
|
[string]$Ticket,
|
|
[switch]$Force = $FALSE
|
|
);
|
|
|
|
if ([string]::IsNullOrEmpty($Hostname)) {
|
|
Write-IcingaConsoleError 'Failed to install Icinga Agent certificates. Please provide a hostname';
|
|
return $FALSE;
|
|
}
|
|
|
|
# Default for Icinga 2.8.0 and above
|
|
[string]$NewCertificateDirectory = (Join-Path -Path $Env:ProgramData -ChildPath 'icinga2\var\lib\icinga2\certs\');
|
|
[string]$OldCertificateDirectory = (Join-Path -Path $Env:ProgramData -ChildPath 'icinga2\etc\icinga2\pki\');
|
|
[string]$CertificateDirectory = $NewCertificateDirectory;
|
|
if ((Compare-IcingaVersions -RequiredVersion '2.8.0') -eq $FALSE) {
|
|
# Certificate path for versions older than 2.8.0
|
|
$CertificateDirectory = $OldCertificateDirectory;
|
|
Move-IcingaAgentCertificates -Source $NewCertificateDirectory -Destination $OldCertificateDirectory;
|
|
} else {
|
|
Move-IcingaAgentCertificates -Source $OldCertificateDirectory -Destination $NewCertificateDirectory;
|
|
}
|
|
|
|
if (-Not (Test-IcingaAgentCertificates -CertDirectory $CertificateDirectory -Hostname $Hostname -Force $Force)) {
|
|
Write-IcingaConsoleNotice ([string]::Format('Generating host certificates for host "{0}"', $Hostname));
|
|
|
|
$arguments = [string]::Format('pki new-cert --cn {0} --key {1}{0}.key --cert {1}{0}.crt',
|
|
$Hostname,
|
|
$CertificateDirectory
|
|
);
|
|
|
|
if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) {
|
|
Write-IcingaConsoleError 'Failed to generate host certificate';
|
|
return $FALSE;
|
|
}
|
|
}
|
|
|
|
if ([string]::IsNullOrEmpty($Endpoint) -And [string]::IsNullOrEmpty($CACert)) {
|
|
Write-IcingaConsoleWarning 'Your host certificates have been generated successfully. Please either specify an endpoint to connect to or provide the path to a valid ca.crt';
|
|
return $FALSE;
|
|
}
|
|
|
|
if (-Not [string]::IsNullOrEmpty($Endpoint)) {
|
|
if (-Not (Test-IcingaAgentCertificates -CertDirectory $CertificateDirectory -Hostname $Hostname -TestTrustedParent -Force $Force)) {
|
|
|
|
Write-IcingaConsoleNotice ([string]::Format('Fetching trusted master certificate from "{0}"', $Endpoint));
|
|
|
|
# Argument --key for save-cert is deprecated starting with Icinga 2.12.0
|
|
if (Compare-IcingaVersions -RequiredVersion '2.12.0') {
|
|
$arguments = [string]::Format('pki save-cert --trustedcert {0}trusted-parent.crt --host {1} --port {2}',
|
|
$CertificateDirectory,
|
|
$Endpoint,
|
|
$Port
|
|
);
|
|
} else {
|
|
$arguments = [string]::Format('pki save-cert --key {0}{1}.key --trustedcert {0}trusted-parent.crt --host {2} --port {3}',
|
|
$CertificateDirectory,
|
|
$Hostname,
|
|
$Endpoint,
|
|
$Port
|
|
);
|
|
}
|
|
|
|
if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) {
|
|
Write-IcingaConsoleError 'Unable to connect to your provided Icinga CA. Please verify the entered configuration is correct.' `
|
|
'If you are not able to connect to your Icinga CA from this machine, you will have to provide the path' `
|
|
'to your Icinga ca.crt and use the CA-Proxy certificate handling.';
|
|
return $FALSE;
|
|
}
|
|
}
|
|
|
|
if (-Not (Test-IcingaAgentCertificates -CertDirectory $CertificateDirectory -Hostname $Hostname -TestCACert -Force $Force)) {
|
|
[string]$PKIRequest = 'pki request --host {0} --port {1} --ticket {4} --key {2}{3}.key --cert {2}{3}.crt --trustedcert {2}trusted-parent.crt --ca {2}ca.crt';
|
|
|
|
if ([string]::IsNullOrEmpty($Ticket)) {
|
|
$PKIRequest = 'pki request --host {0} --port {1} --key {2}{3}.key --cert {2}{3}.crt --trustedcert {2}trusted-parent.crt --ca {2}ca.crt';
|
|
}
|
|
|
|
$arguments = [string]::Format($PKIRequest,
|
|
$Endpoint,
|
|
$Port,
|
|
$CertificateDirectory,
|
|
$Hostname,
|
|
$Ticket
|
|
);
|
|
|
|
if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) {
|
|
Write-IcingaConsoleError 'Failed to sign Icinga certificate';
|
|
return $FALSE;
|
|
}
|
|
|
|
if ([string]::IsNullOrEmpty($Ticket)) {
|
|
Write-IcingaConsoleNotice 'Your certificates were generated successfully. Please sign the certificate now on your Icinga CA master. You can lookup open requests with "icinga2 ca list"';
|
|
} else {
|
|
Write-IcingaConsoleNotice 'Icinga certificates successfully installed';
|
|
}
|
|
}
|
|
|
|
return $TRUE;
|
|
} elseif (-Not [string]::IsNullOrEmpty($CACert)) {
|
|
if (-Not (Copy-IcingaAgentCACertificate -CAPath $CACert -Desination $CertificateDirectory)) {
|
|
return $FALSE;
|
|
}
|
|
Write-IcingaConsoleNotice 'Host-Certificates and ca.crt are present. Please start your Icinga Agent now and manually sign your certificate request on your CA master. You can lookup open requests with "icinga2 ca list"';
|
|
}
|
|
|
|
return $TRUE;
|
|
}
|
|
|
|
function Start-IcingaAgentCertificateProcess()
|
|
{
|
|
param(
|
|
$Arguments
|
|
);
|
|
|
|
$Binary = Get-IcingaAgentBinary;
|
|
$Process = Start-IcingaProcess -Executable $Binary -Arguments $Arguments;
|
|
|
|
if ($Process.ExitCode -ne 0) {
|
|
Write-IcingaConsoleError ([string]::Format('Failed to create certificate.{0}Arguments: {1}{0}Error:{2} {3}', "`r`n", $Arguments, $Process.Message, $Process.Error));
|
|
return $FALSE;
|
|
}
|
|
|
|
Write-IcingaConsoleNotice $Process.Message;
|
|
return $TRUE;
|
|
}
|
|
|
|
function Move-IcingaAgentCertificates()
|
|
{
|
|
param(
|
|
[string]$Source,
|
|
[string]$Destination
|
|
);
|
|
|
|
$SourceDir = Join-Path -Path $Source -ChildPath '\*';
|
|
$TargetDir = Join-Path -Path $Destination -ChildPath '\';
|
|
|
|
Move-Item -Path $SourceDir -Destination $TargetDir;
|
|
}
|
|
|
|
function Test-IcingaAgentCertificates()
|
|
{
|
|
param(
|
|
[string]$CertDirectory,
|
|
[string]$Hostname,
|
|
[switch]$TestCACert,
|
|
[switch]$TestTrustedParent,
|
|
[bool]$Force
|
|
);
|
|
|
|
if ($Force) {
|
|
return $FALSE;
|
|
}
|
|
|
|
if ($TestCACert) {
|
|
if (Test-Path (Join-Path -Path $CertDirectory -ChildPath 'ca.crt')) {
|
|
Write-IcingaConsoleNotice 'Your ca.crt is present. No generation or fetching required';
|
|
return $TRUE;
|
|
} else {
|
|
Write-IcingaConsoleWarning 'Your ca.crt is not present. Manuall copy or fetching from your Icinga CA is required.';
|
|
return $FALSE;
|
|
}
|
|
}
|
|
|
|
if ($TestTrustedParent) {
|
|
if (Test-Path (Join-Path -Path $CertDirectory -ChildPath 'trusted-parent.crt')) {
|
|
Write-IcingaConsoleNotice 'Your trusted-parent.crt is present. No fetching or generation required';
|
|
return $TRUE;
|
|
} else {
|
|
Write-IcingaConsoleWarning 'Your trusted master certificate is not present. Fetching from your CA server is required';
|
|
return $FALSE;
|
|
}
|
|
}
|
|
|
|
if ((-Not (Test-Path ((Join-Path -Path $CertDirectory -ChildPath $Hostname) + '.key'))) `
|
|
-Or -Not (Test-Path ((Join-Path -Path $CertDirectory -ChildPath $Hostname) + '.crt'))) {
|
|
return $FALSE;
|
|
}
|
|
|
|
[string]$hostCRT = [string]::Format('{0}.crt', $Hostname);
|
|
[string]$hostKEY = [string]::Format('{0}.key', $Hostname);
|
|
|
|
$certificates = Get-ChildItem -Path $CertDirectory;
|
|
# Now loop each file and match their name with our hostname
|
|
foreach ($cert in $certificates) {
|
|
if ($cert.Name.toLower() -eq $hostCRT.toLower() -Or $cert.Name.toLower() -eq $hostKEY.toLower()) {
|
|
$file = $cert.Name.Replace('.key', '').Replace('.crt', '');
|
|
if (-Not ($file -clike $Hostname)) {
|
|
Write-IcingaConsoleWarning ([string]::Format('Certificate file {0} is not matching the hostname {1}. Certificate generation is required.', $cert.Name, $Hostname));
|
|
return $FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-IcingaConsoleNotice 'Icinga host certificates are present and valid. No generation required';
|
|
|
|
return $TRUE;
|
|
}
|
|
|
|
function Copy-IcingaAgentCACertificate()
|
|
{
|
|
param(
|
|
[string]$CAPath,
|
|
[string]$Desination
|
|
);
|
|
|
|
# Copy ca.crt from local path or network share to certificate path
|
|
if ((Test-Path $CAPath)) {
|
|
Copy-Item -Path $CAPath -Destination (Join-Path -Path $Desination -ChildPath 'ca.crt') | Out-Null;
|
|
Write-IcingaConsoleNotice ([string]::Format('Copied ca.crt from "{0}" to "{1}', $CAPath, $Desination));
|
|
} else {
|
|
# It could also be a web ressource
|
|
try {
|
|
$response = Invoke-WebRequest $CAPath -UseBasicParsing;
|
|
[int]$Index = $response.RawContent.IndexOf("`r`n`r`n") + 4;
|
|
|
|
[string]$CAContent = $response.RawContent.SubString(
|
|
$Index,
|
|
$response.RawContent.Length - $Index
|
|
);
|
|
Set-Content -Path (Join-Path $Desination -ChildPath 'ca.crt') -Value $CAContent;
|
|
Write-IcingaConsoleNotice ([string]::Format('Downloaded ca.crt from "{0}" to "{1}', $CAPath, $Desination))
|
|
} catch {
|
|
Write-IcingaConsoleError 'Failed to load any provided ca.crt ressource';
|
|
return $FALSE;
|
|
}
|
|
}
|
|
|
|
return $TRUE;
|
|
}
|
|
|
|
Export-ModuleMember -Function @('Install-IcingaAgentCertificates');
|