Computer >> 컴퓨터 >  >> 네트워킹 >> VPN

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법

이 글은 필자의 새 Pluralsight 강좌 '온프레미스 리소스를 AWS 인프라에 연결하기(Connecting On-prem Resources to your AWS Infrastructure)'의 일부를 바탕으로 재구성했습니다.

Amazon Web Services에서 운영 중인 리소스에 접속해야 할 때가 종종 있지 않으신가요? 퍼블릭 EC2 인스턴스에 SSH로 접속하거나 S3 데이터를 암호화하는 정도라면 보안상 크게 문제될 것이 없습니다. 하지만 백엔드 RDS 데이터베이스 인스턴스나 외부에 공개되지 않은 AWS 데이터에 접근해야 한다면 이야기가 달라집니다. 관리자들이 이런 리소스를 일반 사용자의 접근 범위 밖에 두는 데에는 분명한 이유가 있습니다. 그러나 정작 필요할 때 접근할 수 없다면 그 리소스가 무슨 소용일까요?

결국 여러분의 자산을 보호하는 ACL과 보안 그룹을 우회하는 안전하고 신뢰할 수 있는 방법이 필요합니다. 앞서 언급한 Pluralsight 강좌에서 다루는 해결책 중 하나는 Direct Connect입니다. 하지만 Direct Connect의 비용이 회사 예산에 부담된다면 VPN 터널이 좋은 대안이 될 수 있습니다.

가상 사설망(VPN)이란?

가상 사설망(VPN)은 흔히 제한된 네트워크 활동을 허용하거나 익명 브라우징을 위해 사용됩니다. 하지만 이 글에서 다룰 주제는 그런 용도가 아닙니다.

VPN은 공용 네트워크를 통해 두 지점 간에 데이터를 안전하게 전송할 수 있게 해주는 지점 간(point-to-point) 연결입니다. 사실상 터널을 활용하면 지리적으로 떨어져 있는 두 개의 프라이빗 사이트를 하나의 사설 네트워크처럼 묶을 수 있습니다. 우리의 맥락에서는 로컬 사무실 네트워크와 프라이빗 리소스를 호스팅하는 AWS VPC를 연결한다는 의미입니다.

방법은 두 가지입니다.

  • AWS Virtual Private Gateway 위에 구축되는 관리형 VPN Connection 사용
  • 자체 VPN 구축

이 글에서는 직접 구축하는 방법에 초점을 맞추겠습니다.

OpenVPN Access Server

이름에서 알 수 있듯이 OpenVPN은 오픈소스 프로젝트로, 무료 커뮤니티 에디션을 내려받아 자체 VPN 서버에 직접 구성할 수도 있습니다. 하지만 OpenVPN社는 AWS 친화적인 통합 기능과 자동화된 구성 도구가 기본 탑재된 OpenVPN Access Server를 EC2 AMI 형태로도 제공합니다.

현재로서는 AWS VPC 내에서 AMI를 실행하고 통제된 원격 연결을 허용하는 방식이 사실상 표준적인 방법으로 자리 잡았습니다.

비용은 어떨까요? 단순히 테스트 목적이고 동시에 두 개 이하의 연결만 사용할 계획이라면 AMI 자체는 무료입니다. 물론 EC2 인스턴스의 일반 비용은 발생하지만, 계정이 아직 프리 티어(Free Tier) 대상이라면 그마저도 무료로 이용할 수 있습니다.

VPN을 실제 프로덕션 환경에 배치하게 되면 필요한 동시 접속 수에 따라 라이선스를 구매하면 됩니다. 세부 내용은 OpenVPN 공식 페이지에서 확인할 수 있습니다.

이 가이드에서 수행할 작업은 다음과 같습니다.

  • OpenVPN Access Server가 사전 설치된 Ubuntu AMI를 선택하여 내 VPC에 프로비저닝 및 실행
  • SSH로 서버에 접속해 VPN 구성
  • 관리자 사용자 설정
  • 로컬 머신을 OpenVPN 클라이언트로 만들고 AWS VPC 내 프라이빗 인스턴스에 접속

준비되셨나요? 시작해 보겠습니다.

OpenVPN Access Server 시작하기

