You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
8.0 KiB
PowerShell

$domain = ""
$CertDomain = "*."
$XG_IP = "10.38.50.254";
$XG_Admin_Port= "4444";
$username = "admin";
$baseuri = "https://$($XG_IP):$($XG_Admin_Port)/webconsole/APIController?reqxml=";
$hn = hostname
$settingPath = "c:\CHON\"
$email = ""
#Notes
# Requires Posh ACME https://www.powershellgallery.com/packages/Posh-ACME/3.15.1
#Start-Process powershell "Install-Module -Name Posh-ACME -RequiredVersion 3.12.0" -Verb runAs
#New-PACertificate $certDomain -AcceptTOS
# Check if Password File Exists
try {
$password = Import-CliXML $settingPath"$hn-passwordcf.xml";
} catch {
#if is doesnt exist ask for creds,
write-warning "Can't read password file"
$password = New-Object -TypeName psobject
$password | Add-Member -MemberType NoteProperty -Name XGPass -Value $null
$password | Add-Member -MemberType NoteProperty -Name CloudFlareAPI -Value $null
#$password | Add-Member -MemberType NoteProperty -Name CloudFlare2 -Value $null
$password.XGPass = Read-Host -AsSecureString -prompt "Admin password:"
$password.CloudFlareAPI = Read-Host -AsSecureString -prompt "CloudFlare API KEY:"
# export to file
$password | Export-CLIXML $settingPath"$hn-passwordcf.xml";
}
# $password = (New-Object PSCredential "user",$password).GetNetworkCredential().Password
$password.XGPass = (New-Object PSCredential "user",$password.XGPass).GetNetworkCredential().Password
# $password.CloudFlareAPI = (New-Object PSCredential "user",$password.CloudFlareAPI).GetNetworkCredential().Password
# $password.CloudFlare2 = (New-Object PSCredential "user",$password.CloudFlare2).GetNetworkCredential().Password
#cloudflare part
Write-Host "#############################"
Write-Host "# Posh-ACME CLOUDFLARE CERT #"
Write-Host "#############################"
$pArgs = @{
CFAuthEmail = $email
CFAuthKeySecure = $password.CloudFlareAPI
}
New-PACertificate "*.$($domain)" -Plugin Cloudflare -PluginArgs $pArgs -force
## START XG Part
Write-Host "############################"
Write-Host "# Sophos XG LE Cert Update #"
Write-Host "############################"
# Allow invalid HTTPS certificates when using IWR so we can update the cert
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Ssl3, [Net.SecurityProtocolType]::Tls, [Net.SecurityProtocolType]::Tls11, [Net.SecurityProtocolType]::Tls12
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
try {
# invoke-restm ethod -uri $url -method GET
}
catch {
}
finally {
#enable checks again
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null
}
# Get a list of HTTP based rules where HTTPS is enabled
Write-Host "Getting list of Web Policies..."
$progressPreference = 'silentlyContinue'
$response = Invoke-WebRequest -Uri "$baseuri<Request><Login><Username>$username</Username><Password>$($password.XGPass)</Password></Login><Get><FirewallRule /></Get></Request>" -Method GET #-OutFile "certs.tar"
$progressPreference = 'continue'
$v = [xml]$response.Content
# get the list of certificates managed by poashacme and match them to a prefedined list
$certificates = @(
"CN=$CertDomain"
);
$certificates | % {
$domain = $_
echo "Loading certificate $_...";
$cert = get-pacertificate -list | ? {$_.subject -eq $domain}
$ContentType = "application/octet-stream"
$certFile = $cert[0].PfxFile
$keyFile = $cert[0].KeyFile
$certFileName = Split-Path $certFile -leaf
$boundary = [guid]::NewGuid().ToString()
$certFileBin = [System.IO.File]::ReadAllBytes($certFile)
$certName = $cert[0].NotAfter.tostring("yyyy-MM-dd") + "-" + $cert[0].AllSans[0] -replace "\*.","wc-"
$baseName = $cert[0].AllSans[0] -replace "\*.","."
$enc = [System.Text.Encoding]::GetEncoding("iso-8859-1")
$template = @"
--$boundary
Content-Type: application/xml; charset=utf-8
Content-Disposition: form-data; name=reqxml
<Request>
<Login>
<Username>$username</Username>
<Password>$($password.XGPass)</Password>
</Login>
<Set operation="add">
<Certificate>
<Name>$certName</Name>
<Action>UploadCertificate</Action>
<CertificateFormat>pkcs12</CertificateFormat>
<Password>poshacme</Password>
<CertificateFile>$certFileName</CertificateFile>
</Certificate>
</Set>
</Request>
--$boundary
Content-Disposition: form-data; filename="$certFileName"; name="certFileName"
Content-Type: $ContentType
$($enc.GetString($certFileBin))
--$boundary--
"@
$body = $template
echo "Uploading certificate to XG as $certName..."
$uri = "$($baseuri)<Request><Login><Username>$username</Username><Password>$($password.XGPass)</Password></Login><Set operation=`"add`"><Certificate><Name>$certName</Name><Action>UploadCertificate</Action><CertificateFormat>pkcs12</CertificateFormat><Password>pwd</Password><CertificateFile>$fileName</CertificateFile></Certificate></Set></Request>"
# Upload the certificate
$response = Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri $uri -Method POST -body $body -ContentType "multipart/form-data; boundary=$boundary"
$result = [xml]$response
$r = ([xml]$result).Response.Certificate.Status
if ($r.code -ne 200) {
Write-Warning "Whoa; there was a problem uploading the certificate: Code: $($r.code), Message: $($r."#text")";
} else {
Write-Host "Certificate $domain uploaded successfully."
}
Write-Host "Matching HTTP rules to certificate '$baseName'... " -NoNewline;
#AF 15/03/2022 added (-and $_.Status -eq "Enable" ) to the following line to only update enabled WAF Rules
$v.Response.FirewallRule | ? {$_.PolicyType -eq "HTTPBased" -and $_.HTTPBasedPolicy.HTTPS -eq "Enable" -and $_.Status -eq "Enable"} | % {
$SecurityPolicy = $_
# Write-Host "Testing against $($v.Response.SecurityPolicy.Name)..."
$x = $_.HTTPBasedPolicy.Domains.Domain | ? {$_ -match $baseName}
$x | % {
#check if this cert exists then if yes do this bit if not do other bit. - need to add (AF)
if ($SecurityPolicy.HTTPBasedPolicy.Certificate -ne $null) {
$SecurityPolicy.HTTPBasedPolicy.Certificate = [string]$certName
}
else {
$ne = $v.CreateElement("Certificate")
$ne.InnerText = $certname
$SecurityPolicy.HTTPBasedPolicy.AppendChild($ne)
}
}
Write-Host "Matched $($x.count) domains(s)."
if ($x.count -gt 0) {
Write-Host "Updating policy for $($SecurityPolicy.Name), this could take a minute... " -NoNewline
$body = @{"reqxml" = "<Request><Login><Username>$username</Username><Password>$($password.XGPass)</Password></Login><Set operation=`"update`">$($SecurityPolicy.OuterXml)</Set></Request>"};
$uri = $baseuri = "https://$($XG_IP):$($XG_Admin_Port)/webconsole/APIController"
$response = Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri $uri -Method POST -Body $body
# $r = ([xml]$response).Response.SecurityPolicy.Status
$r = ([xml]$response).Response.FirewallRule.Status
if ($r.code -ne 200) {
Write-Warning "Whoa; there was a problem updating the policy: Code: $($r.code), Message: $($r."#text")";
} else {
Write-Host "OK!";
}
}
}
}
#Copy-Item -path $certfile -destination $settingPath
#https://dejanstojanovic.net/powershell/2018/february/use-powershell-to-install-ssl-certificate-on-iis/
$r = ([xml]$response).Response.FirewallRule.Status