public subnet에 띄운 ec2에 고정된 공인ip, 즉 elastic ip를 붙이고 이를 route 53에서 구입한 도메인과 연결해본다


Elastic IP 생성 및 ec2와 연결

1. Elastic IP를 생성한다. 생성하는 모습은 생략함

 

2. 생성한 elastic ip를 선택하고 작업 탭을 눌러 "탄력적 IP 주소 연결"을 누른다

리소스 유형 = 인스턴스고르고 연결할 ec2 고르면 된다. 프라이빗 주소는 그 인스턴스의 사설ip를 고르면 된다

 

3. 그러면 해당 ec2의 상세화면에서 public ip로 elastic ip가 연결된 걸 볼 수 있다 

 


route53에서 구입한 도메인과 elastic ip연결

1. 구입한 도메인의 호스팅 영역에 들어가서 "레코드 생성"을 누른다

 

2. 다음과 같이 생성해주면 끝

값으로는 아까 생성한 elastic ip를 주면 된다

 

3. 이렇게 하고 나면, www.petdori.com으로 트래픽을 보내면 ec2로 가진다. 

소마 프로젝트를 진행하면서, 인프라 쪽을 내가 어느 정도 담당하고 있어서(사실 담당한다고 하기에도 민망할 정도로 기본적인 부분들만 담당하긴 하지만) RDS를 띄워보기로 했다. Private Subnet에 RDS를 띄우기로 했는데, 문제는 "로컬에서 Private Subnet에 어떻게 접근하는가?" 였다.

 

Private Subnet은 외부와 단절된 네트워크로, 외부에서 직접 접근이 불가능하다. NAT Gateway를 둬서 Private Subnet에서 외부로 트래픽을 보낼 순 있어도, 외부에서 먼저 Private Subnet으로 트래픽을 보낼 순 없다. VPN등을 통해 직접 로컬에서 Private Subnet으로 연결할 순 있으나, 비용이 무시무시하다는 소문이 들려서 다른 방법을 찾아보기로 했다

 

당장 떠오르는 방법은 Public Subnet에 EC2를 둔 후, ssh로 EC2에 원격으로 연결한 다음 거기서 Private Subnet으로 접근하는 것. 같은 VPC안의 애들끼리는 서로 통신이 가능하기 때문에 이 방법을 쓸 수 있을 것이다. 이렇게 외부에서 내부 네트워크로의 안전한 접근을 제어하기 위해 사용되는 중간 서버를 Bastion Host라고 부른다.

 

로컬에서 ssh로 Public Subnet의 EC2에 원격으로 연결한 뒤, 거기서 Private Subnet의 RDS로 직접 쿼리를 날릴 순 있다.

 

이렇게 하면 로컬에서 Private Subnet에 있는 RDS로 create등의 쿼리를 작성해 날릴 수 있다. 그러나 "얘를 로컬에서 돌리고 있는 스프링부트와 어떻게 연결하는가"가 숙제. 스프링부트에서 만들어지는 쿼리를 터미널에 인풋으로 주도록 내가 직접 구축을 해야 하나..? 그건 너무 에바같은데.. 

 

이 때 ssh 포트 포워딩(다른 말로는 ssh 터널링)을 통해 이 문제를 해결할 수 있다. ssh 포트포워딩이란 ssh를 사용해 로컬 머신과 원격 서버 사이에서 포트 전달을 설정하는 것으로, 이를 통해 로컬에서 특정 포트로 트래픽을 보내면 ssh터널(ssh를 통해 연결된 통로라고 생각)을 통해 원격서버의 특정 포트로 보낼 수가 있다. 즉 내가 로컬의 3306포트와 원격 서버의 3306포트를 포트포워딩하면, 내가 로컬의 3306포트로 보내는 트래픽을 원격 서버의 3306포트로 보낼 수가 있는 거다. (참고로 이 예시는 로컬 포트 포워딩에 해당하며, 리모트 포트 포워딩을 하면 원격 서버에서 특정 포트로 들어오는 트래픽을 내 로컬 머신의 포트에서 받을 수 있다)

 

이런 로컬 포트 포워딩은 다음과 같이 설정해 사용 가능하다

ssh -L [로컬에서 사용할 포트]:[최종적으로 접근할 곳(ip:port형태)] [SSH Server 주소]

예시로, aws에서 지급받은 pem키와 함께 사용하려면 다음과 같이 하면 된다.

