Serverless Computing | Check your expired public certificates
Check for expired public certificates serverless, using an Azure Function App. Magically run the required PowerShell script directly at the Portal without deploying VMs or App Services. At this post I combine Azure Function Apps, with a PowerShell script to check the certificate expirations and the Send-MailMessage PowerShell function for sending emails directly from the PowerShell script.
Setup the Azure Function App
At the Azure Portal, create a new Function App. Select Consumption Plan and .NET Runtime Stack
Once the Function App is created, we need to enable PowerShell language support. To do so, open it, select the Function App and at the Platform features tab, open the Application Settings
Change the FUNCTIONS_EXTENSION_VERSION to ~1 and delete the FUNCTIONS_WORKER_RUNTIME line
Before:
After:
Create the Function
Once you click Save, go back to the Function App, select the “Functions” and press “New function”
If we change the application settings correctly, the “Experimental Language Support” option will appear. Enable it and the templates will be able to support PowerShell (And more languages). To get started click the “Time trigger” template.
At the window, select “PowerShell” for language and set the schedule. “Enter a cron expression of the format ‘{second} {minute} {hour} {day} {month} {day of week}’ to specify the schedule.”
Entering 0 0 0 1 * * the function will run once per day
Add the PowerShell script
Once the Function is created, you will be directed to the “Function Name” run.ps1 file. There we can run PowerShell scripts.
Below is the script, change the required variables to fit your needs and paste it to the Function run.ps1 file. The variables that you need to change is:
$WebsiteURLs | This is the list, comma separated, of the URLs you want to check for certificate expiration
$From | The email address of the Sender
$To | The email address of the Recipient
$Cc | The email address of the CC Recipient
$Subject | The subject of the email
$SMTPServer | The email server you will use to send the emails. You can Use the SendGrid service from Azure that currenlty provides 25000 email per month for free. More details here: https://sendgrid.com/docs/API_Reference/SMTP_API/getting_started_smtp.html
$SMTPPort | The port that the SMTP service requires
$username | The username to authenticate to the SMTP Service
$password = ConvertTo-SecureString “here you need to add the password in plain text” -AsPlainText -Force
$WebsiteURLs= @("e-apostolidis.gr","azureheads.gr") $WebsitePort=443 $Threshold=120 $Severe=30 $ID=0 $body += "<html><body><br>" $body += "<font color =""darkblue"">" $body += "# Website_URL: Current Certificate: Expiration Date: Days Remaining: Errors:" foreach ($WebsiteURL in $WebsiteURLs){ $CommonName=$WebsiteURL $ID+=1 Try{ $Conn = New-Object System.Net.Sockets.TcpClient($WebsiteURL,$WebsitePort) Try { $Stream = New-Object System.Net.Security.SslStream($Conn.GetStream(),$false, { param($sender, $certificate, $chain, $sslPolicyErrors) return $true }) $Stream.AuthenticateAsClient($CommonName) $Cert = $Stream.Get_RemoteCertificate() $CN=(($cert.Subject -split "=")[1] -split ",")[0] $ValidTo = [datetime]::Parse($Cert.GetExpirationDatestring()) $ValidDays = $($ValidTo - [datetime]::Now).Days if ($ValidDays -lt $Threshold) { $fontcolor += "<font color =darkgreen>" } if ($ValidDays -lt $Severe) { $fontcolor += "<font color =darkred>" } $body += "<br />" $body += $fontcolor $body += "$ID $WebsiteURL $CN $ValidTo $ValidDays" } Catch { Throw $_ } Finally { $Conn.close() } } Catch { $body += "<br />" $body +="<font color=red> gest </font>" $body += " $ID $WebsiteURL" $body += "</body></html>" } } $From = "[email protected]" $To = "[email protected]" $Cc = "[email protected]" $Subject = "check the certificates" $SMTPServer = "mail.mailserver.gr" $SMTPPort = "587" $username = "username" $password = ConvertTo-SecureString "password" -AsPlainText -Force $mycred = New-Object System.Management.Automation.PSCredential($username, $password) [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true } Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject -SmtpServer $SMTPServer -UseSSL -port $SMTPPort -Credential ($mycred) -Body $body -BodyAsHtml
Press SAve & Run and you are ready. Now on, once per day the script will run and it will sent an email with the certificates. Something like this:
Feel free to play with the colors on the script. I have added Dark Green for the valid certificates and Red for those that is about to expire.
Credits
Use this line to ignore the certificate check on the email server when sending the email
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true }
The basic script for checking for certificate revocation:
https://isc.sans.edu/forums/diary/Assessing+Remote+Certificates+with+Powershell/20645/
At his blog is the idea for sending emails with powershell with html:
http://www.techtrek.io/send-automated-email-with-powershell/
Pantelis Apostolidis is a Sr. Specialist, Azure at Microsoft and a former Microsoft Azure MVP. For the last 20 years, Pantelis has been involved to major cloud projects in Greece and abroad, helping companies to adopt and deploy cloud technologies, driving business value. He is entitled to a lot of Microsoft Expert Certifications, demonstrating his proven experience in delivering high quality solutions. He is an author, blogger and he is acting as a spokesperson for conferences, workshops and webinars. He is also an active member of several communities as a moderator in azureheads.gr and autoexec.gr. Follow him on Twitter @papostolidis.