본문 바로가기

클라우드/AWS

[AWS] 비밀값 관리를 도와주는 솔루션

중요한 정보를 보호하기 위한 방법

1. 접근통제 - 아무나 접근하여 변경하는 것을 막아야한다.

     1.1 식별

     1.2 인증

     1.3 인가(권한 유무 확인)

 

 

우회해서 접근했을 때 정보를 보호하기 위한 방법

1. 암호화

     1.1 기밀성

     1.2 무결성(권한 있는 사용자가 인가된 절차에 따라 정보를 바꾼 것. 정보가 잘못된 방법이나 사용자로부터 변경되지 않았음을 보장)

     1.3 가용성(권한 있는 사용자가 정보를 요청했을 때 정보를 제공할 수 있어야 한다.)

 

비밀값 관리 원칙

1. 버전(형상)관리 시스템에 업로드하면 안된다. - github 등

→ 비밀정보가 들어있는 파일은 gitignore에 등록해 업로드 되지 않도록 해야한다.

→ 비공개저장소(private)로 업로드 하더라도 가급적이면 올리지 않는게 좋음

 

2. 비밀값은 최소한의 인원만 알고있어야 한다.

→ 사용자별로 계정을 발급하고 계정을 통제하는 것이 올바른 방법

 

3. 비밀값이 아닌 값은 분리해서 관리해야한다.

→ 내가 중요하게 다뤄야 하는 데이터와 일반 데이터는 분리해야한다.

 가급적이면 물리적으로 분리하는게 제일 좋음(다른 하드웨어 공간으로)

 논리적으로라도 분리해야함 - 별도의 테이블로 가져가는 것

 WHY? 비밀정보가 유출되었을 때 비밀정보가 함께 유출될 가능성이 높아지기 때문

 

 

AWS Secret Manager

- 비밀값을 aws secret manager에 저장해두고 API호출로 받아간다. 키 관리자체가 복잡한데 secret manager을 사용하면 키관리와 같은 복잡한 기능을 신경쓰지 않아도 되게 만들어준다.

 

KMS(Key Manager Service)

- 암호화 할때 사용하는 키를 관리하는 서비스

 

 

대칭키/비대칭키

  • 대칭키(비밀키, 유일키)
    • 암호화 키와 복호화 키가 동일
    • 관용 암호화 방식(옛날부터 관습적으로 사용해옴)
    • DES, 2DES(보안강도가 낮아서 이제 쓰이지 않음), 3DES, AES, ARIA, SEED,......

 

  • 비대칭키(공개키 암호화 방식)
    • 암호화키와 복호화 키가 다름
    • 개인키 + 공개키 쌍으로 구성

-----------------------------암호화---------------------------->

평문 ----------------> 알고리즘 +  ----------------> 암호문

<----------------------------복호화-----------------------------

 

 

보안강도 = 비도

암호문으로 암호화에 사용된 키를 찾아내는데 걸리는 시도횟수

예) 비도 128 = 2^128 만큼 시도해야 암호화에 사용된 키를 알아낼 수 있다.

 

 

Secret Manager 사용 실습

먼저 P313 AWS CLI를 위한 사용자 생성을 해야한다.

 

사용자 계정 추가

- 프로그램 방식 : 다른 곳에서 EC2같은 곳에 접속을 해 API를 액세스키아이디와 비밀키를 통해 호출              

 

 

 

 

 

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/

[ec2-user@ip-172-31-44-99 ~]$ cd /var/www

[ec2-user@ip-172-31-44-99 www]$ ls

aws-exercise-a  aws-exercise-b  passenger-5.3.6.tar.gz

[ec2-user@ip-172-31-44-99 www]$ rm -rf *

[ec2-user@ip-172-31-44-99 www]$ ls

[ec2-user@ip-172-31-44-99 www]$ git clone https://github.com/deopard/aws-exercise-a.git

Cloning into 'aws-exercise-a'...

remote: Enumerating objects: 39, done.

remote: Total 39 (delta 0), reused 0 (delta 0), pack-reused 39

Unpacking objects: 100% (39/39), done.

[ec2-user@ip-172-31-44-99 www]$ cd aws-exercise-a/

[ec2-user@ip-172-31-44-99 aws-exercise-a]$ git checkout secrets-manager

Branch 'secrets-manager' set up to track remote branch 'secrets-manager' from 'origin'.

Switched to a new branch 'secrets-manager'

[ec2-user@ip-172-31-44-99 aws-exercise-a]$ ls

app.js  LICENSE  package.json  package-lock.json

[ec2-user@ip-172-31-44-99 aws-exercise-a]$ cat app.js

const express = require('express');
const app = express();

// Use this code snippet in your app.
// If you need more information about configurations or implementing the sample code, visit the AWS docs:
// https://aws.amazon.com/developers/getting-started/nodejs/

// Load the AWS SDK
var AWS = require('aws-sdk'),
    endpoint = "https://secretsmanager.ap-northeast-2.amazonaws.com",
    region = "ap-northeast-2",
    secretName = "production/aws-exercise-2",		⇐ Secrets Manager의  보안 암호 이름
    secret,
    binarySecretData;

// Create a Secrets Manager client
var client = new AWS.SecretsManager({
    endpoint: endpoint,
    region: region,
    accessKeyId: 'AKIA4UVI7DSHO3T3RZPD', 				⇐ 본인의 ACCESS_KEY_ID를 입력
    secretAccessKey: 'NFEF+FKVNR5eaztTsWSinq5kPw+W970FdRIdYTAv' 	⇐ 본인의 SECRET_ACCESS_KEY를 입력
});

app.get('/', (req, res) => {
  client.getSecretValue({ SecretId: secretName }, function (err, data) {
    if (err) {
      if (err.code === 'ResourceNotFoundException')
        console.log("The requested secret " + secretName + " was not found");
      else if (err.code === 'InvalidRequestException')
        console.log("The request was invalid due to: " + err.message);
      else if (err.code === 'InvalidParameterException')
        console.log("The request had invalid params: " + err.message);
    }
    else {
      // Decrypted secret using the associated KMS CMK
      // Depending on whether the secret was a string or binary, one of these fields will be populated
      if (data.SecretString !== "") {
        secret = JSON.parse(data.SecretString);
      } else {
        binarySecretData = data.SecretBinary;
      }
    }

    res.send(`SecretsManager로 실행되는 AWS exercise의 A project입니다.<br />
- Admin 비밀번호: ${secret.admin_password}<br />
- 비밀 값: ${secret.secret_key}`);
  });
});

app.listen(3000, () => {
  console.log('Example app listening on port 3000!');
});

app.get('/health', (req, res) => {
  res.status(200).send();
});