EC2 대시보드에서 올바른 AWS 리전을 확인한 뒤, VPN 서버 역할을 할 인스턴스를 실행합니다. Quick Start AMI 대신 AWS Marketplace 탭을 클릭하고 'openvpn access server'를 검색합니다. OpenVPN은 접속 가능한 클라이언트 수가 단계적으로 늘어나는 라이선스가 적용된 여러 공식 이미지를 제공합니다.

여기서는 'Bring Your Own License(BYOL)' 방식의 Ubuntu 이미지를 사용하겠습니다. 앞서 말했듯이 이번 실습에는 라이선스가 필요하지 않습니다.

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법
AWS Marketplace에서 제공되는 OpenVPN Access Server AMI

AMI를 선택하면 팝업창에 인스턴스 유형과 EBS 스토리지 옵션별 시간당 비용이 표시됩니다. 이는 어디까지나 일반적인 AWS 인프라 비용이며 라이선스 비용은 포함되지 않습니다.

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법
AWS에 직접 청구되는 OpenVPN Access Server AMI 비용

인스턴스 유형은 프리 티어 범위 내에 들어가도록 t2.micro로 낮춥니다. 트래픽이 많은 프로덕션 서버라면 좀 더 높은 성능이 필요할 수 있습니다.

잠시 후 같은 서브넷에 두 번째 인스턴스를 실행할 계획이므로, 인스턴스 세부 정보 구성 페이지에서 'us-east-1b'를 선택하고 메모해 둡니다.

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법
서브넷을 선택하고 기록해 두세요

보안 그룹 페이지가 바로 OpenVPN AMI 설정이 빛을 발하는 부분입니다. 필요한 모든 항목이 열려 있는 보안 그룹이 자동으로 제안됩니다. 22번 포트는 서버로의 SSH 트래픽용, 943번은 관리 GUI 접속용, 443번은 TLS로 암호화된 HTTP 트래픽용, 그리고 OpenVPN은 1194번 포트에서 클라이언트의 인바운드 연결을 수신합니다.

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법
OpenVPN AMI에 기본 포함된 보안 그룹

참고: 실무 환경에서는 유효한 회사 IP 대역의 요청만 허용하도록 규칙을 더 엄격하게 조이는 것이 좋지만, 단기 테스트에는 이대로도 충분합니다.

이제 설정을 검토하고, 나열된 SSH 암호화 키를 확인한 뒤 인스턴스를 실행합니다.

인스턴스가 시작되면 중요한 로그인 정보와 함께 빠른 시작 안내가 표시됩니다. 특히 SSH 접속에 사용할 사용자 계정 이름이 openvpnas라는 점을 기억하세요. 동일한 정보가 담긴 이메일도 발송됩니다.

EC2 콘솔로 돌아오면 새 머신이 부팅되는 동안 퍼블릭 IP 주소를 확인할 수 있습니다. 문제는 인스턴스를 재부팅하면 같은 IP를 다시 받는다는 보장이 없다는 것인데, 이는 상당한 혼란을 초래할 수 있습니다. 따라서 Elastic IP를 할당하는 것이 좋습니다.

Elastic IPs를 클릭한 뒤 Allocate new address를 선택하고, 새 주소를 기록한 후 페이지를 닫습니다. 해당 주소를 선택한 상태에서 Actions → Associate Address를 클릭합니다. Instance 입력란을 클릭하면 태그 덕분에 알아보기 쉬운 OpenVPN 인스턴스가 목록에 나타납니다. 이를 선택하고 Associate를 클릭하면 끝입니다. 이제부터 이 주소가 서버 접근용 고정 퍼블릭 IP가 됩니다.

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법
새 Elastic IP 주소를 인스턴스에 연결하세요

서버 접속하기

터미널에서 SSH 명령어에 이 인스턴스용으로 생성한 키 페어와 함께 퍼블릭 IP 주소를 입력합니다.

ssh -i KeyPairName.pem openvpnas@<PublicIPAddress>

Windows나 macOS 환경에서는 절차가 조금 다를 수 있지만, 공식 문서가 필요한 모든 도움을 줄 것입니다.

