[WireGuard] 3. WireGuard의 구조와 설정 파일 이해하기
PrivateKey, PublicKey 부터 Address, Endpoint, AllowedIPs 까지
이번 글에서는 WireGuard의 기본 구조를 알아보고, 최종적으로 아래의 설정 파일을 이해하고 해석하는 것을 목표로 한다.
예제 설정 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Interface]
# HOME_PC
PrivateKey = HOME_PC_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
# MY_IPHONE
PublicKey = MY_IPHONE_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
[Peer]
# MY_GALAXY_NOTEBOOK
PublicKey = MY_GALAXY_NOTEBOOK_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32

WireGuard의 기본 구조
WireGuard의 주요 개념
WireGuard를 사용하거나 설정파일을 건드리기 전, 아래의 주요 개념을 알고 가면 도움이 된다.
| 개념 | 설명 |
|---|---|
| Interface | WireGuard 가상 네트워크 인터페이스. 또는 자기 자신에 대한 설정 |
| Peer | WireGuard로 연결되는 상대 장치 |
| PrivateKey | 자신의 비밀키 |
| PublicKey | 상대방에게 제공하는 공개키 |
| Address | WireGuard 네트워크 내부 IP |
| Endpoint | 실제 인터넷에서 상대방에게 접속할 주소 |
| AllowedIPs | 해당 Peer를 통해 전달할 IP 범위 |
| ListenPort | WireGuard가 UDP 연결을 받을 포트 |
Interface와 Peer의 관계
WireGuard 설정 파일은 겉보기에는 짧고 단순하지만, 각 항목이 담당하는 역할을 정확히 이해해야 정상적으로 구성할 수 있다. WireGuard 설정의 기본 구조는 크게 두 영역으로 나뉜다. 가장 먼저 기억해야 할 규칙은 다음과 같다.
1
2
3
4
5
[Interface]
# 현재 장치 자신의 설정 = 나 자신
[Peer]
# 통신할 상대방의 설정 = 통신할 상대방
예를 들어 본 설정 파일에 있는 [Peer] 블록은 장치 자신(Peer1이라고 가칭)을 설명하는 영역이 아니라, 자신이 통신할 상대 Peer(Peer2라고 가칭)에 대한 정보를 담는 영역이다. 반대로 상대방(Peer2)의 설정 파일에서는 [Peer]에는 Peer2 자신이 아니라 Peer1의 공개 키와 접속 주소가 들어간다.
이 기본 원칙을 바탕으로 PrivateKey, PublicKey, Address, Endpoint, AllowedIPs의 관계를 이해하면 대부분의 WireGuard 설정을 해석할 수 있다.
설정 파일의 주요 구성 항목
1. Interface
[Interface]는 현재 설정 파일을 적용하는 장치 자신의 WireGuard 인터페이스를 정의한다. 여기에는 해당 장치가 사용할 비밀 키, VPN 내부 주소, UDP 수신 포트, DNS와 같은 로컬 인터페이스 관련 정보가 들어간다.
위에서 든 예시를 기반으로, HOME_PC에서는 [Interface]를 다음과 같이 작성할 수 있다.
1
2
3
4
[Interface]
PrivateKey = HOME_PC_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820
반면, MY_IPHONE 에서는 설정 파일을 다음과 같이 구성한다.
1
2
3
[Interface]
PrivateKey = MY_IPHONE_PRIVATE_KEY
Address = 10.0.0.2/32
두 설정 모두 [Interface]라는 동일한 영역을 사용하지만, 실제 값은 각 장치에 맞게 달라진다. 서버와 클라이언트라는 이름이 달라도 [Interface]에는 언제나 “현재 장치 자신의 정보”가 들어간다는 점이 핵심이다.
주요 항목은 다음과 같다.
| 항목 | 의미 | 예시 |
|---|---|---|
PrivateKey |
현재 장치의 WireGuard 비밀 키 | SERVER_PRIVATE_KEY |
Address |
VPN 내부에서 현재 장치가 사용할 IP 주소 | 10.0.0.1/24 |
ListenPort |
WireGuard가 UDP 연결을 수신할 포트 | 51820 |
DNS |
터널 활성화 시 사용할 DNS 서버 | 1.1.1.1 |
MTU |
WireGuard 가상 인터페이스의 최대 전송 단위 | 1420 |
(1) PrivateKey
PrivateKey는 현재 장치의 신원을 증명하고 암호화 통신에 사용하는 비밀 키다. 이 값은 다른 사람에게 공개해서는 안 되며, 설정 파일의 접근 권한도 제한하는 것이 좋다.
각 Peer는 각각 자신의 Private Key를 가져야 한다. 자신의 Private Key를 상대방 Peer의 설정에 복사하거나, 여러 장치가 하나의 Private Key를 공유하는 방식은 피해야 한다.
(2) Address
Address는 인터넷에서 실제로 사용되는 공인 IP가 아니라, WireGuard 터널 내부에서 사용할 가상 IP 주소다. 즉, WireGuard 내에서 자신의 IP 주소를 뜻한다.
예를 들어 VPN 네트워크를 10.0.0.0/24로 정했다면 다음과 같이 주소를 배정할 수 있다.
1
2
3
4
HOME_PC 10.0.0.1
MY_IPHONE 10.0.0.2
MY_GALAXY_NOTEBOOK 10.0.0.3
...
만약 중앙 서버 형식을 사용한다면, 해당 장치가 여러 Peer가 포함된 VPN 네트워크의 중심 역할을 하므로 다음처럼 네트워크 대역을 지정하는 경우가 많다.
1
Address = 10.0.0.1/24
반면 개별 Peer는 자신에게 하나의 주소만 배정하므로 다음과 같이 /32를 사용하는 구성이 일반적이다.
1
Address = 10.0.0.2/32
이 주소는 서버의 공인 IP나 클라이언트가 인터넷에 접속할 때 사용하는 로컬 IP와는 별개다.
(3) ListenPort
ListenPort는 해당 장치가 WireGuard 패킷을 수신할 UDP 포트다. 예제에서는 흔히 다음 포트를 사용한다.
1
ListenPort = 51820
그러나 51820은 정해진 필수 포트가 아니라 널리 사용되는 기본 예시일 뿐이다. 외부 인터넷에 서버를 공개한다면 방화벽에서 해당 UDP 포트를 허용해야 하며, 운영 환경에 따라 다른 포트를 사용할 수도 있다. 따라서 51820과 같은 잘 알려진 포트가 아닌 다른 포트로 변경하는 것을 권장하며, 포트 번호를 변경하더라도 보안이 자동으로 확보되는 것은 아니므로, 키 관리와 방화벽 정책을 함께 적용해야 한다.
만약 Peer가 클라이언트의 역할만 하는 경우, 서버처럼 외부 연결을 지속적으로 수신할 필요가 없으므로 ListenPort를 생략할 수 있다. 이때 클라이언트는 서버의 Endpoint로 먼저 패킷을 전송하며 통신을 시작한다.
(4) DNS와 MTU
DNS는 WireGuard 인터페이스가 활성화될 때 사용할 DNS 서버를 지정하는 항목이다.
1
DNS = 1.1.1.1
MTU는 한 번에 전송할 수 있는 패킷의 최대 크기를 지정한다.
1
MTU = 1420
WireGuard는 기존 IP 패킷을 다시 UDP 패킷 안에 넣어 전송하므로, 원래 네트워크보다 사용할 수 있는 패킷 크기가 줄어들 수 있다. 일반적인 환경에서는 기본값으로 충분하지만, 특정 네트워크에서 연결은 되면서 일부 웹사이트나 대용량 통신만 실패한다면 MTU를 조정해야 할 수 있다.
2. Peer
Peer는 현재 장치 자신이 연결하거나 통신할 상대방을 의미한다. 예시에서의 HOME_PC 장치에서 다음과 같이 설정될 수 있다.
1
2
3
4
5
6
7
8
9
10
[Interface]
# → 나 자신 (HOME_PC)
PrivateKey = HOME_PC_PRIVATE_KEY
Address = 10.0.0.1/24
...
[Peer]
# → 연결할 상대방 (MY_IPHONE)
PublicKey = MY_IPHONE_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
이를 간단히 해석해보면
MY_IPHONE의 공개 키는 MY_IPHONE_PUBLIC_KEY다. 10.0.0.2로 가는 트래픽은 이 Peer에게 전달한다.
반대로 MY_IPHONE 장치에서는 다음과 같이 설정된다.
1
2
3
4
5
6
7
8
9
10
[Interface]
PrivateKey = MY_IPHONE_PRIVATE_KEY # 여기선 PRIVATE
Address = 10.0.0.2/32
...
[Peer]
PublicKey = HOME_PC_PUBLIC_KEY # 여기선 PUBLIC
AllowedIPs = 10.0.0.0/24
Endpoint = 111.111.111.111:51820
...
[Peer]는 현재 장치가 통신할 상대 Peer를 정의하는 영역이므로, 상대방의 PublicKey, 상대방을 통해 전달할 IP 대역을 나타내는 AllowedIPs, 필요한 경우 실제 접속 주소인 Endpoint와 PersistentKeepalive를 지정한다.
이를 해석해보면
HOME_PC의 공개 키는 HOME_PC_PUBLIC_KEY 이며, 111.111.111.111:51820 주소로 인터넷을 통해 HOME_PC에게 닿을 수 있다. 10.0.0.0/24로 가는 트래픽은 HOME_PC를 통해 전달한다.
하나의 설정 파일에 [Peer] 블록을 여러 개 둘 수도 있으며, 이때 각 Peer의 공개 키와 담당 AllowedIPs가 정확히 대응되는지 확인해야 한다. 특히 서로 다른 Peer에 동일한 VPN IP나 겹치는 주소 범위를 지정하면 어떤 Peer로 패킷을 전달해야 하는지 모호해져 라우팅 문제가 발생할 수 있다.
1
2
3
4
5
6
7
8
9
10
[Interface]
...
[Peer]
PublicKey = CLIENT1_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
[Peer]
PublicKey = CLIENT2_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32
주요 항목은 다음과 같다.
| 항목 | 의미 | 예시 |
|---|---|---|
PublicKey |
상대 Peer의 WireGuard 공개 키 | MY_IPHONE_PUBLIC_KEY |
AllowedIPs |
해당 Peer가 담당할 IP 주소 또는 네트워크 대역 | 10.0.0.2/32 |
Endpoint |
상대 Peer의 실제 인터넷 주소와 UDP 포트 | 111.111.111.111:51820 |
PersistentKeepalive |
NAT/방화벽 환경에서 연결 유지를 위해 Keepalive 패킷을 보내는 주기(초) | 25 |
PresharedKey |
공개키 기반 암호화에 추가로 사용하는 선택적 사전 공유 키 | PRESHARED_KEY |
(1) PublicKey
PublicKey는 자신과 통신할 상대방의 공개 키를 뜻한다.
WireGuard는 사용자 이름이나 비밀번호 대신 공개 키 기반으로 Peer를 식별하고 암호화 통신을 수행한다. 따라서 각 장치는 자신의 PrivateKey를 보관하고, 그로부터 만들어진 PublicKey만 상대방에게 전달한다.
예를 들어 HOME_PC에서 MY_IPHONE을 Peer로 등록한다면 다음과 같이 설정한다.
1
2
[Peer]
PublicKey = MY_IPHONE_PUBLIC_KEY
반대로 MY_IPHONE에서는 HOME_PC의 공개 키를 등록한다.
1
2
[Peer]
PublicKey = HOME_PC_PUBLIC_KEY
즉, [Interface]의 PrivateKey는 나 자신의 키이고, [Peer]의 PublicKey는 상대방의 키다.
PrivateKey는 외부에 공개해서는 안 되지만, PublicKey는 Peer 등록을 위해 상대방에게 전달해도 된다.
(2) Endpoint
Endpoint는 상대 Peer의 실제 인터넷 주소다. IP:PORT 형식 또는 도메인도 사용할 수 있다.
1
2
3
4
5
# IP:PORT 형식의 경우
Endpoint = 111.111.111.111:51820
# 도메인의 경우
Endpoint = vpn.example.com:51820
중앙 서버 구조로 VPN을 사용하는 경우, Server는 고정된 주소를 가지나, Client는 고정된 주소를 가지지 않는 경우가 많다. 때문에 이 경우엔 Server Peer 쪽에는 상대방의 Endpoint를 적지 않고, Client Peer 쪽 설정에만 Server Peer에 대한 Endpoint를 작성하곤 한다.
1
2
3
# Server Peer 쪽 설정
[Peer]
PublicKey = MY_IPHONE_PUBLIC_KEY
1
2
3
4
# Client Peer 쪽 설정
[Peer]
PublicKey = HOME_PC_PUBLIC_KEY
Endpoint = 111.111.111.111:51820
이 경우 WireGuard가 Client에서 들어온 패킷을 보고 Endpoint를 자동으로 학습 한다.
(3) AllowedIPs
AllowedIPs는 해당 Peer로 활동할 수 있도록 허용된 IP 주소 또는 네트워크 대역을 지정한다. “활동할 수 있도록 허용된”이라는 표현에 대해 다양한 표현방법을 고민했으나, 가장 적절한 표현인 것 같다.
WireGuard는 Server-Client 구조가 아닌 Peer-Peer 구조이므로, 누군가가 누구에게 IP를 “할당하지” 않는다. 그저 나 자신과 소통할 Peer 자리를 설치하고, 그 곳으로 통신할 수 있는 창구를 열어놓는(AllowedIPs) 방식인 것이다.
이 관점에서 조금 더 기술적인 명확함을 더해보자. WireGuard는 이 AllowedIPs 라는 값을 송/수신시에 각각의 용도로 활용한다.
1
2
송신시: 어떤 목적지 IP의 패킷을 이 Peer에게 보낼 것인가? (Routing)
수신시: 이 Peer로부터 어떤 출발지 IP의 패킷을 허용할 것인가? (Peer 식별)
예를 들어 HOME_PC Peer에서 다음과 같이 설정했다고 하자.
1
2
3
[Peer]
PublicKey = MY_IPHONE_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
HOME_PC는 10.0.0.2로 향하는 패킷을 MY_IPHONE Peer에게 전달한다. 또한 MY_IPHONE에서 들어온 패킷의 출발지 IP가 10.0.0.2인지 확인한다. 즉, AllowedIPs는 특정 Peer와 그 Peer가 담당하는 IP 범위를 연결하는 설정이라고 이해해도 된다.
중앙 서버형 VPN을 구성할 때에는, 서버쪽 설정에 보통 다음처럼 각 Peer에 고유한 /32 주소를 배정한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Peer]
# Client 1
PublicKey = CLIENT1_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
[Peer]
# Client 2
PublicKey = CLIENT2_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32
[Peer]
# Client 3
PublicKey = CLIENT3_PUBLIC_KEY
AllowedIPs = 10.0.0.4/32
각 주소가 겹치지 않으므로 서버는 목적지 IP만 보고 어느 Peer로 패킷을 보낼지 판단할 수 있다.
(4) PersistentKeepalive
PersistentKeepalive는 일정한 간격으로 상대 Peer에게 작은 패킷을 보내 연결 상태를 유지하기 위한 설정이다. 보통은 NAT나 공유기 뒤에 있는 Client의 연결 상태를 유지하기 위한 옵션이며, 일반적으로 클라이언트 역할의 Peer 설정에 기재한다.
1
2
3
4
[Peer]
PublicKey = HOME_PC_PUBLIC_KEY
Endpoint = 111.111.111.111:51820
PersistentKeepalive = 25
위 설정은 약 25초마다 상대 Peer에게 keepalive 패킷을 전송한다는 의미다.
이 설정은 특히 스마트폰, 가정용 공유기처럼 NAT나 방화벽 뒤에 있는 Peer에서 유용하다. 일정 시간 동안 통신이 없으면 NAT 장비가 기존 UDP 연결 정보를 제거할 수 있는데, PersistentKeepalive가 주기적으로 패킷을 보내 이 연결 정보를 유지해준다. 즉, 필수적인 설정은 아니며, 필요시에 사용하는 보조 설정이다.
참고
1. PrivateKey와 PublicKey 발급과 관리
WireGuard는 사용자 이름과 비밀번호 대신 공개 키 암호 방식에 기반한 인증을 사용한다. 그리고 각 장치는 VPN 통신을 위해 하나의 키 쌍을 생성한다.
이 공개 키 암호 방식에는 중요한 작동 현상이 있는데, Private Key로부터 Public Key는 파생될 수 있지만, Public Key만으로 Private Key를 역산할 수는 없다는 점이다. 따라서 각 장치는 자기 자신을 인증할 수 있는 자신의 Private Key를 안전하게 보관하고, 상대방에게는 Public Key만 전달하는 것이다.
키 생성은 다음 명령으로 수행할 수 있으며, 각각의 장치에 대한 Private-Public Key 쌍을 생성해두어야 한다.
1
wg genkey | tee privatekey | wg pubkey > publickey
일반적인 키 교환 순서는 다음과 같다.
- Peer1이 자신이 사용할 Private Key와 Public Key를 생성한다.
- Peer2가 자신이 사용할 Private Key와 Public Key를 생성한다.
- 각 장치의 Private Key는 해당 장치에만 보관한다.
- Peer1의 Public Key를 Peer2쪽 설정에 등록한다.
- Peer2의 Public Key를 Peer1쪽 설정에 등록한다.
다시 강조하지만, Public Key는 Peer 등록을 위해 상대방에게 전달해야 하지만, Private Key는 전달 대상이 아니다. 특히 Private Key를 공개 저장소에 올리거나, 로그에 출력하거나, 모바일용 QR 코드로 공유하지 않도록 주의해야 한다.
Private Key가 노출되었다고 판단될 경우, 새로운 키 쌍을 생성해 자신과 통신장치의 WireGuard 설정에 반영하고, 기존의 Private-Public Key는 폐기하는 것이 안전하다.
2. Address와 Endpoint
Address와 Endpoint는 모두 IP 주소와 관련되어 있지만, 사용되는 네트워크 층위와 목적이 다르다.
Address: WireGuard 터널 내부에서 현재 장치가 사용하는 가상 IPEndpoint: 인터넷을 통해 상대 Peer를 찾기 위한 실제IP:PORT주소
다음과 같은 구성을 가정해 보자.
1
2
3
HOME_PC의 공인 주소: 111.111.111.111:51820
HOME_PC의 VPN 주소: 10.0.0.1
MY_IPHONE의 VPN 주소: 10.0.0.2
MY_IPHONE의 WireGuard 설정은 다음처럼 작성할 수 있다.
1
2
3
4
5
6
7
8
[Interface]
PrivateKey = MY_IPHONE_PRIVATE_KEY
Address = 10.0.0.2/32
[Peer]
PublicKey = HOME_PC_PUBLIC_KEY
Endpoint = 111.111.111.111:51820
AllowedIPs = 10.0.0.0/24
여기서 Address = 10.0.0.2/32는 MY_IPHONE이 VPN 내부에서 사용할 주소이고, Endpoint = 111.111.111.111:51820은 MY_IPHONE이 인터넷을 통해 서버의 WireGuard 서비스에 접근할 때 사용하는 주소다.
통신 흐름은 다음과 같이 구분된다.
1
2
3
4
5
6
7
8
MY_IPHONE 실제 인터넷 연결
▼
111.111.111.111:51820
HOME_PC의 WireGuard Endpoint
▼
암호화된 터널 내부
▼
10.0.0.2 ↔ 10.0.0.1
일반적인 중앙 서버형 구성에서는 서버가 고정 공인 IP나 도메인을 갖고 있으므로 클라이언트 설정에 서버의 Endpoint를 작성한다. 반면 클라이언트는 공유기나 이동통신망 뒤에 있어 공인 IP가 바뀔 수 있으므로, 클라이언트의 Endpoint를 미리 적지 않고, 클라이언트가 보낸 패킷을 바탕으로 최근 Endpoint를 학하도록 한다, (서버쪽의 설정파일에 클라이언트 [Peer]에는 보통 Endpoint가 생략)
3. AllowedIPs 설정 시 주의할 점
AllowedIPs는 단순히 “통신을 허용할 IP를 대충 적는 목록”이 아니라, 실제 라우팅 경로를 결정하는 설정이다. 결국 AllowedIPs는 “어떤 트래픽을 어느 Peer에게 맡길 것인가”를 결정하는 핵심 연결 고리다. WireGuard 설정을 해석할 때는 항상 다음 질문을 순서대로 확인하는 것이 좋다.
1
2
3
1. 이 Peer의 AllowedIPs는 무엇인가?
2. 어떤 목적지 트래픽이 이 Peer로 나가는가?
3. 이 Peer가 담당하는 VPN 내부 주소는 무엇인가?
설정 파일 해석해보기
이제 글의 처음에 제시했던 설정 파일을 다시 살펴보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Interface]
# HOME_PC
PrivateKey = HOME_PC_PRIVATE_KEY
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
# MY_IPHONE
PublicKey = MY_IPHONE_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
[Peer]
# MY_GALAXY_NOTEBOOK
PublicKey = MY_GALAXY_NOTEBOOK_PUBLIC_KEY
AllowedIPs = 10.0.0.3/32
먼저 [Interface]는 이 설정 파일이 적용되는 HOME_PC 자신을 의미한다.
HOME_PC는 HOME_PC_PRIVATE_KEY라는 자신의 비밀 키를 사용하며, WireGuard 내부에서는 10.0.0.1이라는 주소를 사용한다. 또한 UDP 51820 포트에서 다른 Peer의 WireGuard 연결을 받을 수 있도록 설정되어 있다.
그 아래의 두 [Peer]는 HOME_PC가 통신할 상대방을 의미한다.
첫 번째 Peer는 MY_IPHONE_PUBLIC_KEY를 가진 MY_IPHONE이며, AllowedIPs = 10.0.0.2/32를 통해 10.0.0.2라는 VPN 내부 주소와 연결되어 있다.
두 번째 Peer는 MY_GALAXY_NOTEBOOK_PUBLIC_KEY를 가진 MY_GALAXY_NOTEBOOK이며, 10.0.0.3이라는 VPN 내부 주소와 연결되어 있다.
따라서 HOME_PC 입장에서 이 설정은 다음과 같이 읽을 수 있다.
1
2
3
4
5
6
7
나는 HOME_PC이고,
WireGuard 내부에서는 10.0.0.1을 사용한다.
10.0.0.2는 MY_IPHONE Peer와 통신하고,
10.0.0.3은 MY_GALAXY_NOTEBOOK Peer와 통신한다.
각 Peer는 서로 다른 PublicKey를 통해 식별된다.
결국 WireGuard 설정 파일을 읽을 때는 복잡하게 생각할 필요 없이,
1
2
3
[Interface] → 나는 누구인가?
[Peer] → 누구와 통신할 것인가?
AllowedIPs → 어떤 IP를 그 Peer와 연결할 것인가?
라는 관점으로 바라보면 된다.
이 관계를 이해했다면, WireGuard 설정 파일은 더 이상 단순히 복사해서 사용하는 설정값이 아니라 각 장치의 역할과 통신 관계를 정의한 네트워크 구성도처럼 읽을 수 있다.
Reference
// reading compass
이 글과 이어지는 경로
시리즈, 카테고리, 태그 겹침, 최신도를 점수화해 가까운 글일수록 중심에 배치합니다.
댓글 남기기