SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor

WireGuard 작동 원리: Cryptokey Routing 이해하기

WireGuard의 핵심인 Cryptokey Routing과 AllowedIPs의 역할을 설명합니다. 패킷이 전송되지 않는 이유와 설정 파일에서 발생하는 No route to host 오류의 원인을 분석하고, Noise 핸드셰이크를 통해 보안 터널이 유지되는 과정을 상세히 다룹니다.

WireGuard의 작동 원리, 한 문장 요약

WireGuard는 모든 패킷을 공개 키(public key)에 연결하는 방식으로 작동합니다. 이 메커니즘을 '크립토키 라우팅(cryptokey routing)'이라고 하며, 이것이 설계의 핵심입니다. 피어(peer) 옆에 있는 AllowedIPs 줄은 내 컴퓨터를 떠나는 패킷을 위한 라우팅 테이블이자, 해당 피어로부터 도착하는 패킷을 위한 접근 제어 목록(ACL)입니다. 하나의 설정이 두 가지 역할을 수행합니다. AllowedIPs을 이러한 관점에서 읽으면 모든 WireGuard 설정 파일을 이해할 수 있습니다.

IP 주소를 키로 사용하는 세션 테이블이나 사용자 데이터베이스는 존재하지 않습니다. 피어는 공개 키와 해당 키가 사용할 수 있는 주소 집합으로 정의됩니다. 핸드셰이크와 타이머는 하위 네트워크 환경이 변하더라도 이러한 결합 상태를 유지하기 위해 존재합니다. 이론보다 작동하는 터널을 먼저 경험하고 싶다면 직접 호스팅하는 WireGuard VPN을 구축해 보십시오. 그 후 설정 파일의 특정 줄이 이해되지 않을 때 다시 이곳을 확인하면 됩니다.

AllowedIPs는 라우팅 테이블이자 접근 제어 목록입니다

먼저 아웃바운드 방향부터 살펴봅니다. 커널은 일반적인 방식대로 메인 라우팅 테이블을 통해 패킷을 wg0 장치로 라우팅합니다. 그러면 WireGuard는 해당 패킷의 목적지 주소를 모든 피어의 허용 접두사(prefix)가 담긴 테이블과 대조하며, 가장 긴 접두사 일치(longest prefix match)를 우선합니다. 일치하는 항목이 있으면 피어가 지정되고, 이어서 공개 키, 세션 키, UDP 엔드포인트가 차례로 결정됩니다. 패킷은 해당 피어를 위해 암호화된 뒤 전송됩니다.

어떤 피어의 AllowedIPs에도 목적지가 포함되지 않으면 패킷은 전송되지 않습니다. 암호화에 사용할 키가 없기 때문입니다.

ping: sendmsg: Required key not available

이 오류는 한 가지 의미를 갖습니다. 접근하려는 주소가 어떤 피어에도 등록되어 있지 않다는 뜻입니다. 이와 다른 오류인 ping: sendmsg: Destination address required은 피어는 일치했으나 WireGuard가 해당 피어의 엔드포인트를 알지 못할 때 발생합니다. 설정된 엔드포인트가 없거나 아직 학습되지 않았기 때문입니다.

이제 인바운드 방향을 살펴봅니다. UDP 패킷이 리슨 포트에 도착합니다. WireGuard는 헤더의 수신자 인덱스로 세션을 찾고, 슬라이딩 리플레이 윈도우를 통해 카운터를 확인한 뒤 페이로드를 복호화하고 인증합니다. 그 후에야 내부 패킷을 읽으며, 이 내부 패킷의 출발지 주소는 반드시 전송한 피어의 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을 적으면, 해당 클라이언트는 다른 클라이언트의 주소를 포함하여 터널 내부의 어떤 출발지 주소로도 패킷을 주입할 수 있게 됩니다.

