AWS CLIを利用して、Inspectorを定期実行するLambda functionを作成して実行します
本記事について
本記事はJAWS-UG CLI専門支部の実施する予定だったハンズオン手順書です。
Lambdaでスケジュール実行するための手順でしたが、CloudWatch Eventから直接スケジュール実行が可能になったためこちらは廃止としました。
最新の全工程については下記総合案内をご確認ください。
#91 Amazon Inspector 入門 (CloudWatch Eventで定期診断編)
前提条件
Lambdaへの権限
Lambdaに対してフル権限があること。
AWS CLIのバージョン
以下のバージョンで動作確認済
- AWS CLI 1.11.122
aws --version
結果(例):
aws-cli/1.11.122 Python/2.7.10 Linux/4.1.27-25.49.amzn1.x86_64 botocore/1.5.85
バージョンが古い場合は最新版に更新しましょう。
sudo -H pip install -U awscli
- 準備
=======
まず変数の確認をします。
cat << ETX
AWS_DEFAULT_PROFILE: (0.1) ${AWS_DEFAULT_PROFILE}
IAM_ROLE_NAME (0.2) ${IAM_ROLE_NAME}
IAM_ROLE_ARN (0.3) ${IAM_ROLE_ARN}
ETX
結果(例):
AWS_DEFAULT_PROFILE: (0.1)
IAM_ROLE_NAME (0.2) lambda_inspector_role
IAM_ROLE_ARN (0.3) arn:aws:iam::xxxx:role/lambda_inspector_role
変数が入っていない、適切でない場合は、それぞれの手順番号について作業を
行います。
0.1. プロファイルの指定
プロファイルの一覧を確認します。
cat ~/.aws/credentials \
| grep '\[' \
| sed 's/\[//g' | sed 's/\]//g'
結果(例):
iamFull-prjz-mbpr13
<IAMのフル権限を許可されたプロファイル>
export AWS_DEFAULT_PROFILE='<IAMのフル権限を許可されたプロファイル>'
0.2. IAMロール名の指定
IAM_ROLE_NAME='inspector_role'
0.3. IAMロールARNの指定
IAMロールのARN確認
IAM_ROLE_ARN=$( \
aws iam get-role \
--role-name ${IAM_ROLE_NAME} \
--query 'Role.Arn' \
--output text \
) \
&& echo "${IAM_ROLE_ARN}"
結果(例):
arn:aws:iam::xxxxx:role/lambda_inspector_role
最終確認
cat << ETX
AWS_DEFAULT_PROFILE: (0.1) ${AWS_DEFAULT_PROFILE}
IAM_ROLE_NAME (0.2) ${IAM_ROLE_NAME}
IAM_ROLE_ARN (0.3) ${IAM_ROLE_ARN}
ETX
結果(例):
AWS_DEFAULT_PROFILE: (0.1)
IAM_ROLE_NAME (0.2) lambda_inspector_role
IAM_ROLE_ARN (0.3) arn:aws:iam::5xxxxx:role/lambda_inspector_role
本作業
1.1.lambdafunction名指定
LAMBDA_FUNC_NAME='inspector-lambda'
FILE_LAMBDA_FUNC="${LAMBDA_FUNC_NAME}.js"
結果:
(戻り値なし)
1.2.lambdafunction名確認
cat << ETX
FILE_LAMBDA_FUNC: ${FILE_LAMBDA_FUNC}
ASSESSMENT_TEMPLATE_ARN: ${ASSESSMENT_TEMPLATE_ARN}
ETX
結果(例):
FILE_LAMBDA_FUNC: inspector-lambda.js
ASSESSMENT_TEMPLATE_ARN: arn:aws:inspector:ap-northeast-1:xxxxxxx:target/0-ZVbpDP3K/template/0-YZMRHdpp
1.3.lambdafunctionファイル設定
cat << EOF > ${FILE_LAMBDA_FUNC}
'use strict';
const AWS = require('aws-sdk');
const inspector = new AWS.Inspector();
const params = {
assessmentTemplateArn: "${ASSESSMENT_TEMPLATE_ARN}",
};
exports.handler = (event, context, callback) => {
try {
// Inspector.StartAssessmentRun response will look something like:
// {"assessmentRunArn":"${ASSESSMENT_TEMPLATE_ARN}"
inspector.startAssessmentRun(params, (error, data) => {
if (error) {
console.log(error, error.stack);
return callback(error);
}
console.log(data);
return callback(null, data);
});
} catch (error) {
console.log('Caught Error: ', error);
callback(error);
}
};
EOF
cat ${FILE_LAMBDA_FUNC}
結果(例):
'use strict';
const AWS = require('aws-sdk');
const inspector = new AWS.Inspector();
const params = {
assessmentTemplateArn: "arn:aws:inspector:ap-northeast-1:549352348160:target/0-ZVbpDP3K/template/0-YZMRHdpp",
};
exports.handler = (event, context, callback) => {
try {
// Inspector.StartAssessmentRun response will look something like:
// {"assessmentRunArn":"arn:aws:inspector:ap-northeast-1:549352348160:target/0-ZVbpDP3K/template/0-YZMRHdpp"
inspector.startAssessmentRun(params, (error, data) => {
if (error) {
console.log(error, error.stack);
return callback(error);
}
console.log(data);
return callback(null, data);
});
} catch (error) {
console.log('Caught Error: ', error);
callback(error);
}
};
zip ${LAMBDA_FUNC_NAME}.zip ${FILE_LAMBDA_FUNC}
結果(例):
adding: inspector-lambda.js (deflated 56%)
2.1.lambdafunction用変数指定
LAMBDA_FUNC_DESC='Schedules a recurring Amazon Inspector assessment run'
LAMBDA_RUNTIME='nodejs4.3'
LAMBDA_HANDLER="${LAMBDA_FUNC_NAME}.handler"
FILE_LAMBDA_ZIP="${LAMBDA_FUNC_NAME}.zip"
2.2.設定用変数の確認
cat << ETX
LAMBDA_FUNC_NAME: ${LAMBDA_FUNC_NAME}
LAMBDA_FUNC_DESC: "${LAMBDA_FUNC_DESC}"
LAMBDA_RUNTIME: ${LAMBDA_RUNTIME}
IAM_ROLE_ARN: ${IAM_ROLE_ARN}
LAMBDA_HANDLER: ${LAMBDA_HANDLER}
FILE_LAMBDA_ZIP ${FILE_LAMBDA_ZIP}
ETX
結果(例):
LAMBDA_FUNC_NAME: inspector-lambda
LAMBDA_FUNC_DESC: "Schedules a recurring Amazon Inspector assessment run"
LAMBDA_RUNTIME: nodejs4.3
IAM_ROLE_ARN: arn:aws:iam::549352348160:role/lambda_inspector_role
LAMBDA_HANDLER: inspector-lambda.handler
FILE_LAMBDA_ZIP inspector-lambda.zip
2.3.lambdafunction作成
aws lambda create-function \
--function-name ${LAMBDA_FUNC_NAME} \
--description "${LAMBDA_FUNC_DESC}" \
--zip-file fileb://${FILE_LAMBDA_ZIP} \
--runtime ${LAMBDA_RUNTIME} \
--role ${IAM_ROLE_ARN} \
--handler ${LAMBDA_HANDLER}
結果(例):
{
"TracingConfig": {
"Mode": "PassThrough"
},
"CodeSha256": "FvWrbSR1JNa3VXNC2uB3ibyjimxxxxxxx",
"FunctionName": "inspector-lambda",
"CodeSize": 567,
"MemorySize": 128,
"FunctionArn": "arn:aws:lambda:ap-northeast-1:xxxx:function:inspector-lambda",
"Version": "$LATEST",
"Role": "arn:aws:iam::549352348160:role/lambda_inspector_role",
"Timeout": 3,
"LastModified": "2017-07-24T06:47:34.517+0000",
"Handler": "inspector-lambda.handler",
"Runtime": "nodejs4.3",
"Description": "Schedules a recurring Amazon Inspector assessment run"
}
2.3.lambdafunction確認
aws lambda get-function \
--function-name ${LAMBDA_FUNC_NAME}
結果(例):
{
"Code": {
"RepositoryType": "S3",
"Location": "https://awslambda-ap-nxxxxxxxxxxxx"
},
"Configuration": {
"TracingConfig": {
"Mode": "PassThrough"
},
"Version": "$LATEST",
"CodeSha256": "FvWrbSR1JNa3VXNC2uB3ibyjimWyEzzzzzzzz",
"FunctionName": "inspector-lambda",
"MemorySize": 128,
"CodeSize": 567,
"FunctionArn": "arn:aws:lambda:ap-northeast-1:5493xxxx:function:inspector-lambda",
"Handler": "inspector-lambda.handler",
"Role": "arn:aws:iam::54935x2xxxxxxxx:role/lambda_inspector_role",
"Timeout": 3,
"LastModified": "2017-07-24T06:47:34.517+0000",
"Runtime": "nodejs4.3",
"Description": "Schedules a recurring Amazon Inspector assessment run"
}
}
aws lambda get-function-configuration \
--function-name ${LAMBDA_FUNC_NAME}
結果(例):
{
"TracingConfig": {
"Mode": "PassThrough"
},
"CodeSha256": "FvWrbSR1JNa3VXNC2uB3ibyjimWyE4r+gPvFtI1R1jQ=",
"FunctionName": "inspector-lambda",
"CodeSize": 567,
"MemorySize": 128,
"FunctionArn": "arn:aws:lambda:ap-northeast-1:54xxxxx:function:inspector-lambda",
"Version": "$LATEST",
"Role": "arn:aws:iam::549352348160:role/lambda_inspector_role",
"Timeout": 3,
"LastModified": "2017-07-24T06:47:34.517+0000",
"Handler": "inspector-lambda.handler",
"Runtime": "nodejs4.3",
"Description": "Schedules a recurring Amazon Inspector assessment run"
}
2.3.lambdafunction手動実行用変数設定
FILE_OUTPUT_LAMBDA="${LAMBDA_FUNC_NAME}-out.txt" \
&& echo ${FILE_OUTPUT_LAMBDA}
cat << ETX
LAMBDA_FUNC_NAME: ${LAMBDA_FUNC_NAME}
FILE_OUTPUT_LAMBDA: ${FILE_OUTPUT_LAMBDA}
ETX
結果(例):
LAMBDA_FUNC_NAME: inspector-lambda
FILE_OUTPUT_LAMBDA: inspector-lambda-out.txt
FILE_LOG_LAMBDA="${LAMBDA_FUNC_NAME}-$(date +%Y%m%d%H%M%S).log" \
&& echo ${FILE_LOG_LAMBDA}
2.4.lambdafunction手動実行
他の診断が実行中の場合、エラーとなりますので必ずInspectorno実行状況を確認してから実行してください。
aws lambda invoke \
--function-name ${LAMBDA_FUNC_NAME} \
--log-type Tail \
${FILE_OUTPUT_LAMBDA} \
> ${FILE_LOG_LAMBDA} \
cat ${FILE_LOG_LAMBDA} \
| jp.py 'StatusCode'
結果(例):
200
200が出ていれば成功
2.6.lambdafunctionの実行結果の確認
cat ${FILE_OUTPUT_LAMBDA}
結果(例):
{"assessmentRunArn":"arn:aws:inspector:ap-northeast-1:549352348160:target/0-ZVbpDP3K/template/0-YZMRHdpp/run/0-9wd6AT8V"}
2.7.lambdafunctionののログの確認
cat ${FILE_LOG_LAMBDA} \
| jp.py 'LogResult' \
| sed 's/\"//g' \
| base64 --decode
結果(例):
START RequestId: a411c2f7-703e-11e7-9f55-d756e6d26920 Version: $LATEST
2017-07-24T07:06:41.612Z a411c2f7-703e-11e7-9f55-d756e6d26920 { assessmentRunArn: 'arn:aws:inspector:ap-northeast-1:xxxxxxxx:target/0-ZVbpDP3K/template/0-YZMRHdpp/run/0-9wd6AT8V' }
END RequestId: a411c2f7-703e-11e7-9f55-d756e6d26920
REPORT RequestId: a411c2f7-703e-11e7-9f55-d756e6d26920 Duration: 1452.50 ms Billed Duration: 1500 ms Memory Size: 128 MB Max Memory Used: 43 MB
2.7.Inspectorの実行結果の確認
ASSESSMENT_RUN_ARN=`cat ${FILE_OUTPUT_LAMBDA}|awk -F\" '{print $4}'`
aws inspector describe-assessment-runs \
--assessment-run-arns ${ASSESSMENT_RUN_ARN}
結果(例):
{
"failedItems": {},
"assessmentRuns": [
{
"dataCollected": true,
"name": "template-security-15m/2017-07-24T07:06/zcoQ",
"completedAt": 1500880986.637,
"userAttributesForFindings": [],
"stateChanges": [
{
"state": "CREATED",
"stateChangedAt": 1500880001.32
},
{
"state": "START_DATA_COLLECTION_PENDING",
"stateChangedAt": 1500880001.428
},
{
"state": "START_DATA_COLLECTION_IN_PROGRESS",
"stateChangedAt": 1500880001.502
},
{
"state": "COLLECTING_DATA",
"stateChangedAt": 1500880001.617
},
{
"state": "STOP_DATA_COLLECTION_PENDING",
"stateChangedAt": 1500880901.809
},
{
"state": "DATA_COLLECTED",
"stateChangedAt": 1500880965.342
},
{
"state": "START_EVALUATING_RULES_PENDING",
"stateChangedAt": 1500880965.55
},
{
"state": "EVALUATING_RULES",
"stateChangedAt": 1500880966.067
},
{
"state": "COMPLETED",
"stateChangedAt": 1500880986.637
}
],
"createdAt": 1500880001.32,
"findingCounts": {
"High": 0,
"Medium": 1,
"Informational": 0,
"Low": 0
},
"notifications": [],
"state": "COMPLETED",
"stateChangedAt": 1500880986.637,
"durationInSeconds": 900,
"rulesPackageArns": [
"arn:aws:inspector:ap-northeast-1:406045910587:rulespackage/0-bBUQnxMq"
],
"startedAt": 1500880001.617,
"assessmentTemplateArn": "arn:aws:inspector:ap-northeast-1:549352348160:target/0-ZVbpDP3K/template/0-YZMRHdpp",
"arn": "arn:aws:inspector:ap-northeast-1:549352348160:target/0-ZVbpDP3K/template/0-YZMRHdpp/run/0-9wd6AT8V"
}
]
}
stateがCOMPLETEDに変わっていたら完了
2.8.診断レポートの確認
stateがCOMPLETEDに変わってから実行します
aws inspector get-assessment-report \
--assessment-run-arn ${ASSESSMENT_RUN_ARN}
--report-file-format HTML \
--report-type FINDING
結果(例):
{
"status": "COMPLETED",
"url": "https://inspector-temp-reports-prod-ap-northeast-1.s3-ap-northeast-1.amazonaws.comxxxxxx"
}
ブラウザでURLにアクセスすると診断レポートを閲覧できます