I've written a long series of post about setting up IPsec VPNs between NATed machines. As you've already seen, with some creative configuration it's possible, but is it always worth the sacrifice? Sometimes performance requirements, or lack of support for anything else on the other side make it necessary, but if the other side is also a VyOS, or another open source system, there's an alternative.
While OpenVPN is usually associated with road warrior VPN setups, it is not limited to it. It does have a site to site option and it's very quick and easy to setup. For some strange reason, that option is neglected by just about everyone who otherwise supports OpenVPN: in OpenWRT it's possible to setup through custom config options, while in Mikrotik RouterOS it's not possible to setup at all. In VyOS we have an explicit option for it. OPNsense also supports site to site OpenVPN out of the box (I thought it doesn't, but the authors corrected me).
The advantages are that it takes very few commands to get a tunnel to work, and that it will work in any network where you can forward a single port, even is both sides are behind double NAT. The downside is performance: squeezing even 100mbit/s of encrypted traffic out of it can be impossible, typical iperf figures are 10-20 mbit/s. For many use cases that performance is more than enough, though if you plan to use the tunnel for storage replication or another high-traffic job, that option is definitely not for you and you'll have to resort to IPsec.
Setting up site to site OpenVPN
Generating a key
OpenVPN in site to site mode supports either static pre-shared keys or x.509. For a quick tunnel setup between your own routers, the format option is a lot easier and arguably not less secure. Unlike most IPsec implementations, OpenVPN stores pre-shared keys in files, and uses keys of considerable length (default is 2038. It takes just one command to generate a suitable key:
run generate openvpn key /config/auth/mysite.key
Then you can copy the file to the remote side via SCP or something else. That command is a wrapper for "openvpn --genkey --secret" in case you want to generate a key outside VyOS. It's a good idea to store the keys in /config/auth directory that was specifically meant for authentication data, since /config will be migrated to the new image when you upgrade your system — if you put them in /etc, they will be inaccessible from the upgraded image.
Setting up the tunnel
It's quite straightforward.
Local (listening) side:
set interfaces openvpn vtun10 mode site-to-site set interfaces openvpn vtun10 description 'My remote site' set interfaces openvpn vtun10 local-host 203.0.113.50 # Listen address set interfaces openvpn vtun10 local-address 192.168.34.1 # Tunnel address set interfaces openvpn vtun10 local-port 8000 # Port to listen on set interfaces openvpn vtun10 protocol udp # Can be TCP but TCP is slower set interfaces openvpn vtun10 remote-address 192.168.34.2 # Tunnel peer address set interfaces openvpn vtun10 shared-secret-key-file /config/auth/mysite.key # The file you generated
Remote (connecting) side:
set interfaces openvpn vtun10 mode site-to-site set interfaces openvpn vtun10 remote-host 203.0.113.50 # Remote router external address set interfaces openvpn vtun10 local-address 192.168.34.2 # Tunnel address, don't forget to local/remote addresses for the remote side! set interfaces openvpn vtun10 remote-port 8000 # Port to connect on set interfaces openvpn vtun10 protocol udp # Can be TCP but TCP is slower set interfaces openvpn vtun10 remote-address 192.168.34.1 set interfaces openvpn vtun10 shared-secret-key-file /config/auth/mysite.key
As you can see, with less than 10 commands on each side, you can get a tunnel working.
What about x.509?
It is doable, though I'm not sure if it's really worth the trouble for site to site tunnels.
This is how it's done. Local (listening) side:
set interfaces openvpn vtun10 tls role passive set interfaces openvpn vtun10 tls dh-file /config/auth/dh2048.pem set interfaces openvpn vtun10 tls ca-cert-file /config/auth/ca.crt set interfaces openvpn vtun10 tls cert-file /config/auth/local.crt set interfaces openvpn vtun10 tls key-file /config/auth/local.key
Remote (connecting) side:
set interfaces openvpn vtun10 tls role active set interfaces openvpn vtun10 tls ca-cert-file /config/auth/ca.crt set interfaces openvpn vtun10 tls cert-file /config/auth/remote.crt set interfaces openvpn vtun10 tls key-file /config/auth/remote.key
Routing
Since OpenVPN tunnels look like normal network interfaces, you can setup routing right away as if they were physical links. You can also use push-route commands through custom options (as in, openvpn-option "push ..."). Note that OpenVPN in site to site mode doesn't install any routes by default so you need to take care of it yourself.