{"id":196,"date":"2020-11-22T01:54:12","date_gmt":"2020-11-21T17:54:12","guid":{"rendered":"https:\/\/blog.swineson.me\/en\/?p=196"},"modified":"2021-02-22T23:04:12","modified_gmt":"2021-02-22T15:04:12","slug":"interoperating-cisco-dmvpn-huawei-dsvpn-and-opennhrp","status":"publish","type":"post","link":"https:\/\/blog.swineson.me\/en\/interoperating-cisco-dmvpn-huawei-dsvpn-and-opennhrp\/","title":{"rendered":"Interoperating Cisco DMVPN, Huawei DSVPN and OpenNHRP"},"content":{"rendered":"<p>Traditional point-to-point site-to-site VPN protocols require extensive setup in certain use cases. For example, if you want shortcuts between branch offices rather than let every packet go through the HQ, then you need to set up a cartesian product of tunnels by hand, which is time-consuming and error prone. So, people want something better, something easy to set up and maintain, and dynamic enough. While there are already a lot dynamic point-to-multipoint or full-mesh site-to-site VPN implementations (e.g. <a href=\"https:\/\/www.tinc-vpn.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Tinc VPN<\/a>, <a href=\"https:\/\/www.zerotier.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">ZeroTier<\/a>) on Linux, you don&#8217;t have many choices on these commercial black boxes.<\/p>\n<p>Cisco DMVPN (Cisco Dynamic Multipoint VPN) is one solution to this. Huawei also had their DMVPN-compatible solution called DSVPN (Dynamic Smart VPN). Since the protocol is largely compatible, I&#8217;ll just reference it as DMVPN.<\/p>\n<p><!--more--><\/p>\n<h1>On the DMVPN Protocol<\/h1>\n<p>Strictly speaking, DMVPN is not one protocol, but is stitched from 4 protocols:<\/p>\n<ul>\n<li>Multipoint GRE (mGRE)<\/li>\n<li>Next Hop Resolution Protocol (NHRP) <strong>inside<\/strong> mGRE<\/li>\n<li>(Optional) IPSec encryption <strong>outside<\/strong> mGRE<\/li>\n<li>(Optional) another routing protocol, typically OSPF<\/li>\n<\/ul>\n<h2>Multipoint GRE<\/h2>\n<p>Multipoint GRE is just plain GRE but with a mapping of inside destination IPs to outside destination IPs. It doesn&#8217;t have a single remote tunnel endpoint IP, instead we need to have some external protocol to fill its IP mapping (like the ARP protocol to the Ethernet).<\/p>\n<h2>Next Hop Resolution Protocol<\/h2>\n<p>NHRP is a protocol which can automatically fill the mGRE tunnel&#8217;s IP mapping, it&#8217;s the ARP for mGRE. It works in a straightforward way: some (usually 1 or 2) devices are designated as hubs (NHS, Next Hop Server), while others are all spokes. Hubs does not have any mapping information while NHRP daemon is started, and spokes have statically configured mapping of all hubs&#8217; IP mapping information. When spokes&#8217; NHRP daemon is started, the daemon sends registration packets to the hubs, announcing its existence, its own external and internal IPs and optionally some other routes. When spokes try to connect to each other, they query the packet destination&#8217;s external IP addresses with the hub and try to directly connect them with GRE. If the other end is not reachable, packet is routed to the hub then to the destination.<\/p>\n<h2>IPSec<\/h2>\n<p>IPSec is a protocol mainly used to transparently encrypt IP packets. I&#8217;m not going to talk about it since it is not the point of this article.<\/p>\n<h2>Routing Protocol<\/h2>\n<p>NHRP is not suitable for distributing a lot routes with it. For mid-sized or larger networks, we usually only use NHRP to resolve tunnel endpoint IPs, and use another routing protocol (RIP, OSPF or BGP) for routing the client networks.<\/p>\n<h2>Security<\/h2>\n<p>Since DMVPN can run without IPSec, if the NHRP daemon implementation is flawed, there is possibility that one plain unprotected tunnel can register successfully thus resulting in a downgrade attack.<\/p>\n<h1>Lab Setup<\/h1>\n<p>There are already example setups on the wild Internet using a Cisco router as the hub and other Cisco\/Huawei devices as the spokes (see the references section). Today we try using Huawei USG firewall as the hub. All configurations are provided in 2 parts, one for plaintext mGRE\/NHRP, and one for adding IPSec protection to the existing tunnel.<\/p>\n<p>Security warnings first:<\/p>\n<ul>\n<li>DO NOT use the plaintext config in production! If you want to capture NHRP packets in a lab environment, use this config. It is not secure for production traffic.<\/li>\n<li>DO NOT blindly copy the IPSec ciphers for production. Use strong GCM ciphers and enable PFS if your devices support them.<\/li>\n<\/ul>\n<p>And some notes on cross-vendor compatibility:<\/p>\n<ul>\n<li>Huawei devices send L3MTU as OSPF MTU, and other vendors send L2MTU, so we ignore MTU by default in OSPF config<\/li>\n<li>The maximum MTU of Huawei USG firewalls is 1500, so we just use 1500 for every device<\/li>\n<\/ul>\n<h2>Hub &#8211; Huawei USG<\/h2>\n<p>Test gear: Huawei USG6320, software version V500R005C00SPC200<\/p>\n<p>If you config DSVPN from the USG web interface, here is a quick lookup table for you:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 33.3333%;\">Huawei (English)<\/td>\n<td style=\"width: 33.3333%;\">Huawei (\u4e2d\u6587)<\/td>\n<td style=\"width: 33.3333%;\">Other Vendors<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">Reverse Routes from Branches<\/td>\n<td style=\"width: 33.3333%;\">\u603b\u90e8\u4ece\u5206\u652f\u5b66\u4e60\u53cd\u5411\u8def\u7531<\/td>\n<td style=\"width: 33.3333%;\">send static routes with NHRP<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">Mutual Route Learning<\/td>\n<td style=\"width: 33.3333%;\">\u5206\u652f\u8282\u70b9\u76f8\u4e92\u5b66\u4e60\u8def\u7531<\/td>\n<td style=\"width: 33.3333%;\">no shortcut<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">Route Aggregation to HQ<\/td>\n<td style=\"width: 33.3333%;\">\u5206\u652f\u8282\u70b9\u8def\u7531\u6c47\u805a\u5230\u603b\u90e8<\/td>\n<td style=\"width: 33.3333%;\">shortcut<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Plain Text<\/h3>\n<pre class=\"lang:default decode:true\">interface Tunnel0\r\n description hub\r\n ip address 192.168.1.1 255.255.255.0\r\n tunnel-protocol gre p2mp\r\n source GigabitEthernet0\/0\/0\r\n ospf network-type broadcast\r\n ospf dr-priority 2\r\n alias dsvpn-hub-test\r\n service-manage ping permit\r\n nhrp network-id 1000\r\n nhrp authentication plain 114514\r\n nhrp redirect\r\n nhrp entry multicast dynamic\r\n undo nhrp hub reverse-route enable\r\nospf 1\r\n area 0.0.0.0\r\n  network 192.168.1.0 0.0.0.255<\/pre>\n<h3>With IPSec<\/h3>\n<pre class=\"lang:default decode:true\">ipsec sha2 compatible enable\r\nike dpd type periodic\r\nipsec proposal proposal_1\r\n encapsulation-mode auto\r\n esp authentication-algorithm sha2-256\r\n esp encryption-algorithm aes-256\r\nike proposal 1\r\n encryption-algorithm aes-256\r\n dh group14\r\n authentication-algorithm sha2-256\r\n authentication-method pre-share\r\n integrity-algorithm hmac-sha2-256\r\n prf hmac-sha2-256\r\nike peer peer_1\r\n exchange-mode auto\r\n pre-shared-key 114514\r\n ike-proposal 1\r\n dpd type periodic\r\nipsec profile profile_1\r\n ike-peer peer_1\r\n proposal proposal_1\r\n sa duration traffic-based 5242880\r\n sa duration time-based 3600\r\ninterface Tunnel0\r\n ipsec profile profile_1\r\n<\/pre>\n<h3>Security<\/h3>\n<p>Even if the DMVPN tunnel is configured to use IPSec, a cleartext NHRP request will still result in a NHRP neighbor entry. You are not able to send any packets through the tunnel, though. (This might lead to buffer overflow vulnerabilities from unsolicited NHRP peers.)<\/p>\n<h3>Caveats<\/h3>\n<ul>\n<li>NHRP redirect &amp; multicast config is only available in CLI<\/li>\n<li>OSPF network type can only be broadcast (non-configurable)<\/li>\n<li>OSPF MTU ignore is not user-configurable<\/li>\n<li>MTU is not user-configurable (1500 hardcoded)<\/li>\n<li>Huawei never officially said DSVPN is compatible with DMVPN, so the compatibility is not guaranteed<\/li>\n<li>If an IP address of the same subnet as the one configured on the DMVPN interface doesn&#8217;t have a NHRP entry, an USG spoke will send it to the HUB<\/li>\n<\/ul>\n<p>Huawei extensions to NHRP protocol (use <span class=\"lang:default highlight:0 decode:true crayon-inline\">undo nhrp identity enable<\/span><span style=\"font-size: 1rem;\"> to disable):<\/span><\/p>\n<ul>\n<li>1024 (0x0400): 0-byte padding<\/li>\n<li>1025 (0x0401): device identity (string, length 1-31 bytes, default value is hostname)<\/li>\n<li>1026 (0x0402): 0-byte padding<\/li>\n<li>1027 (0x0403): device serial number (string, 20 bytes)<\/li>\n<\/ul>\n<p>BTW, one free advice for you: if you have two DSVPN instances mapped to one OSPF process from the CLI, do not try to edit DSVPN config from the web; this will lead to unexpected results.<\/p>\n<h2>Spoke 1 &#8211; Cisco IOS XE<\/h2>\n<p>Test gear: Cisco CSR1000v, software IOS XE 16.9.4<\/p>\n<h3>Plain Text<\/h3>\n<pre class=\"lang:default decode:true\">interface Tunnel0\r\n ip address 192.168.1.2 255.255.255.0\r\n no ip redirects\r\n ip mtu 1500\r\n ip nhrp authentication 114514\r\n ip nhrp network-id 1000\r\n ip nhrp holdtime 30\r\n ip nhrp nhs 192.168.1.1 nbma 10.0.0.1 multicast\r\n ip nhrp registration no-unique\r\n ip ospf network broadcast\r\n ip ospf priority 0\r\n ip ospf mtu-ignore\r\n qos pre-classify\r\n tunnel source GigabitEthernet1\r\n tunnel mode gre multipoint\r\nrouter ospf 1\r\n network 192.168.1.0 0.0.0.255 area 0<\/pre>\n<h3>With IPSec<\/h3>\n<pre class=\"lang:default decode:true\">crypto isakmp policy 10\r\n encr aes 256\r\n hash sha256\r\n authentication pre-share\r\n group 14\r\ncrypto isakmp key 114514 address 0.0.0.0 no-xauth\r\ncrypto isakmp keepalive 30 10 periodic\r\ncrypto isakmp diagnose error\r\ncrypto ipsec transform-set dsvpn esp-aes 256 esp-sha256-hmac\r\n mode tunnel\r\ncrypto ipsec profile dsvpn\r\n set transform-set dsvpn\r\ninterface Tunnel0\r\n tunnel protection ipsec profile dsvpn<\/pre>\n<h3>Security<\/h3>\n<p>Not tested.<\/p>\n<h3>Caveats<\/h3>\n<p>NHRP network-id or NHRP domain is just a process ID; it is only used locally, but if you don&#8217;t configure it, NHRP process will be down forever.<\/p>\n<p>The tunnel&#8217;s L2MTU will be hardcoded to 9976 and you cannot configure it. (Note that the transport MTU will be the correct value i.e. 1476, and you can still manually set the L3MTU.) So we explicitly set OSPF to ignore MTU mismatches.<\/p>\n<p>On older devices, the config line<\/p>\n<pre class=\"lang:default decode:true\">ip nhrp nhs 192.168.1.1 nbma 10.0.0.1 multicast<\/pre>\n<p>should be replaced with the old grammar<\/p>\n<pre class=\"lang:default decode:true\">ip nhrp map 192.168.1.1 10.0.0.1\r\nip nhrp map multicast 10.0.0.1\r\nip nhrp nhs 192.168.1.1\r\n<\/pre>\n<h2>Spoke 2 &#8211; VyOS<\/h2>\n<p>Test gear: VyOS 1.2.6 (with patch) \/ VyOS 1.3 nightly (official)<\/p>\n<h3>Plain Text<\/h3>\n<pre class=\"lang:default decode:true \">top\r\nedit interface tunnel tun0\r\nset address '192.168.1.3\/24'\r\nset encapsulation 'gre'\r\nset ip ospf network broadcast\r\nset local-ip '10.0.0.3'\r\nset mtu 1512\r\nset multicast 'enable'\r\n\r\ntop\r\nedit protocols nhrp tunnel tun0\r\nset cisco-authentication '114514'\r\nset holding-time '10'\r\nset map 192.168.1.1\/24 nbma-address '10.0.0.1'\r\nset map 192.168.1.1\/24 register\r\nset map 192.168.1.1\/24 cisco\r\nset multicast 'dynamic'\r\nset redirect<\/pre>\n<h3>With IPSec<\/h3>\n<pre class=\"lang:default decode:true\">top\r\nedit vpn ipsec esp-group dmvpn\r\nset compression 'disable'\r\nset lifetime '3600'\r\nset mode 'tunnel'\r\nset pfs 'enable'\r\nset proposal 1 encryption 'aes256'\r\nset proposal 1 hash 'sha256'\r\n\r\ntop\r\nedit vpn ipsec ike-group dmvpn\r\nset close-action 'restart'\r\nset dead-peer-detection action 'restart'\r\nset dead-peer-detection interval '15'\r\nset dead-peer-detection timeout '30'\r\nset key-exchange 'ikev1'\r\nset lifetime '86400'\r\nset proposal 1 dh-group '14'\r\nset proposal 1 encryption 'aes256'\r\nset proposal 1 hash 'sha256'\r\n\r\ntop\r\nedit vpn ipsec profile dmvpn\r\nset authentication mode 'pre-shared-secret'\r\nset authentication pre-shared-secret '114514'\r\nset bind tunnel tun0\r\nset esp-group 'dmvpn'\r\nset ike-group 'dmvpn'\r\n\r\ntop\r\nset vpn ipsec ipsec-interfaces interface 'eth0'<\/pre>\n<h3>Security<\/h3>\n<p>Current OpenNHRP&#8217;s IPSec configuration works by first generating a IPSec config without local\/remote IPs to StrongSwan, then after a neighbor is discovered, use swanctl with local\/remote IP override to create a dynamic IPSec peer. If the IPSec tunnel is down for some reason, it won&#8217;t be restarted, resulting in packets being sent in cleartext. Due to this reason, I do not recommend using VyOS for DMVPN in production networks.<\/p>\n<h3>Caveats<\/h3>\n<p>OpenNHRP implementation from VyOS 1.2.6 is not compatible with Huawei&#8217;s NHRP implementation. If you really want to use VyOS together with Huawei devices, you need to apply <a href=\"https:\/\/github.com\/Jamesits\/vyos-opennhrp\/commit\/f45bca308bf9a1512eb035544b54710174bf7a6f\" target=\"_blank\" rel=\"noopener noreferrer\">this patch<\/a>. First we need to compile it. On a Debian 8 (jessie):<\/p>\n<pre class=\"lang:sh decode:true\">apt install git build-essential debhelper libc-ares-dev pkg-config\r\nmkdir opennhrp\r\ncd opennhrp \r\ngit clone https:\/\/github.com\/Jamesits\/vyos-opennhrp.git\r\ncd vyos-opennhrp\r\ndpkg-buildpackage -us -uc\r\n<\/pre>\n<p>Then install it onto VyOS:<\/p>\n<pre class=\"lang:sh decode:true\">dpkg -i vyos-opennhrp_0.14.1-1+vyos3+equuleus1_amd64.deb\r\nreboot<\/pre>\n<p>The patch will be available for the current running VyOS image.<\/p>\n<h2>Spoke 3 &#8211; Huawei AR Router<\/h2>\n<p>Test gear: Huawei AR6121-S, VRP 5.170 (V300R019C10SPC300)<\/p>\n<h3>Plain Text<\/h3>\n<pre class=\"lang:default decode:true\">interface Tunnel0\/0\/1\r\n description DSVPN\r\n ip address 192.168.1.4 255.255.255.0\r\n tunnel-protocol gre p2mp\r\n source GigabitEthernet0\/0\/0\r\n ospf network-type broadcast\r\n ospf dr-priority 0\r\n nhrp authentication cipher 114514\r\n nhrp tunnel-if-state related\r\n nhrp registration no-unique\r\n nhrp registration interval 30\r\n nhrp entry 192.168.1.1 10.0.0.1 register preference 10<\/pre>\n<h3>With IPSec<\/h3>\n<pre class=\"lang:default decode:true\">ipsec authentication sha2 compatible enable\r\nipsec proposal dsvpn\r\n esp authentication-algorithm sha2-256\r\n esp encryption-algorithm aes-256\r\nike proposal 1\r\n encryption-algorithm aes-256\r\n dh group14\r\n authentication-algorithm sha2-256\r\n authentication-method pre-share\r\n integrity-algorithm hmac-sha2-256\r\n prf hmac-sha2-256\r\nike peer dsvpn\r\n exchange-mode auto\r\n pre-shared-key cipher 114514\r\n ike-proposal 1\r\n dpd type periodic\r\n dpd idle-time 12\r\n dpd retransmit-interval 5\r\n rsa encryption-padding oaep\r\n rsa signature-padding pss\r\n ikev2 authentication sign-hash sha2-256\r\nipsec profile dsvpn 1\r\n ike-peer dsvpn\r\n proposal dsvpn\r\n sa duration traffic-based 5242880\r\n sa duration time-based 3600\r\ninterface Tunnel0\/0\/1\r\n ipsec profile dsvpn shared<\/pre>\n<h3>Security<\/h3>\n<p>Not tested.<\/p>\n<h3>Caveats<\/h3>\n<p>For an AR router to connect to other routers successfully with IPSec, <span class=\"lang:default highlight:0 decode:true crayon-inline \">ipsec authentication sha2 compatible enable<\/span> might be required.<\/p>\n<p>If IPSec tunnel mode is required (e.g. spoke is behind NAT), manually switch to tunnel mode:<\/p>\n<pre class=\"lang:default decode:true \">ipsec proposal dsvpn\r\n encapsulation-mode tunnel<\/pre>\n<p>Unlike an USG, an AR does not support encapsulation mode auto negotiation.<\/p>\n<p>If an IP address of the same subnet as the one configured on the DMVPN interface doesn&#8217;t have a NHRP entry, an AR spoke will drop it, which would cause some problems in certain topologies.<\/p>\n<h1>Notes<\/h1>\n<p>References:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.pluralsight.com\/blog\/it-ops\/multipoint-gre-tunnel-introduction\" target=\"_blank\" rel=\"noopener noreferrer\">Introduction to Multipoint GRE and NHRP<\/a><\/li>\n<li><a href=\"https:\/\/forum.huawei.com\/enterprise\/en\/establishing-a-dsvpn-over-the-ipsec-tunnel-between-ar-and-cisco\/thread\/390771-863\" target=\"_blank\" rel=\"noopener noreferrer\">Establishing a DSVPN over the IPSec tunnel between AR and Cisco<\/a><\/li>\n<li><a href=\"https:\/\/www.cisco.com\/c\/en\/us\/td\/docs\/ios-xml\/ios\/sec_conn_dmvpn\/configuration\/15-mt\/sec-conn-dmvpn-15-mt-book\/sec-conn-dmvpn-dmvpn.html\" target=\"_blank\" rel=\"noopener noreferrer\">Dynamic Multipoint VPN Configuration Guide, Cisco IOS Release 15M&amp;T<\/a><\/li>\n<li><a href=\"https:\/\/support.huawei.com\/hedex\/hdx.do?lib=EDOC1100122844AZJ0102D&amp;docid=EDOC1100122844&amp;lang=zh&amp;v=04&amp;tocLib=EDOC1100122844AZJ0102D&amp;tocV=04&amp;id=ZH-CN_CONCEPT_0178924237&amp;tocURL=resources%2525252Fadmin%2525252Fsec_admin_dsvpn_0001.html&amp;p=t&amp;fe=1&amp;ui=3&amp;keyword=dsvpn\" target=\"_blank\" rel=\"noopener noreferrer\">DSVPN<\/a><\/li>\n<li><a href=\"https:\/\/www.cisco.com\/c\/en\/us\/td\/docs\/ios-xml\/ios\/ipaddr_nhrp\/configuration\/xe-3s\/nhrp-xe-3s-book.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">IP Addressing: NHRP Configuration Guide, Cisco IOS XE Release 3S<\/a><\/li>\n<li><a href=\"https:\/\/www.ciscolive.com\/c\/dam\/r\/ciscolive\/us\/docs\/2015\/pdf\/BRKCCIE-3003.pdf\">DMVPN for R&amp;S CCIE Candidates &#8211; Johnny Bass &#8211; BRKCCIE-3003<\/a><\/li>\n<li><a href=\"https:\/\/support.huawei.com\/hedex\/pages\/EDOC1100087046AZJ0324D\/09\/EDOC1100087046AZJ0324D\/09\/resources\/dc\/cmdqueryname=ipsec+authentication+sha2+compatible+enable\" target=\"_blank\" rel=\"noopener\">\u914d\u7f6eIPSec\u5b89\u5168\u63d0\u8bae<\/a><\/li>\n<\/ul>\n<div class=\"ms-editor-squiggler\" style=\"color: initial; font: initial; font-feature-settings: initial; font-kerning: initial; font-optical-sizing: initial; font-variation-settings: initial; text-orientation: initial; text-rendering: initial; -webkit-font-smoothing: initial; -webkit-locale: initial; -webkit-text-orientation: initial; -webkit-writing-mode: initial; writing-mode: initial; zoom: initial; place-content: initial; place-items: initial; place-self: initial; alignment-baseline: initial; animation: initial; appearance: initial; aspect-ratio: initial; backdrop-filter: initial; backface-visibility: initial; background: initial; background-blend-mode: initial; baseline-shift: initial; block-size: initial; border-block: initial; border: initial; border-radius: initial; border-collapse: initial; border-inline: initial; inset: initial; box-shadow: initial; box-sizing: initial; break-after: initial; break-before: initial; break-inside: initial; buffered-rendering: initial; caption-side: initial; caret-color: initial; clear: initial; clip: initial; clip-path: initial; clip-rule: initial; color-interpolation: initial; color-interpolation-filters: initial; color-rendering: initial; color-scheme: initial; columns: initial; column-fill: initial; gap: initial; column-rule: initial; column-span: initial; contain: initial; contain-intrinsic-size: initial; content: initial; content-visibility: initial; counter-increment: initial; counter-reset: initial; counter-set: initial; cursor: initial; cx: initial; cy: initial; d: initial; display: block; dominant-baseline: initial; empty-cells: initial; fill: initial; fill-opacity: initial; fill-rule: initial; filter: initial; flex: initial; flex-flow: initial; float: initial; flood-color: initial; flood-opacity: initial; grid: initial; grid-area: initial; height: initial; hyphens: initial; image-orientation: initial; image-rendering: initial; inline-size: initial; inset-block: initial; inset-inline: initial; isolation: initial; letter-spacing: initial; lighting-color: initial; line-break: initial; list-style: initial; margin-block: initial; margin: initial; margin-inline: initial; marker: initial; mask: initial; mask-type: initial; max-block-size: initial; max-height: initial; max-inline-size: initial; max-width: initial; min-block-size: initial; min-height: initial; min-inline-size: initial; min-width: initial; mix-blend-mode: initial; object-fit: initial; object-position: initial; offset: initial; opacity: initial; order: initial; origin-trial-test-property: initial; orphans: initial; outline: initial; outline-offset: initial; overflow-anchor: initial; overflow-wrap: initial; overflow: initial; overscroll-behavior-block: initial; overscroll-behavior-inline: initial; overscroll-behavior: initial; padding-block: initial; padding: initial; padding-inline: initial; page: initial; page-orientation: initial; paint-order: initial; perspective: initial; perspective-origin: initial; pointer-events: initial; position: initial; quotes: initial; r: initial; resize: initial; ruby-position: initial; rx: initial; ry: initial; scroll-behavior: initial; scroll-margin-block: initial; scroll-margin: initial; scroll-margin-inline: initial; scroll-padding-block: initial; scroll-padding: initial; scroll-padding-inline: initial; scroll-snap-align: initial; scroll-snap-stop: initial; scroll-snap-type: initial; shape-image-threshold: initial; shape-margin: initial; shape-outside: initial; shape-rendering: initial; size: initial; speak: initial; stop-color: initial; stop-opacity: initial; stroke: initial; stroke-dasharray: initial; stroke-dashoffset: initial; stroke-linecap: initial; stroke-linejoin: initial; stroke-miterlimit: initial; stroke-opacity: initial; stroke-width: initial; tab-size: initial; table-layout: initial; text-align: initial; text-align-last: initial; text-anchor: initial; text-combine-upright: initial; text-decoration: initial; text-decoration-skip-ink: initial; text-indent: initial; text-overflow: initial; text-shadow: initial; text-size-adjust: initial; text-transform: initial; text-underline-offset: initial; text-underline-position: initial; touch-action: initial; transform: initial; transform-box: initial; transform-origin: initial; transform-style: initial; transition: initial; user-select: initial; vector-effect: initial; vertical-align: initial; visibility: initial; -webkit-app-region: initial; border-spacing: initial; -webkit-border-image: initial; -webkit-box-align: initial; -webkit-box-decoration-break: initial; -webkit-box-direction: initial; -webkit-box-flex: initial; -webkit-box-ordinal-group: initial; -webkit-box-orient: initial; -webkit-box-pack: initial; -webkit-box-reflect: initial; -webkit-highlight: initial; -webkit-hyphenate-character: initial; -webkit-line-break: initial; -webkit-line-clamp: initial; -webkit-mask-box-image: initial; -webkit-mask: initial; -webkit-mask-composite: initial; -webkit-perspective-origin-x: initial; -webkit-perspective-origin-y: initial; -webkit-print-color-adjust: initial; -webkit-rtl-ordering: initial; -webkit-ruby-position: initial; -webkit-tap-highlight-color: initial; -webkit-text-combine: initial; -webkit-text-decorations-in-effect: initial; -webkit-text-emphasis: initial; -webkit-text-emphasis-position: initial; -webkit-text-fill-color: initial; -webkit-text-security: initial; -webkit-text-stroke: initial; -webkit-transform-origin-x: initial; -webkit-transform-origin-y: initial; -webkit-transform-origin-z: initial; -webkit-user-drag: initial; -webkit-user-modify: initial; white-space: initial; widows: initial; width: initial; will-change: initial; word-break: initial; word-spacing: initial; x: initial; y: initial; z-index: initial;\"><\/div>\n<div class=\"ms-editor-squiggler\" style=\"color: initial; font: initial; font-feature-settings: initial; font-kerning: initial; font-optical-sizing: initial; font-variation-settings: initial; text-orientation: initial; text-rendering: initial; -webkit-font-smoothing: initial; -webkit-locale: initial; -webkit-text-orientation: initial; -webkit-writing-mode: initial; writing-mode: initial; zoom: initial; place-content: initial; place-items: initial; place-self: initial; alignment-baseline: initial; animation: initial; appearance: initial; aspect-ratio: initial; backdrop-filter: initial; backface-visibility: initial; background: initial; background-blend-mode: initial; baseline-shift: initial; block-size: initial; border-block: initial; border: initial; border-radius: initial; border-collapse: initial; border-inline: initial; inset: initial; box-shadow: initial; box-sizing: initial; break-after: initial; break-before: initial; break-inside: initial; buffered-rendering: initial; caption-side: initial; caret-color: initial; clear: initial; clip: initial; clip-path: initial; clip-rule: initial; color-interpolation: initial; color-interpolation-filters: initial; color-rendering: initial; color-scheme: initial; columns: initial; column-fill: initial; gap: initial; column-rule: initial; column-span: initial; contain: initial; contain-intrinsic-size: initial; content: initial; content-visibility: initial; counter-increment: initial; counter-reset: initial; counter-set: initial; cursor: initial; cx: initial; cy: initial; d: initial; display: block; dominant-baseline: initial; empty-cells: initial; fill: initial; fill-opacity: initial; fill-rule: initial; filter: initial; flex: initial; flex-flow: initial; float: initial; flood-color: initial; flood-opacity: initial; grid: initial; grid-area: initial; height: initial; hyphens: initial; image-orientation: initial; image-rendering: initial; inline-size: initial; inset-block: initial; inset-inline: initial; isolation: initial; letter-spacing: initial; lighting-color: initial; line-break: initial; list-style: initial; margin-block: initial; margin: initial; margin-inline: initial; marker: initial; mask: initial; mask-type: initial; max-block-size: initial; max-height: initial; max-inline-size: initial; max-width: initial; min-block-size: initial; min-height: initial; min-inline-size: initial; min-width: initial; mix-blend-mode: initial; object-fit: initial; object-position: initial; offset: initial; opacity: initial; order: initial; origin-trial-test-property: initial; orphans: initial; outline: initial; outline-offset: initial; overflow-anchor: initial; overflow-wrap: initial; overflow: initial; overscroll-behavior-block: initial; overscroll-behavior-inline: initial; overscroll-behavior: initial; padding-block: initial; padding: initial; padding-inline: initial; page: initial; page-orientation: initial; paint-order: initial; perspective: initial; perspective-origin: initial; pointer-events: initial; position: initial; quotes: initial; r: initial; resize: initial; ruby-position: initial; rx: initial; ry: initial; scroll-behavior: initial; scroll-margin-block: initial; scroll-margin: initial; scroll-margin-inline: initial; scroll-padding-block: initial; scroll-padding: initial; scroll-padding-inline: initial; scroll-snap-align: initial; scroll-snap-stop: initial; scroll-snap-type: initial; shape-image-threshold: initial; shape-margin: initial; shape-outside: initial; shape-rendering: initial; size: initial; speak: initial; stop-color: initial; stop-opacity: initial; stroke: initial; stroke-dasharray: initial; stroke-dashoffset: initial; stroke-linecap: initial; stroke-linejoin: initial; stroke-miterlimit: initial; stroke-opacity: initial; stroke-width: initial; tab-size: initial; table-layout: initial; text-align: initial; text-align-last: initial; text-anchor: initial; text-combine-upright: initial; text-decoration: initial; text-decoration-skip-ink: initial; text-indent: initial; text-overflow: initial; text-shadow: initial; text-size-adjust: initial; text-transform: initial; text-underline-offset: initial; text-underline-position: initial; touch-action: initial; transform: initial; transform-box: initial; transform-origin: initial; transform-style: initial; transition: initial; user-select: initial; vector-effect: initial; vertical-align: initial; visibility: initial; -webkit-app-region: initial; border-spacing: initial; -webkit-border-image: initial; -webkit-box-align: initial; -webkit-box-decoration-break: initial; -webkit-box-direction: initial; -webkit-box-flex: initial; -webkit-box-ordinal-group: initial; -webkit-box-orient: initial; -webkit-box-pack: initial; -webkit-box-reflect: initial; -webkit-highlight: initial; -webkit-hyphenate-character: initial; -webkit-line-break: initial; -webkit-line-clamp: initial; -webkit-mask-box-image: initial; -webkit-mask: initial; -webkit-mask-composite: initial; -webkit-perspective-origin-x: initial; -webkit-perspective-origin-y: initial; -webkit-print-color-adjust: initial; -webkit-rtl-ordering: initial; -webkit-ruby-position: initial; -webkit-tap-highlight-color: initial; -webkit-text-combine: initial; -webkit-text-decorations-in-effect: initial; -webkit-text-emphasis: initial; -webkit-text-emphasis-position: initial; -webkit-text-fill-color: initial; -webkit-text-security: initial; -webkit-text-stroke: initial; -webkit-transform-origin-x: initial; -webkit-transform-origin-y: initial; -webkit-transform-origin-z: initial; -webkit-user-drag: initial; -webkit-user-modify: initial; white-space: initial; widows: initial; width: initial; will-change: initial; word-break: initial; word-spacing: initial; x: initial; y: initial; z-index: initial;\"><\/div>\n<div class=\"ms-editor-squiggler\" style=\"color: initial; font: initial; font-feature-settings: initial; font-kerning: initial; font-optical-sizing: initial; font-variation-settings: initial; text-orientation: initial; text-rendering: initial; -webkit-font-smoothing: initial; -webkit-locale: initial; -webkit-text-orientation: initial; -webkit-writing-mode: initial; writing-mode: initial; zoom: initial; place-content: initial; place-items: initial; place-self: initial; alignment-baseline: initial; animation: initial; appearance: initial; aspect-ratio: initial; backdrop-filter: initial; backface-visibility: initial; background: initial; background-blend-mode: initial; baseline-shift: initial; block-size: initial; border-block: initial; border: initial; border-radius: initial; border-collapse: initial; border-inline: initial; inset: initial; box-shadow: initial; box-sizing: initial; break-after: initial; break-before: initial; break-inside: initial; buffered-rendering: initial; caption-side: initial; caret-color: initial; clear: initial; clip: initial; clip-path: initial; clip-rule: initial; color-interpolation: initial; color-interpolation-filters: initial; color-rendering: initial; color-scheme: initial; columns: initial; column-fill: initial; gap: initial; column-rule: initial; column-span: initial; contain: initial; contain-intrinsic-size: initial; content: initial; content-visibility: initial; counter-increment: initial; counter-reset: initial; counter-set: initial; cursor: initial; cx: initial; cy: initial; d: initial; display: block; dominant-baseline: initial; empty-cells: initial; fill: initial; fill-opacity: initial; fill-rule: initial; filter: initial; flex: initial; flex-flow: initial; float: initial; flood-color: initial; flood-opacity: initial; grid: initial; grid-area: initial; height: initial; hyphens: initial; image-orientation: initial; image-rendering: initial; inline-size: initial; inset-block: initial; inset-inline: initial; isolation: initial; letter-spacing: initial; lighting-color: initial; line-break: initial; list-style: initial; margin-block: initial; margin: initial; margin-inline: initial; marker: initial; mask: initial; mask-type: initial; max-block-size: initial; max-height: initial; max-inline-size: initial; max-width: initial; min-block-size: initial; min-height: initial; min-inline-size: initial; min-width: initial; mix-blend-mode: initial; object-fit: initial; object-position: initial; offset: initial; opacity: initial; order: initial; origin-trial-test-property: initial; orphans: initial; outline: initial; outline-offset: initial; overflow-anchor: initial; overflow-wrap: initial; overflow: initial; overscroll-behavior-block: initial; overscroll-behavior-inline: initial; overscroll-behavior: initial; padding-block: initial; padding: initial; padding-inline: initial; page: initial; page-orientation: initial; paint-order: initial; perspective: initial; perspective-origin: initial; pointer-events: initial; position: initial; quotes: initial; r: initial; resize: initial; ruby-position: initial; rx: initial; ry: initial; scroll-behavior: initial; scroll-margin-block: initial; scroll-margin: initial; scroll-margin-inline: initial; scroll-padding-block: initial; scroll-padding: initial; scroll-padding-inline: initial; scroll-snap-align: initial; scroll-snap-stop: initial; scroll-snap-type: initial; shape-image-threshold: initial; shape-margin: initial; shape-outside: initial; shape-rendering: initial; size: initial; speak: initial; stop-color: initial; stop-opacity: initial; stroke: initial; stroke-dasharray: initial; stroke-dashoffset: initial; stroke-linecap: initial; stroke-linejoin: initial; stroke-miterlimit: initial; stroke-opacity: initial; stroke-width: initial; tab-size: initial; table-layout: initial; text-align: initial; text-align-last: initial; text-anchor: initial; text-combine-upright: initial; text-decoration: initial; text-decoration-skip-ink: initial; text-indent: initial; text-overflow: initial; text-shadow: initial; text-size-adjust: initial; text-transform: initial; text-underline-offset: initial; text-underline-position: initial; touch-action: initial; transform: initial; transform-box: initial; transform-origin: initial; transform-style: initial; transition: initial; user-select: initial; vector-effect: initial; vertical-align: initial; visibility: initial; -webkit-app-region: initial; border-spacing: initial; -webkit-border-image: initial; -webkit-box-align: initial; -webkit-box-decoration-break: initial; -webkit-box-direction: initial; -webkit-box-flex: initial; -webkit-box-ordinal-group: initial; -webkit-box-orient: initial; -webkit-box-pack: initial; -webkit-box-reflect: initial; -webkit-highlight: initial; -webkit-hyphenate-character: initial; -webkit-line-break: initial; -webkit-line-clamp: initial; -webkit-mask-box-image: initial; -webkit-mask: initial; -webkit-mask-composite: initial; -webkit-perspective-origin-x: initial; -webkit-perspective-origin-y: initial; -webkit-print-color-adjust: initial; -webkit-rtl-ordering: initial; -webkit-ruby-position: initial; -webkit-tap-highlight-color: initial; -webkit-text-combine: initial; -webkit-text-decorations-in-effect: initial; -webkit-text-emphasis: initial; -webkit-text-emphasis-position: initial; -webkit-text-fill-color: initial; -webkit-text-security: initial; -webkit-text-stroke: initial; -webkit-transform-origin-x: initial; -webkit-transform-origin-y: initial; -webkit-transform-origin-z: initial; -webkit-user-drag: initial; -webkit-user-modify: initial; white-space: initial; widows: initial; width: initial; will-change: initial; word-break: initial; word-spacing: initial; x: initial; y: initial; z-index: initial;\"><\/div>\n<div class=\"ms-editor-squiggler\" style=\"color: initial; font: initial; font-feature-settings: initial; font-kerning: initial; font-optical-sizing: initial; font-variation-settings: initial; text-orientation: initial; text-rendering: initial; -webkit-font-smoothing: initial; -webkit-locale: initial; -webkit-text-orientation: initial; -webkit-writing-mode: initial; writing-mode: initial; zoom: initial; place-content: initial; place-items: initial; place-self: initial; alignment-baseline: initial; animation: initial; appearance: initial; aspect-ratio: initial; backdrop-filter: initial; backface-visibility: initial; background: initial; background-blend-mode: initial; baseline-shift: initial; block-size: initial; border-block: initial; border: initial; border-radius: initial; border-collapse: initial; border-inline: initial; inset: initial; box-shadow: initial; box-sizing: initial; break-after: initial; break-before: initial; break-inside: initial; buffered-rendering: initial; caption-side: initial; caret-color: initial; clear: initial; clip: initial; clip-path: initial; clip-rule: initial; color-interpolation: initial; color-interpolation-filters: initial; color-rendering: initial; color-scheme: initial; columns: initial; column-fill: initial; gap: initial; column-rule: initial; column-span: initial; contain: initial; contain-intrinsic-size: initial; content: initial; content-visibility: initial; counter-increment: initial; counter-reset: initial; counter-set: initial; cursor: initial; cx: initial; cy: initial; d: initial; display: block; dominant-baseline: initial; empty-cells: initial; fill: initial; fill-opacity: initial; fill-rule: initial; filter: initial; flex: initial; flex-flow: initial; float: initial; flood-color: initial; flood-opacity: initial; grid: initial; grid-area: initial; height: 0px; hyphens: initial; image-orientation: initial; image-rendering: initial; inline-size: initial; inset-block: initial; inset-inline: initial; isolation: initial; letter-spacing: initial; lighting-color: initial; line-break: initial; list-style: initial; margin-block: initial; margin: initial; margin-inline: initial; marker: initial; mask: initial; mask-type: initial; max-block-size: initial; max-height: initial; max-inline-size: initial; max-width: initial; min-block-size: initial; min-height: initial; min-inline-size: initial; min-width: initial; mix-blend-mode: initial; object-fit: initial; object-position: initial; offset: initial; opacity: initial; order: initial; origin-trial-test-property: initial; orphans: initial; outline: initial; outline-offset: initial; overflow-anchor: initial; overflow-wrap: initial; overflow: initial; overscroll-behavior-block: initial; overscroll-behavior-inline: initial; overscroll-behavior: initial; padding-block: initial; padding: initial; padding-inline: initial; page: initial; page-orientation: initial; paint-order: initial; perspective: initial; perspective-origin: initial; pointer-events: initial; position: initial; quotes: initial; r: initial; resize: initial; ruby-position: initial; rx: initial; ry: initial; scroll-behavior: initial; scroll-margin-block: initial; scroll-margin: initial; scroll-margin-inline: initial; scroll-padding-block: initial; scroll-padding: initial; scroll-padding-inline: initial; scroll-snap-align: initial; scroll-snap-stop: initial; scroll-snap-type: initial; shape-image-threshold: initial; shape-margin: initial; shape-outside: initial; shape-rendering: initial; size: initial; speak: initial; stop-color: initial; stop-opacity: initial; stroke: initial; stroke-dasharray: initial; stroke-dashoffset: initial; stroke-linecap: initial; stroke-linejoin: initial; stroke-miterlimit: initial; stroke-opacity: initial; stroke-width: initial; tab-size: initial; table-layout: initial; text-align: initial; text-align-last: initial; text-anchor: initial; text-combine-upright: initial; text-decoration: initial; text-decoration-skip-ink: initial; text-indent: initial; text-overflow: initial; text-shadow: initial; text-size-adjust: initial; text-transform: initial; text-underline-offset: initial; text-underline-position: initial; touch-action: initial; transform: initial; transform-box: initial; transform-origin: initial; transform-style: initial; transition: initial; user-select: initial; vector-effect: initial; vertical-align: initial; visibility: initial; -webkit-app-region: initial; border-spacing: initial; -webkit-border-image: initial; -webkit-box-align: initial; -webkit-box-decoration-break: initial; -webkit-box-direction: initial; -webkit-box-flex: initial; -webkit-box-ordinal-group: initial; -webkit-box-orient: initial; -webkit-box-pack: initial; -webkit-box-reflect: initial; -webkit-highlight: initial; -webkit-hyphenate-character: initial; -webkit-line-break: initial; -webkit-line-clamp: initial; -webkit-mask-box-image: initial; -webkit-mask: initial; -webkit-mask-composite: initial; -webkit-perspective-origin-x: initial; -webkit-perspective-origin-y: initial; -webkit-print-color-adjust: initial; -webkit-rtl-ordering: initial; -webkit-ruby-position: initial; -webkit-tap-highlight-color: initial; -webkit-text-combine: initial; -webkit-text-decorations-in-effect: initial; -webkit-text-emphasis: initial; -webkit-text-emphasis-position: initial; -webkit-text-fill-color: initial; -webkit-text-security: initial; -webkit-text-stroke: initial; -webkit-transform-origin-x: initial; -webkit-transform-origin-y: initial; -webkit-transform-origin-z: initial; -webkit-user-drag: initial; -webkit-user-modify: initial; white-space: initial; widows: initial; width: initial; will-change: initial; word-break: initial; word-spacing: initial; x: initial; y: initial; z-index: initial;\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Traditional point-to-point site-to-site VPN protocols require extensive setup in certain use cases. For example, if you want shortcuts between branch offices rather than let every packet go through the HQ, then you need to set up a cartesian product of tunnels by hand, which is time-consuming and error prone. So, people want something better, something [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[9,15,2,5],"tags":[],"class_list":["post-196","post","type-post","status-publish","format-standard","hentry","category-cisco-ios-xe","category-huawei","category-linux","category-networking"],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/posts\/196"}],"collection":[{"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/comments?post=196"}],"version-history":[{"count":26,"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/posts\/196\/revisions"}],"predecessor-version":[{"id":276,"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/posts\/196\/revisions\/276"}],"wp:attachment":[{"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/media?parent=196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/categories?post=196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.swineson.me\/en\/wp-json\/wp\/v2\/tags?post=196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}