Instances 콘솔을 떠나기 전에 한 가지 중요한 작업이 남아 있습니다. OpenVPN 인스턴스를 선택한 상태에서 Actions → Networking → Change Source/Dest checking 순으로 이동해 검사가 비활성화되어 있는지 확인합니다. 이 작업을 하지 않으면 거의 아무것도 동작하지 않습니다.

이제 SSH 세션으로 돌아갑니다. 세션이 시작되면 OpenVPN EULA 동의 화면과 설정 마법사가 나타납니다. 나중에 설정을 변경해야 할 경우 다음 명령으로 마법사를 다시 실행할 수 있습니다.

sudo ovpn-init --ec2

마법사의 기본값 대부분은 그대로 사용해도 되지만, 진행 과정을 간단히 살펴보겠습니다. 질문과 필요한 설명은 다음과 같습니다.

primary Access Server node? yes [백업 또는 페일오버 노드를 구성하는 경우 no로 답합니다.]
Admin Web UI에 사용할 네트워크 인터페이스와 IP 지정 [1 — 모든 인터페이스; 추후 고정 IP로 변경 가능]
Admin Web UI 포트 번호 [기본값]
OpenVPN 데몬의 TCP 포트 번호 [기본값]
클라이언트 트래픽을 기본적으로 VPN 경유? [no — 우리가 만들려는 것은 원격 클라이언트를 VPC로 안전하게 연결하는 VPN이지, 전체 트래픽 우회용이 아닙니다. DNS 트래픽도 마찬가지입니다.]
클라이언트 DNS 트래픽을 기본적으로 VPN 경유? [no]
내부 DB를 통한 로컬 인증 사용? [no — 유용할 수 있지만, 간단함을 위해 Linux/AWS 인증을 사용합니다.]
프라이빗 서브넷에 대한 클라이언트 접근을 기본 허용? [yes — VPN의 핵심 목적입니다.]
Admin UI에 'openvpn'으로 로그인? [yes]
OpenVPN Access Server 라이선스 키 입력 [테스트에는 불필요]

마법사가 완료되면 연결 정보가 표시되고 NTP(네트워크 시간 데몬) 설치가 권장됩니다. 다만 Ubuntu에는 기본적으로 설치되어 실행 중이므로 별도 작업이 필요 없습니다.

앞서 언급했듯이 웹 GUI 로그인을 위해 openvpn 사용자에게 비밀번호를 부여해야 합니다. sudo 권한으로 passwd 명령을 실행합니다.

sudo passwd openvpn

서버 쪽 준비는 여기까지입니다. 이제 브라우저로 웹 GUI에 접속하겠습니다. 서버의 퍼블릭 IP에 https 접두사와 /admin을 붙여 접속합니다.

https://<PublicIPAddress>/admin

인증 기관(CA)이 발급한 인증서가 아닌 자체 서명(self-signed) 인증서를 사용하기 때문에 '연결이 비공개로 안전하지 않음' 경고가 표시됩니다.

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법
자체 서명 인증서 사용 시 나타나는 정상적인 경고

VPN을 회사 내 특정 사용자에게만 노출하는 상황이라면 큰 문제가 되지 않으며, 사용자들은 우리 인증서를 신뢰할 수 있습니다. 경고를 건너뛰고 로그인한 뒤 EULA에 동의합니다.

시간이 된다면 OpenVPN 관리 콘솔이 제공하는 다양한 기능을 직접 둘러보는 것도 좋습니다.

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법
OpenVPN 관리 콘솔

VPN 클라이언트 설정하기

이제 앞서 확인한 웹 접속 주소에서 '/admin'을 뺀 주소로 클라이언트 UI 페이지를 열어 보겠습니다. 이곳은 단순한 로그인 화면으로, 앞서 만든 openvpn 사용자로 인증하면 됩니다. (새 사용자는 언제든지 관리 콘솔에서 생성할 수 있습니다.)

로그인 화면 뒤에는 각 플랫폼별로 OpenVPN 클라이언트 앱 설치 방법을 안내하는 링크 목록이 있습니다. 마지막 링크 이름은 바로 'Yourself(본인)'입니다.

OpenVPN으로 AWS 프라이빗 리소스에 안전하게 접근하는 방법
OpenVPN 클라이언트 페이지