ssh -i [pem키 경로] -L 3306:[RDS 엔드포인트]:3306 [사용자명(ex:ubuntu)]@[Bastion Host public ip]

 

이렇게하면 로컬의 3306포트와 Private RDS의 3306이 연결됐으니 이제 스프링부트에서도 datasource를 내 로컬의 3306으로 한 뒤 쓰면 된다. 물론 각각 보안그룹들이 다 설정돼있어야 한다!(RDS는 Bastion으로부터 3306포트로 오는 인바운드 허용, Bastion은 22번 인바운드와 3306아웃바운드 허용 등..) 이 때 Public Subnet에 둔 EC2는 점프호스트로 쓰는 거라고 볼 수 있다

 

 

하지만! SSM이란 서비스를 사용하면 좀 더 쉽게 Private Subnet접근이 가능하다.

 

 

SSM이란?

AWS System Manager. Simple System Manager라고도 불리며 이의 줄임말이 SSM이다. 다양한 기능들을 제공하는데, Session manager라는 걸 통해 EC2접속을 할 수 있는 서비스도 제공한다.

 

https://aws.amazon.com/ko/blogs/architecture/how-wego-secured-developer-connectivity-to-amazon-relational-database-service-instances/

https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html

 

AWS Systems Manager Session Manager - AWS Systems Manager

