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

5분 만에 WireGuard VPN 서버 구축하기 – 빠르고 쉬운 완벽 가이드

좋은 VPN이 모바일 통신의 보안과 프라이버시를 지키는 데 얼마나 중요한지는 이미 잘 알고 계실 겁니다.

공항이나 카페의 공용 WiFi에서 은행 업무를 처리해야 할 때도, 온라인 대화를 엿듣는 불청객이 걱정될 때도, 검증된 VPN이 제공하는 터널링 암호화는 그 어떤 것보다 든든한 방패가 되어 줍니다.

문제는 진짜 '좋은' VPN, 즉 편리하면서도 합리적인 가격의 VPN을 찾는 일입니다.

상용 VPN의 한계

시중에는 상용 VPN 서비스가 넘쳐나고, 스마트폰이나 노트북에 설정하는 것도 대체로 어렵지 않습니다. 하지만 이런 서비스에는 두 가지 잠재적인 단점이 있습니다.

첫째, 월 평균 10달러 내외의 비용이 들어 결코 저렴하지 않습니다. 둘째, 업체가 실수로든 고의로든 사용자 데이터를 유출하거나 오용하지 않는다는 것을 100% 확신할 수 없습니다. 게다가 저렴한 VPN일수록 데이터 사용량이나 접속 가능한 기기 수를 제한하는 경우가 많습니다.

WireGuard가 주는 것

그런데 이미 클라우드 기반 리눅스 서버를 운영하고 있다면, WireGuard VPN을 직접 구축하는 것이 추가 비용 없이 강력하고 타협 없는 보안과 프라이버시를 확보하는 가장 좋은 방법이 될 수 있습니다.

VPN을 본인과 지인 몇 명의 기기로만 제한할 계획이라면 서버에 가해지는 부하는 거의 느끼지 못할 정도입니다. 설령 AWS EC2 t2.micro 예약 인스턴스를 새로 생성해 비용을 지불하더라도 연간 비용은 대부분의 상용 VPN보다 훨씬 저렴합니다. 게다가 데이터에 대한 완전한 통제권까지 얻게 됩니다.

이 글에서는 우분투(Ubuntu) 리눅스 서버에서 오픈소스 WireGuard 소프트웨어를 활용해 이 모든 과정을 실제로 구현하는 방법을 보여 드립니다.

왜 하필 WireGuard일까요? 사용법이 정말 간단하고, 공격에 특히 강하도록 설계되었으며, 그 성능이 뛰어나 최근 리눅스 커널 자체에 통합될 만큼 인정받기 때문입니다.

실제 작업 시간은 정말로 5분, 아니 그 이하면 충분합니다. 다만 사전 계획, 예상치 못한 문제 해결, 필요하다면 새 서버 구축 등에는 추가 시간이 들 수 있다는 점은 감안하세요.

환경 설정하기

먼저 사용 중인 방화벽에서 UDP 포트 51820을 열어야 합니다. AWS EC2 인스턴스에 연결된 보안 그룹이라면 아래와 같이 설정하면 됩니다.

이제 리눅스 서버에서 sudo 권한으로 셸을 열고 WireGuard와 resolvconf 패키지를 설치합니다.

엄밀히 말하면 여기서 resolvconf는 꼭 필요하지 않지만, 리눅스 머신을 WireGuard 클라이언트로 설정할 때 필요한 패키지이기에 함께 설치해 두겠습니다.

apt install wireguard resolvconf

암호화 키 생성하기

wg genkey 명령은 새로운 개인 암호화 키를 생성해 /etc/wireguard 디렉터리에 파일로 저장합니다. 이 디렉터리는 WireGuard 설치 시 자동으로 생성됩니다.

chmod 명령은 해당 개인 키 파일에 적절한 제한적 권한을 부여합니다. 리눅스의 모든 작업이 그렇듯 다른 방법도 있지만, 올바르게 처리하는 것이 무엇보다 중요합니다.

wg genkey | sudo tee /etc/wireguard/private.key
chmod go= /etc/wireguard/private.key

다음으로 개인 키 값을 이용해 짝이 되는 공개 키를 생성합니다. 이 역시 /etc/wireguard 디렉터리에 저장됩니다. 목표는 서버의 공개 키를 사용할 모든 클라이언트 기기의 WireGuard 설정에 추가하고, 클라이언트들의 공개 키를 서버 설정에 추가하는 것입니다.

개인 키는 절대 해당 머신 밖으로 나가서는 안 되며, 항상 철저히 보호해야 합니다.

cat /etc/wireguard/private.key | wg pubkey | sudo tee

WireGuard 서버 설정하기

이제 서버 설정 파일을 만들 차례입니다. 관례에 따라 파일 이름을 wg0.conf로 정하겠지만, 원하는 이름을 사용해도 무방합니다. 여러 개의 설정(다른 파일명)을 동시에 운영하는 것도 가능합니다.

설정 파일의 모습은 다음과 같습니다.

[Interface]
Address = 10.5.5.1/24
ListenPort = 51820
# /etc/wireguard/privatekey에 있는 본인의 개인 키 사용
PrivateKey = your_key
[Peer]
# 워크스테이션 공개 키
PublicKey = your_key
# VPN 내 클라이언트 IP 주소
AllowedIPs = 10.5.5.2/32
[Peer]
# 노트북 공개 키
PublicKey = your_key
# VPN 내 클라이언트 IP 주소
AllowedIPs = 10.5.5.3/32

이 파일은 Interface 섹션 하나와 Peer 섹션 두 개로 구성되어 있습니다. Interface 섹션은 서버가 사용할 사설 NAT 네트워크 주소를 정의합니다. 클라이언트는 물론 서버의 공개 IP를 통해 접근을 요청한 뒤 이 사설 주소로 연결됩니다.

