$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$username$($password.XGPass)" -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 $username $($password.XGPass) $certName UploadCertificate pkcs12 poshacme $certFileName --$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)$username$($password.XGPass)$certNameUploadCertificatepkcs12pwd$fileName" # 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" = "$username$($password.XGPass)$($SecurityPolicy.OuterXml)"}; $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