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 ) ) {
2020-05-30 08:19:34 -04:00
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 ) ) {
2020-05-13 10:53:15 -04:00
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 ) {
2020-05-30 08:19:34 -04:00
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 ) ) {
2020-05-22 10:34:18 -04:00
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' ;
2020-05-30 08:19:34 -04:00
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 ) ) {
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice ( [ string ] :: Format ( 'Fetching trusted master certificate from "{0}"' , $Endpoint ) ) ;
2019-09-29 12:25:40 -04:00
2020-04-28 07:48:15 -04:00
# Argument --key for save-cert is deprecated starting with Icinga 2.12.0
if ( Compare-IcingaVersions -RequiredVersion '2.12.0' ) {
2020-04-28 08:04:34 -04:00
$arguments = [ string ] :: Format ( 'pki save-cert --trustedcert {0}trusted-parent.crt --host {1} --port {2}' ,
2020-04-28 07:48:15 -04:00
$CertificateDirectory ,
2020-04-28 08:04:34 -04:00
$Endpoint ,
$Port
2020-04-28 07:48:15 -04:00
) ;
} else {
2020-04-28 08:04:34 -04:00
$arguments = [ string ] :: Format ( 'pki save-cert --key {0}{1}.key --trustedcert {0}trusted-parent.crt --host {2} --port {3}' ,
2020-04-28 07:48:15 -04:00
$CertificateDirectory ,
$Hostname ,
2020-04-28 08:04:34 -04:00
$Endpoint ,
$Port
2020-04-28 07:48:15 -04:00
) ;
}
2019-09-29 12:25:40 -04:00
if ( ( Start-IcingaAgentCertificateProcess -Arguments $arguments ) -eq $FALSE ) {
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleError 'Unable to connect to your provided Icinga CA. Please verify the entered configuration is correct.' `
2020-08-04 08:48:32 -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.' ;
2020-05-30 08:19:34 -04:00
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 ) {
2020-05-30 08:19:34 -04:00
Write-IcingaConsoleError 'Failed to sign Icinga certificate' ;
return $FALSE ;
2019-09-29 12:25:40 -04:00
}
if ( [ string ] :: IsNullOrEmpty ( $Ticket ) ) {
2020-05-13 10:53:15 -04:00
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 {
2020-05-13 10:53:15 -04:00
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 ;
}
2020-05-13 10:53:15 -04:00
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 ) {
2020-05-13 10:53:15 -04:00
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 ;
}
2020-05-13 10:53:15 -04:00
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' ) ) {
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice 'Your ca.crt is present. No generation or fetching required' ;
2019-09-29 12:25:40 -04:00
return $TRUE ;
} else {
2020-05-13 10:53:15 -04:00
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' ) ) {
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice 'Your trusted-parent.crt is present. No fetching or generation required' ;
2019-09-29 12:25:40 -04:00
return $TRUE ;
} else {
2020-05-13 10:53:15 -04:00
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' ) ) ) `
2020-08-04 08:48:32 -04:00
-Or -Not ( Test-Path ( ( Join-Path -Path $CertDirectory -ChildPath $Hostname ) + '.crt' ) ) ) {
2019-09-29 12:25:40 -04:00
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 ) ) {
2020-05-13 10:53:15 -04:00
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 ;
}
}
}
2020-05-22 07:42:23 -04:00
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 ;
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice ( [ string ] :: Format ( 'Copied ca.crt from "{0}" to "{1}' , $CAPath , $Desination ) ) ;
2019-09-29 12:25:40 -04:00
} else {
2020-07-31 04:20:53 -04:00
Set-IcingaTLSVersion ;
2019-09-29 12:25:40 -04:00
# 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 ;
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice ( [ string ] :: Format ( 'Downloaded ca.crt from "{0}" to "{1}' , $CAPath , $Desination ) )
2019-09-29 12:25:40 -04:00
} catch {
2020-05-13 10:53:15 -04:00
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' ) ;