SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-31

WireGuard 속도 저하 원인 해결 및 MTU 최적화 방법

WireGuard 속도가 느려지는 주요 원인인 MTU 설정 오류와 경로 문제를 진단합니다. 이분법을 이용한 MTU 확인법, TCP MSS 클램핑 설정, VPS CPU 점유율 확인 등 실제 성능을 개선하는 구체적인 점검 단계를 안내합니다.

WireGuard 속도 저하의 실제 원인

WireGuard의 속도 저하는 네 가지 원인 중 하나에서 발생하며, 각 원인의 발생 가능성은 동일하지 않습니다. 첫 번째는 MTU(maximum transmission unit)입니다. 터널이 경로상의 특정 링크가 처리하기에 너무 큰 패킷을 생성하면, 대용량 전송은 중단되지만 작은 패킷은 정상적으로 보입니다. 두 번째는 경로 자체의 문제입니다. 이는 터널을 생성하기 전부터 이미 제한 요소로 작용하고 있었을 가능성이 큽니다. 세 번째는 소규모 공유 VPS의 CPU 성능입니다. 암호화 작업이 동일한 호스트를 사용하는 다른 모든 게스트와 자원을 경쟁하게 됩니다. 네 번째는 피어(peer) 자체의 연결 상태입니다.

이 순서대로 점검하십시오. MTU를 가장 먼저 확인해야 하는 이유는 WireGuard 자체에 의해 발생하는 유일한 원인이기 때문이며, 그 증상이 단순한 속도 저하처럼 보이지 않기 때문입니다. MTU 설정이 잘못되면 일반적으로 터널은 즉시 연결되고, ping에 응답하며, SSH 로그인까지는 성공하지만, 파일을 복사하는 순간 멈추는 현상이 나타납니다.

이 모든 점검에 앞서 한 가지 증상은 배제할 필요가 있습니다. 새로운 사이트에 접속할 때마다 로딩이 시작되기까지 수 초가 걸린 뒤 전체 속도로 전송된다면, 이는 처리량(throughput) 문제가 아니라 이름 해석(name resolution) 문제입니다. DNS over WireGuard는 고유한 장애 유형을 가지고 있으며, MTU를 변경해도 해결되지 않습니다.

WireGuard MTU가 1420인 이유는 무엇입니까?

터널로 전송하는 모든 패킷은 암호화되어 새로운 패킷 내부에 래핑됩니다. 이 래핑 과정에서 바이트가 소모되며, 해당 바이트는 페이로드에서 차감됩니다.

WireGuard 데이터 헤더는 32바이트입니다. 여기에는 4바이트 유형 필드, 4바이트 수신자 인덱스, 8바이트 카운터, 16바이트 Poly1305 인증 태그가 포함됩니다. 그 주위를 8바이트의 UDP 헤더가 감싸고 있습니다. 다시 그 바깥쪽에는 외부 IP 헤더가 위치하는데, IPv4의 경우 20바이트, IPv6의 경우 40바이트입니다. 따라서 Endpoint이 IPv4 주소일 때 총 캡슐화 크기는 60바이트이며, IPv6일 때는 80바이트가 됩니다. WireGuard 프로토콜 페이지에는 이러한 수치가 도출되는 메시지 레이아웃이 문서화되어 있습니다.

wg-quick은 이를 추측하지 않습니다. Endpoint로 라우팅되는 인터페이스의 MTU를 읽은 다음 80을 뺍니다. 일반적인 1500바이트 이더넷 경로에서는 1420이 산출되며, 이것이 ip link show wg0이 출력하는 값입니다. 60이 아닌 80을 빼는 이유는 외부 헤더가 20바이트 더 큰 IPv6를 통해 해당 엔드포인트에 도달하더라도 동일한 수치가 안전하게 유지되도록 하기 위함입니다.

