icinga-powershell-framework/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1

238 lines
9.5 KiB
PowerShell
Raw Normal View History

2019-09-29 12:25:40 -04:00
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;
2019-09-29 12:25:40 -04:00
}
# 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));
2019-09-29 12:25:40 -04:00
$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;
2019-09-29 12:25:40 -04:00
}
}
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;
2019-09-29 12:25:40 -04:00
}
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));
2019-09-29 12:25:40 -04:00
# 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
);
}
2019-09-29 12:25:40 -04:00
if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) {
Write-IcingaConsoleError 'Unable to connect to your provided Icinga CA. Please verify the entered configuration is correct.' `
2019-09-29 12:25:40 -04:00
'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;
2019-09-29 12:25:40 -04:00
}
}
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;
2019-09-29 12:25:40 -04:00
}
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"';
2019-09-29 12:25:40 -04:00
} else {
Write-IcingaConsoleNotice 'Icinga certificates successfully installed';
2019-09-29 12:25:40 -04:00
}
}
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"';
2019-09-29 12:25:40 -04:00
}
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));
2019-09-29 12:25:40 -04:00
return $FALSE;
}
Write-IcingaConsoleNotice $Process.Message;
2019-09-29 12:25:40 -04:00
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';
2019-09-29 12:25:40 -04:00
return $TRUE;
} else {
Write-IcingaConsoleWarning 'Your ca.crt is not present. Manuall copy or fetching from your Icinga CA is required.';
2019-09-29 12:25:40 -04:00
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';
2019-09-29 12:25:40 -04:00
return $TRUE;
} else {
Write-IcingaConsoleWarning 'Your trusted master certificate is not present. Fetching from your CA server is required';
2019-09-29 12:25:40 -04:00
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));
2019-09-29 12:25:40 -04:00
return $FALSE;
}
}
}
Write-IcingaConsoleNotice 'Icinga host certificates are present and valid. No generation required';
2019-09-29 12:25:40 -04:00
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));
2019-09-29 12:25:40 -04:00
} 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))
2019-09-29 12:25:40 -04:00
} catch {
Write-IcingaConsoleError 'Failed to load any provided ca.crt ressource';
2019-09-29 12:25:40 -04:00
return $FALSE;
}
}
return $TRUE;
}
Export-ModuleMember -Function @('Install-IcingaAgentCertificates');