SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-29

Cách khắc phục tốc độ WireGuard bị chậm hiệu quả

Tốc độ WireGuard chậm thường do MTU sai gây treo gói tin lớn. Hướng dẫn cách tìm path MTU, clamp TCP MSS, kiểm tra CPU steal time và đo băng thông thực tế để tối ưu tunnel.

Nguyên nhân thực sự khiến tốc độ WireGuard bị chậm

Tốc độ WireGuard chậm thường bắt nguồn từ một trong bốn nguyên nhân, và xác suất xảy ra của chúng không giống nhau. Đầu tiên là MTU (maximum transmission unit): tunnel tạo ra các gói tin quá lớn so với một liên kết trên đường truyền, khiến việc truyền tải dữ liệu lớn bị khựng lại trong khi các gói tin nhỏ vẫn hoạt động bình thường. Thứ hai là bản thân đường truyền, vốn đã bị giới hạn từ trước khi có tunnel. Thứ ba là CPU trên các VPS dùng chung cấu hình thấp, nơi việc mã hóa phải cạnh tranh tài nguyên với mọi guest khác trên cùng host. Thứ tư là kết nối của chính peer.

Hãy kiểm tra theo thứ tự đó. MTU đứng đầu vì đây là nguyên nhân duy nhất trong danh sách do chính WireGuard gây ra, và vì triệu chứng của nó không giống như bị chậm. MTU sai thường biểu hiện bằng việc tunnel kết nối ngay lập tức, phản hồi ping, cho phép đăng nhập SSH, nhưng sau đó bị treo ngay khi bạn copy file.

Có một triệu chứng cần loại trừ trước khi thực hiện bất kỳ bước nào ở trên. Nếu mỗi trang web mới đều mất vài giây để bắt đầu tải rồi mới truyền dữ liệu ở tốc độ tối đa, thì đó là do phân giải tên miền chứ không phải do băng thông. DNS over WireGuard có các kiểu lỗi riêng, và việc thay đổi MTU không giải quyết được vấn đề này.

Tại sao MTU của WireGuard là 1420?

Mọi gói tin bạn gửi vào tunnel đều được mã hóa và đóng gói bên trong một gói tin mới. Phần đóng gói này chiếm dung lượng, và dung lượng đó được trừ vào payload của bạn.

Header dữ liệu của WireGuard là 32 byte: gồm 4 byte trường type, 4 byte receiver index, 8 byte counter và 16 byte Poly1305 authentication tag. Bao quanh đó là UDP header 8 byte. Bao quanh tiếp là IP header bên ngoài, chiếm 20 byte đối với IPv4 và 40 byte đối với IPv6. Do đó, tổng dung lượng đóng gói là 60 byte khi Endpoint của bạn là địa chỉ IPv4 và 80 byte khi là IPv6. Trang giao thức WireGuard ghi lại cấu trúc thông điệp mà các con số này được lấy ra.

wg-quick không đoán con số này. Nó đọc MTU của interface định tuyến đến Endpoint của bạn, sau đó trừ đi 80. Trên đường truyền Ethernet 1500 byte thông thường, kết quả là 1420, đây là giá trị mà ip link show wg0 hiển thị. Nó trừ đi 80 thay vì 60 để đảm bảo con số này vẫn an toàn nếu endpoint đó được truy cập qua IPv6, nơi header bên ngoài lớn hơn 20 byte.

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 hàng đó là kết quả tính toán, không phải đo đạc. Trên đường truyền 1500 byte sạch với endpoint IPv4, 1440 sẽ vừa vặn, vì vậy giá trị mặc định 1420 để dư ra 20 byte. Biên độ đó là có chủ đích và bạn không cần bận tâm về nó.

Hàng cuối cùng mới là vấn đề. Khi một liên kết trên đường truyền chỉ tải được 1400 byte, một tunnel vẫn để ở mức 1420 sẽ tạo ra gói tin bên ngoài 1500 byte cho mỗi phân đoạn đầy đủ, lớn hơn 100 byte so với mức liên kết đó chấp nhận. Giá trị phù hợp là 1320.

