AWS – Globally Adjusting ELB SSL Policy

A while back, I had to adjust the policy of all Elastic Load Balancers in my organization to disable SSLv3 due to the POODLE exploit. This can be an error-prone task if done by hand, especially if your architecture spans multiple regions and/or more than a handful of ELBs. The nice thing about cloud architecture, is that nearly everything can be automated and/or scripted.  For that reason, I went ahead and wrote a PowerShell script to handle this.

Most other write-ups I have seen do not take into account Stickiness policies, which are also applied to listeners.  If you run the Set-ELBLoadBalancerPolicyOfListener cmdlet with only an SSL policy applied, it will remove any other existing listener policies.  It is important to check the ELB for other policies, and make sure they are reapplied.  There is logic in this script that handles that.

It is important to note that this script makes use of Amazon’s template SSL Negotation Policies, but could be adapted to make use of your own.

As of 4/9/15, you cannot simply set the ELB policy to a newer reference policy, although AWS documentation states otherwise.  For this reason, a new policy must be created which references the AWS Reference-Security-Policy of choice.  You can retrieve a list of available reference policies with the Get-ELBLoadBalancerPolicy cmdlet.

Code also available on my GitHub

# AWS Global ELB SSL Policy
# Brian Dwyer - Intelligent Digital Services - 4/5/15

# Variables
$PolicyName="SSL-POLICY--$(Get-Date -Format yy-MM-ddTHHmmss)"
$ELBReferencePolicy='ELBSecurityPolicy-2015-03'

# Dependencies
Import-Module AWSPowerShell



Write-Host 'Finding AWS Regions containing ELBs...'

$RegionsWithELBs = @{}

ForEach ( $region in (Get-EC2Region).RegionName )
{
    $ELB_Count = (Get-ELBLoadBalancer -Region $region).count
    if ( $ELB_Count -ge 1 )
    {
        $RegionsWithELBs.Add($region, $ELB_Count)
    }
}

# Display ELB Regions & Count
$tformat = @{Expression={$_.Name};Label="Region"}, @{Expression={$_.Value};Label="ELB Count"}
$RegionsWithELBs.GetEnumerator() | Sort-Object Value -Descending | Format-Table $tformat -AutoSize




ForEach ( $region in $RegionsWithELBs.Keys )
{
    # Verify reference policy existence in region
    if ( (Get-ELBLoadBalancerPolicy -Region $region).PolicyName -contains $ELBReferencePolicy )
    {
        Write-Host "`nModifying ELBs in region: '$region' `n"

        # Loop through the ELBs
        ForEach ( $lb in (Get-ELBLoadBalancer -Region $region ).LoadBalancerName )
        {
            # Verify ELB serves HTTPS
            if ( (Get-ELBLoadBalancer -Region $region -LoadBalancerName $lb).ListenerDescriptions.Listener.Protocol -contains 'HTTPS' )
            {

                # Find Existing Policies (App/Cookie Stickiness, etc.)

                $PoliciesToApply = @($PolicyName)

                ForEach ( $currentpolicy in ((Get-ELBLoadBalancer -Region $region -LoadBalancerName $lb).ListenerDescriptions | Where-Object { $_.Listener.Protocol -contains 'HTTPS'}).PolicyNames )
                {
                    if ( (Get-ELBLoadBalancerPolicy -Region $region -LoadBalancerName $lb -PolicyName $currentpolicy).PolicyTypeName -ne 'SSLNegotiationPolicyType' )
                    {
                        $PoliciesToApply += @($currentpolicy)
                    }
                }

                # Configure SSL Policy
                Write-Host "`nCreating '$PolicyName' from '$ELBReferencePolicy' for $lb"
                New-ELBLoadBalancerPolicy -Region $region -LoadBalancerName $lb -PolicyName $PolicyName `
                  -PolicyTypeName SSLNegotiationPolicyType `
                  -PolicyAttribute @{ AttributeName="Reference-Security-Policy";AttributeValue="$ELBReferencePolicy"} `
                  -Force
                Write-Host "Activating policy '$PolicyName' for ELB: $lb"
                Set-ELBLoadBalancerPolicyOfListener -Region "$region" -LoadBalancerName "$lb" -LoadBalancerPort 443 -PolicyName $PoliciesToApply

                # Cleanup Old Policies
                ForEach ($policy in (Get-ELBLoadBalancerPolicy -Region "$region" -LoadBalancerName "$lb" | Where-Object {$_.PolicyTypeName -eq 'SSLNegotiationPolicyType'}).PolicyName)
                {
                    if ( $policy -ne $PolicyName -and $policy -ne $ELBReferencePolicy )
                    {
                        Write-Host "Removing old policy '$policy' from ELB: $lb"
                        Remove-ELBLoadBalancerPolicy -Region "$region" -LoadBalancerName "$lb" -PolicyName $policy -Force
                    }
                }
            }
        }
    }
    Else
    {
        Write-Host "Region $region does not contain policy $ELBReferencePolicy"
    }
}
Advertisements

One thought on “AWS – Globally Adjusting ELB SSL Policy

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s