[GCP] Google Cloud와 L2TP VPN 연결하기
안녕하세요 김세호입니다.
가상 사설네트워크(VPN, Virtual Private Network) 연결은 비교적 낮은 가격으로 이기종 네트워크 간 사설 연결을 하는 솔루션입니다.
Medium 블로그에도 박형준님께서 “Google Cloud VPN 구성 및 연결 가이드”라는 제목으로 2월에 포스팅해 주신 글이 올라와 있습니다. Google Cloud에서 Site-to-Site VPN을 통하여 AWS 환경과 연결에 대한 내용 이었는데요,
이번에 포스팅할 내용은 기업의 오피스 또는 데이터센터의 VPN장비와 Google Cloud를 연결하는 Site-to-Site VPN과는 다른 형태인 Point-to-Site VPN으로 개인 작업환경에서 Google Cloud내 가상머신등의 리소스에 접근하기 위한 사설 네트워크를 연결해 주는 솔루션입니다.
Google Cloud는 VPN 이외에도 IAP(Identity Aware Proxy) for TCP forwarding 등의 방법을 통해 접근하는 방법을 제공하며 블로그에도 이정운님께서 작성하신 “[GCP]DNS 부터 하나씩 해보는 Google cloud 로 서비스 해보기 5탄 — IAP for TCP forwarding 과 Label” 이 포스팅되어있으니 참고하셔도 좋을듯 합니다.
시작하기에 앞서, VPN 프로토콜에 대한 내용을 잠시 알아보도록 하겠습니다.
대표적인 VPN 프로토콜은 PPTP, L2TP, OpenVPN, IKEv2 등이 있으며 이외에도 다양한 방식을 제공하고 있습니다.
PPTP (Point-to-Point Tunneling Protocol)
PPP(Point-to-Point Protocol) 기술을 확장하여 만든 규격이며, L2TP와 같이 PPTP도 암호화 터널을 생성해 연결을 하도록 합니다. 대부분의 VPN을 지원하는 플랫폼 및 장치에서 기본적으로 지원하지만, 시간이 지날수록 많은 보안결함으로 인하여 최신 OS에서는 더이상 사용하지 않고 있습니다.
L2TP (Layer 2 Tunneling Protocol)
L2F와 PPTP 프로토콜을 결합하여 만든 규격으로 IKE(Internet Key Exchange)와 ESP(Encapsulation Security Payload)를 사용하는 IPsec 기술을 이용하여 암호화를 합니다. 대부분의 운영체제에서 기본적으로 지원하며 쉽고 빠르게 설정할 수 있습니다. L2TP 프로토콜은 UDP 포트 500번을 사용하기 때문에 NAT 방화벽을 사용하고 있다면 차단이 될 수 있어 포트포워딩등의 고급 구성이 필요할 수 있습니다.
OpenVPN
OpenVPN은 OpenSSL 라이브러리 및 SSLv3/TLSv1 프로토콜과 다른 기술을 함께 사용하여 강력하고 안정적인 VPN 솔루션을 제공하며, 프로파일을 통하여 여러 운영체제에서 쉽게 연결을 할 수 있습니다. 공식적으로 포트를 할당받은 프로토콜이 아니고, 포트를 자율적으로 설정할 수 있어 방화벽을 우회할 수 있는 구성도 가능하지만 소프트웨어를 설치해야 하는 단점도 존재합니다.
IKEv2 (Internet Key Exchange)
IPsec 기반 터널링 프로토콜로 Microsoft와 Cisco에 의해 개발되었습니다. 다양한 OS에서 호환이 가능하지만, 비교적 최신 OS (윈도우 7이상) 플랫폼에서만 이용할 수 있고 구현 방법이 까다롭습니다.
이와 같이, 다양한 프로토콜 방식으로 구현이 가능한 Point-to-Site VPN 구성 중 오늘은 L2TP 방식에 대해 설명하고, 부가적으로 OpenVPN과 IKEv2도 잠깐 언급을 하도록 하겠습니다.
시작하기에 앞서, 현재 Google Cloud에 구성된 네트워크 환경을 알아보도록 하겠습니다.
이전에 포스팅되었던 “[GCP] CloudSQL과 VPC 네트워크에 대한 이해” 를 읽은 분이라면 아래 구성도가 익숙하실 겁니다.
개발환경을 위한 2개의 VPC가 피어링 되어있고, 각 VPC들은 Cloud SQL과 피어링되어 연결되어 있는 모습입니다.
기존 환경 (데이터센터, 사무실)과 Site-to-Site VPN 또는 Interconnect 전용선으로 연결이 되어있고, 자택 또는 외부에서 사내 리소스에 접근하기 위한 Point-to-SIte VPN이 구성되어있다면 좋겠지만, 그렇지 못한 경우 새벽에 긴급한 업무처리를 해야하는 작업이 발생한다면 난감한 상황이 될 것 입니다.
물론, 외부에서 접근이 가능한 bastion 호스트를 두고 자택의 IP주소를 firewall에 등록해서 작업을 할 수 있겠지만 보안상 좋은 방법은 아닐것입니다.
만약 VPN 또는 Interconnect 전용선 연결이 없는 상태에서 Point-to-Site VPN을 구성한다면 아래와 같이 DMZ 영역에 Public IP를 가지는 VM을 생성하고, 2개의 NIC (Network Interface Card)을 할당하여 각각 서로 다른 VPC로 연결하는 아키텍처를 구성할듯 합니다.
본 블로그에서는 편의상 기존에 구성된 VPC (dev-test-a)에 Point-to-Site VPN 서버를 구성하고 외부에서 해당 VPN서버를 통하여 VPC에 존재하는 VM 서버로의 Private IP를 이용한 연결을 확인해 보도록 하겠습니다.
VPN 서버를 구성하기 위하여 구글 클라우드 콘솔로 접속하여 “Menu” → “Compute Engine” → “VM Instances”를 선택합니다. VM 생성을 위해 상단의 “Create Instance”를 클릭합니다.
대부분의 설정은 기본값을 이용하지만 아래의 내용들을 참고하여 수정합니다.
- 인스턴스 이름은 dev-test-a-vpn으로 지정하겠습니다.
- 테스트를 할 VPC (dev-test-a)가 위치하는 리전을 선택하고, 인스턴스 타입은 n1-standard-1을 이용하겠습니다.
- OS는 Ubuntu 18.04 LTS Minimal을 이용할 예정이므로 Change 버튼을 눌러 아래와 같이 변경합니다.
- Management, security, disks, networking, sole tenancy 링크를 클릭하여 확장하고 Networking 탭을 선택합니다.
- Network tags에 “vpnserver”를 입력합니다. 차후 Firewall 에 필요한 포트를 오픈할때 태그로 사용할 예정입니다.
- Network interfaces에 연필 아이콘을 클릭하여 VM 인스턴스를 생성할 VPC를 선택하고, 실서비스에 이용할 예정이라면 Public IP주소가 변경되지 않도록 External IP부분에 고정아이피 주소를 할당하도록 합니다.
- IP Forwarding을 “On”으로 변경합니다. (옵션에 대한 자세한 내용은 링크를 참고하세요)
* VPN 서버 구성을 위해 해당 옵션은 반듯이 On이 되어야 합니다.
- Create 버튼을 클릭하여 VM 인스턴스를 생성합니다.
VM 인스턴스 생성이 완료되었다면 SSH버튼을 클릭하여 인스턴스 로그인 후 VPN 설정 작업을 시작합니다.
L2TP VPN 서버 설정을 위해 아래의 명령을 복사하여 실행을 합니다.
wget https://git.io/vpnsetup -O vpnsetup.sh && sudo sh vpnsetup.sh
스크립트가 완료되면 아래와 같은 화면이 출력되며 VPN 연결을 구성하기 위해 필요한 Server IP, IPsec PSK, Username, Password 정보를 메모해 둡니다.
========================================IPsec VPN server is now ready for use!Connect to your new VPN with these details:Server IP: x.x.x.xIPsec PSK: 2BShdsfhuashfbkjdsnvAwSC2Username: vpnuserPassword: LurdsofsdjUHEvF5Write these down. You’ll need them to connect!Important notes: https://git.io/vpnnotesSetup VPN clients: https://git.io/vpnclientsIKEv2 guide: https://git.io/ikev2========================================
VPN 설정 스크립트의 내용을 간단히 살펴보면,
- L2TP 구성을 위한 xl2tpd 패키지를 설치하고 libreswan을 다운받아 컴파일 후 설치합니다.
- IPsec 관련 설정을 /etc/ipsec.conf 파일에 PSK를 /etc/ipsec.secrets 파일에 설정합니다.
- L2TP 네트워크 Pool은 192.168.42.0/24 대역을 사용할 예정이며, /etc/xl2tpd/xl2tpd.conf 파일과 /etc/ppp/options.xl2tpd 파일에 기본값과 옵션값들을 지정합니다.
- VPN 사용자정보는 /etc/ipsec.d/passwd 파일에 저장되며, 사용자 비밀번호는 openssl passwd 명령을 이용 암호화하여 저장합니다.
- 커널에 네트워크 관련 sysctl 설정을 지정합니다. 대표적으로 net.ipv4.ip_forward=1 등 입니다.
- Iptables 룰을 설정하고 ipsec, xl2tpd 데몬을 실행합니다.
설정이 완료되었으니 클라이언트를 이용하여 VPN 서버로 연결을 테스트합니다. 클라이언트 설정은 맥과 윈도우즈 2가지 경우를 테스트 하였습니다.
[맥 사용자 가이드]
맥 사용자의 경우 “System Preferences” → “Network” 에서 좌측하단의 + 버튼을 눌러 아래와 같이 Interface 및 VPN Type을 지정합니다.
생성된 서비스 화면에서 Server Address, Account Name을 메모해둔 정보에서 복사하여 입력합니다.
Authencation Settings 버튼을 클릭하여 Password, Shared Secret을 메모해둔 정보에서 복사하여 입력합니다.
Advanced 버튼을 클릭하여
- Options 탭의 “Send all traffic over VPN connection” 을 체크합니다.
- TCP/IP 탭의 Configure IPv6를 “Link-local only”로 선택합니다.
Connect 버튼을 클릭하여 VPN 서버로 연결을 시도하면 아래와 같은 에러화면이 출력됩니다.
Firewall 설정이 오픈되지 않아 발생하는 오류이기 때문에 아래의 명령 또는 Google Cloud 콘솔내 Firewall 메뉴에서 다음 3가지 UDP 포트를 오픈합니다.
$ gcloud compute --project=[PROJECT_NAME] firewall-rules create vpnserver --direction=INGRESS --priority=1000 --network=[VPC_NAME] --action=ALLOW --rules=udp:1701,udp:500,udp:4500 --source-ranges=[CLIENT_IP] --target-tags=vpnserver
* CLIENT_IP는 외부 전체를 허용할 경우 0.0.0.0/0 으로 입력하시면 됩니다.
Connect 버튼을 클릭하여 VPN 서버로 연결을 다시 시도하면 아래와 같이 VPN이 연결된 화면이 출력됩니다.
VPN이 작동되는 것을 확인하기 위하여 VPC (dev-test-a)에 미리 만들어진 VM 인스턴스의 Private IP로 연결을 테스트해 봅니다.
$ ssh saeho@10.30.0.2Linux dev-test-a-vm1 4.9.0–11-amd64 #1 SMP Debian 4.9.189–3+deb9u2 (2019–11–11) x86_64The programs included with the Debian GNU/Linux system are free software;the exact distribution terms for each program are described in theindividual files in /usr/share/doc/*/copyright.Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extentpermitted by applicable law.Last login: Tue Jul 7 04:31:46 2020 from 10.30.0.8saeho@dev-test-a-vm1:~$
[윈도우즈 사용자 가이드]
윈도우즈 사용자의 경우 “설정” → “네트워크 및 인터넷” → “VPN” → “+ VPN 연결추가”를 통하여 메모해둔 정보를 다음과 같이 입력합니다.
VPN 연결이 추가되었지만 아직 추가적인 몇가지 작업이 필요합니다. 우측의 “관련설정” → “어댑터 옵션 변경”을 클릭하여 네트워크 연결 창을 오픈합니다.
구성된 VPN연결이 보이고 마우스 우측버튼을 클릭하여 “속성” 정보를 오픈합니다. “보안” 탭의 “다음 프로토콜 허용”을 클릭하고 “CHAP(Challenge Handshake 인증 프로토콜)”과 “Microsoft CHAP Version 2”를 체크하고 “확인”을 클릭합니다.
“명령 프롬프트” 앱을 관리자 권한으로 실행 후 다음의 명령을 붙여넣어 실행하고
REG ADD HKLM\SYSTEM\CurrentControlSet\Services\PolicyAgent /v AssumeUDPEncapsulationContextOnSendRule /t REG_DWORD /d 0x2 /f
만약 정상 작동하지 않는다면, 다음의 명령을 붙여넣어 실행하고 시스템을 리부팅합니다.
REG ADD HKLM\SYSTEM\CurrentControlSet\Services\RasMan\Parameters /v ProhibitIpSec /t REG_DWORD /d 0x0 /f
“설정” → “네트워크 및 인터넷” → “VPN” 으로 이동하면 다음과 같이 추가한 VPN 연결정보를 확인할 수 있습니다. 연결 버튼을 클릭하여 VPN 연결을 시작합니다.
정상적으로 연결이 되었다면 아래와 같은 화면을 볼수 있고, VPN 상태정보를 확인하면 192.168.42.0/24 Pool에서 IP를 받아온것을 확인할 수 있습니다.
지금까지 L2TP를 이용한 VPN 설정을 알아보았는데요, 추가적으로 조금 더 보안이 강화된 IKEv2를 이용한 방법도 알아보도록 하겠습니다.
대부분의 최신 OS 플랫폼에서는 IKEv2를 표준으로 지원합니다. VPN서버에 설치된 Libreswan은 X.509 인증서에 RSA Signature를 이용하여 IKEv2 클라이언트의 인증을 지원하며 지원되는 OS들은 Windows 7이상, OS X, Android 4.x이상과 iOS등 입니다.
IKEv2를 VPN 서버에 설정하기 위해 아래의 명령을 복사하여 실행을 합니다.
wget https://git.io/ikev2setup -O ikev2.sh && sudo bash ikev2.sh
스크립트 실행 중 다음과 같은 정보를 입력하는 과정을 거치게 되며 대부분의 경우 엔터를 입력하셔도 무방하며, 최종적으로 IKEv2를 적용할지를 묻는 We are ready to set up IKEv2 now. Do you want to continue? [y/N] 질문에 대해서 Y를 입력하시면 됩니다.
========================================Do you want IKEv2 VPN clients to connect to this server using a DNS name,e.g. vpn.example.com, instead of its IP address? [y/N]Enter the IPv4 address of this VPN server: [x.x.x.x]Provide a name for the IKEv2 VPN client.Use one word only, no special characters except ‘-’ and ‘_’.Client name: [vpnclient]Specify the validity period (in months) for this VPN client certificate.Enter a number between 1 and 120: [120]Do you want to enable MOBIKE support? [Y/n]Below are the IKEv2 setup options you selected.Please double check before continuing!========================================VPN server address: x.x.x.xVPN client name: vpnclientClient cert valid for: 120 monthsEnable MOBIKE support: Yes========================================We are ready to set up IKEv2 now. Do you want to continue? [y/N] Y## Generating CA certificate…Generating key. This may take a few moments…## Generating VPN server certificate…Generating key. This may take a few moments…## Generating client certificate…Generating key. This may take a few moments…## Exporting CA certificate ‘IKEv2 VPN CA’…## Exporting .p12 file…Enter a *secure* password to protect the exported .p12 file.This file contains the client certificate, private key, and CA certificate.When importing into an iOS or macOS device, this password cannot be empty.Enter password for PKCS12 file:Re-enter password:pk12util: PKCS12 EXPORT SUCCESSFUL## Adding a new IKEv2 connection…## Restarting IPsec service…========================================
스크립트가 완료되면 아래와 같은 화면이 출력되며 VPN 연결을 구성하기 위해 필요한 p12 파일을 로컬 컴퓨터로 복사해 둡니다.
========================================IKEv2 VPN setup is now complete!Client configuration is available at:/root/vpnclient-2020–07–08–13_19_36.p12/root/ikev2vpnca-2020–07–08–13_19_36.cer (for iOS clients)Next steps: Configure IKEv2 VPN clients. See:https://git.io/ikev2clients========================================
IKEv2 설정 스크립트의 내용을 간단히 살펴보면,
- 기 설치된 ipsec, libreswan등의 버전을 검사하고 certutil, pk12util등의 바이너리가 설치되어있는지 검사를 합니다.
- IPsec 관련 설정을 /etc/ipsec.d/ikev2.conf 파일에 설정합니다.
- 스크립트 내에서는 위 입력된 정보를 이용하여 certutil 명령을 실행하여 CA (Certificate Authority)와 Server Certificates 를 생성하게 됩니다.
- Client Certificates 를 생성하고 pk12util 명령을 실행하여 p12 파일로 export 합니다. (p12파일에는 Client Certificate, Private Key, CA Certificate이 포함되어 있습니다)
- 다음의 명령을 실행하면 데이터베이스에 포함이 된것을 확인할 수 있습니다.
$ sudo certutil -L -d sql:/etc/ipsec.dCertificate Nickname Trust AttributesSSL,S/MIME,JAR/XPIIKEv2 VPN CA CTu,u,u34.84.197.184 u,u,uvpnclient u,u,u
- ipsec 데몬을 재실행합니다.
설정이 완료되었으니 클라이언트를 이용하여 VPN 서버로 연결을 테스트합니다. 클라이언트 설정은 맥에서 테스트 하였습니다.
“System Preferences” → “Network” 에서 좌측하단의 + 버튼을 눌러 아래와 같이 Interface 및 VPN Type을 지정합니다.
생성된 서비스 화면에서 VPN Server Address 정보를 복사하여 Server Address, Remote ID 필드에 입력하고, VPN Client Name 정보를 복사하여 Local ID 필드에 입력합니다.
Authentication Settings를 설정하기 전에 다운받은 p12파일을 로컬 컴퓨터의 Keychain에 등록해야 합니다.
P12 파일을 더블클릭하여 다음과 같은 화면에서 Add 버튼을 클릭합니다.
Keychain에 등록이 되고, 검색창에 vpnclient를 입력하여 등록된 Certificate와 Private Key를 확인합니다.
vpnclient certificate를 더블클릭하여 오픈하고 Trust → IP Security (IPsec) 을 “Always Trust”로 변경합니다.
VPN 설정화면으로 돌아와서 Authencation Settings 버튼을 클릭하여 Authentication Settings는 none을 선택하고, Certificate 를 선택 후 Select 버튼을 클릭하여 Identity 선택화면에서 vpnclient를 선택합니다.
Connect 버튼을 클릭하여 VPN 서버로 연결을 다시 시도하면 아래와 같이 VPN이 연결된 화면이 출력됩니다.
지금까지 IPsec을 기반으로 한 L2TP와 IKEv2를 이용하여 VPN 연결을 구성하는 방법을 살펴보았습니다. 제일 처음 프로토콜의 특성에서 언급한것과 같이 L2TP는 특정 UDP 포트가 오픈되어야 하기 때문에 방화벽 오픈이 어려울 경우 사용하기 어려운 점이 있습니다.
이러한 경우에는 SSL 포트를 이용할 수 있는 OpenVPN과 같은 솔루션을 이용하면 방화벽을 오픈하지 않고도 VPN 연결을 구성할 수 있습니다.
OpenVPN은 Google Cloud의 Marketplace에서 검색하면 OpenVPN Access Server를 Launch 버튼을 이용하여 기 구성된 VPC에 VM 인스턴스로 생성할 수 있고,
OpenVPN 서버를 생성하면 다음과 같은 화면이 출력되며, 관리자를 위한 엔드포인트를 제공하여 브라우저로 접속하여 설정, 유저, 인증관리등을 하실 수 있습니다.
OpenVPN의 클라이언트 구성은 홈페이지에 설명이 잘 되어있고, Support를 통하여 기술지원을 받을수도 있습니다.
* OpenVPN은 기본 2개의 동시접속만 지원하며, 추가적인 연결이 필요할 경우는 라이센스의 구매가 필요합니다.
Disclaimer: 본 글의 작성자는 Google 직원이지만 Google cloud 를 공부하는 한 개인으로서 작성된 글입니다. 본 글의 내용, 입장은 Google 을 대변하지 않으며 Google 이 해당 콘텐츠를 보장하지 않습니다.
참고 자료 #1
IPsec VPN Server Auto Setup Scripts
https://github.com/hwdsl2/setup-ipsec-vpn
OpenVPN Access Server on GCP
https://openvpn.net/google-cloud-vpn/