Identifying Legacy TLS Traffic in Cloudflare with PowerShell

Identifying Legacy TLS Traffic in Cloudflare with PowerShell

Cloudflare makes it incredibly easy to restrict deprecated TLS versions for all of your services, provided that your traffic is being proxied through them. While enforcing secure versions of TLS is easy, you should still do your due diligence before restricting TLS 1.0 and 1.1 if you are still allowing that traffic today.

There is a widget that will show your entire domain's observed traffic broken out by TLS version over a rolling 24 hour period, but in order to drill deeper to determine what source/destinations are involved, you will need to use either the Logpush or Logpull API.

Example Traffic Served Over TLS Depiction from SSL/TLS>Overview in Cloudflare admin portal

If you are not familiar, see my other post, Using the Cloudflare Logpull API with PowerShell, for a quick primer. Following the steps in that post will ensure that you retrieve your API key, Zone ID, and enable log retention, which will all be required to proceed here.


In this example we will be using the Logpull API to fetch events which include the ClientSSLProtocol field to display which version of TLS was used for the connection. This script will fetch the previous hour's worth of logs via the /logs/received endpoint for your zone and save as a .ndjson file locally:

#Specify filepath to export logs
$exportPath = "C:\some\file\path.ndjson"

#Cloudflare API Key
$apiKey = "YOUR_API_KEY_HERE"
#Cloudflare Zone
$zone = "YOUR_ZONE_ID_HERE"
#Cloudflare Profile Email Address
$email = "YOUR_EMAIL_ADDRESS_HERE"

#Get time from 1 hour ago in ISO 8601 format; e.g. 2022-03-23T02:30:19Z
$timeStart = (Get-Date -AsUTC).AddHours(-1).ToString("yyyy-MM-ddTHH:mm:ss") + "Z"
#Get time from 1 minute ago in ISO 8601 format; e.g. 2022-03-23T03:29:19Z
$timeEnd = (Get-Date -AsUTC).AddMinutes(-1).ToString("yyyy-MM-ddTHH:mm:ss") + "Z"

#Specify fields to return
$fields = "ClientIP,ClientRequestHost,ClientSSLProtocol,ClientRequestMethod,ClientRequestURI,EdgeEndTimestamp,EdgeResponseBytes,EdgeResponseStatus,EdgeStartTimestamp,RayID"
#URL endpoint with parameters
$url = "https://api.cloudflare.com/client/v4/zones/$zone/logs/received?start=$timeStart&end=$timeEnd&fields=$fields"

#Required authentication headers
$headers = @{
    "X-Auth-Key"   = $apiKey
    "X-Auth-Email" = $email
    "Content-Type" = "application/json"
}

#Send request, store response
$response = Invoke-RestMethod -Method Get -Uri $url -Headers $headers

#Create .ndjson file at $exportPath if it doesn't already exist, add contents of response to file
if (!(Test-Path -Path $exportPath)) {
    New-Item -Path $exportPath
    Add-Content -Path $exportPath -Value $response
} else {
    Add-Content -Path $exportPath -Value $response
}
Fetch one hour's worth of logs and save to a .ndjson file locally
Example output

Now that we have a file with newline-delimited JSON, we can convert this to a CSV, for example, to manually inspect the logs and filter for a specific versions of observed TLS traffic:

#Specify filepath to .ndjson file
$inputPath = "C:\some\file\path.ndjson"

#Specify filepath to export CSV
$exportPath = "C:\some\file\path.csv"

#Get content of file, convert from JSON to PowerShell objects, export as CSV
Get-Content -Path $inputPath | ConvertFrom-Json | Export-Csv -Path $exportPath
Convert NDJSON to CSV
Example CSV output

The example outlined above can be a quick way to identify a sample of traffic and look for specific hosts and URIs with external connections over a particular TLS version. You could easily run the first script as a scheduled task or cron job to get traffic over a longer period of time, depending on your needs.

This method will not scale well with large datasets - for that, it would be recommended to use the Logpush API to send Cloudflare logs to a system capable of indexing large amounts of data.

Great! Next, complete checkout for full access to Mr. Clix It.
Welcome back! You've successfully signed in.
You've successfully subscribed to Mr. Clix It.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info has been updated.
Your billing was not updated.