rules/Azure.VMSS.Rule.ps1
# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # # Validation rules for Azure Virtual Machine Scale Sets # #region Virtual machine scale set # Synopsis: Use VM naming requirements Rule 'Azure.VMSS.Name' -Ref 'AZR-000261' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } { # https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute # Between 1 and 64 characters long $Assert.GreaterOrEqual($TargetObject, 'Name', 1) $Assert.LessOrEqual($TargetObject, 'Name', 64) # Alphanumerics, underscores, periods, and hyphens # Start with alphanumeric # End with alphanumeric or underscore Match 'Name' '^[A-Za-z0-9]((-|\.)*\w){0,79}$' } # Synopsis: Use VM naming requirements Rule 'Azure.VMSS.ComputerName' -Ref 'AZR-000262' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2020_06'; 'Azure.WAF/pillar' = 'Operational Excellence'; } { # https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules#microsoftcompute $maxLength = 64 $matchExpression = '^[A-Za-z0-9]([A-Za-z0-9-.]){0,63}$' if (IsWindowsOS) { $maxLength = 15 # Alphanumeric or hyphens # Can not include only numbers $matchExpression = '^[A-Za-z0-9-]{0,14}[A-Za-z-][A-Za-z0-9-]{0,14}$' } # Between 1 and 15/ 64 characters long $Assert.GreaterOrEqual($TargetObject, 'Properties.virtualMachineProfile.osProfile.computerNamePrefix', 1) $Assert.LessOrEqual($TargetObject, 'Properties.virtualMachineProfile.osProfile.computerNamePrefix', $maxLength) # Alphanumerics and hyphens # Start and end with alphanumeric Match 'Properties.virtualMachineProfile.osProfile.computerNamePrefix' $matchExpression } # Synopsis: Use SSH keys instead of common credentials to secure virtual machine scale sets against malicious activities. Rule 'Azure.VMSS.PublicKey' -Ref 'AZR-000288' -Type 'Microsoft.Compute/virtualMachineScaleSets' -If { VMSSHasLinuxOS } -Tag @{ release = 'GA'; ruleSet = '2022_09'; 'Azure.WAF/pillar' = 'Security'; } -Labels @{ 'Azure.MCSB.v1/control' = 'DP-4' } { $Assert.In($TargetObject, 'properties.virtualMachineProfile.OsProfile.linuxConfiguration.disablePasswordAuthentication', $True). Reason($LocalizedData.VMSSPublicKey, $PSRule.TargetName) } # Synopsis: Protect Custom Script Extensions commands Rule 'Azure.VMSS.ScriptExtensions' -Ref 'AZR-000333' -Type 'Microsoft.Compute/virtualMachineScaleSets', 'Microsoft.Computer/virtualMachineScaleSets/CustomScriptExtension', 'Microsoft.Compute/virtualMachineScaleSets/extensions' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } { $vmssConfig = @($TargetObject); ## Extension Prof if ($vmssConfig.properties.virtualMachineProfile.extensionProfile.extensions) { foreach ($extensions in $vmssConfig.properties.virtualMachineProfile.extensionProfile.extensions ) { $cleanValue = [PSRule.Rules.Azure.Runtime.Helper]::CompressExpression($extensions.properties.settings.commandToExecute); $Assert.NotMatch($cleanValue, '.', "SecretReference") } } else { return $Assert.Pass(); } } # Synopsis: Use Azure Monitor Agent as replacement for Log Analytics Agent. Rule 'Azure.VMSS.MigrateAMA' -Ref 'AZR-000318' -Type 'Microsoft.Compute/virtualMachineScaleSets' -If { HasOMSOrAMAExtension } -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } { $property = $TargetObject.Properties.virtualMachineProfile.extensionProfile.extensions.properties | Where-Object { (($_.publisher -eq 'Microsoft.EnterpriseCloud.Monitoring') -and ($_.type -eq 'MicrosoftMonitoringAgent')) -or (($_.publisher -eq 'Microsoft.EnterpriseCloud.Monitoring') -and ($_.type -eq 'OmsAgentForLinux')) } $subresource = @(GetSubResources -ResourceType 'Microsoft.Compute/virtualMachineScaleSets/extensions' | Where-Object { (($_.Properties.publisher -eq 'Microsoft.EnterpriseCloud.Monitoring') -and ($_.Properties.type -eq 'MicrosoftMonitoringAgent')) -or (($_.Properties.publisher -eq 'Microsoft.EnterpriseCloud.Monitoring') -and ($_.Properties.type -eq 'OmsAgentForLinux')) }) $extensions = @($property; $subresource) $Assert.Less($extensions, '.', 1).Reason($LocalizedData.LogAnalyticsAgentDeprecated) } # Synopsis: Use Azure Monitor Agent for collecting monitoring data. Rule 'Azure.VMSS.AMA' -Ref 'AZR-000346' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } { $amaTypes = @('AzureMonitorWindowsAgent', 'AzureMonitorLinuxAgent') $property = $TargetObject.Properties.virtualMachineProfile.extensionProfile.extensions.properties | Where-Object { $_.publisher -eq 'Microsoft.Azure.Monitor' -or $_.type -in $amaTypes } $subresource = @(GetSubResources -ResourceType 'Microsoft.Compute/virtualMachineScaleSets/extensions' | Where-Object { $_.properties.publisher -eq 'Microsoft.Azure.Monitor' -or $_.properties.type -in $amaTypes }) $amaExtensions = @($property; $subresource) $Assert.GreaterOrEqual($amaExtensions, '.', 1). Reason($LocalizedData.VMSSAzureMonitorAgent) } # Synopsis: Deploy virtual machine scale set instances using availability zones in supported regions to ensure high availability and resilience. Rule 'Azure.VMSS.AvailabilityZone' -Ref 'AZR-000436' -Type 'Microsoft.Compute/virtualMachineScaleSets' -Tag @{ release = 'GA'; ruleSet = '2024_09'; 'Azure.WAF/pillar' = 'Reliability'; } { # Check if the region supports availability zones. $provider = [PSRule.Rules.Azure.Runtime.Helper]::GetResourceType('Microsoft.Compute', 'virtualMachineScaleSets') $availabilityZones = GetAvailabilityZone -Location $TargetObject.Location -Zone $provider.ZoneMappings # Don't flag if the region does not support availability zones. if (-not $availabilityZones) { return $Assert.Pass() } $Assert.GreaterOrEqual($TargetObject, 'zones', 2).Reason( $LocalizedData.VMSSAvailabilityZone, $TargetObject.name, $TargetObject.location, ($availabilityZones -join ', ') ) } # Synopsis: Deploy virtual machine scale set instances using the best-effort zone balance in supported regions to ensure an approximately balanced distribution of instances across availability zones. Rule 'Azure.VMSS.ZoneBalance' -Ref 'AZR-000438' -Type 'Microsoft.Compute/virtualMachineScaleSets' -If { RegionSupportsAvailabilityZones } -Tag @{ release = 'GA'; ruleSet = '2024_09'; 'Azure.WAF/pillar' = 'Reliability'; } { $Assert.HasDefaultValue($TargetObject, 'properties.zoneBalance', $false) } # Synopsis: Avoid attaching public IPs directly to virtual machine scale set instances. Rule 'Azure.VMSS.PublicIPAttached' -Ref 'AZR-000450' -Type 'Microsoft.Compute/virtualMachineScaleSets', 'Microsoft.Compute/virtualMachineScaleSets/virtualMachines' -Tag @{ release = 'GA'; ruleSet = '2024_09'; 'Azure.WAF/pillar' = 'Security'; } { if ($PSRule.TargetType -eq 'Microsoft.Compute/virtualMachineScaleSets') { $configurations = @( $TargetObject.properties.virtualMachineProfile.networkProfile.networkInterfaceConfigurations | ForEach-Object { $_.properties.ipConfigurations } | Where-Object { $null -ne $_ } GetSubResources -ResourceType 'Microsoft.Compute/virtualMachineScaleSets/virtualMachines' | ForEach-Object { $_.properties.networkProfile.networkInterfaceConfigurations } | ForEach-Object { $_.properties.ipConfigurations } | Where-Object { $null -ne $_ } GetSubResources -ResourceType 'Microsoft.Compute/virtualMachineScaleSets/virtualMachines' | ForEach-Object { $_.properties.networkProfileConfiguration.networkInterfaceConfigurations } | ForEach-Object { $_.properties.ipConfigurations } | Where-Object { $null -ne $_ } ) if ($configurations.Count -eq 0) { return $Assert.Pass() } foreach ($config in $configurations) { $Assert.HasDefaultValue($config, 'properties.publicIPAddressConfiguration.name', $null).Reason($LocalizedData.VMSSPublicIPAttached) } } else { $configurations = @( $TargetObject.properties.networkProfile.networkInterfaceConfigurations | ForEach-Object { $_.properties.ipConfigurations } | Where-Object { $null -ne $_ } $TargetObject.properties.networkProfileConfiguration.networkInterfaceConfigurations | ForEach-Object { $_.properties.ipConfigurations } | Where-Object { $null -ne $_ } ) if ($configurations.Count -eq 0) { return $Assert.Pass() } foreach ($config in $configurations) { $Assert.HasDefaultValue($config, 'properties.publicIPAddressConfiguration.name', $null).Reason($LocalizedData.VMSSPublicIPAttached) } } } #endregion Rules #endregion Virtual machine scale set #region Helper functions function global:IsLinuxVMSS { [CmdletBinding()] [OutputType([System.Boolean])] param () process { return $Assert.HasField($TargetObject, 'properties.virtualMachineProfile.OsProfile.linuxConfiguration').Result } } function global:RegionSupportsAvailabilityZones { [CmdletBinding()] param ( ) $provider = [PSRule.Rules.Azure.Runtime.Helper]::GetResourceType('Microsoft.Compute', 'virtualMachineScaleSets') $availabilityZones = GetAvailabilityZone -Location $TargetObject.Location -Zone $provider.ZoneMappings if (-not $availabilityZones) { return $false } $true } #endregion Helper functions # SIG # Begin signature block # MIIoLAYJKoZIhvcNAQcCoIIoHTCCKBkCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDKi9mBIAhJ2YVU # c8+/r4zYA2x4r/sbPlH9g0610Rc0TaCCDXYwggX0MIID3KADAgECAhMzAAAEBGx0 # Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz # NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo # DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3 # a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF # HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy # 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC # Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj # L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp # h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3 # cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X # dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL # E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi # u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1 # sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq # 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb # DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/ # V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg # Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03 # a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr # rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg # OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy # 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9 # sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh # dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k # A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB # w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn # Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90 # lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w # ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o # ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG # AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV # HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG # AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl # AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb # C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l # hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6 # I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0 # wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560 # STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam # ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa # J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah # XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA # 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt # Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr # /Xmfwb1tbWrJUnMTDXpQzTGCGgwwghoIAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB # BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIMKrwUdwz2zvriPXARXYO2Dq # Eu1OdSk9LkEhMkUTpaUlMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB # BQAEggEAMg30wqRrdZu45agGize3jE8wcUK4nJZPuGuMuTR8PAlr2OiOAItgojOu # 7c56E63RehI8nhWtDi0l6mc1BoTQkrjoJQCUs/xVlMwsVxKlBX9s7wYqkZ5Tj5vX # voF95K3ioCjj5rIZZf6TxjfdIEAGGvQhXhlKL8ODWYjjfkqhiHshQj2XOuC+PWIx # 2H16Zedl8P4itwDmL6uzY4aPRhru3OXAcDJRxjmQS9wI+aBXteHlJb3v3R2Eu46z # G2XtoUZq9zxr3n+Z1bMdAboWipLE9KPcZosL/iDvv78SZN3NKVgEsqwRhyCpCp0f # 3l8aJarQ4TGOhOY5atflcdVJO0nnfaGCF5YwgheSBgorBgEEAYI3AwMBMYIXgjCC # F34GCSqGSIb3DQEHAqCCF28wghdrAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFRBgsq # hkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl # AwQCAQUABCARUITHvXK8wlz3QWP9OfcJ1jPeqkpAt5NsvytAeADWNAIGZxqK/xjs # GBIyMDI0MTEwNzE3MDUxNS4yMVowBIACAfSggdGkgc4wgcsxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy # aWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo5NjAwLTA1 # RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCC # Ee0wggcgMIIFCKADAgECAhMzAAAB74k/VqFYzKjaAAEAAAHvMA0GCSqGSIb3DQEB # CwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV # BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTIzMTIwNjE4NDU0 # OFoXDTI1MDMwNTE4NDU0OFowgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMx # JzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo5NjAwLTA1RTAtRDk0NzElMCMGA1UE # AxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEB # BQADggIPADCCAgoCggIBAKMLWOKfDOAfCE5qRmrLXugTgEgEqybmRfgNSYIFYjSU # VWkSIrmZnYqHn2ygvieznamEUxBgYbmTKkKKm6eDA/02hvhUZUTpqgyjmFn03K1d # HllGBv1nw1HoSYsogJGEPiyiM8yD9GcZFNx1/v9Ni/IzXSMuOYvIoR6Awd+8jA+Y # z4A/uHNAt8TEN2oIna7rgZ3leWesU6S7lT2Ms4qTXLvRz5PC3Tj9Euqu6/V8Y/wu # Zia0e+sHhNwGwANdKZwWOHRWBCRfjNcXCqcgbyuBj7MOolhA1k/w7VijiRJyQdPj # dcLSgzjTJ7b72X+tNiIMUzeeVl7aOG06QYI7oaqJOnnTEj0hOkleLS8R6TwB6NPg # 8owQ7Zs/FTrenre5luN03kv6WAhwI0wI0jRIiilLiBpVHhLL8igO/W8Nal74jbz8 # rLyNZN553Q7cfE8kxmpfhAHcjoOfBmseIqfqgTfy2AFMIIAq8Shg5ODuvaUXQi5u # 3/f5U+8q1MJRtk8U4byNm32roAWh2W9Ce2KiVghi2pKsvJcBAiVcaFniA1y/h2/V # gCKWdtYD0KydiH44oQWv/jDgzr2Uj7Jqhncv+39R9elP/7JzuFL8WiVyasYUlMFi # VLicTVy4puXBn9Q4bbpIuEM41ZcZkMowko3neg4tJKTiV1HQeWxtPiF4uVaU4SUl # AgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQU7UxaooXCsJu2vD0/wDrdsBVInMswHwYD # VR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZO # aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIw # VGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBc # BggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0 # cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYD # VR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMC # B4AwDQYJKoZIhvcNAQELBQADggIBABgZlrdoIO51uT0RV2Q/zFxAZm4gAg9HH0rU # IDu5HMG3zR8LRpaS5hiFAy8cclEdShtIzhTDfM3t8cQ3yGFoENv01FoacVZ20fGY # n14zPommfoqIjKL1Tk6DtAJNkyXXufbDh512rm+2TitFY5W+mIMEYkBEqJdYH27a # LHRYfYQwUYeqMiGNZReE+BHgLo0oU1ce9a9d5wnZZesme+9AZcB80kYRMlkalHjW # dQ3eKN+IJKMUPFqYY+zLmJi73Tge/265Jdh3mbQnF/ZY0lJeQ8aU2Gs7buk/GBPX # XWbIBHrVLdLaFznvbM33KgkQ5sT3xXLkoQzdlfndwt583zUXUL2n9wAqQTq71Xqv # LKX+pKDG7VSp45kK0b+JodIoyjEzsyrhIwWw9P/yJ453AKVilzDQKNl7koHHbEtr # gHWd4WJvwnz+BKiyMx0XeceLIfHVh51kO3FJKB6B4myLR9tSB3OxUwli+pXDnZap # A27QZELv1m5Wt5RUp0ImZQwEcGlOnpUWikvQl/hKuCD7NEP2LBtz25muf7z2h2ki # dvOdiuc8oeI7bqp7V6Q3CX93uujYi0/+WCHPQOgPuQQZ6KQolYd22jt5UmgmGStR # xqdO5QfTyD41jAbpL4+MFIH83I0Xpsdr/FH5x4BiFyPHSIGK/3QyfQmIZ+cDb+Eu # Pl6+FNwCMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG # 9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO # BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEy # MDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw # MTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt # ZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az # /1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V2 # 9YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oa # ezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkN # yjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7K # MtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRf # NN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SU # HDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoY # WmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5 # C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8 # FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TAS # BgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1 # Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUw # UzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNy # b3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoG # CCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIB # hjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fO # mhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9w # a2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggr # BgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNv # bS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3 # DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEz # tTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJW # AAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G # 82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/Aye # ixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI9 # 5ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1j # dEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZ # KCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xB # Zj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuP # Ntq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvp # e784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCA1Aw # ggI4AgEBMIH5oYHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScw # JQYDVQQLEx5uU2hpZWxkIFRTUyBFU046OTYwMC0wNUUwLUQ5NDcxJTAjBgNVBAMT # HE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAEtw # jzWDFt5rUTHaYVtfHtyT7SD/oIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg # UENBIDIwMTAwDQYJKoZIhvcNAQELBQACBQDq1tStMCIYDzIwMjQxMTA3MDU1NDUz # WhgPMjAyNDExMDgwNTU0NTNaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAOrW1K0C # AQAwCgIBAAICH3YCAf8wBwIBAAICEo8wCgIFAOrYJi0CAQAwNgYKKwYBBAGEWQoE # AjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkq # hkiG9w0BAQsFAAOCAQEAe877QsiGsxz9/vRLdj2rj4aBB10Xoapx8+m2ZBtG4NW2 # BCH0v/tyAwvcXS4ysxD/Jg9Y7DYpqENBv8i2rzxBewWyZtBlZT5Gzk29arNpIhCk # 4cibiu13Ug48iPwMQpKsZDbCK6nGEj6daFMQDVETBy7Idr+X/ertPis3Vgs3T22E # TwlVv5oKSFC8szTJOQlV2dzKKqy1rYn2jXbE42Rv/6Aq//7QWG16KGl6+Eb8+c3m # iul3OmHYNMPD/IpTenxVstriKW7jxgAy1nHVaXHgRFq5p6mrOkAiy351QWnYrx9J # gWehPBSnG9k3FKkhXjLlMFL8uqRBYrt9KWr+aw12OjGCBA0wggQJAgEBMIGTMHwx # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1p # Y3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB74k/VqFYzKjaAAEAAAHv # MA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQw # LwYJKoZIhvcNAQkEMSIEIM6BWb7AoAyRmgL7TKtipLNYqnCPggytRax4Ohujaflh # MIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQg8GEoRbgWjfBTPT01DHZrQNtx # 2xfyOi8zkuLMeafJf6MwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg # MjAxMAITMwAAAe+JP1ahWMyo2gABAAAB7zAiBCCQA97DdIhMdcJ/0NAB4AL+9A0S # v4Z4jhoTdIaw92xGETANBgkqhkiG9w0BAQsFAASCAgA7fKGWIdqqchpfa1zblDqo # fpE4b6WNFi1AsJLUiawqb7WxbWYYDFfiFv3xzQWmjOfRmYPdRLExOkzAAvhNbr97 # 6ldvPNH5bZ26G2x6VyG0Hg3xetxkly1aFSeoWROVW2dw+7icVm8fF5zY3pv4ZH6t # LW2E6D5RS/GoMRIFqqf0VcFK9+acvcN93s123D0Ye1wHXBwHcHK8TMTmJBo5mJuV # qA/hEQImzrldmtQ3PMDCl2AAwbfn7pxr7CS7xZCKzFFibavQfezjje4XyecodwKc # GYMj+ifSU0Ic78IVq/83kjPYB2bwjFH43BNtoW0XsEVYYtAgHJTBoiRFRfTqq/e4 # 2pqQHLv/KrVNi/gdGNr2bnb145EajUb+CXIQhdqlaGFYlZbYce9eValJWKBG3SxA # n8nXmYTYMpUAhxn/wqUDBYVd5wJ5sbW8aiVzQPAiRtaorzeUPv4zm5oFPy8N96J2 # tY76ygw0t1GAOnXgd892X2DKI7HHqiaSOQXHVofwCs2J2plFqEl6cyncCgdfb+A/ # RAy7biCEj2ZvTCTSMDn802mAWoPh2pvLRZuU2bYwMSAnucOVC3Q/6cmZN5ezU8B3 # EhRY+aEVUrlFrJxArkiPl5USyoJPtbt3rq4Ym/BSdEX5AoBvd4t0yo9Ianzip+PI # ctAWa0iNwCPUxbhe7IVZPg== # SIG # End signature block |