접두사가 겹치는 경우 가장 긴 접두사 일치 방식을 사용하므로 구체적인 쪽이 우선합니다. 두 피어에 동일한 접두사가 설정되면 나중에 설정된 피어로 항목이 이동하며, 먼저 설정된 피어는 아무런 오류 메시지 없이 해당 트래픽을 수신하지 못하게 됩니다. wg show wg0 allowed-ips은 현재 커널에 실제로 적용된 테이블을 출력합니다. 디스크의 설정 파일과 실제 실행 상태가 달라졌을 때는 이 명령의 결과가 기준이 됩니다.

cryptokey 라우팅을 고려한 설정 파일 읽기

서버 측 설정:

[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, PostUpSaveConfig는 인터페이스를 활성화하는 셸 스크립트인 wg-quick에 속합니다. 커널은 이 설정들을 직접 처리하지 않습니다. wg-quick strip wg0wg 도구가 실제로 로드하는 축소된 설정을 출력하며, 이는 이러한 분리 구조를 확인하는 가장 빠른 방법입니다.

핸드셰이크의 실제 동작 방식

WireGuard의 핸드셰이크는 Noise Protocol Framework의 Noise_IKpsk2를 사용합니다. IK 부분은 시스템 관리자에게 유용한 정보입니다. 응답자의 정적 공개 키는 이미 개시자에게 알려져 있는데, 이는 [Peer] 블록 내의 PublicKey이기 때문입니다. 개시자는 자신의 정적 공개 키를 첫 번째 메시지 안에 암호화하여 보냅니다. 따라서 인증서 교환이나 신원 확인을 위한 왕복 과정이 없습니다. 수동적 관찰자는 응답자의 개인 키를 보유하지 않는 한 어떤 키가 호출 중인지 알 수 없습니다.

이 방식의 비용은 1회 왕복입니다. 개시 메시지는 148바이트, 응답은 92바이트이며 그 직후부터 데이터가 흐릅니다. 각 측은 핸드셰이크마다 새로운 임시 Curve25519 키 쌍을 생성하며, 세션 키는 정적 키와 임시 키를 혼합한 Diffie-Hellman 결과 체인에서 도출됩니다. 임시 개인 키는 즉시 폐기되므로 전방향 비밀성(forward secrecy)이 보장됩니다. 따라서 오늘 트래픽을 기록한 공격자가 내년에 서버의 개인 키를 탈취하더라도 기록된 내용을 해독할 수 없습니다.

핸드셰이크 개시 메시지에는 TAI64N 타임스탬프가 포함되며, 각 피어는 상대방으로부터 받은 가장 큰 타임스탬프를 기억하므로 재전송된 개시 메시지는 거부됩니다. 데이터 패킷은 논스(nonce)로 사용되는 64비트 카운터를 포함하며, 수신자는 최근 확인된 카운터의 슬라이딩 윈도우를 유지합니다. 이를 통해 TCP 방식의 연결 상태 없이도 재전송과 심각한 순서 뒤바뀜 문제를 처리합니다.

세션 키는 오래 유지되지 않으며, 타이머는 설정 가능한 값이 아니라 컴파일 시점에 고정됩니다.

ChartWireGuard protocol timers, in seconds
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 showlatest handshake을 상대적인 시간으로 출력하는 이유이며, 정상적으로 작동 중인 바쁜 터널에서 해당 시간이 작게 유지되는 이유입니다. 트래픽을 활발히 전송하는 중에도 이 시간이 계속 증가한다면 터널이 유휴 상태인 것이 아니라 핸드셰이크가 실패하고 있다는 뜻입니다.

피어에 클라이언트나 서버 역할이 없는 이유

양쪽 끝단은 동일한 코드와 동일한 설정 형식을 사용합니다. 서버 모드라는 것은 존재하지 않습니다. 사용자가 느끼는 비대칭성은 Endpoint에서 비롯되며, Endpoint는 선택 사항입니다.

엔드포인트가 설정된 피어는 핸드셰이크를 시작할 수 있습니다. 설정이 없는 피어는 대기하다가, 올바르게 인증된 첫 번째 패킷으로부터 상대방의 주소와 포트를 학습합니다. 학습된 엔드포인트는 저장되며, 새로운 주소에서 유효한 패킷이 도착할 때마다 업데이트됩니다. 이것이 로밍이 작동하는 방식입니다. 노트북이 와이파이에서 모바일 네트워크로 이동해도 동일한 터널이 유지되는 이유는, 세션이 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.com

nmap은 open|filtered 상태를 보고하는데, 이는 방화벽이 패킷을 조용히 폐기할 때와 동일한 결과입니다. 적어도 사용자의 공개 키를 보유하지 않은 사람에게는 WireGuard가 실행 중인지 여부와 관계없이 포트가 동일하게 동작합니다.

mac2이라는 두 번째 필드는 서비스 거부(DoS) 공격에 대응합니다. 수신자가 부하 상태일 때 유효한 시작 요청을 받으면 발신자의 소스 주소와 연결된 64바이트 쿠키 응답을 보냅니다. 발신자가 해당 쿠키를 다시 보내기 전까지는 비용이 많이 드는 공개 키 연산을 수행하지 않습니다. 이는 CPU 자원을 소모하기 전에 소스 주소가 실제임을 증명하며, 부하가 발생할 때만 활성화됩니다.

왜 0.0.0.0/0이 피어를 기본 경로로 만드는가

AllowedIPs이 라우팅 테이블이기 때문에, AllowedIPs = 0.0.0.0/0, ::/0는 해당 피어에 대한 모든 목적지를 점유합니다. 이것이 전체 풀 터널 설정의 핵심입니다.

이 동작을 가능하게 하는 라우팅 방식은 설정 줄 자체보다 더 흥미롭습니다. wg0을 통한 일반적인 기본 경로는 루프를 발생시킵니다. 트래픽을 운반하는 암호화된 UDP 패킷 역시 머신을 떠나야 하는데, 이 패킷이 자기 자신의 기본 경로와 일치하기 때문입니다. wg-quick은 정책 라우팅(policy routing)을 통해 이를 방지합니다. 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 main

0xca6c은 16진수로 51820이며, 51820은 테이블 번호이기도 합니다. suppress_prefixlength 0 규칙은 메인 테이블이 자체 기본 경로를 건너뛰게 만듭니다. 따라서 로컬 서브넷과 같은 특정 경로는 여전히 우선순위를 가지며, 그 외의 모든 트래픽은 터널 테이블로 전달됩니다. 스플릿 터널(split tunnel)은 이러한 과정이 전혀 필요하지 않습니다. AllowedIPs = 10.8.0.0/24, 10.20.0.0/16와 같이 더 좁은 범위의 목록은 메인 테이블에서 일반적인 경로로 처리되기 때문입니다.

풀 터널이 스스로 해결하지 못하는 한 가지는 이름 해석(name resolution)입니다. 클라이언트가 로컬 네트워크로부터 학습한 리졸버는 보통 그대로 유지되며, 해당 리졸버의 경로가 더 구체적이기 때문입니다. 이는 별도의 작업이며, WireGuard 터널 외부로 유출되는 DNS에서 다룹니다.

PersistentKeepalive의 실제 용도

WireGuard는 트래픽이 없을 때 아무것도 전송하지 않습니다. 하트비트도, 세션 갱신도, 네트워크상의 그 어떤 신호도 없습니다. 이러한 정적 상태는 배터리 수명을 절약하고 앞서 언급한 스캐너 탐지를 방지하는 데 도움이 되지만, 특정 환경에서는 문제를 일으킵니다.

NAT(Network Address Translation) 또는 상태 저장 방화벽 뒤에 있는 피어는 해당 장치에 매핑 정보가 존재할 때만 외부에서 접근할 수 있으며, 이 매핑은 나가는 패킷에 의해 생성됩니다. 일반적인 UDP 매핑 유지 시간은 약 30초부터 시작합니다. 매핑이 만료되면 외부에서 들어오는 패킷은 중간 장치에 의해 차단되며, NAT 뒤의 피어가 무언가를 보낼 때까지 터널은 끊긴 것처럼 보입니다. PersistentKeepalive = 25은 25초마다 빈 인증 패킷을 전송하여 가장 짧은 일반 유지 시간보다 먼저 신호를 보내므로 매핑이 계속 열려 있게 합니다.

이 설정은 NAT 뒤에 있는 피어에 적용하십시오. 공인 IP 주소와 열린 UDP 포트를 가진 서버에는 이 설정이 필요 없으며, 오히려 불필요한 트래픽만 발생시킵니다. 이를 자동 keepalive와 혼동하지 마십시오. 자동 keepalive는 피어가 데이터를 수신한 후 다시 보낼 데이터가 없을 때 10 초 뒤에 작동합니다. 이 기능은 항상 활성화되어 있으며 설정할 수 없습니다.

LAN 트래픽을 터널로 라우팅하는 것은 WireGuard의 기능이 아닙니다

피어 B가 홈 네트워크 192.168.50.0/24에 있고, 피어 A가 이 네트워크에 접근해야 한다고 가정합니다. 두 개의 서로 다른 시스템이 합의해야 하며, 그중 하나만이 WireGuard입니다.

WireGuard의 역할: A의 AllowedIPs192.168.50.0/24을 추가합니다. 이렇게 하면 A는 해당 프리픽스를 B로 라우팅하고, B로부터 오는 해당 소스 주소를 가진 패킷을 수락하게 됩니다. 이 설정이 없으면 암호화 키 라우팅(cryptokey routing)은 목적지에 대한 키를 찾지 못하고 소스에 대한 권한도 부여하지 않습니다.

커널의 역할: B에서 net.ipv4.ip_forward1이어야 합니다. 그렇지 않으면 커널은 B 자신을 목적지로 하지 않는 모든 복호화된 패킷을 폐기합니다. B의 방화벽 forward 체인은 해당 트래픽을 허용해야 합니다. LAN에 있는 호스트들은 10.8.0.0/24를 향하는 반환 경로를 가지고 있어야 하며, 그렇지 않다면 B가 소스 NAT를 적용하여 응답이 B를 통해 돌아오도록 해야 합니다.

WireGuard의 작업은 복호화된 패킷을 커널에 전달하는 시점에서 종료됩니다. 그 이후의 모든 과정은 일반적인 Linux 라우팅 및 필터링 영역입니다. 이러한 이유로 이 실패는 wg show가 아닌 nft list ruleset 카운터나 ip -s link show wg0에서 확인됩니다. 웹 인터페이스를 통해 피어를 관리하고 싶다면 Docker에서 wg-easy 실행하기를 통해 피어 항목을 자동으로 생성할 수 있습니다. 단, 포워딩 규칙은 여전히 호스트에서 설정해야 합니다.

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를 사용 중이라는 사실을 숨기지 못합니다. 핸드셰이크 메시지는 크기가 고정되어 있고, 첫 번째 바이트가 메시지 유형을 나타내며, 전송 계층은 UDP입니다. 심층 패킷 분석(DPI)으로 쉽게 식별할 수 있으므로, VPN을 차단하는 네트워크에서는 이를 막을 수 있습니다. 난독화 기능은 의도적으로 제외되었습니다.
  • 트래픽의 양이나 타이밍을 숨기지 못합니다. 페이로드는 16바이트 단위로만 패딩되므로, 관찰자는 사용자가 언제 데이터를 보내는지, 대략 어느 정도의 양을 보내는지 알 수 있습니다.
  • 마지막으로 확인된 엔드포인트를 유지합니다. 공인 IP 주소를 가진 피어는 상대방의 현재 공인 IP를 저장하며, wg show 명령으로 이를 확인할 수 있습니다. 설정 파일에 고정된 터널 주소와 결합하면, 이는 사용자가 네트워크를 이동할 때마다 따라다니는 고유 식별자가 됩니다. 개인 VPS 환경에서는 문제가 없으나, 상용 서비스들이 프로토콜 위에 별도의 계층을 추가하는 이유이기도 합니다.
  • 사람이 아닌 키를 인증합니다. 개인 키 파일을 가진 사람이 곧 피어입니다. /etc/wireguard 디렉터리는 700 모드로, 키 파일은 600 모드로 유지하십시오.
  • 폐기 목록이나 만료 기한이 없습니다. 해당 피어 정보를 가진 모든 서버에서 피어 항목을 삭제해야 접근이 차단되며, 정적 키는 삭제하기 전까지 계속 유효합니다.

이러한 특성이 WireGuard를 취약하게 만드는 것은 아닙니다. 오히려 프로토콜을 간결하게 유지하며, 간결함이야말로 WireGuard의 핵심입니다. WireGuard는 인증과 암호화만 수행하며, 신원 관리와 주소 할당은 그 위에 구축하는 시스템의 몫으로 남겨둡니다. WireGuard와 Tailscale 비교에서 설명한 조정 계층은 바로 이러한 간극을 메우기 위해 존재하며, 방금 살펴본 것과 동일한 데이터 평면을 사용합니다.

FAQ

WireGuard에서 암호키 라우팅(cryptokey routing)이란 무엇입니까?

암호키 라우팅은 모든 패킷을 공개 키에 결합하는 규칙입니다. 각 피어 항목은 AllowedIPs에 접두사 목록을 포함합니다. 아웃바운드 시, WireGuard는 패킷의 목적지를 각 피어의 목록과 대조하여 가장 긴 접두사가 일치하는 피어를 선택하므로, 이 목록은 라우팅 테이블 역할을 합니다. 인바운드 시, 패킷이 복호화되고 인증되면 패킷의 내부 출발지 주소는 반드시 해당 피어의 목록 안에 포함되어야 하며, 그렇지 않으면 패킷은 폐기됩니다. 따라서 이 목록은 접근 제어 목록(ACL) 역할도 수행합니다. WireGuard는 별도의 라우팅 설정이나 내부 방화벽을 두지 않으며, 이 하나의 목록이 두 가지 역할을 모두 수행합니다.

양쪽 피어 모두에 PersistentKeepalive를 설정해야 합니까?

아니요. NAT(네트워크 주소 변환) 뒤에 있거나 상태 저장 방화벽 뒤에 있는 쪽(보통 클라이언트)에만 설정하십시오. WireGuard는 유휴 상태일 때 아무것도 전송하지 않으므로, 상대방이 해당 피어에 도달할 수 있게 하는 매핑 정보가 보통 1분 이내에 만료되어 터널이 한쪽 방향으로 죽은 것처럼 보일 수 있습니다. PersistentKeepalive = 25는 25초마다 빈 인증 패킷을 전송하여 매핑을 유지합니다. 공인 IP 주소를 가지고 있고 UDP 포트가 열려 있는 피어는 이 설정이 필요하지 않습니다.

터널을 통한 핑(ping) 시도 시 "Required key not available" 오류가 발생하는 이유는 무엇입니까?

목적지 주소가 어떤 피어의 AllowedIPs에도 포함되어 있지 않기 때문입니다. 이 경우 암호키 라우팅이 패킷을 암호화할 키를 찾지 못하여 커널이 전송을 거부한 것입니다. wg show wg0 allowed-ips을 실행하여 출력된 내용과 핑을 시도하는 주소를 비교해 보십시오. 유사한 오류인 Destination address required은 다른 문제입니다. 이는 피어는 일치했지만 WireGuard가 해당 피어에 대한 엔드포인트를 가지고 있지 않은 경우입니다. 엔드포인트가 설정되지 않았고, 해당 피어로부터 아직 인증된 패킷이 도착하지 않았기 때문입니다.

방화벽이 WireGuard를 탐지하고 차단할 수 있습니까?

네. WireGuard는 트래픽을 인증하고 암호화하지만, 자신을 숨기려는 시도는 하지 않습니다. 핸드셰이크 메시지는 148바이트와 92바이트로 고정되어 있고, 모든 메시지의 첫 번째 바이트는 메시지 유형을 식별하며, 전송 프로토콜은 UDP이므로 심층 패킷 분석(DPI)을 통해 프로토콜을 쉽게 식별할 수 있습니다. UDP를 차단하거나 프로토콜 지문을 분석하는 네트워크는 WireGuard를 차단할 것입니다. 터널을 숨기려면 다른 프로토콜로 감싸야 하며, 이는 WireGuard 설정이 아닌 별도의 도구가 필요한 작업입니다.