ChartMTU arithmetic for common underlays
The data behind this chart
[
  {
    "label": "Ethernet, IPv4 endpoint",
    "path_mtu": 1500,
    "encap_overhead": 60,
    "usable_wg0_mtu": 1440
  },
  {
    "label": "Ethernet, IPv6 endpoint",
    "path_mtu": 1500,
    "encap_overhead": 80,
    "usable_wg0_mtu": 1420
  },
  {
    "label": "PPPoE DSL, IPv4 endpoint",
    "path_mtu": 1492,
    "encap_overhead": 60,
    "usable_wg0_mtu": 1432
  },
  {
    "label": "Extra tunnel in the path",
    "path_mtu": 1400,
    "encap_overhead": 80,
    "usable_wg0_mtu": 1320
  }
]

4개의 행은 측정이 아닌 산술적 계산 결과입니다. IPv4 엔드포인트를 사용하는 깨끗한 1500바이트 경로에서는 1440가 적합하므로, 기본값인 1420을 사용하면 20바이트의 여유가 남습니다. 이 여유 공간은 의도된 것이며 사용자가 신경 쓸 문제가 아닙니다.

마지막 행은 문제가 되는 경우입니다. 경로상의 특정 링크가 1400 바이트만 허용할 때, 터널이 여전히 1420로 설정되어 있으면 모든 최대 크기 세그먼트에서 1500바이트의 외부 패킷이 생성됩니다. 이는 해당 링크가 허용하는 것보다 100바이트 더 큰 값입니다. 이 경우 적합한 값은 1320입니다.

1320을 그대로 복사해서 사용하지 마십시오. 경로 MTU는 사용자의 경로에 종속된 속성이며, 이를 확인하는 유일한 방법은 직접 측정하는 것입니다.

잘못된 MTU 설정의 증상

실패는 점진적으로 나타나지 않습니다. 작은 패킷과 큰 패킷 사이에서 명확하게 구분됩니다.

  • ping을(를) 터널을 통해 실행하면 일반적인 크기에서는 모두 정상적으로 작동합니다.
  • SSH 로그인은 완료되며 타이핑 반응도 정상입니다.
  • curl -I https://example.com은(는) 헤더를 즉시 반환합니다.
  • curl https://example.com을(를) 큰 페이지에 대해 실행하면 처음 몇 킬로바이트 이후 멈춥니다.
  • scp을(를) 큰 파일에 대해 실행하면 시작은 되지만 특정 퍼센트에서 멈춥니다.
  • SSH 세션은 많은 양의 출력을 생성하는 명령을 실행하는 순간 멈춥니다.

이 모든 현상은 TCP 연결이 대량의 데이터를 전송할 때만 최대 크기의 세그먼트를 생성하기 때문에 발생합니다. 핸드셰이크와 첫 번째 요청은 경로상의 모든 MTU보다 작기 때문에 통과합니다. 첫 번째 최대 크기 세그먼트에서 정체가 시작되므로, 연결이 쓸모없어지기 직전까지는 정상적으로 보입니다.

다음 링크의 MTU보다 큰 외부 패킷은 다음 두 가지 운명 중 하나를 맞이합니다.

패킷이 단편화(fragmented)됩니다. 라우터가 패킷을 쪼개고 수신 측에서 조각들을 재조립합니다. 전송은 성공하지만 속도는 느려집니다. 하나의 패킷을 위해 두 개의 패킷을 처리해야 하며, 수신 측은 두 조각이 모두 도착할 때까지 상태를 유지해야 하기 때문입니다. 조각 하나라도 손실되면 원래 패킷 전체가 손실되므로, 1%의 손실률을 가진 경로라도 실제로는 훨씬 더 나쁜 경로처럼 동작합니다. 많은 방화벽이 정책상 IP 단편을 차단하며, 이 경우 결과는 다음 항목과 같아집니다.