AWS Systems Manager Session Manager Session Manager is a fully managed AWS Systems Manager capability. With Session Manager, you can manage your Amazon Elastic Compute Cloud (Amazon EC2) instances, edge devices, on-premises servers, and virtual machines (

docs.aws.amazon.com

 

Session Manager를 사용하면 기존에 했던 것처럼 Bastion Host를 둘 필요 없이 Private Subnet에 있는 EC2인스턴스에 직접 접근이 가능하다(당연히 퍼블릭도 가능). ssh로 연결할 때 사용하던 pem키 관리 및 EC2인스턴스들에 22번 포트를 여는 인바운드 설정도 할 필요가 없다. 즉 더 안전하게 사용 가능한 방법이라고도 볼 수 있다. 또한 포트포워딩도 지원하기 때문에 로컬에서 Private Subnet에 있는 RDS로의 접근 역시 가능하다!

(Session Manager를 통해 EC2들에 대한 직접 액세스는 가능하나 RDS등은 직접 액세스는 안 돼서 포트포워딩을 거쳐야 함. 즉 EC2라는 관리 인스턴스를 "점프 호스트"로 사용해 RDS로 접근하는 것이며, ssh 포트포워딩을 통해 public에 있던 EC2를 점프호스트로 쓰던 것과 같은 원리이다.)

 

참고로 이때 SSM을 통해 직접 액세스하게 되는 EC2는 22번 인바운드는 열릴 필요가 없으나, 443번 아웃바운드는 열려있어야 한다. 해당 EC2에서 AWS SSM에게 지속적인 폴링을 통해 연결을 유지하기 때문이다. 따라서 보안그룹 설정시 꼭 주의할 것. 관련된 내용은 아래 링크의 [엔드포인트에 연결] 섹션을 참고하면 된다

 

https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/session-manager-prerequisites.html

 

1단계: Session Manager 사전 조건 완료 - AWS Systems Manager

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

그럼 본격적으로 SSM으로 포트포워딩을 설정해 로컬에서 Private Subnet의 RDS에 접속하는 법을 알아보자.

 


1. 로컬환경에 aws cli 설치하기

https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions

 

최신 버전의 AWS CLI 설치 또는 업데이트 - AWS Command Line Interface

이전 버전에서 업데이트하는 경우 unzip 명령을 실행하면 기존 파일을 덮어쓸지 묻는 메시지가 표시됩니다. 스크립트 자동화와 같은 경우에 이러한 프롬프트를 건너뛰려면 unzip에 대한 -u 업데이

docs.aws.amazon.com

 

2. aws IAM을 만든 다음, Access Key와 Secret Access Key를 발급받는다.

 

3. 로컬에서 터미널을 띄우고 aws configure를 입력해 구성한다

$ aws configure
AWS Access Key ID [None]: {각자에게 주어진 Access Key}
AWS Secret Access Key [None]: {각자에게 주어진 Secret Access Key}
Default region name [None]: ap-northeast-2
Default output format [None]: json

 

4. 로컬에 Session Manager Plugin을 설치한다

https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html

 

용 Session Manager 플러그인 설치 AWS CLI - AWS Systems Manager

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

5. EC2를 띄우고, 그 EC2에 AmazonSSMManagedInstanceCore라는 정책이 있는 역할을 부여한다

참고로 EC2에 SSM agent가 설치돼있어야 한다. aws에서 제공하는 AMI로 만들어진 EC2들은 ssm agent가 기본적으로 깔려있는 애들이 많다! 다음 링크의 [SSM Agent의 상태 확인] 섹션을 참고해 SSM agent가 설치돼있는지 살펴보고, 안돼있으면 설치해야한다. 설치된 상황이라면 해당 역할을 부여한 후 SSM agent를 재시작해준다.

 

재시작하는 커맨드는 상태 확인 커맨드에서 status만 restart로 바꾸면 된다.

 

https://docs.aws.amazon.com/ko_kr/systems-manager/latest/userguide/ami-preinstalled-agent.html

 

Amazon Machine Images(AMIs), SSM Agent 사전 설치 - AWS Systems Manager

SSM Agent가 이 목록에 없는 AWS 관리형 AMIs에 사전 설치되어 있을 수 있습니다. 이 경우 일반적으로 운영 체제(OS)에서 모든 Systems Manager 기능이 완벽하게 지원되지 않습니다. 또는 SSM Agent가 AWS Marketp

docs.aws.amazon.com

 

6. 터미널에 다음 커맨드를 입력한다

aws ssm start-session --target {EC2 인스턴스의 id} \
                       --document-name AWS-StartPortForwardingSessionToRemoteHost \
                       --parameters '{"portNumber":["3306"],"localPortNumber":["3306"],"host":["{RDS 엔드포인트}"]}'

 

그러면 ssh 포트포워딩을 했을 때처럼 로컬의 3306포트와 RDS의 3306포트가 연결된다.

 

 

 

 

 

참고한 글

https://blog.naver.com/PostView.naver?blogId=alice_k106&logNo=221364560794 

 

150. [SSH, Network] SSH 포트 포워딩(SSH 터널링)의 개념 및 사용 방법

이번 포스트에서는 'SSH 포트 포워딩' 또는 'SSH 터널링' 이라고 불리는 것에 대해서 설명한다. 1. ...

blog.naver.com

https://musma.github.io/2019/11/29/about-aws-ssm.html

 

AWS SSM으로 EC2 인스턴스에 접근하기 (SSH 대체)

목차 서론 들어가기: 더 좋은 방법 대상 독자 SSM: AWS Systems Manager 원격 호스트 접속 방법 비교: SSH (기존) vs. SSM (개선) S...

musma.github.io

https://hbase.tistory.com/328

 

[Linux] ssh 터널링(ssh port forwarding) - Local / Remote / Dynamic Tunneling

sh는 Secure SHell의 줄임말로 원격 호스트에 접속하기 위해 사용되는 보안 프로토콜이다. 당연하게도 ssh는 원격 호스트로 접속하기 위해 가장 많이 사용된다. 그런데 ssh는 원격 호스트로의 접속과

hbase.tistory.com

https://hwan-shell.tistory.com/382

 

AWS Session manager 란? (설명 및 설정 방

EC2를 접속할 때 기본적으로 SSH를 통해서 접속합니다. SSH를 통해서 접속하려면 SSH key가 필요하고 EC2 Inbound 22 port를 허용해 줘야 합니다. SSH를 사용하게 되면 Key 없이는 접속할 수 없고, Key를 분실

hwan-shell.tistory.com

https://aws.amazon.com/ko/about-aws/whats-new/2022/05/aws-systems-manager-support-port-forwarding-remote-hosts-using-session-manager/

 

AWS Systems Manager, Session Manager를 사용한 원격 호스트로의 포트 포워딩 지원 발표

AWS Systems Manager가 Session Manager를 사용한 원격 호스트로의 포트 포워딩 지원을 발표합니다. AWS Systems Manager는 AWS 애플리케이션 및 리소스를 위한 운영 허브이며, 하이브리드 클라우드 환경에 대해

aws.amazon.com

 

윈도우가 깔린 컴퓨터를 켜면, 처음에 어떤 유저로 들어갈 건지 고를 수 있다.

리눅스도 마찬가지다.

각각의 유저별로, 하나의 컴퓨터에 대해 할 수 있는 동작들이 다르다. 누구는 A를 할 수 있지만 누구는 할 수 없고 등등..

 

AWS도 이와 비슷하게 "유저들"이라는 개념이 있다.

조직원들이 쓰고 있는 전체 자원들에 대해, 누구는 A를 할 수 있지만 누구는 못 하게끔 설정이 가능하다.

 

AWS에서, "계정"과 "사용자"는 다른 개념이다.

계정은 root, 즉 리눅스에서의 super user같은 개념이다. 과금의 주체가 되는 주인이라고 보면 된다.

사용자는 이용자, 즉 root가 허가한 권한만 갖는 애들이라고 보면 된다. 위에서 방금 말했던 "유저들"이란 개념을 상기하자.

 

AWS계정을 처음 만들면 root 사용자로 시작하는 것이며, 모든 AWS서비스 및 리소스에 대한 전체 액세스 권한을 갖는다(모든 걸 다 할 수 있다는 의미).

그 후 root가 유저들을 만들면서 이 유저들한테 특정 권한들(어떤 리소스에 대해 어떤 동작을 허가한다와 같은)을 줄 수 있는 거다. 이것이 사용자라는 개념이라고 이해하면 된다. 관리자 유저한테는 ~~권한들을 주고, 개발자 유저한테는 ~~권한들을 주고, 감사자 유저한테는 ~~권한들을 주고 그런 식으로 세팅할 수 있는 것.

 

암튼.. 이런 것들에 대해 적용되는 개념이 IAM = Identity and Access Management이다.

 


IAM이라는 서비스와 구성요소

IAM은 한 줄로 말하자면 AWS에서 사용자를 만들고 권한을 주는 것을 통해 AWS 리소스에 대한 액세스를 안전하게 제어할 수 있게끔 하는 서비스이다. 각 유저들에 대한 권한 제어는 policy(=정책)라는 json포맷의 텍스트(쉽게 말하면 "어떤 걸 할 수 있다"들의 목록같은 거다)를 통해 이뤄지며, IAM은 다음과 같은 4개로 구성된다.

 

  • 사용자 : 위에서 말한 개념
  • 그룹 : 각 사용자들을 그룹핑 가능하며, 그룹에 정책을 지정하면 그룹원들이 동일한 권한들을 갖게 할 수 있다
  • 역할
  • 정책

 

먼저 정책에 대해 얘기해보자.

다시 한 번 말하자면 "어떤 걸 할 수 있다"라는 것들..즉 "권한들의 목록"이 정책이다 라고 보면 되며, 사용자들은 이렇게 연결된 정책에서 지정된 권한들만 쓸 수 있다.. 그렇기 때문에 사용자를 만들고 그룹을 배정해주든 정책을 연결해주든 아무것도 안 해준다면 사실상 그 놈은 아무고토 할 수가 없다. 왜냐하먄 어떠한 권한도 없는 셈이니까. 리소스 기반 정책과 자격증명 기반 정책으로 분류할 수 있다

 

  • 리소스 기반 정책 : "리소스"에 연결되는 정책. 예를 들면 S3 bucket에는 ~~만 액세스할 수 있다! 처럼
  • 자격 증명 기반 정책 : "사용자나 그룹 또는 역할"에게 권한을 부여하는 식으로 사용하는 정책. 예를 들면 넌 EC2에 대해서는 읽기만 가능해! 등등

 

여기서 자격 증명 기반 정책은 다음과 같이 두 종류로 분류할 수 있다

 

  • Inline Policy : 1 : 1로 사용되는 정책. 적용된 사용자가 없어지면 이 정책도 사라진다
  • Managed Policy : 1 : N으로 사용되는 정책. 즉 정책을 object화해서 다른 애들한테도 이 정책을 멕일 수 있다. 적용된 사용자가 사라져도 이 정책은 남아있다.

 

여기서 Managed Policy는 다음과 같이 두 종류로 분류할 수 있다. 이번이 마지막임ㅋㅋㅋㅋ

 

  • AWS managed Policy : AWS에서 미리 만들어둔 애들. 변경할 수 없다
  • Customer managed Policy : 사용자가 생성한 정책! 

 

참고로 Customer managed Policy를 만들 땐 Policy generator라는 걸 쓰는게 좋다. 하나하나 타이핑해서 json파일을 만드는 것보단 프로그램을 통해 편하게 만들 수 있기 때문. 

(또한 이렇게 정책들을 다 멕인 후에, simulator를 통해서 이런저런 정책들이 적용된 상황에서의 테스트가 가능하다)

 

 

그 다음으론, 역할에 대해 얘기해보자.

얘는 쉽게 말해서, 임시로 권한들을 부여하는 기능(즉 당일 회수되는 임시 출입증을 발급하는..)이라고 보면 된다. 내가 원래 다른 권한들을 가지고 있어도, 특정 역할을 잠깐 맡는다면 그 역할에 부여된 정책들을 임시로 사용할 수 있는 거다.

주의할 점은 병합의 개념이 아니기 때문에, 기존에 정책들을 가지고 있던 사용자가 역할을 받으면 원래 가지고 있던 정책들은 가려진다. 즉 역할을 통해 임시로 받는 권한들만 사용 가능해진다.

참고로, AWS lambda와 같은 AWS 서비스들도 역할이란 걸 받을 수 있으니 알아두면 좋다:)

 


IAM에서 정책을 평가하는 방법

그럼 IAM에서 정책은 어떤 순서대로 적용될까? 한마디로 사용자에게 부여된 권한들은 어떤 순서로 평가돼서 특정 리소스들에 대해 얘는 거부되는 거고, 얘는 승인하는건지 평가되는지 알아보자.

 

참고로, AWS는 어떤 권한에 대해 명시적으로 언급하지 않았다면 그 권한에 대해 암묵적으로 Deny, 즉 거부가 된다. 명시적으로 Allow, 즉 승인을 해줘야만 그 권한을 이용가능하다고 생각하면 된다.

 

암튼 평가 순서는

 

  1. 우선, 그 권한에서 이야기하는 작업이 명시적으로 거부되는지를 본다. 만약 명시적으로 거부했다면 더 볼 필요도 없이 해당 권한이 없는 걸로 결론짓고 제낀다. 명시적으로 거부되지 않았다면, 다음 스텝으로 넘어간다
  2. 그럼 그 작업이 명시적으로 승인되는지를 본다. 만약 명시적으로 승인됐다면 그 권한이 있는 걸로 결론지어진다. 만약 그렇지 않다? 이는 그 권한에 대해 아무런 명시도 안 한 것이니 암묵적으로 거부했다고 판단한다. 즉 해당 권한이 없는 것으로 결론짓는다

 

뭐 이런 식으로 해당 권한이 있고 없고가 결정된다고 보면 된다. 이렇게 평가된 정책들에 대해, 사용자에게 부여된 자격 증명 기반 정책들을 통과하고, 리소스들에 부여된 리소스 기반 정책(VPC 엔드포인트 정책, S3 버킷 정책 등등)을 통과해야 비로소 해당 리소스에 접근할 수 있게 되는 것이다.

 


IAM 권한 경계

자격 증명 기반 정책들이 IAM 사용자들에게 부여할 수 있는 최대 권한을 설정하는 기능이다. 즉 나한테 부여된 정책들 중 내가 쓸 수 있는 정책들을 제한해주는 기능이라고 보면 된다. 따라서 권한 경계와 나에게 부여된 자격 증명 기반 정책의 교집합이 내가 쓸 수 있는 정책이 될 것이다.

 


AWS orginizations

다중 계정을 관리하는 것을 말한다. 사용자들을 그룹핑해서 그룹을 만들어주던 것을 계정에도 그대로 적용해서, 계정들도 조직을 만들어 그룹핑함으로써 특정 조직은 어떤 걸 할 수 있게 하고, 특정 조직은 어떤 걸 못 하게 하고 이런 걸 설정할 수가 있다. 

이렇게 조직에 허가되는 정책을 SCP(Service Control Polity)라고 한다. 즉.. 사용자는 자신이 속한 계정이 속한 organization에서 허가된 권한들만 쓸 수 있는 거..

 

정리하면, 내가 만약 AWS에서 뭔가 작업하고 싶다면

 

  1. 일단 내가 속한 계정의 조직이 이 작업을 허용했는지 봐야 하고
  2. 적용된 IAM 권한 경계를 따져서 내가 할 수 있는 건지 봐야하고
  3. 내게 부여된 자격 증명 기반 정책이 이 작업을 허용하고 있는지

 

를 따지게 되는 거다.. 이렇게 보니 꽤나 복잡한 듯

+ Recent posts