목표시스템
AWS 계정관리에서 Access key 를 90일만 사용하도록 권장하고 있다
보안 때문이라도 90일 넘는 Access key 는 삭제하고 다시 새로운 Access key 를 만들어서 사용해야 한다
하지만, 사용자들은 Cli 로만 접근해서 사용한다면 90일 지났는지 알 수 없다
(AWS 콘솔로 들어가야지 확인가능하다)
그래서 람다로 스케쥴을 걸어서 매일 Access key 가 90일이 지난 사용자들이 있는 지 확인해서
90일이 지난 Access key 를 가지오 있는 사용자들에게 메시지를 보내서 알 수 있게 하려고 한다
사용하는기술
Javascript : 그냥 요즘 javascript 를 많이 쓰고 있어서
serverless framework : 서버리스 프레임워크 중에서 제일 맘에 들어서
lambda : aws 계정관리 이니 당연히 lambd
cloudwatch : cron 설정해서 매일 확인 또는 매주 확인 시키려고 함
VSCode : 에디터가 이거밖에 없다
dooray : 회사용 메신저 (잔디에서 바꿨다)
환경구성하기
Step 1. 개발할 폴더 만들고 VScode 에 project manager 로 등록
D:\workspace\monitoring-aws-iamkey
Step 2. node 프로젝트 초기설정
npm 초기세팅 해주고 author 추가
npm init -y
npm init -y
생성된
package.json 파일
Step 3. 필요한 node 패키지를 설치한다
필요한 패키지 설치해준다
개발할 때만 사용하는 패키지 설치
npm i -D aws-sdk
운영용으로도 사용하는 패키지 설치
npm i request
Step 4. serverless framework 설정파일을 만든다
serverless.yml 파일
해당 람다 함수가 user 이 List 와 Accesskey 의 List 를 조회하고
그리고, Inactive 된 AccessKey 를 삭제하니 DeleteAccessKey 권한을 부여합니다
iamRoleStatements:
- Effect: "Allow"
Action:
- "iam:ListUsers"
- "iam:ListAccessKeys"
- "iam:DeleteAccessKey"
Resource:
Fn::Join:
- ":"
- - "arn:aws:iam:"
- Ref: AWS::AccountId
- "user/*"
NOTE : serverless.yml 에서 변수를 다른 파일을 참조해서 읽어오도록 해봤습니다
DOORAYURL: ${file(./config/config.${self:provider.stage}.json):DOORAYURL}
config.dev.json 파일
{ "DOORAYURL" : "https://hook.dooray.com/services/DOORAY_WEBHOOK_URL" }
개발하기
Step 1. index.js 만들기
src 폴더 아래 index.js 파일 생성
설명
메인 함수는 searchUsers 입니다, event, context, callback 전부 사용하지 않아요.
module.exports.sendNotification = (event, context, callback) => {
searchUsers();
};
searchUsers 는 전체 사용자 리스트를 불러오고
각 사용자별로 searchAccessKey 를 실행합니다
const searchUsers = () => {
let params = {};
iam.listUsers(params, function(err, data) {
if (err) console.log(err, err.stack);
for(var index = 0; index < data.Users.length; index++){
searchAccessKey(data.Users[index].UserName);
}
});
};
searchAccessKey 는 사용자별로 2개까지 생성할 수 있는 AccessKey 를 불러와서
사용하지 않는 AccessKey 는 삭제를 시키고
90일이 지난 AccessKey 는 메시지를 보냅니다
const searchAccessKey = (userName) => {
let params = { UserName : userName };
iam.listAccessKeys(params, function(err, data) {
if (err) console.log(err, err.stack);
else {
for(let index=0; index < data.AccessKeyMetadata.length; index++){
if (isInActivateKey(data.AccessKeyMetadata[index])) {
deleteKey(userName, data.AccessKeyMetadata[index].AccessKeyId);
}
if (isExpiredKey(data.AccessKeyMetadata[index])) {
sendMessage(userName, data.AccessKeyMetadata[index]);
}
}
}
});
};
sendMessage 는 두레이 메신저로 보낼 수 있는 포멧으로 만들어서 request 로 보냅니다
const sendMessage = (userName, meta) => {
let sendObj = {
"botName": "AWS Bot",
"botIconImage": "https://s3.ap-northeast-2.amazonaws.com/ICON_BUCKET/aws.png",
"text": userName + "님 AWS Access Key 를 새로 생성해주세요",
"attachments": [{
"text": `${userName}님의 AccessKey가 생성된지 ${expirationPeriodDays}일이 지나서 보안에 위배되니 AWS Console 로 접속해서 새로 생성해주세요`,
"color": "red"
}]
};
let requestOptions = {
uri : process.env.DOORAYURL,
method: 'POST',
headers : {
'Content-Type': 'application/json'
},
body : JSON.stringify(sendObj).toString('utf8')
};
request(requestOptions, function(err, res, body) {
if (err) console.log(err, err.stack);
else console.log(res.statusCode);
});
NOTE : 처음에는 동기형태로 async / await 로 만들어서 모든 사용자를 확인한 후에 메시지를 조합해서 1번만 보내는 걸로 만들었더니 실행시간 40초나 걸려서, 그냥 async 로 만들어서 따로 메시지를 보내는 방식으로 다시 바꿨습니다. 그랬더니 실행시간은 3~4초면 됨
Step 2. 테스트 하기
로컬PC에서 테스트 할 때 사용하는 테스트 파일
index.localtest.js
const lambda = require('../src/index');
const event = {};
lambda.sendNotification(event);
저는 로컬테스트 폴더를 만들어서 node 로 테스트 실행합니다
node localtest/index.localtest.js
Step 3. 배포하기
sls deploy -v --aws-profile AWS_ACCOUNT_ID
MFA 인증받은 ACCOUNT_ID 를 사용해서 배포합니다
--aws-profile 를 매번 써주기 싫으면
set AWS_PROFILE=AWS_ACCOUNT_ID
환경변수로 AWS_PROFILE 을 등록해놓습니다.
그러면 sls 가 알아서 AWS_PROFILE 을 참고해서 해당 계정을 사용합니다
함수만 재배포하기
sls deploy -v -f sendNotification --aws-profile AWS_ACCOUNT_ID
sendNotification 함수만 재배포 해줍니다.
실행결과
serverless.yml 파일에서 해당 람다함수를 매주 월요일 UTC 기준으로 0시니
대한민국시간으로 매주월요일 9시에 실행됩니다
events:
- schedule: cron(0 0 ? * MON *)
두레이 메신저의 내용
자원삭제하기
sls remove --aws-profile AWS_ACCOUNT_ID
cloudformation 이 실행되면서 관련된 자원들이 전부 삭제됩니다
참조사이트
https://github.com/NiteDesign/Lambda-IAM-Key-Rotation
깃허브에 정리가 잘되어 있는 소스가 있어서 참고많이 했습니다
'IT > Serverless' 카테고리의 다른 글
서버리스 api gateway 도메인 적용 (0) | 2019.08.14 |
---|---|
서버리스 사이트 스크린샷 찍기 (예전방식) (0) | 2019.08.12 |
서버리스 웹브라우저 한글폰트 적용하기 (0) | 2019.08.12 |
서버리스 네이버 검색어 가져오기 (serverless) (0) | 2019.08.09 |
DynamoDB : Attribute name is a reserved keyword 해결방법 (0) | 2019.08.01 |
DeletionPolicy 옵션 사용시 주의사항 (0) | 2019.07.31 |
CloudFormation / Serverless Framework 삭제시 리소스 유지 (0) | 2019.07.30 |
네이버 블로그 파워링크 클릭 (0) | 2019.07.30 |