패킷이 폐기(dropped)되며, 알림을 받을 수도 있고 받지 못할 수도 있습니다. 단편화를 수행하지 않는 라우터는 송신 측에 ICMP(internet control message protocol) "fragmentation needed" 메시지를 보내 수용 가능한 MTU를 알립니다. 이 메시지가 도착하면 경로 MTU 탐색(path MTU discovery)이 작동하여 송신 측이 스스로 세그먼트 크기를 낮춥니다. 많은 네트워크가 ICMP를 필터링하므로 이 메시지가 도착하지 않는 경우가 많습니다. 그 외에는 손실을 보고하는 주체가 없습니다. 이것이 블랙홀 현상입니다. 패킷은 떠나지만 돌아오는 것은 없으며, 양쪽 끝의 로그 어디에도 오류가 기록되지 않고 타임아웃이 발생할 때까지 전송이 멈춘 상태로 유지됩니다.

적절한 MTU 값을 찾는 방법

경로를 측정한 뒤 계산을 수행합니다. 터널이 아닌 언더레이(underlay)를 테스트해야 하므로, 클라이언트에서 서버의 공인 IP 주소로 ping을 보내되 패킷 분할(fragmentation)을 금지합니다.

ping -M do -s 1472 -c 3 203.0.113.10

-M do는 DF(don't fragment) 비트를 설정하여 경로상의 라우터가 패킷을 분할하지 못하게 합니다. -s은 ICMP 페이로드 크기입니다. 전체 IPv4 패킷은 해당 페이로드에 8바이트의 ICMP 헤더와 20바이트의 IP 헤더를 더한 크기이므로, -s 1472은 정확히 1500바이트를 전송합니다.

세 가지 결과가 중요합니다. 응답이 정상적이라면 1500바이트가 통과하는 것이며 MTU는 문제가 아닙니다. 로컬 오류가 발생한다면 자신의 인터페이스가 요청한 크기보다 이미 작다는 의미입니다.

ping: local error: message too long, mtu=1500

중간 라우터로부터 응답이 오면 답을 직접 얻은 것이므로 거기서 멈추면 됩니다.

From 203.0.113.1 icmp_seq=1 Frag needed and DF set (mtu = 1492)

1472바이트에서 100% 패킷 손실이 발생하고 더 작은 크기에서 정상 응답이 온다면 블랙홀(black hole) 사례입니다. 어떤 라우터도 정보를 주지 않으므로 이분법(halving)으로 한계를 찾습니다. 성공한 크기와 실패한 크기를 각각 하나씩 잡고 중간값을 테스트한 뒤, 결과에 따라 범위를 좁혀 나갑니다. 매 단계마다 범위가 절반으로 줄어들므로 5~6회면 충분합니다.

이분법을 이용한 단계별 작업 예시

각 줄은 클라이언트에서 서버의 공인 IP 주소로 실행하는 명령어입니다. 주석은 반환된 결과를 기록합니다.

ping -M do -s 1472 -c 3 203.0.113.10   # 100% loss, so 1500 is too big
ping -M do -s 1272 -c 3 203.0.113.10   # replies, so 1300 fits
ping -M do -s 1372 -c 3 203.0.113.10   # replies, so 1400 fits
ping -M do -s 1422 -c 3 203.0.113.10   # 100% loss, so 1450 is too big
ping -M do -s 1397 -c 3 203.0.113.10   # 100% loss, so 1425 is too big
ping -M do -s 1384 -c 3 203.0.113.10   # 100% loss, so 1412 is too big

성공한 가장 큰 페이로드는 1372이므로, 이 경로는 최소 1400바이트에서 1412바이트 미만을 전송할 수 있습니다. 안전한 쪽을 선택합니다. 경로 MTU가 1400일 때, 80바이트의 캡슐화를 빼면 wg0 MTU는 1320이 됩니다.

tracepath은 스스로 동일한 탐색을 수행하므로, 이분법을 시작하기 전에 한 번 실행해 볼 가치가 있습니다.

tracepath -n 203.0.113.10

마지막 줄에 발견된 결과가 표시됩니다.

     Resume: pmtu 1492 hops 12 back 12

두 도구 모두 증거라기보다는 시작점으로 간주해야 합니다. 일부 호스트는 ICMP를 완전히 차단하거나 속도 제한을 걸기 때문에, 이분법 결과가 실제 경로 MTU보다 작게 나올 수 있습니다. 실패하던 전송을 다시 시도하는 것이 실제 테스트입니다.

잘못된 추측은 명령어 한 번으로 되돌릴 수 있으므로, 먼저 실시간으로 값을 적용합니다.

sudo ip link set mtu 1320 dev wg0

멈췄던 전송을 다시 시도합니다. 성공한다면 클라이언트의 [Interface] 블록에 값을 영구적으로 설정합니다.

[Interface]
PrivateKey = <client private key>
Address = 10.8.0.2/32
MTU = 1320
sudo wg-quick down wg0 && sudo wg-quick up wg0
ip link show wg0

ip link show wg0은 이제 mtu 1320을 출력해야 합니다. 여전히 이전 값을 출력한다면 wg-quick가 수정한 파일을 읽지 못한 것입니다. /etc/wireguard/wg0.conf을 수정했는지, 그리고 MTU[Peer] 아래가 아닌 [Interface] 아래에 위치하여 무시되지 않는지 확인하십시오.

MTU는 인터페이스의 속성이며 피어 간에 협상되지 않습니다. 클라이언트에서만 설정하면 클라이언트가 보내는 패킷만 작아집니다. 서버는 여전히 자신의 wg0 MTU에 맞춰 패킷을 생성하므로, 업로드가 작동하더라도 다운로드는 여전히 블랙홀 현상을 겪을 수 있습니다. 양쪽 끝에 모두 값을 설정하거나 서버에서 MSS를 클램핑(clamp)하십시오.

MSS 클램핑이 TCP만 해결하고 다른 것은 해결하지 못하는 이유

서버가 피어의 트래픽을 전달하는 경우, 즉 NAT(네트워크 주소 변환)를 사용하는 표준 WireGuard VPS 설정에서는 하나의 규칙으로 모든 피어의 TCP 문제를 해결할 수 있으며, 제어할 수 없는 각 클라이언트에서 값을 일일이 찾을 필요가 없습니다.

MSS(최대 세그먼트 크기)는 각 측이 SYN 패킷에 포함하여 수신 가능한 세그먼트의 크기를 알리는 TCP 옵션입니다. 클램핑은 전송 중인 이 옵션을 실제 경로의 MTU에 맞게 다시 작성하므로, 데이터가 이동하기 전에 양쪽 끝단이 더 작은 세그먼트 크기에 합의하게 됩니다. 이 방식은 핸드셰이크 과정에서 수행되며, 경로상에서 차단될 가능성이 있는 ICMP 메시지에 의존하지 않기 때문에 효과적입니다.

nftables를 사용하는 경우, 기존 테이블 아래에 /etc/nftables.conf을 사용하여 다음 테이블을 추가합니다.

table inet mangle {
  chain forward {
    type filter hook forward priority mangle; policy accept;
    tcp flags syn tcp option maxseg size set rt mtu
  }
}

sudo systemctl reload nftables을 사용하여 다시 로드합니다. iptables를 사용하는 환경에서는 다음 한 줄로 동일한 작업을 수행할 수 있습니다.

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

규칙이 패킷 경로에 올바르게 적용되었는지 확인합니다. 클라이언트가 새 연결을 생성하는 동안 sudo nft list table inet mangle 또는 sudo iptables -t mangle -L FORWARD -n -v을 실행하여 카운터가 증가하는지 확인합니다. 카운터가 0에 머물러 있다면 패킷이 해당 훅을 통과하지 않는 것이며, 따라서 규칙이 아무런 동작을 하지 않는 상태입니다.

이제 솔직한 한계를 말씀드립니다. 클램핑은 TCP에만 적용되며 다른 프로토콜은 처리하지 않습니다. 또한 전달되는 트래픽에만 적용되므로, WireGuard 서버 자체에서 실행되는 서비스는 forward 훅을 거치지 않아 클램핑되지 않습니다. 이 규칙은 로드된 이후에 생성되는 연결에만 영향을 미치며, 기존 세션은 이미 합의된 MSS를 그대로 유지합니다.

UDP는 핸드셰이크 과정에서 다시 작성할 내용이 없으므로 영향을 받지 않습니다. 대부분의 UDP 트래픽은 그대로 유지됩니다. HTTP/3의 기반인 QUIC는 자체적으로 사용 가능한 패킷 크기를 탐색하며 의도적으로 작은 크기에서 시작합니다. 문제가 되는 것은 1400바이트가 넘는 DNSSEC(DNS 보안 확장) 응답과 같이 하나의 큰 데이터그램을 보내고 통과를 기대하는 UDP 트래픽입니다. 이러한 쿼리는 타임아웃이 발생하고 TCP를 통해 재시도되는데, 이로 인해 사용자는 사이트가 완전히 작동하지 않는 대신 느리게 로딩되는 것을 경험하게 됩니다.

VPS의 CPU가 병목인가요?

WireGuard는 ChaCha20-Poly1305로 암호화하고 Curve25519로 키를 교환합니다. 데이터 경로상에 AES는 존재하지 않으며, 이로 인해 흔히 오해하는 사실이 하나 있습니다. 바로 CPU의 AES-NI 명령어가 WireGuard에는 아무런 도움이 되지 않는다는 점입니다. AES-NI를 지원하는 호스트라고 해서 WireGuard 성능이 향상되지는 않습니다. ChaCha20은 암호화 가속 기능이 없는 CPU에서도 소프트웨어만으로 빠르게 동작하기 때문에 선택되었습니다.

그렇다고 WireGuard의 자원 소모가 없는 것은 아닙니다. 1 vCPU VPS 환경에서는 하나의 코어가 애플리케이션 작업과 더불어 암호화 처리 및 네트워크 인터럽트를 모두 담당합니다.

데이터 전송 중에 다음 명령어로 측정하십시오.

sudo apt install -y sysstat
mpstat -P ALL 1

세 개의 열을 확인하십시오. %soft은 커널 패킷 처리가 수행되는 softirq 시간입니다. %steal는 하이퍼바이저가 다른 작업에 자원을 할당한 시간입니다. %idle은 남은 가용 시간입니다.

단일 코어에서 %soft가 100에 가깝다면 해당 서버가 패킷 처리 한계에 도달한 것이며, 이는 코어를 추가하여 해결할 수 있는 실질적인 제한입니다. 같은 시점에 top에서 ksoftirqd/0이 프로세스 목록 최상단에 나타난다면, 이는 다른 관점에서 동일한 결과를 보여주는 것입니다.

%steal이 몇 퍼센트 이상이라면 이는 사용자가 해결할 수 없는 문제입니다. 호스트가 오버서브스크립션(oversubscription) 상태여서 vCPU가 물리 코어를 기다리고 있기 때문입니다. 이는 저렴한 공유 플랜에서 흔히 발생하며 시간대에 따라 변동됩니다. 노이즈 이웃으로 인한 스틸 타임(Steal time)은 별도의 조사가 필요하며, 어떤 MTU 값을 설정하더라도 해결되지 않습니다.

또 다른 요소는 클라이언트가 어떤 구현체를 사용하는지입니다. Linux 커널 모듈은 빠른 경로를 제공하며 피어의 암호화 작업을 여러 코어로 분산합니다. 반면 사용자 공간 구현체인 wireguard-go은 더 느리며, macOS와 iOS 클라이언트가 이를 사용합니다. 해당 플랫폼들은 앱이 커널 모듈을 로드하는 것을 허용하지 않기 때문입니다.

경로 문제입니까, 아니면 피어 자체의 링크 문제입니까?

설정을 조정하기 전에 동일한 클라이언트에서 몇 분 간격으로 두 가지 수치를 측정하십시오. 터널을 사용하지 않을 때의 처리량과 터널을 사용할 때의 처리량입니다. 이 두 수치가 없으면 추측에 불과합니다.

서버에서 iperf3 -s를 실행하십시오. 직접 테스트를 수행하려면 공인 IP 주소에서 TCP 5201 포트에 접근할 수 있어야 하므로, 테스트하는 동안만 포트를 열고 테스트가 끝나면 규칙을 삭제하십시오. 포트가 다시 닫혔는지 확인하십시오. 닫혔을 것이라고 가정해서는 안 됩니다.

# on the client, outside the tunnel
iperf3 -c 203.0.113.10
# then through the tunnel
iperf3 -c 10.8.0.1

두 수치가 비슷하다면 WireGuard의 오버헤드는 매우 적으며 경로 자체가 병목 지점입니다. %soft은 낮은데 터널을 통한 처리량이 직접 연결보다 훨씬 낮다면 MTU 설정을 다시 확인하십시오. 패킷 단편화(fragmentation)는 연결을 끊지는 않지만 처리량을 감소시키므로, 연결이 중단되는 대신 성능이 일정 비율만큼 손실되는 형태로 나타납니다.

가정용 인터넷은 보통 비대칭적이므로 양방향 모두 테스트하십시오. iperf3 -c 10.8.0.1 -R을 사용하면 흐름이 반전되어 서버가 데이터를 전송하게 됩니다. 500/20 Mbps 회선을 사용하는 클라이언트는 터널을 통해 20 Mbps 이상의 업로드 속도를 낼 수 없으며, 서버 측 설정을 변경해도 이 제한은 바뀌지 않습니다.

그다음 병렬 스트림으로 테스트하십시오.

iperf3 -c 10.8.0.1 -P 4

네 개의 스트림을 동시에 실행했을 때 단일 스트림보다 훨씬 많은 데이터가 전송된다면, 단일 TCP 연결이 경로의 대역폭을 모두 채우지 못하는 것입니다. 단일 스트림의 처리량은 수신 윈도우 크기를 왕복 시간(RTT)으로 나눈 값에 의해 제한되므로, 150 ms 경로에서 많은 데이터를 전송하려면 큰 윈도우 크기가 필요합니다. 자신의 제한 값을 확인하십시오.

sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem

각 항목의 세 번째 값은 Linux가 자동으로 조정할 수 있는 최대값입니다. 패킷 손실 또한 단일 스트림의 성능을 강하게 제한합니다. TCP 혼잡 제어 알고리즘은 손실에 반응하며, 경로가 길수록 손실 복구 비용이 커지기 때문입니다. 클라이언트에서 mtr -rwc 100 203.0.113.10를 100회 실행하여 경로상 어디에서 손실이 발생하는지 확인하십시오. 특정 홉에서 시작되어 마지막 홉까지 계속되는 손실은 실제 손실입니다. 중간 홉에서만 발생하고 이후 사라지는 손실은 해당 라우터가 ICMP를 후순위로 처리하는 것이며, 이는 성능에 아무런 영향이 없습니다.

네트워크와 분리된 서버 자체의 상태를 반복적으로 확인하려면, 문서화된 방법으로 VPS 성능을 벤치마킹하십시오. 그래야 설정을 변경한 후에도 동일한 테스트를 수행하여 결과를 정확하게 비교할 수 있습니다.

WireGuard가 해결할 수 없는 문제

WireGuard는 터널입니다. 이 터널은 경로상 가장 느린 링크보다 빠를 수 없으며, 터널을 추가하면 경로 속도는 항상 약간 느려집니다.

WireGuard는 압축을 수행하지 않습니다. OpenVPN의 comp-lzo에 해당하는 기능은 없으며, 앞으로도 추가할 계획이 없습니다. 암호화 이전에 데이터를 압축하면 평문에 대한 정보가 유출되기 때문입니다. 대부분의 대용량 데이터는 이미 압축된 상태이므로 실제 사용 환경에서 이로 인한 손해는 없습니다. 이는 WireGuard와 OpenVPN을 비교할 때 고려해야 할 실질적인 차이점 중 하나이며, 의도적인 설계 선택입니다.

풀 터널(full tunnel)은 모든 패킷의 경로를 변경합니다. 이전에는 사용자에게서 가까운 CDN(콘텐츠 전송 네트워크)으로 직접 향하던 트래픽이 이제는 사용자의 VPS를 거쳐 CDN으로 전달됩니다. 만약 VPS가 다른 대륙에 있다면 모든 요청은 그 우회 경로만큼의 지연 시간을 감수해야 하며, 왕복 시간(RTT)은 그에 따라 증가합니다. 어떤 설정값으로도 이 시간을 단축할 수는 없습니다. VPS를 더 가까운 곳으로 옮기거나, VPN이 필요한 트래픽만 우회하도록 스플릿 터널(split tunnel)을 사용하십시오. 어떤 트래픽이 어디로 갈지는 전적으로 AllowedIPs에 의해 결정되며, cryptokey routing은 이 결정이 어떻게 이루어지는지 설명합니다.

제공자의 제한 사항은 터널 외부에 존재하므로 간과하기 쉽습니다. 월간 대역폭 제한이 있는 요금제는 할당량을 모두 소진하면 포트 속도를 훨씬 낮게 제한하는 경우가 많으며, 이 경우 터널이 고장 난 것처럼 보일 수 있습니다. MTU를 조정하며 시간을 낭비하기 전에 먼저 제공자의 관리 패널을 확인하십시오.

PersistentKeepalive는 처리량(throughput)에 영향을 주지 않습니다. 이 설정은 NAT 매핑을 유지하여 서버가 홈 라우터 뒤에 있는 클라이언트에 계속 도달할 수 있도록 하는 용도일 뿐입니다. 이 값을 25초 미만으로 낮추면 패킷만 추가될 뿐 아무것도 해결되지 않습니다.

다음 순서대로 측정하십시오

  1. 문제를 재현한 뒤, 멈춤(hang) 현상인지 단순히 속도가 느려지는 것인지 확인하십시오. 멈춤 현상은 MTU 문제일 가능성이 높지만, 속도 저하는 그렇지 않습니다.
  2. 클라이언트에서 서버의 공인 IP 주소로 ping -M do을 실행하여 경로 MTU(path MTU)를 확인하고 기록하십시오.
  3. 확인된 값에서 80을 뺀 뒤, 양쪽 끝단의 wg0 인터페이스에 해당 MTU를 설정하고 실패했던 전송을 다시 테스트하십시오.
  4. 서버가 피어 간의 트래픽을 포워딩하는 경우, 서버에 MSS clamping을 추가하십시오.
  5. 전송 중에 mpstat -P ALL 1을 실행하여 %soft%steal의 값을 확인하십시오.
  6. 터널 외부와 내부에서 양방향으로, 단일 스트림 및 -P 4 옵션을 사용하여 iperf3을 실행하십시오.
  7. 서버를 대상으로 mtr -rwc 100를 실행하여 마지막 홉까지 지속되는 패킷 손실이 있는지 확인하십시오.

서버 요금제 변경은 5단계에서 CPU가 한계치에 도달했다고 판단될 때만 고려하십시오. 1단계부터 4단계까지는 비용이 들지 않으며, 대부분의 터널 속도 저하 문제를 해결할 수 있습니다.

FAQ

WireGuard 터널에서 ping은 빠른데 다운로드는 왜 느린가요?

이러한 현상은 MTU 문제의 전형적인 징후입니다. 작은 패킷은 경로상의 모든 링크를 통과할 수 있으므로 ping이나 SSH 로그인은 정상적으로 작동합니다. 대용량 전송은 최대 크기의 세그먼트를 보내는데, 캡슐화된 패킷은 일부 링크가 허용하는 크기보다 커집니다. 이때 라우터가 ICMP 메시지를 반환하지 않고 패킷을 폐기하면 손실이 보고되지 않아 전송이 멈추게 됩니다. 서버의 공인 IP 주소를 대상으로 ping -M do 이분 탐색을 수행하여 경로 MTU를 찾고, 캡슐화 오버헤드인 80바이트를 뺀 값을 양쪽 끝의 wg0 MTU로 설정하십시오.

WireGuard의 MTU는 얼마로 설정해야 하나요?

모든 상황에 맞는 범용적인 값은 없으며, 이것이 바로 기본값인 1420이 일부 사용자에게 실패하는 이유입니다. 1420은 1500에서 WireGuard 헤더, UDP 헤더, 외부 IPv6 헤더를 합친 80바이트를 뺀 값입니다. PPPoE DSL이나 트래픽이 다른 터널을 통과하는 환경처럼 경로의 최대 전송 단위가 1500바이트 미만인 경우 더 작은 값이 필요합니다. 먼저 경로 MTU를 측정한 뒤 80을 빼서 설정하십시오.

MSS 클램핑으로 MTU 설정을 대체할 수 있나요?

아니요. 클램핑은 TCP 핸드셰이크 과정에서 MSS 옵션을 다시 작성하여 양쪽 끝이 더 작은 세그먼트를 보내도록 유도하며, 이는 인터페이스를 건드리지 않고 TCP 문제를 해결합니다. 하지만 UDP는 다시 작성할 핸드셰이크가 없으므로 영향을 받지 않습니다. 또한 클램핑은 서버가 포워딩하는 트래픽에만 적용되므로, WireGuard 서버 자체에서 실행되는 서비스는 혜택을 받지 못합니다. 인터페이스에 올바른 MTU를 설정하고, 제어할 수 없는 피어의 설정을 보완하기 위해 클램핑을 함께 사용하는 것이 좋습니다.

더 빠른 VPS 플랜을 쓰면 WireGuard가 빨라지나요?

CPU가 병목 현상의 원인일 때만 그렇습니다. 명령어 하나로 이를 확인할 수 있습니다. 전송 중에 mpstat -P ALL 1를 실행하십시오. 단일 코어에서 %soft이 100에 가깝다면 패킷 처리가 한계에 도달한 것이며, 더 많은 코어를 사용하면 성능이 향상됩니다. %steal이 높다면 호스트가 과도하게 할당된 상태이므로 다른 플랜이나 다른 호스트로 옮겨야 합니다. 두 수치가 모두 낮은데도 터널이 느리다면 CPU는 유휴 상태이므로 더 큰 플랜으로 변경해도 아무런 변화가 없습니다.

같은 네트워크인데 왜 Mac이 Linux 클라이언트보다 느린가요?

Linux 클라이언트는 커널 내장 WireGuard 모듈을 사용하여 커널 공간에서 패킷을 처리하고 피어의 암호화 작업을 CPU 코어 전체로 분산합니다. macOS와 iOS 앱은 커널 모듈 로드를 허용하지 않는 플랫폼 정책 때문에 사용자 공간 구현체인 wireguard-go을 사용합니다. 사용자 공간은 커널과 애플리케이션 사이에서 각 패킷을 복사해야 하며, 이 복사 과정에서 처리량 저하가 발생합니다. 이는 예상된 성능 차이이며 클라이언트 설정으로 해결할 수 없습니다.