가령 위의 예시는 www.google.com 에 대한 IPv6 주소로 curl 요청을 보내는 예시입니다. 브라켓으로 IPv6 주소를 감싸고 있으며, 다시 전체 URL을 따옴표로 묶고 있는 것을 볼 수 있습니다. 따옴표를 쓰지 않으면 파싱에 문제가 생기니, IPv6 주소로 요청을 보낼때는 전체를 감싼다고 인식하시면 되겠습니다.
resolve 에서 IPv6 활용하기
IPv6 주소를 직접 curl 대상 주소로 사용할 때는 위와 같습니다. 간혹 IP Spoofing 을 해야 하는 경우 --resolve를 쓰고 계실텐데요, 이때도 다음과 같은 형태로 IPv6 주소를 활용할 수 있습니다.
% curl https://www.google.com --resolve www.google.com:443:'[2404:6800:4004:80f::2004]' -I
HTTP/2 200
content-type: text/html; charset=ISO-8859-1
p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
date: Thu, 03 Feb 2022 08:37:37 GMT
server: gws
x-xss-protection: 0
x-frame-options: SAMEORIGIN
expires: Thu, 03 Feb 2022 08:37:37 GMT
...
--resolve를 사용할 때도 IPv6 주소를 브라켓으로 감싸고 따옴표를 넣어 주시면 되겠습니다. 역시나 콜론이 많이 사용되고 있기 때문에 필요한 작업이라고 인식하면 되겠습니다.
두 번의 포스팅을 통해 VPC 와 Gateway 를 생성했습니다. 그럼 EC2 를 바로 만들면 되나요? 라고 생각하실 수 있겠습니다만 일단은 생성한 VPC 가 Gateway 를 통해 인터넷과 교감을 할 수 있도록 라우팅 테이블 Routing Table 을 설정하는 작업을 먼저 진행해 보겠습니다. 사실 순서는 큰 상관이 없지만 <네트워크에 대한 작업> 을 마무리하고 <서버에 대한 작업>을 한다고 생각하시면 좋겠습니다.
Gateway 구성 : Internet Gateway / Egress Only Internet Gateway ("OpenVPN 구축 #2" 포스팅)
Routing Table 조정 (본 포스팅!)
IPv6 주소를 갖는 EC2 배포 (본 포스팅!)
OpenVPN 설치 및 구성
VPN 접속 시험
기타
라우팅 조정
1.4 Routing Table 조정
라우팅 테이블 Routing Table 은 VPC 로 들어오는 트래픽과 나가는 트래픽에 대한 경로를 지정해 주는 역할을 합니다. 물론 라우팅 테이블만 설정했다고 하여 모든 통신이 정상적으로 이루어지는 것은 아닙니다. 말 그대로 경로에 대한 지정일 뿐, 실제 트래픽을 허용할 것인지는 Network ACL 과 Security Group 을 통해 IP 주소 대역, 포트 단위로 결정됩니다.
라우팅 테이블을 설정하기 위해서는 VPC 제품 하위 메뉴에 위치한 <Route Tables> 를 통해 진행할 수 있습니다. 기본적으로 VPC 가 생성되면 VPC 에 대한 기본 라우팅 테이블이 자동으로 생성됩니다. 기본 라우팅 테이블은 VPC 에 할당된 IPv4, IPv6 주소를 대상으로 VPC 내에서 (=local) 통신이 가능하도록 하는 정책만 들어 있는 상태입니다.
우리가 해야하는 일은 위 이미지의 핑크색 상자에 들어 있는 내용과 같이 외부로 부터의 트래픽 송수신을 위한 정책을 추가하는 것입니다. IGW (Internet Gateway) 로는 SSH 접근을 위해 IPv4 에 대한 정책을 추가했고, EIGW (Egress Only Internet Gateway) 에는 실제 v6 주소 목적지에 대한 VPN 터널링을 위해 IPv6 주소에 대한 정책을 추가했습니다.
정책 추가를 위해 라우팅 테이블 목록에서 IPv6 용으로 만든 VPC 에 할당된 기본 라우팅 테이블을 선택합니다. Actions 버튼을 누르지 않아도 화면 아랫쪽에서 <Routes> 탭을 선택하면 라우팅 테이블에 대한 상세 정책 목록이 출력됩니다. 정책 추가를 위해 <Edit routes> 버튼을 누르겠습니다.
IPv4 의 모든 주소를 나타내는 CIDR block 은 0.0.0.0/0 으로 표기되며, IPv6 의 모든 주소를 나타내는 CIDR block 은 ::/0 으로 표기합니다. 목적지 주소에 v4, v6 에 대한 CIDR block 을 추가하고 v4 는 IGW 로, v6 는 EIGW 를 이용하도록 대상(Target) 제품을 지정해 줍니다. 이미 생성한 IGW 와 EIGW 가 드롭 다운 목록에 노출되기 때문에 설정은 쉽게 하실 수 있습니다. 경로 입력이 끝나면 우측 하단의 <Save Routes> 버튼을 누릅니다.
1.5 IPv6 주소를 갖는 EC2 인스턴스 배포
네트워크의 구성이 끝났으니 이제 실제 OpenVPN 바이너리가 구동되고 목적이 v6 주소까지 터널링을 해줄 EC2 인스턴스를 생성해 보도록 하겠습니다. 사용자가 얼마나 많은지, 트래픽 규모가 어떠한지에 따라 인스턴스 타입이 결정되어야 하겠지만, 이 포스팅에서는 AWS 무료 티어에서도 사용할 수 있는 t2.micro 타입의 인스턴스를 사용하도록 하겠습니다. 소규모의 사용량이라면 이 인스턴스로도 큰 문제가 없습니다.
EC2 인스턴스의 생성은 많이들 해보셨을 작업이기 때문에 주의할 점을 중심으로 설명드리겠습니다. EC2 생성 마법사의 세번째 단계에는 IP 주소 할당에 대한 정책을 선택하도록 되어 있습니다. 우리가 진행하는 OpenVPN 은 단일 인스턴스 환경이기 때문에, 해당 서버가 사용자들로부터 IPv4 를 통해 VPN 연결을 시도할 수 있어야 하고, IPv6 주소를 보유하여 v6 주소를 갖고 있는 목적지 서버와 연결할 수 있어야 합니다.
이 목적을 달성하기 위해서는 <3. Configure Instance> 단계에서 하단에 있는 <Auto-assign Public IP> 와 <Auto-assign IPv6 IP> 를 Enable 로 선택하여 v4 와 v6 를 통해 공인 IP 를 사용할 수 있도록 해야 합니다. 그런데 IPv6 는 왜 <Public> 이라는 말이 없을까요? 기본적으로 IPv6 주소 체계는 Private / Public 를 가지고 있지 않습니다. 따라서 옵션의 이름도 단순히 <Auto-assign IPv6 IP> 라고 되어 있다는 점 참고하시기 바랍니다!
EC2 생성 마법사를 완료하고 인스턴스 생성을 기다립니다. 생성이 완료되면 위와 같은 화면을 볼 수 있게 됩니다. 다른 기본적인 사항은 특별히 확인할 내용이 없고, 네트워킹 Networking 탭을 중심으로 살펴보면 됩니다. 설명했던 것처럼 v4 는 Private, Public 의 주소가 할당되지만 v6 는 하나의 주소만 할당된 것이 보입니다. 이제 인프라의 준비가 끝났습니다.
9월에 첫 포스팅을 올리고 시간이 너무 많이 흘렀습니다. 기억이 더 가물가물 해지기 전에 OpenVPN 구축 포스팅을 마무리 해볼까 합니다. 지난 포스팅에서 우리는 `IPv6 대역을 갖고 있는 VPC 생성` 을 했고 `VPC 내에 Public Subnet 생성` 까지 완료했습니다. 자세한 내용은 아래 링크를 통해 지난 포스팅을 참고하시기 바랍니다!
Gateway 구성 : Internet Gateway / Egress Only Internet Gateway (본 포스팅!)
Routing Table 조정
IPv6 주소를 갖는 EC2 배포
OpenVPN 설치 및 구성
VPN 접속 시험
기타
라우팅 조정
1.3. Gateway 구성
1.3.1. Internet Gateway
OpenVPN 을 이용한 IPv6 VPN 구성시 VPC 에는 두개의 Gateway 가 필요합니다. 보통 v4 주소 환경에서 인터넷으로 나가고 들어오는 트래픽 처리를 위해 사용하는 Internet Gateway 가 첫번째 요소입니다. v4 주소라고 명기한 것은 다 이유가 있겠죠? Internet Gateway 는 나가는 트래픽, 즉 아웃바운드 트래픽에 대하여 IPv6 주소를 처리하지 못합니다. 이 때문에 별도로 Egress Only Gateway 를 구성해야 합니다.
정리를 잘 해두기 위하여 위의 내용은 취소선으로만 표기하고 나두었습니다. AWS 에서 제공하는 Gateway 에는 Internet Gateway 와 Egress Only InternetGateway 가 있습니다. Internet Gateway 는 양방향 (Inbound, Outbound) 의 인터넷 트래픽을 위해 사용하는 구성 요소이고 Egress Only InternetGateway 는 단방향 (Outbound) 전용 게이트웨이 입니다.
왜 그렇게 기억하고 있었는지 모르겠지만 OpenVPN 을 통해 실제 IPv6 를 사용하는 서버까지 터널링을 위해서 꼭 Egress Only Internet Gateway 를 사용할 필요는 없습니다. 다만, 각 인스턴스로 IPv6 로 요청이 들어오지 않도록 확실히 분리할 필요가 있다면 IPv6 터널링 용으로 Egress Only Internet Gateway 를 사용하면 됩니다.
Internet Gateway : OpenVPN EC2 인스턴스로 SSH, OpenVPN 접속을 처리하기 위한 목적 Egress Only Internet Gateway : 터널링을 통해 IPv6 목적지로 연결 (EC2 <-> Dest. IPv6 서버) 하기 위한 용도
Internet Gateway 를 생성하기 위해 VPC 제품 페이지에서 Internet Gateway 메뉴로 들어갑니다. 별도의 VPC 를 만들었기 때문에 Default VPC 에 있는 Internet Gateway 를 사용할 수는 없습니다. Internet Gateway 는 VPC 단위로 연결할 수 있다는 것도 기억해 두면 좋겠습니다. 제 경우 구분을 위해 Tag 에 "ipv6" 를 넣어주었습니다.
Internet Gateway 가 생성되면 어떤 VPC 와도 연결되어 있지 않은 상태입니다. 아래의 화면에서 보이는 것처럼 Detached 라는 메세지가 연결된 VPC 가 없다는 것을 알려줍니다. 우측 상단의 "Actions" 버튼을 눌러 앞서 생성한 VPC 에 연결(Attach) 해보도록 하겠습니다.
앞서 가이드 했던 것처럼 VPC 생성시에도 Tag 를 잘 달아두었다면 Attach to VPC 를 하는 과정에 어려움 없이 VPC 를 잘 선택할 수 있습니다. 물론 제 경우 VPC 가 하나라서 Tag 가 있고 없고 상관은 없습니다만 규모가 좀 되는 인프라를 운영중이시면 Tag 가 확실히 도움이 될 겁니다. VPC 를 선택후 <Attach internet gateway> 버튼을 눌러 연결 작업을 마무리 합니다.
연결 작업이 정상적으로 완료되면 아래와 같은 Summary 화면을 보게 됩니다. 연결한 내용에 이상이 없는지 한 번 살펴보고 지나가시면 됩니다.
1.3.2. Egress Only Internet Gateway
설명했던 것처럼 VPN 연결은 IPv4 로만 허용하고 터널링은 IPv6 를 쓰기 위해 Egress Only Internet Gateway 를 따로 만들어 보도록 하곘습니다. AWS 의 제품 설명 페이지를 유심히 읽어 보셨다면 아시겠지만 Egress Only Internet Gateway 는 IPv6 전용입니다. IPv4 를 터널링 한다면 Internet Gateway 만 사용하는 것으로 충분합니다.
VPC 화면의 메뉴중 <Egress Only Internet Gateway> 를 선택합니다. 새로운 Egress Only Internet Gateway 를 아래 화면처럼 생성하도록 하겠습니다. 일반 Internet Gateway 와 특별히 차이가 없기 때문에 Tag 지정만 유의해서 진행하시면 되겠습니다. VPC 목록에도 Tag 가 표시되기 때문에 VPC 생성시 Tag 를 잘 달아두었다면 어려움 없으실 겁니다.
생성된 Egress Only Internet Gateway 는 eigw 로 시작되는 고유 ID 를 갖게 됩니다. Internet Gateway 의 생성 화면과 달리 생성 할때 이미 VPC 를 지정했기 때문에 별로도 Attach 하는 과정이 나오지는 않습니다. 비슷한 제품인데 담당 조직이 다른지 생성 화면과 절차가 차이가 있네요? Egress Only Internet Gateway 가 훨씬 편한 것 같습니다 ^^
이번 포스팅에서는 두개의 Internet Gateway 를 생성해 보았습니다. 다음 포스팅에서는 VPC 의 라우팅 테이블을 설정하여 OpenVPN 트래픽이 정상적으로 EC2 를 통해 연결되고 터널링 될 수 있도록 해보겠습니다.
VPN 과 관련한 여러가지 시험, 환경을 구축하다보니 로컬 라우팅 테이블이 꼬이는 현상이 발생하여 조사를 해보았습니다. 평소 사용하고 있던 IPv4 VPN 와 IPv6 VPN, 그리고 개별 과제로 만들고 있는 OpenVPN 기반의 IPv6 까지 아주 난장판이라 이런 문제가 생긴다고 생각해서 트러블슈팅 방법을 좀 정리해 보고자 합니다. (미래의 내가, 과거의 나를 찾을 것이 분명하니...)
지저분해지는 IPv6 라우팅 테이블
안그래도 복잡했던 로컬 IPv6 라우팅 테이블이 심하게 꼬인 것은 로컬 환경에서 OpenVPN Web UI 디버깅을 위해 OpenVPN 을 설치하고 구동하면서 부터였습니다. 오늘 아침 개발조직에 IPv6 접근 가이드를 해주기 위해 WIKI 를 정리하다보니 평소 사용하던 IPv6 VPN 에 연결하더라도 v6 웹 사이트 (가령 v6.google.com) 에 접근이 안되는 것을 확인했습니다.
미처 캡쳐를 해두진 못했지만 netstat -nr 로 로컬의 라우팅 테이블을 살펴보니 스태틱으로 잡힌 테이블이 너무 많았습니다. VPN 연결시 생성되는 인터페이스인 utun 시리즈도 무려 6개나 존재하더군요. 인터페이스를 down 으로 하는 것과 라우팅 테이블은 별개라 한땀 한땀 삭제를 해주어야 했습니다. 사용한 명령들은 대략 아래의 패턴입니다.
// 한 땀, 한 땀 삭제...
sudo route delete -inet6 ##v6주소##%utun0
// default 를 잠식한 utun 시리즈 삭제는 -ifscope 으로...
sudo route delete -inet6 default -ifscope utun1
이렇게 삭제를 하고나니 라우팅 테이블이 깔끔해졌습니다. 이제 라우팅 테이블을 지저분하게 만든 범인을 찾기 위해 간단한 스크립트로 리눅스 환경에서의 watch 를 구현하여 netstat -nr 명령을 반복하도록 해보았습니다. 우리가 기대하는 것은 VPN 연결시 필요한 라우팅 테이블이 추가 되었다가 VPN 연결을 종료하면 라우팅 테이블이 정리되는 것이겠죠!?
// Mac 환경에서 리눅스 watch 스타일로 명령 구동하기
while true; do clear; netstat -nr; sleep 2; done;
회사가 제공한 VPN 시험
먼저 회사가 제공한 IPv6 VPN 을 살펴보았습니다. 심증은 <범인은 OpenVPN 이다!> 였지만 확실하게 하기 위해서죠. 개발팀도 분명 비슷한 증상을 겪을 수 있으니 FAQ 를 준비하는 목적도 있었습니다. 자, 우선 IPv6 VPN 연결전에는 아래와 같이 깔끔한 라우팅 테이블 목록을 볼 수 있습니다. 물론... 앞서 이야기 한 것처럼 한 땀, 한 땀 라우팅 테이블을 정리한 상태입니다 ㅜㅜ
회사에서 셋업한 IPv6 VPN 을 연결해 보니 utun 인터페이스로 다수의 라우팅 테이블이 추가되는 것을 확인할 수 있었습니다.
다시 VPN 연결을 끊었을때 v4, v6 쪽으로 추가된 라우팅 테이블이 깔끔하게 정리되는 것을 확인할 수 있었습니다. 범인은 OpenVPN 일까요? 확인해 보았습니다.
AWS 에 구축한 IPv6 OpenVPN 시험
이번에는 AWS 에 구축해 둔 IPv6 OpenVPN 을 시험해 보았습니다. VPN 에 연결되면 이전의 다른 VPN 과 마찬가지로 다량의 라우팅 테이블이 추가되는 것을 확인할 수 있었습니다. 이번에도 동일하게 utun4 를 사용했군요. 터널 인터페이스가 만들어지고 삭제되는 과정도 좀 궁금하지만 따로 알아보기로 하고...
자 이제... 대망의 연결 종료의 시간이 되었습니다. OpenVPN 연결을 종료했을때 깔끔하게 라우팅 테이블이 정리되었으면 하는 바램을 갖고... 도전!
이런... 예상과 다르게 너무 깔끔하게 라우팅 테이블이 정리가 되었습니다. 문제가 생기길 기대(?)했는데 깔끔해진 걸 보니... 뭔가 OpenVPN 에 등록해 둔 Profile 들을 시험하는 과정에, 연결이 깔끔하지 못했거나 강제 종료된 경우 등 예외 상황에서 문제의 현상이 나오는 것일 가능성이 생겼습니다.
AWS EC2 를 이용한 OpenVPN 구축 연재는 아래 글타래로... (2편은 아직 못쓴...)
Mac 로컬 환경의 OpenVPN 시험
내친김에 로컬 환경의 시험도 해보았습니다. 조금 까리한 것은 로컬에서는 초기에 proto udp 로 시험하다보니 AF_INET6 로 서버가 구동되는 문제가 있어서 proto udp4 로 설정해둔 상태였습니다. 만약, 이 상태에서도 문제가 없다면 proto udp 일때 AF_INET6 로 구동되는 과정, 종료되는 과정의 문제라고 생각해도 될 것 같았습니다.
참고로 utun4 는 로컬의 OpenVPN 서버가 점유하고 있는 터널이고, utun7 은 로컬의 Tunnelblick 이 연결을 맺으면서 생성한 인터페이스입니다. 자, 이제 연결을 끊어보겠습니다.
오오... 찾은 것 같습니다. Tunnelblick 종료시 utun7 이 빠졌고, OpenVPN 서버 종료시 utun4 가 빠졌지만, Internet6 쪽에 추가된 스태틱 라우팅 하나가 빠지지 않은 것을 확인할 수 있었습니다. 설정의 문제인지는 조금 더 조사해 봐야하고 로컬 환경에서만 생기는 문제인지 명확하진 않습니다만, 최소한 FAQ 에 기술해두고 개발자 분들께 가이드 하는데는 문제 없을것 같습니다.
뭔가 완전히 잘 알지 못하는 분야는 늘 시행착오가 생기는 것 같습니다. 오늘도 몇 가지 시행착오를 겪으면서 한 걸음, 한 걸음, 뚜벅 뚜벅 걸어나가 봅니다!