Đừng copy giá trị 1320 này. Path MTU là thuộc tính của đường truyền của bạn, và cách duy nhất để biết nó là phải đo đạc.

Dấu hiệu của MTU sai

Lỗi này không diễn ra từ từ. Nó là sự phân tách rõ rệt giữa các gói tin nhỏ và gói tin lớn.

  • ping qua tunnel hoạt động ở mọi kích thước thông thường.
  • Đăng nhập SSH hoàn tất và thao tác gõ phím phản hồi nhanh.
  • curl -I https://example.com trả về header ngay lập tức.
  • curl https://example.com trên một trang web lớn bị treo sau vài kilobyte đầu tiên.
  • scp của một file lớn bắt đầu rồi dừng lại ở một tỷ lệ phần trăm nào đó.
  • Một phiên SSH bị đóng băng ngay khi bạn chạy lệnh in ra nhiều dữ liệu.

Tất cả những điều này xảy ra vì kết nối TCP chỉ tạo các segment kích thước tối đa khi có dữ liệu lớn cần truyền. Quá trình handshake và request đầu tiên đều nằm trong giới hạn MTU trên đường truyền. Sự cố bắt đầu tại segment kích thước tối đa đầu tiên, đó là lý do tại sao kết nối trông có vẻ ổn định cho đến khi nó trở nên vô dụng.

Một gói tin bên ngoài lớn hơn MTU của chặng tiếp theo sẽ gặp một trong hai kết cục.

Nó bị phân mảnh (fragmented). Một router chia nhỏ gói tin và phía nhận sẽ ghép lại các mảnh. Việc truyền tải vẫn hoạt động nhưng chậm hơn, vì bạn phải tốn hai gói tin cho một dữ liệu và bên nhận phải giữ trạng thái cho đến khi cả hai đến nơi. Mất một mảnh đồng nghĩa với mất toàn bộ gói tin gốc, vì vậy đường truyền có tỷ lệ mất gói 1% sẽ hoạt động tệ hơn nhiều. Nhiều firewall cũng chặn IP fragment theo chính sách, biến kết cục này thành kết cục tiếp theo.

Nó bị hủy và bạn có thể không được thông báo. Một router không hỗ trợ phân mảnh sẽ gửi thông báo ICMP (internet control message protocol) "fragmentation needed" ngược lại cho người gửi, kèm theo MTU mà nó có thể chấp nhận. Nếu thông báo đó đến nơi, cơ chế path MTU discovery sẽ hoạt động và người gửi tự giảm kích thước segment. Nhiều mạng lọc ICMP nên thông báo này thường không đến được. Không có gì khác báo cáo về việc mất gói. Đó chính là hố đen (black hole): gói tin rời đi, không có gì quay lại, không có lỗi nào xuất hiện trong log ở cả hai đầu, và quá trình truyền tải bị treo cho đến khi hết thời gian chờ (timeout).

Làm thế nào để tìm MTU phù hợp?

Hãy đo đường truyền, sau đó thực hiện phép trừ. Hãy kiểm tra lớp mạng bên dưới thay vì tunnel, bằng cách ping địa chỉ public của server từ client và cấm phân mảnh gói tin.

ping -M do -s 1472 -c 3 203.0.113.10

