AWSのITコストを削減 Simpline

選ばれ続けること

 

エンジニアブログ

ホーム - エンジニアブログ - [AWS]AWS Configでルール違反検知 その3

[AWS]AWS Configでルール違反検知 その3

2018.08.15

こんにちは。

シンプラインのmiddleです。


前回に引き続き、壁の話をお送りします。

どうぞよろしくお願いいたします。


 


★今回のお題


セキュリティグループの開けてはいけないポートを開けてしまった時、検知したい


その1 背景〜使用するサービス選択

その2 AWS Configとは

その3 カスタムルール作成① ←本日はこちら

その4 カスタムルール作成②

その5 AWS Config設定〜まとめ


 


★書けました


こんな感じになりました。

※完成まで紆余曲折ありすぎたのですが、そこはAWSがどうこうというよりPythonの話なので、割愛します。



# Description: Check that security groups do not have an inbound rule
# with port except permitted.
#
# Trigger Type: Change Triggered
# Scope of Changes: EC2:SecurityGroup
# Accepted Parameters: examplePort1, examplePort2, ...
# Example Values: 22,80,443, ...
#
# You can designate some ports permitted by fill in okPort.
# note: It doesn't accept by Ranges.


import boto3
import json

APPLICABLE_RESOURCES = ["AWS::EC2::SecurityGroup"]

def evaluate_compliance(configuration_item, rule_parameters):

# Check if resource was deleted
if configuration_item['configurationItemStatus'] == "ResourceDeleted":
compliance_type = 'NOT_APPLICABLE'
annotation = "This resource was deleted."

# Check the resource for applicability
elif configuration_item["resourceType"] not in APPLICABLE_RESOURCES:
compliance_type = 'NOT_APPLICABLE'
annotation = "The rule apply to only resources of type SecurityGroup."

else:
# Check IP violation
for ipsg in configuration_item['configuration']['ipPermissions']:
if 'fromPort' not in ipsg:
compliance_type = 'NON_COMPLIANT'
annotation = 'Exposed ports range is ALL.'
break

else:
fp = ipsg['fromPort']
rp = []
rp = rule_parameters['okPort'].split(',')
if str(fp) not in rp:
compliance_type = 'NON_COMPLIANT'
annotation = 'A forbidden port is exposed.'
break

else:
compliance_type = 'COMPLIANT'
annotation = 'Security group is compliant.'

return {
"compliance_type": compliance_type,
"annotation": annotation
}


def lambda_handler(event, context):

invoking_event = json.loads(event['invokingEvent'])
rule_parameters = json.loads(event['ruleParameters'])
configuration_item = invoking_event["configurationItem"]
evaluation = evaluate_compliance(configuration_item, rule_parameters)
config = boto3.client('config')

print('Compliance evaluation for %s: %s' % (configuration_item['resourceId'], evaluation["compliance_type"]))
print('Annotation: %s' % (evaluation["annotation"]))

response = config.put_evaluations(
Evaluations=[
{
'ComplianceResourceType': invoking_event['configurationItem']['resourceType'],
'ComplianceResourceId': invoking_event['configurationItem']['resourceId'],
'ComplianceType': evaluation["compliance_type"],
"Annotation": evaluation["annotation"],
'OrderingTimestamp': invoking_event['configurationItem']['configurationItemCaptureTime']
},
],
ResultToken=event['resultToken'])


fromPort」というパラメータが、開いているポート範囲の開始値です。

単一ポートのみを開けていた場合はその値が、レンジで開けた場合は最小値が該当します。



★「fromPort」の例


80番ポートを開けた場合

→「80


22番〜80番ポートを開けた場合

→「22



ちなみに後者の場合、「toPort」という値(開いているポート範囲の終了値)に80が該当します。

前者の場合は「toPort」も80です。


また、これらのパラメータの値は、設定変更の操作履歴として記録されたイベントからとってきます。

ということはつまり、変更履歴が残ってない値はチェック出来ないのでは?


心配になったので、またサポートに問い合わせしたところ、問題ないと回答をいただきました。



セキュリティグループの変更をトリガーとして発行されるイベントには、セキュリティグループの既存ルールも含めてデータが格納されています。



※一部抜粋&改変してます。


一旦以上です。

次回に続きます。

よろしくお願いいたします。

1 Star 0 いいねしてね!
Loading...