WireGuard 작동 원리: 크립토키 라우팅 이해하기
WireGuard의 핵심인 크립토키 라우팅과 AllowedIPs의 역할을 설명합니다. 패킷이 전송되지 않는 이유와 엔드포인트 설정 오류를 해결하는 방법을 다루며, wg0.conf 설정 파일의 구조를 명확하게 이해하도록 돕습니다.
WireGuard의 작동 원리, 한 문장 요약
WireGuard는 모든 패킷을 공개 키(public key)에 연결하여 작동합니다. 이 메커니즘을 '크립토키 라우팅(cryptokey routing)'이라고 부르며, 이것이 설계의 전부입니다. 피어(peer) 옆에 있는 AllowedIPs 줄은 내 컴퓨터를 떠나는 패킷을 위한 라우팅 테이블이자, 해당 피어로부터 도착하는 패킷을 위한 접근 제어 목록(ACL)입니다. 설정 하나가 두 가지 역할을 수행합니다. AllowedIPs을 이러한 관점에서 읽으면 모든 WireGuard 설정 파일을 쉽게 이해할 수 있습니다.
IP 주소를 키로 사용하는 세션 테이블이나 사용자 데이터베이스는 존재하지 않습니다. 피어는 공개 키와 해당 키가 사용할 수 있는 주소 집합으로 정의됩니다. 핸드셰이크와 타이머는 하위 네트워크 환경이 변하더라도 이러한 결합 상태를 유지하기 위해 존재합니다. 이론보다 작동하는 터널을 먼저 경험하고 싶다면 직접 호스팅하는 VPS 기반 WireGuard VPN을 구축해 보십시오. 설정 파일의 특정 줄이 이해되지 않을 때 다시 돌아와 이 글을 읽으면 됩니다.
AllowedIPs는 라우팅 테이블이자 접근 제어 목록입니다
먼저 아웃바운드 방향을 살펴봅니다. 커널은 일반적인 방식대로 메인 라우팅 테이블을 통해 패킷을 wg0 장치로 라우팅합니다. 그 후 WireGuard는 해당 패킷의 목적지 주소를 모든 피어의 허용된 프리픽스(prefix)를 담고 있는 테이블과 대조하며, 가장 긴 프리픽스 일치(longest prefix match) 방식을 따릅니다. 일치하는 항목이 있으면 특정 피어가 지정되고, 이는 공개 키(public key)를, 다시 세션 키와 UDP 엔드포인트를 결정합니다. 패킷은 해당 피어를 위해 암호화되어 전송됩니다.
어떤 피어의 AllowedIPs도 목적지를 포함하지 않으면 패킷은 전송되지 않습니다. 암호화에 사용할 키가 없기 때문입니다.
ping: sendmsg: Required key not available이 오류는 한 가지를 의미합니다. 접근하려는 주소가 어떤 피어에도 등록되어 있지 않다는 뜻입니다. 이와 다른 오류인 ping: sendmsg: Destination address required은 피어는 일치했으나 WireGuard가 해당 피어의 엔드포인트를 알지 못할 때 발생합니다. 설정된 엔드포인트가 없거나 아직 학습되지 않았기 때문입니다.
이제 인바운드 방향을 살펴봅니다. UDP 패킷이 리슨 포트에 도착합니다. WireGuard는 헤더의 수신자 인덱스에서 세션을 찾고, 슬라이딩 리플레이 윈도우(sliding replay window)를 통해 카운터를 확인한 뒤 페이로드를 복호화하고 인증합니다. 그 후에야 내부 패킷을 읽으며, 이 내부 패킷의 출발지 주소는 반드시 전송한 피어의 AllowedIPs 범위 내에 있어야 합니다. 그렇지 않으면 패킷은 폐기됩니다. 동적 디버그(dynamic debug)가 활성화되어 있다면 커널은 다음과 같은 형식의 줄로 이유를 출력합니다.
wg0: Packet has unallowed src IP (10.8.0.9) from peer 2 (203.0.113.10:51820)서버 측의 피어가 /32을 얻는 이유가 바로 이것입니다. AllowedIPs = 10.8.0.2/32로 설정된 피어는 10.8.0.2에서 오는 패킷만 보낼 수 있으며 다른 주소에서는 보낼 수 없습니다. 대신 0.0.0.0/0을 입력하면 해당 클라이언트는 다른 클라이언트의 주소를 포함하여 터널 내부의 모든 출발지 주소를 사용하는 패킷을 주입할 수 있게 됩니다.
중복되는 프리픽스는 구체성(specificity)에 따라 해결되는데, 이는 가장 긴 프리픽스 일치 방식을 사용하기 때문입니다. 두 피어에 동일한 프리픽스가 설정되면 동작이 달라집니다. 마지막으로 설정된 피어로 항목이 이동하며, 첫 번째 피어는 아무런 오류 메시지 없이 해당 트래픽 수신을 중단합니다. wg show wg0 allowed-ips은 현재 커널에 실제로 적용된 테이블을 출력합니다. 디스크의 설정 파일과 실행 중인 상태가 일치하지 않을 때 확인해야 할 기준은 바로 이 테이블입니다.
암호화 키 라우팅을 고려한 설정 파일 읽기
서버 측:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <server private key>
[Peer]
PublicKey = <laptop public key>
AllowedIPs = 10.8.0.2/32클라이언트 측:
[Interface]
Address = 10.8.0.2/32
PrivateKey = <laptop private key>
[Peer]
PublicKey = <server public key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25동일한 키워드가 양쪽에서 반대되는 의미를 갖습니다. 클라이언트에서는 "모든 목적지를 이 피어로 전송하라"는 의미이며, 서버에서는 "이 피어로부터 오직 이 주소만 허용하라"는 의미입니다. 이러한 비대칭성은 역할이 아닌 값에서 발생합니다.
이 키들 중 절반은 프로토콜과 무관합니다. Address, DNS, MTU, PostUp 및 SaveConfig는 인터페이스를 활성화하는 셸 스크립트인 wg-quick에 속합니다. 커널은 이 키들을 인식하지 못합니다. wg-quick strip wg0는 wg 도구가 실제로 로드하는 축소된 설정을 출력하며, 이는 이러한 분리를 확인하는 가장 빠른 방법입니다.
핸드셰이크의 실제 동작 방식
WireGuard의 핸드셰이크는 Noise Protocol Framework의 Noise_IKpsk2를 사용합니다. IK 부분은 시스템 관리자에게 유용한 정보입니다. 응답자의 정적 공개 키는 이미 개시자에게 알려져 있는데, 이는 [Peer] 블록 내의 PublicKey이기 때문입니다. 또한 개시자는 자신의 정적 공개 키를 첫 번째 메시지 내부에 암호화하여 전송합니다. 따라서 인증서 교환이나 신원 확인을 위한 왕복 과정이 없습니다. 수동적 관찰자는 응답자의 개인 키를 보유하지 않는 한 어떤 키가 호출을 시도하는지 알 수 없습니다.
이 과정에는 한 번의 왕복 시간이 소요됩니다. 개시 메시지는 148바이트, 응답은 92바이트이며, 그 직후부터 데이터 흐름이 시작됩니다. 각 측은 핸드셰이크마다 새로운 임시 Curve25519 키 쌍을 생성하며, 세션 키는 정적 키와 임시 키를 혼합한 Diffie-Hellman 결과 체인에서 파생됩니다. 임시 개인 키는 즉시 폐기되므로 전방향 비밀성(forward secrecy)이 보장됩니다. 따라서 오늘 트래픽을 기록한 공격자가 내년에 서버의 개인 키를 탈취하더라도 기록된 내용을 해독할 수 없습니다.
핸드셰이크 개시 메시지에는 TAI64N 타임스탬프가 포함되며, 각 피어는 상대방으로부터 수신한 가장 큰 타임스탬프를 기억하므로 재전송된(replayed) 개시 메시지는 거부됩니다. 데이터 패킷은 nonce로 사용되는 64비트 카운터를 포함하며, 수신자는 최근에 확인한 카운터의 슬라이딩 윈도우를 유지합니다. 이를 통해 TCP 방식의 연결 상태 없이도 재전송과 심각한 순서 뒤바뀜 문제를 처리합니다.
세션 키는 오래 유지되지 않으며, 타이머는 설정 가능하지 않고 컴파일 시점에 고정됩니다.
The data behind this chart
[
{
"label": "REKEY_TIMEOUT",
"seconds": 5,
"notes": "resend a handshake initiation that got no answer"
},
{
"label": "KEEPALIVE_TIMEOUT",
"seconds": 10,
"notes": "send a keepalive after receiving data and sending none back"
},
{
"label": "REKEY_ATTEMPT_TIME",
"seconds": 90,
"notes": "give up on the handshake and report the peer as down"
},
{
"label": "REKEY_AFTER_TIME",
"seconds": 120,
"notes": "sender begins a fresh handshake for a new session key"
},
{
"label": "REJECT_AFTER_TIME",
"seconds": 180,
"notes": "the old session key is refused and traffic stops"
}
]이 값들은 측정치가 아니라 프로토콜 사양에 정의된 상수입니다. 5개의 상수가 전체 세션 수명 주기를 결정합니다. 120초 동안 사용하면 송신자는 새로운 핸드셰이크를 시작하며, 180초가 지나면 이전 키는 즉시 거부되므로 새로운 핸드셰이크가 완료될 때까지 트래픽이 중단됩니다. 응답이 없는 개시 메시지는 5초마다 재전송되며 90초 후에 포기됩니다. 이것이 wg show가 latest handshake을 상대적인 시간으로 출력하는 이유이며, 정상적으로 작동 중인 바쁜 터널에서 해당 시간이 작게 유지되는 이유입니다. 트래픽을 활발히 전송하는 중에도 이 시간이 계속 증가한다면 터널이 유휴 상태인 것이 아니라 핸드셰이크가 실패하고 있다는 뜻입니다.
피어에 클라이언트나 서버 역할이 없는 이유
양쪽 끝단은 동일한 코드와 동일한 설정 형식을 실행합니다. 서버 모드라는 것은 존재하지 않습니다. 사용자가 느끼는 비대칭성은 Endpoint에서 비롯되며, Endpoint는 선택 사항입니다.
엔드포인트가 설정된 피어는 핸드셰이크를 시작할 수 있습니다. 설정이 없는 피어는 대기하다가, 올바르게 인증된 첫 번째 패킷으로부터 상대방의 주소와 포트를 학습합니다. 학습된 엔드포인트는 저장되며, 새로운 주소로부터 유효한 패킷이 도착할 때마다 업데이트됩니다. 이것이 로밍이 작동하는 방식입니다. Wi-Fi에서 모바일 네트워크로 이동하는 노트북이 동일한 터널을 유지하는 이유는, 세션이 IP 주소가 아닌 키와 인덱스로 식별되기 때문입니다. TCP 관점에서의 연결이라는 개념 자체가 없으므로 재연결 과정도 없습니다.
동일한 메커니즘으로 인해 알아두어야 할 사실이 하나 있습니다. 공인 주소를 가진 피어는 항상 상대방의 마지막으로 알려진 공인 IP를 보유하며, wg show 명령어로 이를 확인할 수 있습니다.
고정된 프리미티브와 협상 과정의 부재
WireGuard에는 암호 제품군(ciphersuite) 목록이 없습니다. 인증된 암호화에는 ChaCha20-Poly1305, 키 교환에는 Curve25519, 해싱에는 BLAKE2s, 키 유도에는 HKDF를 사용합니다. 모든 배포 환경이 동일한 방식을 사용하므로 파싱해야 할 협상 단계가 없으며, 더 취약한 옵션으로 강제 전환되는 다운그레이드 경로도 존재하지 않습니다. 이로 인한 트레이드오프는 명확합니다. 만약 사용된 프리미티브 중 하나가 취약해지면, 설정 변경이 아닌 프로토콜 전체의 새 버전을 배포하고 양쪽 끝단 모두 업데이트를 수행해야 합니다. 이러한 단일 결정 덕분에 TLS 기반 터널이 가지는 대부분의 코드와 실패 모드가 제거되었으며, 이는 WireGuard와 OpenVPN 비교에서 다루는 핵심적인 차이점입니다.
포트가 스캐너에 응답하지 않는 이유
모든 핸드셰이크 메시지에는 mac1라는 필드가 포함되어 있습니다. 이는 응답자의 정적 공개 키에서 파생된 키를 사용하여 메시지에 대해 계산된 MAC(메시지 인증 코드)입니다. 해당 공개 키를 모르는 발신자는 유효한 mac1를 생성할 수 없으며, 수신자는 어떠한 응답도 없이 해당 패킷을 폐기합니다. 오류 메시지나 리셋 패킷, ICMP 메시지조차 발생하지 않습니다.
그 결과 UDP 스캔을 수행하면 아무런 응답도 돌아오지 않습니다.
sudo nmap -sU -p 51820 vpn.example.comnmap은 open|filtered을 보고하는데, 이는 방화벽이 패킷을 조용히 폐기할 때와 동일한 결과입니다. 적어도 사용자의 공개 키를 보유하지 않은 사람에게는 WireGuard가 리스닝 중인지 여부와 관계없이 포트가 동일하게 동작합니다.
두 번째 필드인 mac2은 서비스 거부(DoS) 공격에 대한 부하를 처리합니다. 수신자가 부하 상태일 때 유효한 시작 요청을 받으면 발신자의 소스 주소와 연결된 64바이트 쿠키 응답을 보냅니다. 이후 발신자가 해당 쿠키를 다시 보내올 때까지는 비용이 많이 드는 공개 키 연산을 수행하지 않습니다. 이는 CPU 자원을 소모하기 전에 소스 주소가 실제임을 증명하며, 부하가 발생할 때만 활성화됩니다.
0.0.0.0/0이 피어를 기본 경로로 만드는 이유
AllowedIPs은 라우팅 테이블이므로, AllowedIPs = 0.0.0.0/0, ::/0는 해당 피어에 대한 모든 목적지를 가로챕니다. 이것이 전체 풀 터널 설정의 핵심입니다.
이 동작을 가능하게 하는 라우팅 방식은 설정 줄 자체보다 더 흥미롭습니다. wg0을 통한 일반적인 기본 경로는 루프를 발생시킵니다. 트래픽을 운반하는 암호화된 UDP 패킷 또한 머신을 떠나야 하는데, 이 패킷이 자기 자신의 기본 경로와 일치하기 때문입니다. wg-quick은 정책 라우팅을 통해 이를 방지합니다. WireGuard의 자체 발신 패킷에 fwmark를 표시하고, 터널 기본 경로를 별도의 라우팅 테이블에 배치한 뒤, 표시되지 않은 트래픽만 해당 경로에 도달하도록 규칙을 추가합니다. ip rule show를 실행하면 그 결과를 확인할 수 있습니다.
32764: from all lookup main suppress_prefixlength 0
32765: not from all fwmark 0xca6c lookup 51820
32766: from all lookup main0xca6c은 16진수로 51820이며, 51820은 테이블 번호이기도 합니다. suppress_prefixlength 0 규칙은 메인 테이블이 자체 기본 경로를 건너뛰게 만듭니다. 따라서 로컬 서브넷과 같은 특정 경로는 여전히 우선순위를 유지하며, 그 외의 모든 트래픽은 터널 테이블로 전달됩니다. 스플릿 터널은 이러한 과정이 전혀 필요하지 않습니다. AllowedIPs = 10.8.0.0/24, 10.20.0.0/16와 같이 더 좁은 범위의 목록은 메인 테이블에서 일반적인 경로로 처리되기 때문입니다.
풀 터널이 자체적으로 해결하지 못하는 한 가지는 이름 해석(name resolution)입니다. 클라이언트가 로컬 네트워크로부터 학습한 리졸버는 보통 그대로 유지되며, 해당 리졸버에 대한 경로가 더 구체적이기 때문입니다. 이는 별도의 작업이며, WireGuard 터널 외부로 유출되는 DNS에서 다룹니다.
PersistentKeepalive의 실제 용도
WireGuard는 트래픽이 없을 때 아무것도 전송하지 않습니다. 하트비트도, 세션 갱신도, 네트워크상의 그 어떤 신호도 없습니다. 이러한 침묵은 배터리 수명을 절약하고 앞서 언급한 스캐너 환경에 도움이 되지만, 특정 구성에서는 문제를 일으킵니다.
NAT(network address translation) 뒤에 있거나 상태 저장 방화벽(stateful firewall) 뒤에 있는 피어는 해당 장치에 매핑이 존재할 때만 외부에서 접근할 수 있으며, 이 매핑은 나가는 패킷에 의해 생성됩니다. 일반적인 UDP 매핑 유지 시간은 약 30초부터 시작합니다. 매핑이 만료되면 외부에서 들어오는 패킷은 중간 장치(middlebox)에 의해 차단되며, NAT 뒤의 피어가 무언가를 보낼 때까지 터널은 죽은 것처럼 보입니다. PersistentKeepalive = 25은 25초마다 빈 인증 패킷을 전송하는데, 이는 가장 짧은 일반적인 유지 시간보다 짧으므로 매핑이 계속 열려 있게 합니다.
이 설정은 NAT 뒤에 있는 피어에 적용하십시오. 공인 IP 주소와 열린 UDP 포트를 가진 서버에는 이 설정이 필요 없으며, 오히려 불필요한 트래픽만 발생시킵니다. 이를 자동 keepalive와 혼동하지 마십시오. 자동 keepalive는 피어가 데이터를 수신한 후 다시 보낼 데이터가 없을 때 10 초 뒤에 작동합니다. 이 기능은 항상 켜져 있으며 설정할 수 없습니다.
LAN 트래픽을 터널로 라우팅하는 것은 WireGuard의 기능이 아닙니다
피어 B가 홈 네트워크 192.168.50.0/24에 있고, 피어 A가 이 네트워크에 접근해야 한다고 가정해 보겠습니다. 두 개의 독립적인 시스템이 서로 합의해야 하며, 그중 하나만이 WireGuard입니다.
WireGuard의 역할: A의 AllowedIPs에 192.168.50.0/24을 추가합니다. 이렇게 하면 A는 해당 프리픽스를 B로 라우팅하고, B로부터 해당 소스 주소를 가진 패킷을 수신합니다. 이 설정이 없으면 cryptokey 라우팅은 목적지에 대한 키를 찾지 못하고 소스에 대한 권한도 부여하지 않습니다.
커널의 역할: B에서 net.ipv4.ip_forward은 1이어야 합니다. 그렇지 않으면 커널은 B 자신을 목적지로 하지 않는 모든 복호화된 패킷을 폐기합니다. B의 방화벽 forward 체인은 해당 트래픽을 허용해야 합니다. LAN의 호스트들은 10.8.0.0/24로 돌아가는 경로를 알고 있어야 하며, 그렇지 않다면 B가 소스 NAT를 적용하여 응답이 B를 거쳐 돌아오도록 해야 합니다.
WireGuard의 역할은 복호화한 패킷을 커널에 전달하는 데서 끝난다. 그 이후의 처리는 일반적인 Linux 라우팅 및 필터링이므로, 이 문제가 nft list ruleset 카운터 또는 ip -s link show wg0에서 나타나며 wg show에서는 나타나지 않는다. 웹 인터페이스로 피어를 관리하려면 Docker에서 wg-easy 실행을 사용할 수 있다. 이 경우 피어 항목은 자동으로 생성되지만, 포워딩 규칙은 여전히 호스트에서 관리해야 한다. 조정 계층이 프리픽스를 대신 배포하는 경우에도 이 구분은 유지된다. Tailscale 서브넷 라우터를 사용해 VPS에서 프라이빗 네트워크 광고를 설정하면 각 피어에서 수동으로 AllowedIPs을 수정할 필요가 없다. 그러나 라우터 자체의 포워딩 sysctl과 방화벽 규칙은 직접 설정해야 한다.
WireGuard가 커널에서 동작하는 이유
wg0은 네트워크 장치 드라이버입니다. 패킷은 일반적인 라우팅 스택을 통해 도달하고, softirq 컨텍스트에서 암호화되며, 사용자 공간(userspace)으로 넘어가지 않고 UDP 소켓을 통해 나갑니다. 이것이 높은 처리량의 원천이며, 모듈 코드가 약 4,000줄 정도로 유지되는 이유이기도 합니다. 이 정도 규모는 검토가 가능하여 2020년 3월 Linux 5.6 메인라인에 병합되었습니다. Ubuntu 24.04와 Debian 13은 이를 기본으로 제공하므로 wireguard-tools 패키지만 설치하면 됩니다.
일반 인터페이스로 동작한다는 점은 실무적으로 중요한 의미를 갖습니다. tcpdump -ni wg0은 암호화되지 않은 내부 패킷을 보여주고, tcpdump -ni eth0 udp port 51820는 암호화된 외부 패킷을 보여줍니다. 이 둘을 비교하면 어느 방향에서 문제가 발생했는지 즉시 파악할 수 있습니다. netfilter와 트래픽 셰이핑은 wg0을 다른 일반적인 링크와 동일하게 처리합니다. 호스트 커널을 공유하는 컨테이너 가상화 환경처럼 커널 모듈을 사용할 수 없는 경우, wireguard-go이 TUN 장치를 통해 사용자 공간에서 동일한 프로토콜을 구현합니다. 다만 모든 패킷이 커널 경계를 두 번씩 넘나들어야 하므로 처리량 저하는 불가피합니다.
WireGuard가 보호하지 않는 영역
WireGuard의 위협 모델은 의도적으로 좁게 설정되었으며, 프로토콜이 조용하게 작동하는 특성 때문에 오해를 불러일으키기 쉽습니다. 명확히 설명하겠습니다.
- WireGuard를 사용 중이라는 사실을 숨기지 않습니다. 핸드셰이크 메시지는 크기가 고정되어 있고, 첫 번째 바이트가 메시지 유형을 나타내며, 전송 계층은 UDP입니다. 심층 패킷 분석(DPI)으로 쉽게 식별할 수 있으므로, VPN을 차단하는 네트워크에서는 WireGuard를 막을 수 있습니다. 난독화 기능은 설계 단계에서 제외되었습니다.
- 트래픽의 양이나 타이밍을 숨기지 않습니다. 페이로드는 16바이트 단위로만 패딩되므로, 관찰자는 사용자가 언제 데이터를 보내는지, 대략 어느 정도의 양을 보내는지 알 수 있습니다.
- 마지막으로 확인된 엔드포인트를 유지합니다. 공인 IP 주소를 가진 피어는 상대방의 현재 공인 IP를 저장하며,
wg show명령으로 이를 확인할 수 있습니다. 설정 파일에 고정된 터널 주소와 결합하면, 사용자가 네트워크를 이동할 때마다 따라다니는 고유 식별자가 됩니다. 개인 VPS 환경에서는 문제가 없으나, 상용 서비스들이 이 프로토콜 위에 별도의 계층을 추가하는 이유이기도 합니다. - 사람이 아닌 키를 인증합니다. 개인 키 파일을 가진 사람이 곧 피어입니다.
/etc/wireguard디렉터리는 700 모드로, 키 파일은 600 모드로 유지하십시오. - 폐기 목록이나 만료 기한이 없습니다. 해당 키를 가진 모든 서버에서 피어 항목을 삭제해야만 접근이 차단되며, 정적 키는 삭제하기 전까지 계속 유효합니다.
이러한 특성들이 WireGuard를 취약하게 만드는 것은 아닙니다. 오히려 WireGuard를 간결하게 유지하며, 간결함이야말로 이 프로토콜의 핵심입니다. WireGuard는 인증과 암호화만 수행하며, 신원 관리나 주소 할당은 그 위에 구축하는 시스템에 맡깁니다. WireGuard와 Tailscale 비교에서 설명한 조정 계층은 바로 이러한 간극을 메우기 위해 존재하며, 방금 살펴본 데이터 평면을 그대로 사용합니다. 이러한 계층이 구축되면, 다음으로 결정할 사항은 터널 내부에서 실행 중인 서비스에 누가 접근할 수 있게 할 것인가이며, 이는 Tailscale serve와 funnel 선택하기를 통해 단일 포트에 대해 해결할 수 있습니다.
FAQ
WireGuard에서 cryptokey routing이란 무엇입니까?
Cryptokey routing은 모든 패킷을 공개 키(public key)에 결합하는 규칙입니다. 각 피어 항목은 AllowedIPs에 접두사(prefix) 목록을 포함합니다. 아웃바운드 시, WireGuard는 패킷의 목적지를 모든 피어의 목록과 대조하여 가장 긴 접두사가 일치하는 피어를 선택하므로, 이 목록은 라우팅 테이블 역할을 합니다. 인바운드 시, 패킷이 복호화되고 인증되면 패킷의 내부 출발지 주소는 반드시 해당 피어의 목록 내에 있어야 하며, 그렇지 않으면 패킷은 폐기됩니다. 따라서 이 목록은 접근 제어 목록(ACL) 역할도 수행합니다. WireGuard는 별도의 라우팅 설정이나 내부 방화벽을 두지 않으며, 이 하나의 목록이 두 가지 역할을 모두 수행합니다.
양쪽 피어 모두에 PersistentKeepalive를 설정해야 합니까?
아니요. NAT(network address translation) 뒤에 있거나 상태 저장 방화벽(stateful firewall) 뒤에 있는 쪽에 설정하십시오. 보통 클라이언트 측입니다. WireGuard는 유휴 상태일 때 아무것도 전송하지 않으므로, 상대방이 해당 피어에 도달할 수 있게 하는 매핑이 보통 1분 이내에 만료되어 터널이 한쪽 방향으로 죽은 것처럼 보일 수 있습니다. PersistentKeepalive = 25는 25초마다 빈 인증 패킷을 전송하여 매핑을 유지합니다. 공인 IP 주소를 가지고 있고 UDP 포트가 열려 있는 피어에는 이 설정이 필요하지 않습니다.
터널을 통한 ping 시 "Required key not available" 오류가 발생하는 이유는 무엇입니까?
목적지 주소가 어떤 피어의 AllowedIPs에도 포함되어 있지 않기 때문입니다. 이 경우 cryptokey routing이 패킷을 암호화할 키를 찾지 못하여 커널이 전송을 거부합니다. wg show wg0 allowed-ips을 실행하여 출력 결과와 핑을 시도하는 주소를 비교하십시오. 유사한 오류인 Destination address required은 다른 문제입니다. 이는 피어는 일치했으나 WireGuard가 해당 피어에 대한 엔드포인트(endpoint)를 가지고 있지 않은 경우입니다. 엔드포인트가 설정되지 않았고, 해당 피어로부터 아직 인증된 패킷이 도착하지 않았을 때 발생합니다.
방화벽이 WireGuard를 탐지하고 차단할 수 있습니까?
네. WireGuard는 트래픽을 인증하고 암호화하지만, 스스로를 위장하려는 시도는 하지 않습니다. 핸드셰이크 메시지는 각각 148바이트와 92바이트로 고정되어 있고, 모든 메시지의 첫 번째 바이트는 메시지 유형을 식별하며, 전송 계층은 UDP를 사용합니다. 따라서 심층 패킷 분석(DPI)을 통해 프로토콜을 쉽게 식별할 수 있습니다. UDP를 차단하거나 프로토콜 핑거프린팅을 수행하는 네트워크는 WireGuard를 차단할 것입니다. 터널을 숨기려면 다른 프로토콜로 감싸야 하는데, 이는 WireGuard 설정이 아닌 별도의 도구가 필요한 작업입니다.