-M do thiết lập bit DF (don't fragment), vì vậy không router nào trên đường đi được phép chia nhỏ gói tin. -s là kích thước payload ICMP. Một gói IPv4 đầy đủ bao gồm payload đó cộng với 8 byte header ICMP và 20 byte header IP, vì vậy -s 1472 đặt chính xác 1500 byte lên đường truyền.

Có ba kết quả cần lưu ý. Phản hồi sạch nghĩa là 1500 byte đã truyền thành công và MTU không phải là vấn đề của bạn. Lỗi cục bộ nghĩa là interface của chính bạn đã nhỏ hơn kích thước bạn yêu cầu:

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

Một phản hồi từ router ở giữa sẽ cung cấp trực tiếp câu trả lời cho bạn, và bạn có thể dừng lại tại đó:

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

Mất gói tin 100% ở mức 1472, trong khi các kích thước nhỏ hơn vẫn phản hồi sạch, là trường hợp "hố đen" (black hole). Không có router nào báo lỗi cho bạn, vì vậy hãy tìm giới hạn bằng cách chia đôi. Giữ lại một kích thước bạn biết là hoạt động được và một kích thước bạn biết là thất bại, kiểm tra điểm giữa, và di chuyển biên giới tương ứng với kết quả. Mỗi vòng lặp sẽ chia đôi phạm vi còn lại, vì vậy năm hoặc sáu vòng là đủ.

Ví dụ về phương pháp chia đôi, từng vòng một

Mỗi dòng là một lệnh bạn chạy trên client nhắm vào địa chỉ public của server. Phần chú thích ghi lại kết quả trả về.

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

Payload lớn nhất truyền thành công là 1372, vì vậy đường truyền này hỗ trợ ít nhất 1400 byte và nhỏ hơn 1412. Hãy chọn giá trị an toàn. Path MTU là 1400, trừ đi 80 byte đóng gói (encapsulation), cho ra MTU của wg0 là 1320.

tracepath tự thực hiện tìm kiếm tương tự, và bạn nên chạy thử một lần trước khi bắt đầu chia đôi:

tracepath -n 203.0.113.10

Dòng cuối cùng của nó báo cáo kết quả tìm thấy:

     Resume: pmtu 1492 hops 12 back 12

Hãy coi cả hai công cụ này là điểm khởi đầu thay vì bằng chứng xác thực. Một số host giới hạn tốc độ hoặc chặn hoàn toàn ICMP, vì vậy phương pháp chia đôi có thể báo cáo MTU nhỏ hơn thực tế. Việc truyền dữ liệu đang bị lỗi mới là bài kiểm tra thực sự.

Hãy áp dụng giá trị trực tiếp trước, vì nếu đoán sai, bạn chỉ cần một lệnh để hoàn tác:

sudo ip link set mtu 1320 dev wg0

Thử lại quá trình truyền dữ liệu đang bị treo. Nếu nó hoàn tất, hãy lưu giá trị vĩnh viễn trong block [Interface] của client:

[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 bây giờ sẽ in ra mtu 1320. Nếu nó vẫn in ra giá trị cũ, wg-quick đã không đọc file bạn vừa chỉnh sửa. Hãy kiểm tra xem bạn đã sửa đúng /etc/wireguard/wg0.conf chưa và MTU đã nằm dưới [Interface] hay chưa, thay vì nằm dưới [Peer], nơi nó sẽ bị bỏ qua.

MTU là thuộc tính của một interface và không bao giờ được thương lượng giữa các peer. Việc thiết lập nó trên client chỉ làm giảm kích thước các gói tin mà client gửi đi. Server vẫn tiếp tục tạo các gói tin theo MTU của wg0 trên chính nó, vì vậy các file tải xuống vẫn có thể bị "hố đen" sau khi việc tải lên đã hoạt động. Hãy thiết lập giá trị ở cả hai đầu, hoặc clamp MSS trên server.

Tại sao MSS clamping chỉ sửa được TCP mà không sửa được gì khác

Nếu server chuyển tiếp lưu lượng cho các peer, điều mà nó thực hiện trong bất kỳ cấu hình WireGuard VPS tiêu chuẩn nào sử dụng NAT (network address translation), thì một rule duy nhất sẽ sửa lỗi TCP cho mọi peer và giúp bạn không phải đi tìm giá trị MTU trên từng client mà bạn không quản lý.

MSS (maximum segment size) là một tùy chọn TCP mà mỗi bên đưa vào gói tin SYN để thông báo kích thước segment lớn nhất mà họ có thể nhận. Clamping sẽ ghi đè tùy chọn đó khi gói tin đang truyền để khớp với MTU thực tế của đường truyền, nhờ đó cả hai đầu đều đồng ý sử dụng segment nhỏ hơn trước khi dữ liệu bắt đầu được gửi. Cách này hiệu quả vì nó diễn ra trong quá trình handshake và không phụ thuộc vào thông báo ICMP vốn thường bị chặn trên đường truyền.

Với nftables, hãy thêm bảng này vào /etc/nftables.conf bên dưới các bảng hiện có của bạn:

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

Reload bằng sudo systemctl reload nftables. Trên máy dùng iptables, lệnh tương đương chỉ là một dòng:

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

Xác nhận rule nằm trên đường đi của gói tin. Chạy sudo nft list table inet mangle hoặc sudo iptables -t mangle -L FORWARD -n -v trong khi client mở các kết nối mới và theo dõi bộ đếm tăng lên. Nếu bộ đếm đứng yên ở số 0, nghĩa là các gói tin không đi qua hook đó và rule không có tác dụng.

Bây giờ là những giới hạn thực tế. Clamping chỉ áp dụng cho TCP và không gì khác, đồng thời nó chỉ áp dụng cho lưu lượng được chuyển tiếp (forwarded traffic). Do đó, một dịch vụ chạy trực tiếp trên server WireGuard sẽ không bao giờ đi qua forward hook và không bao giờ được clamp. Nó cũng chỉ ảnh hưởng đến các kết nối được mở sau khi rule được load: các phiên làm việc hiện tại vẫn giữ nguyên MSS mà chúng đã thỏa thuận trước đó.

UDP không bị ảnh hưởng vì UDP không có handshake để ghi đè. Hầu hết lưu lượng UDP vẫn hoạt động bình thường. QUIC, giao thức truyền tải bên dưới HTTP/3, tự dò tìm kích thước gói tin khả dụng và chủ động bắt đầu với kích thước nhỏ. Thứ không hoạt động được là UDP khi gửi một datagram lớn và mong đợi nó đi lọt, ví dụ như phản hồi DNSSEC (DNS security extensions) có kích thước trên 1400 byte. Các truy vấn đó sẽ bị timeout và thử lại qua TCP, kết quả là người dùng thấy trang web tải chậm thay vì bị lỗi hoàn toàn.

CPU của VPS có phải là giới hạn không?

WireGuard mã hóa bằng ChaCha20-Poly1305 và trao đổi khóa bằng Curve25519. Không có AES trong đường truyền dữ liệu, và điều này dẫn đến một hệ quả mà nhiều người hiểu sai: các tập lệnh AES-NI trong CPU của bạn không có tác dụng gì với WireGuard. Một máy chủ quảng cáo hỗ trợ AES-NI không mang lại tính năng tăng tốc hiệu năng cho WireGuard. ChaCha20 được chọn vì nó chạy rất nhanh trên phần mềm thuần túy, kể cả trên các CPU không có bộ tăng tốc mã hóa.

Điều đó không có nghĩa là WireGuard không tốn tài nguyên. Trên một VPS có 1 vCPU, một nhân đó phải xử lý cả mã hóa lẫn ngắt mạng (network interrupt), bên cạnh các tác vụ ứng dụng khác của bạn.

Hãy đo lường trong khi quá trình truyền dữ liệu đang chạy:

sudo apt install -y sysstat
mpstat -P ALL 1

Đọc ba cột. %soft là thời gian softirq, nơi xử lý gói tin của kernel diễn ra. %steal là thời gian hypervisor dành cho các máy ảo khác. %idle là phần tài nguyên còn lại.

%soft gần mức 100 trên nhân duy nhất của bạn nghĩa là máy chủ đã chạm ngưỡng xử lý gói tin, và đây là giới hạn thực tế mà việc tăng thêm nhân CPU sẽ giải quyết được. top hiển thị ksoftirqd/0 ở đầu danh sách tiến trình tại cùng thời điểm, đây cũng là kết quả tương tự nhưng từ một góc nhìn khác.

%steal cao hơn vài phần trăm nghĩa là giới hạn này nằm ngoài khả năng khắc phục của bạn, vì máy chủ vật lý đang bị quá tải (oversubscribed) và vCPU của bạn phải chờ đợi nhân vật lý. Điều này phổ biến trên các gói shared rẻ nhất và biến động theo thời gian trong ngày. Steal time từ hàng xóm ồn ào cần một quy trình điều tra riêng, và không giá trị MTU nào có thể giúp ích cho vấn đề này.

Một yếu tố nữa là client đang chạy bản cài đặt nào. Module kernel Linux là đường dẫn nhanh nhất và nó phân bổ việc mã hóa của một peer ra nhiều nhân. wireguard-go, bản cài đặt userspace, chậm hơn và đây là thứ mà các client macOS và iOS sử dụng, vì các nền tảng đó không cho phép ứng dụng load kernel module.

Đó là do đường truyền hay do chính liên kết của peer?

Trước khi tinh chỉnh bất cứ thứ gì, hãy lấy hai con số từ cùng một client cách nhau vài phút: throughput khi không có tunnel và throughput khi có tunnel. Nếu không có cặp số này, bạn chỉ đang đoán mò.

Chạy iperf3 -s trên server. Bài kiểm tra trực tiếp cần cổng TCP 5201 mở trên địa chỉ public, vì vậy hãy mở nó trong thời gian kiểm tra và xóa rule đó sau khi xong. Xác nhận cổng đã đóng lại thay vì chỉ giả định.

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

Nếu hai con số này gần bằng nhau, WireGuard đang tiêu tốn rất ít tài nguyên và đường truyền mới là giới hạn. Nếu con số qua tunnel thấp hơn nhiều so với kết nối trực tiếp trong khi %soft vẫn ở mức thấp, hãy quay lại kiểm tra MTU. Phân mảnh (fragmentation) làm giảm throughput mà không gây lỗi rõ rệt, nên nó xuất hiện ở đây dưới dạng mất mát phần trăm thay vì bị treo.

Kiểm tra cả hai chiều, vì kết nối tại nhà thường là bất đối xứng. iperf3 -c 10.8.0.1 -R đảo ngược luồng để server gửi dữ liệu. Một client trên đường truyền 500/20 sẽ không bao giờ đẩy được nhiều hơn 20 Mbit upload vào tunnel, và không thay đổi nào ở phía server có thể khắc phục điều đó.

Sau đó, kiểm tra với các luồng song song:

iperf3 -c 10.8.0.1 -P 4

Nếu bốn luồng cùng lúc truyền tải nhiều hơn hẳn một luồng, thì một kết nối TCP đơn lẻ đang không tận dụng hết đường truyền. Throughput của một luồng bị giới hạn bởi receive window chia cho round trip time, vì vậy một đường truyền 150 ms cần một window lớn để truyền tải nhiều dữ liệu. Hãy đọc các giới hạn của chính bạn:

sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem

Giá trị thứ ba trong mỗi dòng là mức tối đa mà Linux sẽ tự động điều chỉnh (autotune). Mất gói tin (packet loss) cũng giới hạn nghiêm ngặt một luồng đơn lẻ, vì mất gói là thứ mà cơ chế kiểm soát tắc nghẽn TCP phản ứng lại, và một đường truyền dài khiến việc khôi phục trở nên tốn kém. Chạy mtr -rwc 100 203.0.113.10 từ client trong một trăm chu kỳ để xem mất gói xuất hiện ở đâu dọc theo lộ trình. Mất gói bắt đầu tại một hop và tiếp tục đến hop cuối cùng là mất gói thực sự. Mất gói tại một hop trung gian nhưng biến mất ở các hop sau đó là do router đó ưu tiên thấp cho ICMP, và nó không có ý nghĩa gì cả.

Để có một bức tranh chính xác về chính server, tách biệt khỏi mạng, hãy benchmark VPS bằng một phương pháp có tài liệu để bạn có thể chạy lại cùng một bài kiểm tra sau khi thay đổi và so sánh các kết quả tương đương nhau.

Những hạn chế của WireGuard

WireGuard là một tunnel. Nó không thể nhanh hơn đường truyền chậm nhất trên lộ trình mà nó sử dụng, và việc thêm nó vào luôn làm đường truyền chậm đi đôi chút.

Nó không thực hiện nén dữ liệu. Không có tính năng nào tương đương với comp-lzo của OpenVPN và cũng không có kế hoạch phát triển tính năng này, vì việc nén trước khi mã hóa sẽ làm lộ thông tin về plaintext. Hầu hết dữ liệu lớn đều đã được nén sẵn, nên trên thực tế bạn không mất gì cả. Đây là một trong những khác biệt thực tế cần cân nhắc khi bạn so sánh WireGuard với OpenVPN, và đó là một lựa chọn thiết kế có chủ đích.

Một full tunnel làm thay đổi lộ trình của mọi gói tin. Lưu lượng vốn dĩ đi từ bạn đến một CDN (content delivery network) gần đó nay sẽ đi từ bạn đến VPS của bạn rồi mới đến CDN. Nếu VPS nằm ở một châu lục khác, mọi yêu cầu đều phải chịu độ trễ của quãng đường vòng đó và round trip time sẽ tăng tương ứng. Không có giá trị cấu hình nào rút ngắn được điều này. Hãy chuyển VPS đến gần hơn, hoặc sử dụng split tunnel để chỉ những lưu lượng cần VPN mới đi đường vòng. Lưu lượng nào đi đâu được quyết định hoàn toàn bởi AllowedIPs, và cryptokey routing giải thích cách quyết định đó được thực hiện.

Các giới hạn của nhà cung cấp nằm ngoài tunnel và rất dễ bị bỏ quên. Một gói cước có giới hạn băng thông hàng tháng thường sẽ bóp băng thông cổng xuống tốc độ thấp hơn nhiều khi hết dung lượng, và khi đó tunnel trông như bị hỏng. Hãy kiểm tra bảng điều khiển của bạn trước khi tốn cả buổi tối để chỉnh MTU.

PersistentKeepalive không ảnh hưởng đến throughput. Nó tồn tại để giữ cho NAT mapping luôn mở nhằm giúp server vẫn có thể kết nối tới client nằm sau router gia đình. Việc hạ giá trị này xuống dưới 25 giây chỉ làm tăng số lượng gói tin và không giải quyết được vấn đề gì.

Thực hiện đo đạc theo thứ tự sau

  1. Tái hiện sự cố và ghi chú xem đó là tình trạng treo hay chỉ là chậm dần đều. Treo máy thường chỉ ra vấn đề về MTU. Chậm dần đều thì không.
  2. Thực hiện bisect bằng ping -M do từ client đến địa chỉ public của server, sau đó ghi lại path MTU.
  3. Trừ đi 80, thiết lập MTU đó trên wg0 ở cả hai đầu, rồi kiểm tra lại quá trình truyền tải đang bị lỗi.
  4. Thêm MSS clamping trên server nếu nó chuyển tiếp lưu lượng cho các peer.
  5. Chạy mpstat -P ALL 1 trong quá trình truyền tải và đọc %soft cùng %steal.
  6. Chạy iperf3 bên ngoài tunnel và bên trong tunnel, theo cả hai hướng, với luồng đơn và với -P 4.
  7. Chạy mtr -rwc 100 đến server và tìm kiếm tình trạng mất gói tin kéo dài đến hop cuối cùng.

Chỉ thay đổi gói dịch vụ của server sau khi bước 5 cho thấy CPU đã đạt ngưỡng giới hạn. Các bước từ 1 đến 4 không tốn chi phí và giải quyết được hầu hết các báo cáo về tunnel chậm.

FAQ

Tại sao tunnel WireGuard của tôi ping nhanh nhưng tải xuống lại chậm?

Sự chênh lệch này là dấu hiệu điển hình của vấn đề MTU. Các gói tin nhỏ có thể đi qua mọi liên kết trên đường truyền, vì vậy ping và đăng nhập SSH vẫn hoạt động bình thường. Khi truyền tải dữ liệu lớn, các phân đoạn (segment) đầy đủ được gửi đi; phiên bản đóng gói (encapsulated) của chúng lớn hơn mức mà một số liên kết cho phép. Nếu router loại bỏ các gói này mà không gửi lại thông báo ICMP, hệ thống sẽ không ghi nhận mất mát và quá trình truyền tải bị treo. Hãy xác định MTU của đường truyền bằng cách dùng ping -M do theo phương pháp chia đôi (bisection) đến địa chỉ public của server, trừ đi 80 byte cho phần đóng gói, sau đó đặt kết quả đó làm MTU cho wg0 ở cả hai đầu.

Tôi nên đặt MTU bao nhiêu cho WireGuard?

Không có con số chung cho mọi trường hợp, đó là lý do tại sao giá trị mặc định 1420 không hoạt động với một số người. 1420 là 1500 trừ đi 80 byte cho header của WireGuard, header UDP và header IPv6 bên ngoài. Nếu đường truyền của bạn chịu tải dưới 1500 byte, điều thường thấy trên các kết nối PPPoE DSL hoặc bất cứ nơi nào lưu lượng đi qua một tunnel khác, bạn cần một giá trị nhỏ hơn. Hãy đo MTU của đường truyền trước, sau đó trừ đi 80.

MSS clamping có thay thế được việc thiết lập MTU không?

Không. Clamping ghi đè tùy chọn MSS trong quá trình bắt tay (handshake) TCP để cả hai đầu gửi các phân đoạn nhỏ hơn, giúp sửa lỗi TCP mà không cần can thiệp vào interface. UDP không có quá trình bắt tay để ghi đè nên không bị ảnh hưởng. Clamping cũng chỉ áp dụng cho lưu lượng mà server chuyển tiếp (forward), vì vậy các dịch vụ chạy trực tiếp trên server WireGuard sẽ không được hưởng lợi. Hãy dùng cả hai: thiết lập MTU đúng trên interface và dùng clamping để xử lý các peer mà bạn không kiểm soát được cấu hình.

Gói VPS mạnh hơn có làm WireGuard nhanh hơn không?

Chỉ khi CPU là giới hạn, và một lệnh sẽ cho bạn biết điều đó. Hãy chạy mpstat -P ALL 1 trong khi đang truyền tải dữ liệu. %soft gần 100 trên nhân CPU duy nhất của bạn nghĩa là việc xử lý gói tin đã đạt ngưỡng tối đa và thêm nhân sẽ giúp cải thiện. %steal cao nghĩa là host đang bị quá tải (oversubscribed), vì vậy giải pháp là đổi gói dịch vụ hoặc đổi nhà cung cấp. Nếu cả hai chỉ số đều thấp trong khi tunnel vẫn chậm, CPU đang rảnh rỗi và việc nâng cấp gói dịch vụ sẽ không thay đổi được gì.

Tại sao Mac của tôi chậm hơn client Linux trên cùng một mạng?

Client Linux sử dụng module WireGuard trong kernel, giúp xử lý gói tin ở không gian kernel (kernel space) và phân bổ việc mã hóa của một peer trên nhiều nhân CPU. Các ứng dụng trên macOS và iOS sử dụng wireguard-go, một triển khai ở không gian người dùng (userspace), vì các nền tảng này không cho phép ứng dụng load module kernel. Userspace phải sao chép từng gói tin giữa kernel và ứng dụng, việc sao chép này làm giảm băng thông. Khoảng cách này là điều bình thường và không có thiết lập client nào có thể khắc phục được.