{"id":65187,"date":"2023-03-27T17:40:53","date_gmt":"2023-03-27T09:40:53","guid":{"rendered":"https:\/\/version-2.com\/?p=65187"},"modified":"2024-09-13T16:31:23","modified_gmt":"2024-09-13T08:31:23","slug":"reaching-beyond-1gbps-how-we-achieved-nat-traversal-with-vanilla-wireguard","status":"publish","type":"post","link":"https:\/\/version-2.com\/zh\/2023\/03\/reaching-beyond-1gbps-how-we-achieved-nat-traversal-with-vanilla-wireguard\/","title":{"rendered":"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"65187\" class=\"elementor elementor-65187\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-65bf1a97 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"65bf1a97\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;b820a88&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-39fc5f4a\" data-id=\"39fc5f4a\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-504d7003 elementor-widget elementor-widget-text-editor\" data-id=\"504d7003\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"max-w-post-content\"><p class=\"text-base leading-normal text-left text-h3 text-black\">Nord Security engineers have been hard at work developing Meshnet, a mesh networking solution that employs the WireGuard tunneling protocol. Here are the technical details on how we tackled the challenge of optimizing Meshnet\u2019s speed.<\/p><div class=\"my-64 text-center flex justify-center\"><p><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png\" width=\"1200\" height=\"675\" \/><span style=\"box-sizing: border-box; display: inline-block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;\"><span style=\"box-sizing: border-box; display: block; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;\"><img style=\"display: block; max-width: 100%; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;\" alt=\"\" aria-hidden=\"true\" \/><\/span><img decoding=\"async\" style=\"position: absolute; inset: 0px; box-sizing: border-box; padding: 0px; border: none; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%; object-fit: contain;\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_3840,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png\" srcset=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png 1x, https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_3840,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png 2x\" alt=\"Blog thumbnail photo\" data-nimg=\"intrinsic\" \/><noscript><\/noscript><\/span><\/p><p class=\"text-nano leading-normal text-left text-center text-gray-600 my-8\">Meshnet is powered by NordLynx, a protocol based on <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Wireguard<\/a>. WireGuard is an excellent tunneling protocol. It is open, secure, lightweight, lean, and \u2013 thanks to the in-kernel implementations like in the <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/stable\/linux.git\/tree\/drivers\/net\/wireguard\" target=\"_blank\" rel=\"noopener noreferrer\">Linux kernel<\/a> or the Windows <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/git.zx2c4.com\/wireguard-nt\/about\/\" target=\"_blank\" rel=\"noopener noreferrer\">NT kernel<\/a> \u2013 really, really fast.<\/p><\/div><div class=\"style_postContent__uJLGT text-black break-words\" data-content-type-blog=\"true\"><div class=\"Article_wrapper__YyQ2_\"><div class=\"my-64 text-center\"><p><span style=\"box-sizing: border-box; display: inline-block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;\"><span style=\"box-sizing: border-box; display: block; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;\"><img style=\"display: block; max-width: 100%; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;\" alt=\"\" aria-hidden=\"true\" \/><\/span><img decoding=\"async\" style=\"position: absolute; inset: 0px; box-sizing: border-box; padding: 0px; border: none; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%; object-fit: contain;\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_3840,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog1.png\" srcset=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog1.png 1x, https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_3840,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog1.png 2x\" alt=\"natblog1\" data-nimg=\"intrinsic\" \/><img decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog1.png\" width=\"1066\" height=\"463\" \/><\/span><\/p><p>An iperf3 speed test between NordVPN\u2019s staging VPN servers with a single TCP connection tunneled over WireGuard.<\/p><\/div><p class=\"text-base leading-normal\">At the heart of it is \u201c<a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.wireguard.com\/#cryptokey-routing\" target=\"_blank\" rel=\"noopener noreferrer\">cryptokey routing<\/a>,\u201d which makes creating a tunnel almost as easy as tracking a few hundred bytes of state. So having hundreds or even thousands of tunnels from a single machine is feasible.<\/p><p class=\"text-base leading-normal\">These properties make WireGuard a very appealing building block for peer-to-peer mesh networks. But before getting there, a challenge or two must still be overcome. So let\u2019s dig into them!<\/p><h2 id=\"Ground rules\" class=\"text-h2 leading-none text-left\"><b>Ground rules<\/b><\/h2><p class=\"text-base leading-normal\">Here are ground rules to help us to better weigh tradeoffs. First, privacy and security is a priority, so any tradeoff compromising end-to-end encryption or exposing too much information is automatically off the table. Second, speed and stability is one of the most important qualities of Meshnet. Finally, to cover all major operating systems (Windows, Android, iOS, macOS, and Linux), any ideas or solutions must be implementable on those platforms.<\/p><p class=\"text-base leading-normal\">So here are the ground rules:<\/p><p class=\"text-base leading-normal\"><b>Rule #1<\/b><\/p><p class=\"text-base leading-normal\">Everything will be end-to-end encrypted. Any user data passing between devices must be inaccessible to anyone else \u2013 even to Nord Security itself.<\/p><p class=\"text-base leading-normal\"><b>Rule #2<\/b><\/p><p class=\"text-base leading-normal\">No mixing of the data plane (i.e., the code that processes packets) and control plane (i.e., the code that configures the network), if possible. That\u2019s because any additional logic (e.g., NAT traversal, packet filtering\/processing) added to the WireGuard will slow it down.<\/p><p class=\"text-base leading-normal\"><b>Rule #3<\/b><\/p><p class=\"text-base leading-normal\">No solutions that target a single WireGuard implementation. Remember those fast in-kernel implementations? In order to reach high throughput everywhere, we must be able to adapt to the intricacies of every platform.<\/p><p class=\"text-base leading-normal\">Great! Now let\u2019s get cracking!<\/p><h2 id=\"NAT traversal 101\" class=\"text-h2 leading-none text-left\"><b>NAT traversal 101<\/b><\/h2><p class=\"text-base leading-normal\">Every peer-to-peer application (including Meshnet) has a NAT traversal implementation at its heart. While this is a rather wide topic (just look at the amount of related RFCs: <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc3261\" target=\"_blank\" rel=\"noopener noreferrer\">RFC3261<\/a>, <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc4787\" target=\"_blank\" rel=\"noopener noreferrer\">RFC4787<\/a>, <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc5128\" target=\"_blank\" rel=\"noopener noreferrer\">RFC5128<\/a>, <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8489\" target=\"_blank\" rel=\"noopener noreferrer\">RFC8489<\/a>, <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8445\" target=\"_blank\" rel=\"noopener noreferrer\">RFC8445<\/a>, <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8656\" target=\"_blank\" rel=\"noopener noreferrer\">RFC8656<\/a>\u2026), the core principle is quite simple: NATs are generally designed to support outgoing connections really well.<\/p><p class=\"text-base leading-normal\">They achieve this by forwarding any outgoing packets while remembering just enough information to be able to discern where and how to forward incoming response packets whenever they arrive. The exact nature of this information and how it is used will determine the type of the NAT and its specific behavior. For example, Linux NATs are based on the conntrack kernel module and one can easily check the state of this information at any moment using the conntrack -L command.<\/p><div class=\"border-gray-300 border mb-32 \"><div class=\"bg-gray-200 p-24 border-b border-gray-300\"><div><div class=\"table-row text-black\"><p><span class=\"pr-32 text-gray-600 table-cell text-right select-none\">1<\/span><\/p><div class=\"table-cell\"><span class=\"text-black\">$ <\/span><span class=\"text-black\" style=\"color: #0e1b33;\">sudo<\/span><span class=\"text-black\"> conntrack -L <\/span><\/div><\/div><div class=\"table-row text-black\"><p><span class=\"pr-32 text-gray-600 table-cell text-right select-none\">2<\/span><\/p><div class=\"table-cell\"><span class=\"text-black\">tcp <\/span><span class=\"text-black\" style=\"color: #e09142;\">6<\/span> <span class=\"text-black\" style=\"color: #e09142;\">382155<\/span><span class=\"text-black\"> ESTABLISHED <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">src<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">192.168<\/span><span class=\"text-black\">.3.140 <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">dst<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">172.217<\/span><span class=\"text-black\">.18.3 <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">sport<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">60278<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">dport<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">443<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">src<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">172.217<\/span><span class=\"text-black\">.18.3 <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">dst<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">192.168<\/span><span class=\"text-black\">.3.140 <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">sport<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">443<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">dport<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">60278<\/span> <span class=\"text-black\" style=\"color: #6c6783;\">[<\/span><span class=\"text-black\">ASSURED<\/span><span class=\"text-black\" style=\"color: #6c6783;\">]<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">mark<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">0<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">use<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">1<\/span><\/div><\/div><div class=\"table-row text-black\"><p><span class=\"pr-32 text-gray-600 table-cell text-right select-none\">3<\/span><\/p><div class=\"table-cell\"><span class=\"text-black\">tcp <\/span><span class=\"text-black\" style=\"color: #e09142;\">6<\/span> <span class=\"text-black\" style=\"color: #e09142;\">348377<\/span><span class=\"text-black\"> ESTABLISHED <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">src<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">192.168<\/span><span class=\"text-black\">.228.204 <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">dst<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">35.85<\/span><span class=\"text-black\">.173.255 <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">sport<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">38758<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">dport<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">443<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">src<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">35.85<\/span><span class=\"text-black\">.173.255 <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">dst<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">192.168<\/span><span class=\"text-black\">.228.204 <\/span><span class=\"text-black\" style=\"color: #ffcc99;\">sport<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">443<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">dport<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">38758<\/span> <span class=\"text-black\" style=\"color: #6c6783;\">[<\/span><span class=\"text-black\">ASSURED<\/span><span class=\"text-black\" style=\"color: #6c6783;\">]<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">mark<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">0<\/span> <span class=\"text-black\" style=\"color: #ffcc99;\">use<\/span><span class=\"text-black\" style=\"color: #383c43;\">=<\/span><span class=\"text-black\" style=\"color: #e09142;\">1<\/span><\/div><\/div><div class=\"table-row text-black\"><p><span class=\"pr-32 text-gray-600 table-cell text-right select-none\">4<\/span><\/p><div class=\"table-cell\"><span class=\"text-black\" style=\"color: #6c6783;\">..<\/span><span class=\"text-black\" style=\"color: #6c6783;\">..<\/span><span class=\"text-black\" style=\"color: #6c6783;\">..<\/span><\/div><\/div><pre class=\"text-small overflow-auto\">\u00a0<\/pre><\/div><\/div><\/div><p class=\"text-base leading-normal\">This great <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc4787\" target=\"_blank\" rel=\"noopener noreferrer\">RFC4787<\/a> goes into a lot of detail about NAT behavior in general.<\/p><p class=\"text-base leading-normal\">While outgoing connections are handled transparently, incoming connections can be trouble. Without outgoing packets forwarded first (and consequently without the conntrack information), NATs simply do not have any clue where to forward packets of incoming connections and the only choice left is to drop them. At this moment, we finally arrive at the core part of any peer-to-peer connection establishment:<\/p><blockquote class=\"pl-32 border-gray-300 border-l text-gray-600 my-64\"><p class=\"text-base leading-normal\">Suppose you shoot a packet from both sides of the peer-to-peer connection at each other roughly at the same time. In this case, the connection will appear to be \u201coutgoing\u201d from the perspective of both NATs, allowing hosts to communicate.<\/p><\/blockquote><p class=\"text-base leading-normal\">Let\u2019s unpack it a bit:<\/p><ul class=\"list-disc ml-24\"><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">\u201cShoot a packet\u201d \u2013 send a UDP packet. While there are techniques regarding other protocols, only UDP packets matter in this case, as WireGuard is UDP-based. The packet\u2019s payload contents do not matter (it can even be empty), but it\u2019s important to get the headers right.<\/p><\/div><\/li><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">\u201cat each other\u201d \u2013 the packet\u2019s source and destination addresses and ports, transmitted from different sides of the connection, must mirror each other just after the first translation has been performed but before any translations by the second NAT occur. No matter what source address and port are being used by the NAT on the side for outgoing packets, the other side must send its packets to this exact address and port and vice versa. Unfortunately, some NATs make it very difficult to figure out the translations they are making, which is why NAT traversal is never 100% reliable.<\/p><\/div><\/li><li class=\"ml-20\"><div><p class=\"text-base leading-normal\">\u201croughly at the same time\u201d \u2013 the data about outgoing connections within a NAT isn\u2019t stored forever, so the packet from the other side must reach the NAT before this data disappears. The storage time greatly depends on the NAT \u2013 it varies from half a minute to a few minutes.<\/p><\/div><\/li><\/ul><div class=\"my-64 text-center\"><p><span style=\"box-sizing: border-box; display: inline-block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;\"><span style=\"box-sizing: border-box; display: block; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;\"><img style=\"display: block; max-width: 100%; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;\" alt=\"\" aria-hidden=\"true\" \/><\/span><img decoding=\"async\" style=\"position: absolute; inset: 0px; box-sizing: border-box; padding: 0px; border: none; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%; object-fit: contain;\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_3840,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/blog-how-we-achieved-nat-traversal-with-vanilla-wireguard-2.jpg\" srcset=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/blog-how-we-achieved-nat-traversal-with-vanilla-wireguard-2.jpg 1x, https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_3840,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/blog-how-we-achieved-nat-traversal-with-vanilla-wireguard-2.jpg 2x\" alt=\"blog how we achieved nat traversal with vanilla wireguard 2\" data-nimg=\"intrinsic\" \/><noscript><\/noscript><\/span><\/p><p><img decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/blog-how-we-achieved-nat-traversal-with-vanilla-wireguard-2.jpg\" width=\"1200\" height=\"802\" \/><\/p><p class=\"text-nano leading-normal text-left text-center text-gray-600 my-8\">An example NAT traversal scenario.<\/p><\/div><p class=\"text-base leading-normal\">This technique is surprisingly general. Only small bits and pieces differ within the different cases a typical peer-to-peer application needs to support.<\/p><p class=\"text-base leading-normal\">A few things need to be done right, but all of this is possible with vanilla WireGuard and the established ground rules. Take two packets and send them from the right source to the right destination at roughly the same time, without even worrying about what\u2019s inside of the packets. How hard can it be? #FamousLastWords.<\/p><h2 id=\"WG-STUN\" class=\"text-h2 leading-none text-left\"><b>WG-STUN<\/b><\/h2><p class=\"text-base leading-normal\">The key part of any NAT traversal implementation is figuring out what translations will be performed by the NAT. In some cases, there is no NAT (e.g., host on the open internet), or it is possible to simply request a NAT to perform specific translations instead (e.g., by using UPnP <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc6970\" target=\"_blank\" rel=\"noopener noreferrer\">RFC6970<\/a>, PMP <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc6886\" target=\"_blank\" rel=\"noopener noreferrer\">RFC6886<\/a>). Sometimes, the translation has to be observed in action. Luckily, a standardized protocol STUN (<a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8489\" target=\"_blank\" rel=\"noopener noreferrer\">RFC8489<\/a>) does just that.<\/p><p class=\"text-base leading-normal\">While there are some intricacies with the STUN protocol itself, the so-called STUN binding request is at its core. This binding request usually is formatted by the client behind NAT and processed by the server hosted on the open internet. Upon receiving this request, the server will look at the source IP address and port of the request packet and add it to the payload of the response packet.<\/p><div class=\"my-64 text-center\"><p><span style=\"box-sizing: border-box; display: inline-block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;\"><span style=\"box-sizing: border-box; display: block; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;\"><img style=\"display: block; max-width: 100%; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;\" alt=\"\" aria-hidden=\"true\" \/><\/span><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog3.png\" width=\"1200\" height=\"145\" \/><\/span><\/p><p>A STUN binding request captured with Wireshark.<\/p><\/div><p class=\"text-base leading-normal\">A few of the NATs will use the same translations of the source IP address regardless of the destination (let\u2019s call them \u201cfriendly NATs\u201d). The same source IP address and the source port will be used for the packets going to the STUN server and any Meshnet peer. But there is a catch! The same NAT translations will be performed only as long as the packets are using the same source IP and port for all destinations on the originating host.<\/p><p class=\"text-base leading-normal\">Here\u2019s the first challenge. Vanilla WireGuard is not capable of performing STUN requests on its own. Moreover, once WireGuard reserves a source port for communications with its peers, other programs cannot, generally, use it anymore.<\/p><p class=\"text-base leading-normal\">While it is technically possible to add STUN functionality to WireGuard, it would be in violation of our ground rule #2 and would seriously complicate the relationship with the rule #3. The search continues.<\/p><p class=\"text-base leading-normal\">The WireGuard protocol is designed to create IP tunnels. Maybe it\u2019s possible to transmit STUN requests inside of the tunnel? That way, the STUN request would get encapsulated, resulting in two IP packets: inner (STUN) and outer (WireGuard). Luckily, according to the WireGuard whitepaper, all outer packets destined to any peer should reuse the same source IP and port:<\/p><blockquote class=\"pl-32 border-gray-300 border-l text-gray-600 my-64\"><p class=\"text-base leading-normal\">Note that the listen port of peers and the source port of packets sent are always the same.<\/p><\/blockquote><p class=\"text-base leading-normal\">It\u2019s been the behavior of all WireGuard implementations tested for this blog post.<\/p><p class=\"text-base leading-normal\">Using this property, we can assume that packets destined for distinct WireGuard peers will get the same translations when going through friendly NATs. That\u2019s precisely what we need when using an external service (like STUN) to determine which translations NAT will use when communicating with Meshnet peers.<\/p><p class=\"text-base leading-normal\">But no standard STUN server can communicate with WireGuard directly. Even if we hosted a STUN server at the other end of the tunnel, after decapsulation, the server would respond with the inner packet\u2019s source IP and port \u2013 but we the need outer packet\u2019s source IP and port.<\/p><p class=\"text-base leading-normal\">Say hello to WG-STUN, a small service that maintains WireGuard tunnels with clients and waits for STUN requests inside the tunnels. When a binding request arrives, instead of looking into the binding request packet, the STUN server takes the address from the WireGuard peer itself and writes it into the STUN binding response. Later, it encapsulates the packet according to WireGuard protocol and sends it back to the client. On the client side, to figure out what translations will be performed by the NAT for the WireGuard connections, we just need to add WG-STUN peer and transmit a standard STUN request inside the tunnel.<\/p><div class=\"my-64 text-center\"><p><span style=\"box-sizing: border-box; display: inline-block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;\"><span style=\"box-sizing: border-box; display: block; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;\"><img style=\"display: block; max-width: 100%; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;\" alt=\"\" aria-hidden=\"true\" \/><\/span><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog5.png\" width=\"1200\" height=\"175\" \/><noscript><\/noscript><\/span><\/p><p class=\"text-nano leading-normal text-left text-center text-gray-600 my-8\">A Wireshark capture of a WG-STUN binding request.<\/p><\/div><p class=\"text-base leading-normal\">In the picture above, you can see a standard WG-STUN request. In this case, a STUN request was sent to 100.64.0.4, which is a reserved IP for an in-tunnel STUN service. The request got encapsulated and transmitted by WireGuard to one of the WG-STUN servers hosted by Nord Security. This WG-STUN server is just a standard WireGuard peer with the allowed IP set to 100.64.0.4\/32, and the endpoint pointed to the server itself.<\/p><div class=\"my-64 text-center\"><p><span style=\"box-sizing: border-box; display: inline-block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;\"><span style=\"box-sizing: border-box; display: block; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;\"><img style=\"display: block; max-width: 100%; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;\" alt=\"\" aria-hidden=\"true\" \/><\/span><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog6.png\" width=\"644\" height=\"243\" \/><\/span><\/p><p>\u00a0<\/p><p>A WG-STUN peer configured on Meshnet interface.<\/p><\/div><p class=\"text-base leading-normal\">Note that the WG-STUN service is, by design, a small service that is functionally incapable of doing anything other than responding to STUN requests (and ICMP for reachability testing). This way, we are bounding this service to control-plane only and adhering to rule #2. Because the WG-STUN service is just a standard peer, WireGuard\u2019s <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.wireguard.com\/xplatform\/\" target=\"_blank\" rel=\"noopener noreferrer\">cross-platform interface<\/a> is more than enough to control the WG-STUN peer in any of the WireGuard implementations (rule #3), Most importantly, due to WireGuard\u2019s encryption, we get privacy and security by default (rule #1).<\/p><h2 id=\"Path selection\" class=\"text-h2 leading-none text-left\"><b>Path selection<\/b><\/h2><p class=\"text-base leading-normal\">Now we can perform STUN with vanilla WireGuard and figure out some translations which NAT will perform, provided that our NAT is friendly NAT. Unfortunately, that\u2019s not enough to ensure good connectivity with Meshnet peers. What if there is no NAT at all? What if two NATs are in a chain, and our Meshnet peer is between them? What if a Meshnet peer is running in the VM of a local machine? What if a Meshnet peer managed to \u201cask\u201d its NAT for specific translations via UPnP? There are quite a few possible configurations here. Sometimes we call these configurations \u201cpaths,\u201d describing how one Meshnet peer can reach another. In the real world, the list of potential paths is a lot longer than the list of paths that can sustain the peer-to-peer connection.<\/p><div class=\"my-64 text-center\"><p><span style=\"box-sizing: border-box; display: inline-block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;\"><span style=\"box-sizing: border-box; display: block; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;\"><img style=\"display: block; max-width: 100%; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;\" alt=\"\" aria-hidden=\"true\" \/><\/span><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/blog-how-we-achieved-nat-traversal-with-vanilla-wireguard-7.jpg\" width=\"1200\" height=\"653\" \/><\/span><\/p><p>\u00a0<\/p><p>For example, one Meshnet peer may access the other directly if both are within the same local area network. What\u2019s more, if NAT supports hair-pinning, the same peer may be accessed via the WAN IP address of the router too. Additionally, it is common for a single host to participate in multiple networks at the same time (e.g., by virtualized networks, using multiple physical interfaces, DNATing, etc.). But it is impossible to know in advance which paths are valid and which are not.<\/p><\/div><p class=\"text-base leading-normal\">For this reason, peer-to-peer applications usually implement connectivity checks to determine which paths allow peers to reach one another (e.g., checks standardized in ICE (<a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8445\" target=\"_blank\" rel=\"noopener noreferrer\">RFC8445<\/a>), and when multiple paths pass the checks, they select the best one. These checks are usually performed in the background, separate from a data channel, to avoid interfering with the currently in-use path. For example, if two peers are connected via some relay service (e.g., TURN <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc8656\" target=\"_blank\" rel=\"noopener noreferrer\">RFC8656<\/a>), an attempt to upgrade to a better path (e.g., direct LAN), which is not validated, may cause path interruption until timeout passes and that would be deeply undesirable.<\/p><p class=\"text-base leading-normal\">While WireGuard implementations indicate the reachability of currently configured peers used for the data plane, the lightweight nature of the WireGuard protocol makes alternative path evaluation out of scope. The question is: how can we separate the data plane from connectivity checks?<\/p><p class=\"text-base leading-normal\">Considering the affordable nature of WireGuard tunnels, the most straightforward solution would be to configure two pairs of peers on each Meshnet node \u2013 one for the data plane, the other for connectivity checks. But this solution is not feasible in practice. WireGuard peers are identified by their identity (public key), and each interface has only one identity. Otherwise, cryptokey routing and roaming functionality, in its current form, would break. Moreover, mobile platforms can have at most one interface open at any moment, restricting Meshnet nodes to a single identity at a given time.<\/p><p class=\"text-base leading-normal\">So let\u2019s look for solutions elsewhere. Here\u2019s how we came to the observation which is now the core principle for performing connectivity checks out of the data plane:<\/p><blockquote class=\"pl-32 border-gray-300 border-l text-gray-600 my-64\"><p class=\"text-base leading-normal\">Given that a connection can be established using a pair of endpoints \u2013 it is highly likely that performing the same steps with a different source endpoint will succeed.<\/p><\/blockquote><p class=\"text-base leading-normal\">It is possible to force this observation not to be true, but it wouldn\u2019t be a natural occurrence. NATs will have the same mapping and filtering behavior for any pair of distinct outgoing connections. <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc4787\" target=\"_blank\" rel=\"noopener noreferrer\">RFC4787<\/a> considers NAT determinicity as a desirable property. UPnP <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc6970\" target=\"_blank\" rel=\"noopener noreferrer\">RFC6970<\/a>, PMP <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc6886\" target=\"_blank\" rel=\"noopener noreferrer\">RFC6886<\/a>, and similar protocols will behave similarly for distinct requests. LAN is almost never filtered on a per-source-port basis for outgoing connections.<\/p><p class=\"text-base leading-normal\">On the other hand, making such an assumption allows us to completely separate connectivity checks and the data plane. After performing a connectivity check out-of-band, a path upgrade can be done with a high degree of certainty of success.<\/p><p class=\"text-base leading-normal\">Therefore, in our Meshnet implementation, Meshnet nodes gather endpoints (as per ICE (RFC8445) standard) for two distinct purposes. First, to perform connectivity checks, and second, to upgrade the WireGuard connection in case connectivity checks succeed. Once the list of endpoints is known, the endpoints are exchanged between participating Meshnet nodes using relay servers. For privacy and security, the endpoint exchange messages are encrypted and authenticated using the X25519 <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/en.wikipedia.org\/wiki\/Elliptic-curve_Diffie%E2%80%93Hellman\" target=\"_blank\" rel=\"noopener noreferrer\">ECDH<\/a> algorithm and ChaCha20Poly1305 for <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/en.wikipedia.org\/wiki\/Authenticated_encryption\" target=\"_blank\" rel=\"noopener noreferrer\">AEAD<\/a>. Afterward, the connectivity checks are performed separately from WireGuard using plain old UDP sockets. If multiple endpoint candidates succeed in the connectivity check, the candidate with the lowest round-trip time is preferred.<\/p><p class=\"text-base leading-normal\">We have validated a path using some pair of endpoints, so the corresponding data plane endpoints are selected, and a path upgrade is attempted. If the upgrade fails to establish a connection, it is banned for a period of time, but if it succeeds \u2192 we have successfully established a peer-to-peer connection using vanilla WireGuard.<\/p><p class=\"text-base leading-normal\">And now we can fire up iperf3 and measure what it means. As you may have realized, we are now measuring vanilla WireGuard itself. For example, running two Meshnet nodes in docker containers on a single, rather average laptop equipped with Intel i5-8265U without any additional tweaking or tuning, we can easily surpass the 2Gbps mark for single TCP connection iperf3 test.<\/p><div class=\"my-64 text-center\"><p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog9.png\" width=\"794\" height=\"382\" \/><span style=\"box-sizing: border-box; display: inline-block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;\"><span style=\"box-sizing: border-box; display: block; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;\"><img style=\"display: block; max-width: 100%; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;\" alt=\"\" aria-hidden=\"true\" \/><\/span><img decoding=\"async\" style=\"position: absolute; inset: 0px; box-sizing: border-box; padding: 0px; border: none; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%; object-fit: contain; background-size: contain; background-position: 0% 0%; filter: blur(20px); background-image: url('https:\/\/res.cloudinary.com\/nordsec\/image\/upload\/q_auto:low,f_auto,c_scale,w_100\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/natblog9.png');\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" alt=\"natblog9\" data-nimg=\"intrinsic\" \/><noscript><\/noscript><\/span><\/p><p class=\"text-nano leading-normal text-left text-center text-gray-600 my-8\">iperf3 single TCP connection test between two Meshnet nodes.<\/p><\/div><p class=\"text-base leading-normal\">At the time of writing, the default WireGuard implementation used by Meshnet for Linux is the Linux kernel, Windows \u2013 WireGuard-NT or WireGuard-go, and for other platforms \u2013 boringtun.<\/p><h2 id=\"Conclusion\" class=\"text-h2 leading-none text-left\"><b>Conclusion<\/b><\/h2><p class=\"text-base leading-normal\">By solving a few challenges, Nord Security\u2019s Meshnet implementation managed to build a Meshnet based on WireGuard with peer-to-peer capabilities using only an <a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.wireguard.com\/xplatform\/\" target=\"_blank\" rel=\"noopener noreferrer\">xplatform<\/a> interface and the benefits of in-kernel WireGuard implementations. It surpassed the 1Gbps throughput mark. Currently, the implementation is in the process of being released, so stay tuned for a big speed upgrade!<\/p><p class=\"text-base leading-normal\"><i>Note: <\/i><a class=\"cursor-pointer outline-none transition-colors duration-250 ease-out text-blue-500 hover:text-blue-600 focus:text-blue-400\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\" rel=\"noopener noreferrer\"><i>WireGuard<\/i><\/a><i> and the &#8220;WireGuard&#8221; logo are registered trademarks of Jason A. Donenfeld.<\/i><\/p><\/div><\/div><\/div>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-afb4126 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"afb4126\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;f92550e&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-827c95a\" data-id=\"827c95a\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-fe7f1f7 elementor-widget elementor-widget-shortcode\" data-id=\"fe7f1f7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\t\t<div data-elementor-type=\"page\" data-elementor-id=\"18103\" class=\"elementor elementor-18103\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-748947f elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"748947f\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-7995c19\" data-id=\"7995c19\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-a437045 elementor-widget elementor-widget-image-box\" data-id=\"a437045\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-image-box-wrapper\"><div class=\"elementor-image-box-content\"><h3 class=\"elementor-image-box-title\">About Version 2 Digital<\/h3><p class=\"elementor-image-box-description\">Version 2 Digital is one of the most dynamic IT companies in Asia. The company distributes a wide range of IT products across various areas including cyber security, cloud, data protection, end points, infrastructures, system monitoring, storage, networking, business productivity and communication products.\n<br><br>\nThrough an extensive network of channels, point of sales, resellers, and partnership companies, Version 2 offers quality products and services which are highly acclaimed in the market. Its customers cover a wide spectrum which include Global 1000 enterprises, regional listed companies, different vertical industries, public utilities, Government, a vast number of successful SMEs, and consumers in various Asian cities.<\/p><\/div><\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t\n\t\t<div data-elementor-type=\"page\" data-elementor-id=\"63561\" class=\"elementor elementor-63561\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-1b6aa2c4 elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"1b6aa2c4\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[{&quot;_id&quot;:&quot;c4f773e&quot;,&quot;jet_parallax_layout_image&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_tablet&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_image_mobile&quot;:{&quot;url&quot;:&quot;&quot;,&quot;id&quot;:&quot;&quot;,&quot;size&quot;:&quot;&quot;},&quot;jet_parallax_layout_speed&quot;:{&quot;unit&quot;:&quot;%&quot;,&quot;size&quot;:50,&quot;sizes&quot;:[]},&quot;jet_parallax_layout_type&quot;:&quot;scroll&quot;,&quot;jet_parallax_layout_direction&quot;:&quot;1&quot;,&quot;jet_parallax_layout_fx_direction&quot;:null,&quot;jet_parallax_layout_z_index&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x&quot;:50,&quot;jet_parallax_layout_bg_x_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_x_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y&quot;:50,&quot;jet_parallax_layout_bg_y_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_y_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size&quot;:&quot;auto&quot;,&quot;jet_parallax_layout_bg_size_tablet&quot;:&quot;&quot;,&quot;jet_parallax_layout_bg_size_mobile&quot;:&quot;&quot;,&quot;jet_parallax_layout_animation_prop&quot;:&quot;transform&quot;,&quot;jet_parallax_layout_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;]}]}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-1b283ee5\" data-id=\"1b283ee5\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-4e466f1a elementor-widget elementor-widget-text-editor\" data-id=\"4e466f1a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><strong>About NordLayer<br \/><\/strong>NordLayer is an adaptive network access security solution for modern businesses \u2013 from the world\u2019s most trusted cybersecurity brand, Nord Security.<\/p><p>The web has become a chaotic space where safety and trust have been compromised by cybercrime and data protection issues. Therefore, our team has a global mission to shape a more trusted and peaceful online future for people everywhere.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Nord Security engineers have been hard at work developi [&hellip;]<\/p>\n","protected":false},"author":148637484,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[973,1075,1130,61],"tags":[974,1076,1132],"class_list":["post-65187","post","type-post","status-publish","format-standard","hentry","category-nord-security","category-year2023","category-nordlayer","category-press-release","tag-nord-security","tag-1076","tag-nordlayer"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard - Version 2<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps\" \/>\n<meta property=\"og:locale\" content=\"zh_HK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard - Version 2\" \/>\n<meta property=\"og:description\" content=\"Nord Security engineers have been hard at work developi [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps\" \/>\n<meta property=\"og:site_name\" content=\"Version 2\" \/>\n<meta property=\"article:published_time\" content=\"2023-03-27T09:40:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-13T08:31:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png\" \/>\n<meta name=\"author\" content=\"versionpan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"versionpan\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9810\u8a08\u95b1\u8b80\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 \u5206\u9418\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/03\\\/reaching-beyond-1gbps-how-we-achieved-nat-traversal-with-vanilla-wireguard\\\/\"},\"author\":{\"name\":\"versionpan\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/103ffe36f7fd34a1cc126a30431b94d8\"},\"headline\":\"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard\",\"datePublished\":\"2023-03-27T09:40:53+00:00\",\"dateModified\":\"2024-09-13T08:31:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/03\\\/reaching-beyond-1gbps-how-we-achieved-nat-traversal-with-vanilla-wireguard\\\/\"},\"wordCount\":2650,\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/nordsec\\\/f_auto,c_limit,w_1200,q_auto\\\/v1\\\/nord-security-web\\\/blog\\\/categories\\\/engineering\\\/2023\\\/03\\\/Blog_thumbnail_photo.png\",\"keywords\":[\"Nord Security\",\"2023\",\"NordLayer\"],\"articleSection\":[\"Nord Security\",\"2023\",\"NordLayer\",\"Press Release\"],\"inLanguage\":\"zh-HK\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/version-2.com\\\/2023\\\/03\\\/reaching-beyond-1gbps-how-we-achieved-nat-traversal-with-vanilla-wireguard\\\/\",\"url\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps\",\"name\":\"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard - Version 2\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/nordsec\\\/f_auto,c_limit,w_1200,q_auto\\\/v1\\\/nord-security-web\\\/blog\\\/categories\\\/engineering\\\/2023\\\/03\\\/Blog_thumbnail_photo.png\",\"datePublished\":\"2023-03-27T09:40:53+00:00\",\"dateModified\":\"2024-09-13T08:31:23+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps#breadcrumb\"},\"inLanguage\":\"zh-HK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps#primaryimage\",\"url\":\"https:\\\/\\\/res.cloudinary.com\\\/nordsec\\\/f_auto,c_limit,w_1200,q_auto\\\/v1\\\/nord-security-web\\\/blog\\\/categories\\\/engineering\\\/2023\\\/03\\\/Blog_thumbnail_photo.png\",\"contentUrl\":\"https:\\\/\\\/res.cloudinary.com\\\/nordsec\\\/f_auto,c_limit,w_1200,q_auto\\\/v1\\\/nord-security-web\\\/blog\\\/categories\\\/engineering\\\/2023\\\/03\\\/Blog_thumbnail_photo.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/nordsecurity.com\\\/blog\\\/reaching-beyond-1gbps#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9801\",\"item\":\"https:\\\/\\\/version-2.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#website\",\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\",\"name\":\"Version 2\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/version-2.com\\\/zh\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"zh-HK\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#organization\",\"name\":\"Version 2\",\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/version-2.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/version-2.com\\\/wp-content\\\/uploads\\\/2020\\\/08\\\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1\",\"width\":1795,\"height\":335,\"caption\":\"Version 2\"},\"image\":{\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/version-2.com\\\/zh\\\/#\\\/schema\\\/person\\\/103ffe36f7fd34a1cc126a30431b94d8\",\"name\":\"versionpan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-HK\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g\",\"caption\":\"versionpan\"},\"url\":\"https:\\\/\\\/version-2.com\\\/zh\\\/author\\\/versionpan\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard - Version 2","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps","og_locale":"zh_HK","og_type":"article","og_title":"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard - Version 2","og_description":"Nord Security engineers have been hard at work developi [&hellip;]","og_url":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps","og_site_name":"Version 2","article_published_time":"2023-03-27T09:40:53+00:00","article_modified_time":"2024-09-13T08:31:23+00:00","og_image":[{"url":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png","type":"","width":"","height":""}],"author":"versionpan","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"versionpan","\u9810\u8a08\u95b1\u8b80\u6642\u9593":"18 \u5206\u9418"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps#article","isPartOf":{"@id":"https:\/\/version-2.com\/2023\/03\/reaching-beyond-1gbps-how-we-achieved-nat-traversal-with-vanilla-wireguard\/"},"author":{"name":"versionpan","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/103ffe36f7fd34a1cc126a30431b94d8"},"headline":"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard","datePublished":"2023-03-27T09:40:53+00:00","dateModified":"2024-09-13T08:31:23+00:00","mainEntityOfPage":{"@id":"https:\/\/version-2.com\/2023\/03\/reaching-beyond-1gbps-how-we-achieved-nat-traversal-with-vanilla-wireguard\/"},"wordCount":2650,"publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"image":{"@id":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png","keywords":["Nord Security","2023","NordLayer"],"articleSection":["Nord Security","2023","NordLayer","Press Release"],"inLanguage":"zh-HK"},{"@type":"WebPage","@id":"https:\/\/version-2.com\/2023\/03\/reaching-beyond-1gbps-how-we-achieved-nat-traversal-with-vanilla-wireguard\/","url":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps","name":"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard - Version 2","isPartOf":{"@id":"https:\/\/version-2.com\/zh\/#website"},"primaryImageOfPage":{"@id":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps#primaryimage"},"image":{"@id":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png","datePublished":"2023-03-27T09:40:53+00:00","dateModified":"2024-09-13T08:31:23+00:00","breadcrumb":{"@id":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps#breadcrumb"},"inLanguage":"zh-HK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps"]}]},{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps#primaryimage","url":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png","contentUrl":"https:\/\/res.cloudinary.com\/nordsec\/f_auto,c_limit,w_1200,q_auto\/v1\/nord-security-web\/blog\/categories\/engineering\/2023\/03\/Blog_thumbnail_photo.png"},{"@type":"BreadcrumbList","@id":"https:\/\/nordsecurity.com\/blog\/reaching-beyond-1gbps#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9801","item":"https:\/\/version-2.com\/"},{"@type":"ListItem","position":2,"name":"Reaching beyond 1Gbps: How we achieved NAT traversal with vanilla WireGuard"}]},{"@type":"WebSite","@id":"https:\/\/version-2.com\/zh\/#website","url":"https:\/\/version-2.com\/zh\/","name":"Version 2","description":"","publisher":{"@id":"https:\/\/version-2.com\/zh\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/version-2.com\/zh\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"zh-HK"},{"@type":"Organization","@id":"https:\/\/version-2.com\/zh\/#organization","name":"Version 2","url":"https:\/\/version-2.com\/zh\/","logo":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/version-2.com\/zh\/#\/schema\/logo\/image\/","url":"https:\/\/i0.wp.com\/version-2.com\/wp-content\/uploads\/2020\/08\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1","contentUrl":"https:\/\/i0.wp.com\/version-2.com\/wp-content\/uploads\/2020\/08\/v2-hk-hor-4.png?fit=1795%2C335&ssl=1","width":1795,"height":335,"caption":"Version 2"},"image":{"@id":"https:\/\/version-2.com\/zh\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/version-2.com\/zh\/#\/schema\/person\/103ffe36f7fd34a1cc126a30431b94d8","name":"versionpan","image":{"@type":"ImageObject","inLanguage":"zh-HK","@id":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/72541e15024f6716236decb252e7488d4a7359d4df6f8506b01f447174f92c7c?s=96&d=identicon&r=g","caption":"versionpan"},"url":"https:\/\/version-2.com\/zh\/author\/versionpan\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pbQRKm-gXp","post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/65187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/users\/148637484"}],"replies":[{"embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/comments?post=65187"}],"version-history":[{"count":8,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/65187\/revisions"}],"predecessor-version":[{"id":65195,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/posts\/65187\/revisions\/65195"}],"wp:attachment":[{"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/media?parent=65187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/categories?post=65187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/version-2.com\/zh\/wp-json\/wp\/v2\/tags?post=65187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}