주소 체계는 반드시 제 예시를 따를 필요는 없습니다. 다만 서버나 클라이언트에서 이미 사용 중인 네트워크 대역과 겹치지 않는 유효한 사설 IP 범위를 사용해야 합니다.

앞서 AWS에서 설정한 UDP 보안 그룹 규칙에 맞춰 ListenPort를 51820으로 지정했습니다. 원한다면 다른 포트를 선택해 보안을 조금 더 강화할 수도 있습니다.

마지막으로 서버의 개인 키를 PrivateKey 값으로 붙여 넣으면, WireGuard가 들어오는 클라이언트 요청을 인증할 수 있습니다.

첫 번째 peer 섹션에는 한 클라이언트의 공개 키와 할당된 사설 IP 주소만 담겨 있습니다. 두 번째 peer 섹션도 두 번째 클라이언트 머신에 대해 동일한 정보를 담습니다.

클라이언트에서 공개 키를 가져오는 작업이 이 전체 설정 과정에서 가장 손이 많이 가는 부분입니다. 하지만 어차피 여러분 자신의 VPN이므로, 복사해서 붙여 넣는 방식으로 서버 설정에 바로 반영하면 일일이 타이핑하는 수고를 덜 수 있습니다.

준비가 끝났습니다. 이제 wg-quick 명령으로 VPN을 가동합니다. up 옵션은 방금 만든 wg0.conf 설정을 읽어 새로운 VPN 인터페이스를 구성하라고 지시합니다.

wg-quick up wg0

wg 명령을 실행하면 정상 동작 여부를 확인할 수 있습니다. 마지막으로 systemctl enable을 실행해 서버가 재부팅될 때마다 이 WireGuard 인터페이스가 자동으로 로드되도록 설정합니다.

systemctl enable wg-quick@wg0

WireGuard 클라이언트 설정하기

서버 쪽에서 할 일은 여기까지입니다. 클라이언트 기기에 WireGuard를 설정하는 일은 서버보다 훨씬 쉬울 수도, 비슷할 수도 있습니다.

무슨 뜻이냐면, Windows, macOS, Android, iOS라면 wireguard.com/install 페이지에서 GUI 앱을 받을 수 있습니다. 이 앱들은 키 쌍을 대신 생성해 줍니다. 서버의 IP 주소 또는 도메인과 공개 키만 입력하면 됩니다. 그다음 클라이언트의 공개 키를 앞서 보여 드린 방식대로 서버의 wg0.conf 파일에 추가하면 끝납니다.

반면 리눅스 PC나 노트북을 클라이언트로 추가하려면 조금 더 복잡합니다. 기본적으로 키 생성을 포함해 서버 설정에서 봤던 모든 단계를 따라야 하고, wg0.conf라는 이름(원하는 이름으로)의 설정 파일도 만들어야 합니다. 클라이언트 설정 파일은 다음과 같이 작성합니다.

[Interface]
# 컴퓨터가 VPN에서 사용할 주소
Address = 10.5.5.2/32
DNS = 8.8.8.8
# 파일에서 개인 키 불러오기
PostUp = wg set %i private-key /etc/wireguard/privatekey
# 터널 초기화 확인을 위한 VPN 서버 ping
PostUp = ping -c1 10.47.47.1
[Peer]
# VPN 서버의 WireGuard 공개 키
PublicKey = your_key
# VPN 서버의 공개 IP 주소 (본인 것으로 교체!)
Endpoint = 54.160.21.183:51820
# 10.0.0.0/24는 VPN 서브넷
AllowedIPs = 10.47.47.0/24
# PersistentKeepalive = 25

이번에는 Interface 섹션이 클라이언트 머신을 나타내고, 아래의 Peer 섹션이 서버를 가리킵니다. 먼저 Interface부터 살펴보면, 사설 IP 주소는 서버 설정에서 이 클라이언트에 할당한 주소와 일치해야 합니다.

클라이언트가 로컬 DNS 서버를 우회해야 한다면 여기서 커스텀 DNS 서버를 지정할 수 있습니다. 위 예시의 DNS는 구글이 제공하는 것입니다.

서버에서 했던 것처럼 개인 키를 설정 파일에 직접 하드코딩하는 대신, 로드 시점에 개인 키 파일을 읽도록 지시할 수도 있습니다. 이것이 보안 모범 사례에 더 가깝습니다. 사실 서버에서도 같은 방식을 쓸 수 있습니다. 마지막으로 설정 스크립트는 PostUp의 ping 명령으로 연결 상태를 점검합니다.

Peer, 즉 서버 설정에는 서버의 공개 키가 필요하며, 여기에 입력합니다.

Endpoint는 WireGuard에게 서버의 위치를 알려주는 항목입니다. 이것이 없으면 아무것도 동작하지 않습니다! 서버의 공개 IP 또는 도메인 이름 뒤에 선택한 포트를 붙이면 됩니다. 역시 51820이 WireGuard의 기본 포트입니다.

마지막으로 AllowedIPs 설정은 사용할 네트워크 주소 범위를 정의하며, 선택 사항인 PersistentKeepalive 값은 연결 끊김을 방지해 줍니다.

클라이언트에서 WireGuard를 실행하는 방법은 서버와 완전히 동일하게 wg-quick up wg0을 사용하면 됩니다. 다만 이러한 단계는 리눅스 클라이언트에만 필요하며, 다른 플랫폼에서는 전용 앱을 사용하면 됩니다.

마무리

이것으로 끝입니다. 말씀드린 대로, 약 5분의 작업으로 동작하는 VPN이 완성되었습니다. 이제 온라인 프라이버시를 보호하고 통신을 안전하게 지키기 위한 핑계는 하나 줄어든 셈입니다.