이 링크를 클릭하면 client.ovpn 파일을 내려받게 됩니다. 이 파일에는 서버와 일치하는 구성 설정과 인증에 사용할 실제 키가 담겨 있습니다. 잘못된 손에 넘어가지 않도록 반드시 신중하게 다뤄야 하며, 암호화되지 않은 평문 이메일로 전송해서는 안 됩니다.

파일을 로컬에서 열어 내용을 복사합니다. 그다음 로컬 네트워크의 Linux 가상 머신에서 셸을 열고 client.ovpn이라는 새 파일을 만든 뒤 내용을 붙여넣습니다. 앞서 클라이언트 UI에서 'OpenVPN for Linux' 링크를 확인했다면 추가 작업은 Apt 패키지 매니저(CentOS나 Red Hat이라면 Yum)로 OpenVPN을 설치하는 것뿐임을 알 수 있습니다. 단 한 줄의 명령으로 끝납니다.

nano client.ovpn
sudo apt update
sudo apt install openvpn

이제 VPN 연결을 엽니다. sudo로 root 권한을 얻은 상태에서 openvpn 명령에 config 플래그를 붙여 방금 만든 client.ovpn 파일을 지정합니다.

sudo openvpn --config client.ovpn

인증을 요청받으면 openvpn 계정과 서버에서 생성한 비밀번호를 입력합니다.

이제 로컬 클라이언트에서 두 번째 셸 세션을 열어, VPN이 정상 동작하지 않는다면 불가능한 작업인 프라이빗 IP 주소로 OpenVPN 서버에 SSH 접속을 시도해 보겠습니다.

먼저 ip a 명령으로 이 머신의 모든 활성 네트워크 인터페이스를 확인합니다.

ip a

로컬 네트워크 인터페이스 외에 tun0라는 이름의 인터페이스가 보일 것입니다. 이 인터페이스는 OpenVPN이 생성한 것이며 보통 172.16.x.x 대역에 속합니다.

이제 프라이빗 키(당연히 로컬에 존재해야 함)와 서버의 프라이빗 IP 주소로 원격 서버에 SSH 접속합니다. 성공한다면 여러분의 VPN 완성입니다!

ssh -i KeyPairName.pem openvpnas@<PrivateIPAddress>

마지막으로, 현재 구성된 VPN이 Amazon VPC 내 다른 프라이빗 리소스 접근도 허용한다는 점을 확인해 보겠습니다. 예를 들어 공용 네트워크에 노출할 수 없는 데이터베이스 인스턴스가 VPC에서 실행 중이라면 매우 유용합니다.

표준 Ubuntu EC2 인스턴스를 하나 실행하되, 퍼블릭 IP는 부여하지 않습니다. 단순화를 위해 OpenVPN 서버와 동일한 us-east-1b 서브넷을 지정하고, 보안 그룹은 22번 포트의 SSH 접근만 허용하도록 설정합니다.

인스턴스가 실행되면 프라이빗 IP 주소를 기록하고 로컬 클라이언트로 돌아옵니다. 인스턴스가 완전히 시작되었음을 확인한 뒤, 같은 프라이빗 키와 'ubuntu' 사용자명(일반 Ubuntu EC2 인스턴스의 기본값), 방금 복사한 프라이빗 주소로 SSH 접속합니다.

역시 성공한다면 AWS 프라이빗 리소스로 연결되는 완전히 구성된 VPN 연결이 완성된 것입니다. 이 순간을 만끽하세요.

마지막으로 잊지 마세요. 사용이 끝난 후에는 모든 서버를 종료하고 Elastic IP 주소를 반납해야 불필요한 비용 발생을 막을 수 있습니다.

이 글은 필자의 새 Pluralsight 강좌 '온프레미스 리소스를 AWS 인프라에 연결하기'의 일부를 재구성한 것입니다. Bootstrap IT 사이트에서는 저서 'Linux in Action'과 2시간 이상의 영상과 책 전체 분량의 약 40%에 해당하는 텍스트로 구성된 하이브리드 강좌 'Linux in Motion' 등 더 많은 콘텐츠를 만나볼 수 있습니다.