{"id":734,"date":"2022-03-05T19:41:36","date_gmt":"2022-03-05T18:41:36","guid":{"rendered":"https:\/\/caipirinha.spdns.org\/wp\/?p=734"},"modified":"2024-09-04T03:10:38","modified_gmt":"2024-09-04T01:10:38","slug":"setting-up-dual-stack-openvpn","status":"publish","type":"post","link":"https:\/\/caipirinha.spdns.org\/wp\/?p=734","title":{"rendered":"Setting up Dual Stack VPNs"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"executive-summary\">Executive Summary<\/h2>\n\n\n\n<p>This blog post explains how I set up dual stack (IPv4, IPv6) virtual private networks (VPN) with the open-source packages <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> and <a href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">WireGuard<\/a> on my Linux server caipirinha.spdns.org. Clients (smartphones, tablets, notebooks) which connect to my server will be supplied with a dual stack VPN connection and can therefore use both IPv4 as well as IPv6 via the Linux server to the internet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"background\">Background<\/h2>\n\n\n\n<p>The implementation was originally intended to help a friend who lived in China and who struggled with his commercial VPN that only tunneled IPv4 and did not block IPv6. He often experienced blockages when he tried to access social media sites as his system would prefer IPv6 over IPv4 and so the connection would not run through his VPN. However, due to [<a rel=\"noreferrer noopener\" href=\"https:\/\/link.springer.com\/chapter\/10.1007\/978-3-642-35795-4_56\" target=\"_blank\">6<\/a>], <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> alone is no longer suited to circumvent censorship in China [<a rel=\"noreferrer noopener\" href=\"https:\/\/caipirinha.spdns.org\/wp\/?p=56\" target=\"_blank\">7<\/a>]. <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a> might still work in geographies where <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> is blocked, however.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"preconditions\">Preconditions<\/h2>\n\n\n\n<p>In order to use the approach described here, you should:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>&#8230; have a full dual stack internet connection (IPv4, IPv6)<\/li>\n\n\n\n<li>&#8230; have access to a Linux machine which is already properly configured for dual stack on its principal network interface (e.g., <em>eth0<\/em>)<\/li>\n\n\n\n<li>&#8230; have the Linux machine set up as a router<\/li>\n\n\n\n<li><span style=\"color: initial;\">&#8230; have the package <\/span><a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a><span style=\"color: initial;\"> and\/or <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a><\/span> <span style=\"color: initial;\">installed<\/span> (preferably from a repository of your Linux distribution)<\/li>\n\n\n\n<li>&#8230; know how to create client and server certificates for <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> [<a rel=\"noreferrer noopener\" href=\"https:\/\/openvpn.net\/community-resources\/how-to\/#setting-up-your-own-certificate-authority-ca-and-generating-certificates-and-keys-for-an-openvpn-server-and-multiple-clients\" target=\"_blank\">11<\/a>] and\/or <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a> [<a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/quickstart\/\" target=\"_blank\">12<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/stanislas.blog\/2019\/01\/how-to-setup-vpn-server-wireguard-nat-ipv6\/\" target=\"_blank\">13<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/wiki.archlinux.org\/title\/WireGuard\" target=\"_blank\">19<\/a>] although this blog post will also contain a short description on how to create a set of certificates and keys for openvpn<\/li>\n\n\n\n<li>&#8230; have knowledge of routing concepts, networks, some understanding of shell scripts and configuration files<\/li>\n\n\n\n<li>&#8230; know related system commands like <em>sysctl<\/em><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"description-and-usage\">Description and Usage<\/h2>\n\n\n\n<p>The graph below shows the setup on my machine caipirinha.spdns.org with 5 VPN services (blue, green color) that will be described in this blog post. The machine has also 3 VPN clients configured which are mapped to a commercial service (ocker color), but this will not be topic of this blog post.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/VPN-Diagramm-1-1024x576.jpg\" alt=\"\" class=\"wp-image-760\" srcset=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/VPN-Diagramm-1-1024x576.jpg 1024w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/VPN-Diagramm-1-300x169.jpg 300w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/VPN-Diagramm-1-768x432.jpg 768w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/VPN-Diagramm-1.jpg 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Configuration of VPN Services on caipirinha.spdns.org<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"home-network-setup\">Home Network Setup<\/h3>\n\n\n\n<p>Let us now look at some details of the network setup:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The Linux server is not connected to the internet directly, but it is connected to a small SoHo router which acts as basic firewall and forwards a selection of ports and protocols to the Linux server.<\/li>\n\n\n\n<li>The internal IPv4 network which is setup by the SoHo router is <strong>192.168.2.0\/24<\/strong>.<\/li>\n\n\n\n<li>The internal IPv6 network which is setup by the SoHo router is <strong>fd00:0:0:2\/64<\/strong>; this is configured in the respective menu of the SoHo router as shown below and is within the IPv6 unique local address space [<a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Unique_local_address\" target=\"_blank\">1<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/whstatic.1and1.com\/help\/CloudServer\/EN-US\/d857940.html\" target=\"_blank\">2<\/a>]. I decided to use an IPv6 with a &#8220;2&#8221; in the network address like the &#8220;2&#8221; in the IPv4 network.<\/li>\n\n\n\n<li>The Linux server also gets a public IPv6 address allocated (like all other devices in my home network); this is accomplished by the SoHo router that has IPv6 enabled.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"494\" src=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/IPv6-Setup-des-Routers-1024x494.jpg\" alt=\"\" class=\"wp-image-736\" srcset=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/IPv6-Setup-des-Routers-1024x494.jpg 1024w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/IPv6-Setup-des-Routers-300x145.jpg 300w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/IPv6-Setup-des-Routers-768x371.jpg 768w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/IPv6-Setup-des-Routers.jpg 1366w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Configuration of the internal IPv6 network<\/figcaption><\/figure>\n\n\n\n<p>When everything has been set up correctly, the Linux server should get various IP addresses, and among them various IPv6 addresses:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>a &#8220;real&#8221; and routable one starting with numbers in the range from &#8220;2000:&#8221; until &#8220;3fff:&#8221;.<\/li>\n\n\n\n<li>a SLAAC [<a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/IPv6_address#Stateless_address_autoconfiguration\" target=\"_blank\">3<\/a>] one starting with &#8220;fe80:&#8221;<\/li>\n\n\n\n<li>a &#8220;private&#8221; one starting with &#8220;fd00::2:&#8221;<\/li>\n<\/ul>\n\n\n\n<p>An example is shown here:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>caipirinha:~ # <strong>ifconfig eth0<\/strong>\neth0: flags=4163 mtu 1500\ninet 192.168.2.3 netmask 255.255.255.0 broadcast 192.168.2.255\ninet6 2001:16b8:306c:c700:76d4:35ff:fe5c:d2c3 prefixlen 64 scopeid 0x0\ninet6 fe80::76d4:35ff:fe5c:d2c3 prefixlen 64 scopeid 0x20\ninet6 fd00::2:76d4:35ff:fe5c:d2c3 prefixlen 64 scopeid 0x0\n...<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"enabling-routing\">Enabling Routing<\/h3>\n\n\n\n<p>Routing for IPv4 and IPv6 needs to be enabled on the Linux server. I personally also decided to switch off the privacy extensions on the Linux server, but that is a personal matter of taste:<\/p>\n\n\n\n<pre id=\"enable-loose-reverse-path-filtering-and-prohibit-icmp-redirects\" class=\"wp-block-code\"><code># Enable \"loose\" reverse path filtering and prohibit icmp redirects\nsysctl -w net.ipv4.conf.all.rp_filter=2\nsysctl -w net.ipv4.conf.all.send_redirects=0\nsysctl -w net.ipv4.conf.eth0.send_redirects=0\nsysctl -w net.ipv4.icmp_errors_use_inbound_ifaddr=1\n\n# Enable IPv6 routing, but keep SLAAC for eth0\nsysctl -w net.ipv6.conf.eth0.accept_ra=2\nsysctl -w net.ipv6.conf.all.forwarding=1\n\n# Switch off the privacy extensions\nsysctl -w net.ipv6.conf.eth0.use_tempaddr=0<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">OpenVPN Key Management with Easy-RSA<\/h3>\n\n\n\n<p>For the openVPN server and clients, we need a certification authority and we ultimately need to create signed certificates and keys. This can be done with the help of the package <strong>easy-rsa<\/strong> that is available for various platforms [<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/OpenVPN\/easy-rsa\" target=\"_blank\">22<\/a>] and often is part of Linux distributions, too. Documentation and hands-on examples are given in [<a rel=\"noreferrer noopener\" href=\"https:\/\/easy-rsa.readthedocs.io\/en\/latest\/\" target=\"_blank\">20<\/a>] and [<a rel=\"noreferrer noopener\" href=\"https:\/\/wiki.archlinux.org\/title\/Easy-RSA#top-page\" target=\"_blank\">21<\/a>].<\/p>\n\n\n\n<p>We start with the initialization of a <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Public_key_infrastructure\" target=\"_blank\">Public Key Infrastructure<\/a> (PKI) and the creation of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Certificate_authority\" target=\"_blank\" rel=\"noreferrer noopener\">Certificate Authority<\/a> (CA) followed by the creation of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Certificate_revocation_list\" target=\"_blank\" rel=\"noreferrer noopener\">Certificate Revocation List<\/a> (CRL)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>easyrsa init-pki\neasyrsa build-ca nopass\neasyrsa gen-crl<\/code><\/pre>\n\n\n\n<p>The next step is the creation of a key pair for the server. The public key will be signed by the CA and thus become our server certificate. Furthermore, we create <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Diffie%E2%80%93Hellman_key_exchange\" target=\"_blank\">Diffie-Hellman<\/a> parameters for the server (not needed if you create elliptic keys). All this can be done by:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>easyrsa --days=3652 build-server-full caipirinha.spdns.org nopass\neasyrsa gen-dh<\/code><\/pre>\n\n\n\n<p>In this example, the server certificate is valid for some 3652 days (10 years), the certificate is named <strong>caipirinha.spdns.org.crt<\/strong>, and the private key which must remain on the server is named <strong>caipirinha.spdns.org.key<\/strong>.<\/p>\n\n\n\n<p>Now, we can create client certificates in a similar way. In the example, the client certificates will have a validity of 5 years only:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>easyrsa --days=1825 build-client-full gabriel-SM-G991B nopass\neasyrsa --days=1825 build-client-full gabriel-SM-N960F nopass\neasyrsa --days=1825 build-client-full gabriel-SM-N915FY nopass\neasyrsa --days=1825 build-client-full gabriel-SM-T580 nopass\n...<\/code><\/pre>\n\n\n\n<p>I chose not to use passwords for the private key in order to facilitate the handling. Furthermore, I went for the easy way and created all certificates and keys on one system only. If you intend to deploy a professional solution, you have to keep cyber-security in mind and you may therefore want to exercise more caution and separate the certificate authority on a secured system from the creation of server and client key pairs as it has been advised in [<a rel=\"noreferrer noopener\" href=\"https:\/\/easy-rsa.readthedocs.io\/en\/latest\/\" target=\"_blank\">20<\/a>].<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"server-configuration\">OpenVPN Server Configuration<\/h3>\n\n\n\n<p>Before we go into details of the configuration, we must distinguish 3 concepts of VPNs:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A <em>(full) tunneling<\/em> VPN tunnels all connections through the VPN, once the VPN connection has been established. This offers possibilities, but also has implications:\n<ul class=\"wp-block-list\">\n<li>The VPN client appears to be in the geographic location of the VPN server unless the server itself tunnels through more nodes. This can be useful to circumvent censorship in the geography where the VPN client is located as all connections from the client to services in the internet are channeled through the VPN server.<\/li>\n\n\n\n<li>In a complex multi-level server setup, it can make the client appear in different countries, depending on which destination the client is trying to access. A VPN client might, for example, be in Angola, but connect to a VPN server in Germany which itself has VPN connections to Brazil and to Portugal. If the VPN server is configured accordingly, the VPN client in Angola may appear as being in Portugal when accessing Portuguese web sites and might appear as being located in Brazil when accessing Brazilian web sites and might appear as being located in Germany for everything else.<\/li>\n\n\n\n<li>The VPN server can implement filtering services like filtering out ad servers or doing virus scans of downloads.<\/li>\n\n\n\n<li>The VPN server can implement access restrictions; companies use this sometimes to disallow clients to access web sites which they deem to be related to &#8220;sex, hate, crime, gambling, &#8230;&#8221;.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>A <em>split tunneling<\/em> VPN tunnels only connections to certain networks between the VPN client and the VPN server while all other connections from the VPN client access the internet through the local provider. The typical usage scenario is not related to censorship, but to dedicated resources to which the VPN server grants access (e.g., network shares aka &#8220;samba&#8221;, proxy services, etc.) that shall be accessed from the VPN client while the latter is not physically connected to the home or company network.<\/li>\n\n\n\n<li>An <em>inverse split tunneling<\/em> VPN tunnels almost all connections, with a few exceptions. This concept is often used in companies which want basically all connections to run through their infrastructure so that they can execute virus scans and access restrictions, but which have (correctly) realized that bandwidth-intensive operations like cloud access, access to video conferencing services, etc. should be taken off the VPN tunnel as their performance is deteriorated otherwise.<\/li>\n<\/ul>\n\n\n\n<p>The following configurations will create 4 different VPNs based on 2 concepts above.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>UDP<\/em>-based VPN, <em>full tunneling<\/em>: This is the preferred VPN when all connections shall be tunneled.<\/li>\n\n\n\n<li><em>UDP<\/em>-based VPN, <em>split tunneling<\/em>: This is the preferred VPN when you want to blend in resources from your home network.<\/li>\n\n\n\n<li><em>TCP<\/em>-based VPN, <em>full tunneling<\/em>: TCP can be used when the connection quality to the VPN server is unstable or when UDP is blocked by some gateway in between.<\/li>\n\n\n\n<li><em>TCP<\/em>-based VPN, <em>split tunneling<\/em>: This is the preferred VPN when you want to blend in resources from your home network, but when the connection quality to the VPN server is unstable or when UDP is blocked by some gateway in between.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"udp-based-vpn-full-tunneling\">UDP-based VPN, full tunneling<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># Konfigurationsdatei f\u00fcr den openVPN-Server auf CAIPIRINHA (UDP:1194)\n\nca                    \/root\/pki\/ca.crt\ncert                  \/etc\/openvpn\/caipirinha.spdns.org.crt\nclient-config-dir     \/etc\/openvpn\/conf-1194\ncrl-verify            \/root\/pki\/crl.pem\ndev                   tun4\ndh                    \/root\/pki\/dh.pem\nhand-window           90\nifconfig              192.168.10.1  255.255.255.0\nifconfig-pool         192.168.10.2  192.168.10.239  255.255.255.0\nifconfig-ipv6         fd01:0:0:a::1 fd00::2:3681:c4ff:fecb:5780\nifconfig-ipv6-pool    fd01:0:0:a::2\/112\nifconfig-pool-persist \/etc\/openvpn\/ip-pool-1194.txt\nkeepalive             20 80\nkey                   \/etc\/openvpn\/caipirinha.spdns.org.key\nlog                   \/var\/log\/openvpn-1194.log\nmode                  server\npersist-key\npersist-tun\nport                  1194\nproto                 udp6\nreneg-sec             86400\nscript-security       2\nstatus                \/var\/run\/openvpn\/status-1194\ntls-server\ntopology              subnet\nup                    \/etc\/openvpn\/start_vpn.sh\nverb                  1\nwritepid              \/var\/run\/openvpn\/server-1194.pid\n\n# Topologie des VPN und Default-Gateway\npush \"topology subnet\"\npush \"route-gateway 192.168.10.1\"\npush \"redirect-gateway def1 bypass-dhcp\"\npush \"tun-ipv6\"\npush \"route-ipv6 2000::\/3\"\n# DNS-Server\npush \"dhcp-option DNS 8.8.8.8\"\npush \"dhcp-option DNS 8.8.4.4\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"udp-based-vpn-split-tunneling\">UDP-based VPN, split tunneling<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># Konfigurationsdatei f\u00fcr den openVPN-Server auf CAIPIRINHA (UDP:4396)\n\nca                    \/root\/pki\/ca.crt\ncert                  \/etc\/openvpn\/caipirinha.spdns.org.crt\nclient-config-dir     \/etc\/openvpn\/conf-4396\ncrl-verify            \/root\/pki\/crl.pem\ndev                   tun7\ndh                    \/root\/pki\/dh.pem\nhand-window           90\nifconfig              192.168.13.1  255.255.255.0\nifconfig-pool         192.168.13.2  192.168.13.239  255.255.255.0\nifconfig-ipv6         fd01:0:0:d::1 fd00::2:3681:c4ff:fecb:5780\nifconfig-ipv6-pool    fd01:0:0:d::2\/112\nifconfig-pool-persist \/etc\/openvpn\/ip-pool-4396.txt\nkeepalive             20 80\nkey                   \/etc\/openvpn\/caipirinha.spdns.org.key\nlog                   \/var\/log\/openvpn-4396.log\nmode                  server\npersist-key\npersist-tun\nport                  4396\nproto                 udp6\nreneg-sec             86400\nscript-security       2\nstatus                \/var\/run\/openvpn\/status-4396\ntls-server\ntopology              subnet\nup                    \/etc\/openvpn\/start_vpn.sh\nverb                  1\nwritepid              \/var\/run\/openvpn\/server-4396.pid\n\n# Topologie des VPN und Default-Gateway\npush \"topology subnet\"\npush \"route-gateway 192.168.13.1\"\npush \"tun-ipv6\"\npush \"route-ipv6 2000::\/3\"\n# Routen zum internen Netzwerk setzen\npush \"route 192.168.2.0 255.255.255.0\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"tcp-based-vpn-full-tunneling\">TCP-based VPN, full tunneling<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># Konfigurationsdatei f\u00fcr den openVPN-Server auf CAIPIRINHA  (TCP:8080)\n\nca                    \/root\/pki\/ca.crt\ncert                  \/etc\/openvpn\/caipirinha.spdns.org.crt\nclient-config-dir     \/etc\/openvpn\/conf-8080\ncrl-verify            \/root\/pki\/crl.pem\ndev                   tun5\ndh                    \/root\/pki\/dh.pem\nhand-window           90\nifconfig              192.168.11.1  255.255.255.0\nifconfig-pool         192.168.11.2  192.168.11.239  255.255.255.0\nifconfig-ipv6         fd01:0:0:b::1 fd00::2:3681:c4ff:fecb:5780\nifconfig-ipv6-pool    fd01:0:0:b::2\/112\nifconfig-pool-persist \/etc\/openvpn\/ip-pool-8080.txt\nkeepalive             20 80\nkey                   \/etc\/openvpn\/caipirinha.spdns.org.key\nlog                   \/var\/log\/openvpn-8080.log\nmode                  server\npersist-key\npersist-tun\nport                  8080\nproto                 tcp6-server\nreneg-sec             86400\nscript-security       2\nstatus                \/var\/run\/openvpn\/status-8080\ntls-server\ntopology              subnet\nup                    \/etc\/openvpn\/start_vpn.sh\nverb                  1\nwritepid              \/var\/run\/openvpn\/server-8080.pid\n\n# Topologie des VPN und Default-Gateway\npush \"topology subnet\"\npush \"route-gateway 192.168.11.1\"\npush \"redirect-gateway def1 bypass-dhcp\"\npush \"tun-ipv6\"\npush \"route-ipv6 2000::\/3\"\n# DNS-Server\npush \"dhcp-option DNS 8.8.8.8\"\npush \"dhcp-option DNS 8.8.4.4\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"tcp-based-vpn-split-tunneling\">TCP-based VPN, split tunneling<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># Konfigurationsdatei f\u00fcr den openVPN-Server auf CAIPIRINHA  (TCP:8081)\n\nca                    \/root\/pki\/ca.crt\ncert                  \/etc\/openvpn\/caipirinha.spdns.org.crt\nclient-config-dir     \/etc\/openvpn\/conf-8081\ncrl-verify            \/root\/pki\/crl.pem\ndev                   tun6\ndh                    \/root\/pki\/dh.pem\nhand-window           90\nifconfig              192.168.12.1  255.255.255.0\nifconfig-pool         192.168.12.2  192.168.12.239  255.255.255.0\nifconfig-ipv6         fd01:0:0:c::1 fd00::2:3681:c4ff:fecb:5780\nifconfig-ipv6-pool    fd01:0:0:c::2\/112\nifconfig-pool-persist \/etc\/openvpn\/ip-pool-8081.txt\nkeepalive             20 80\nkey                   \/etc\/openvpn\/caipirinha.spdns.org.key\nlog                   \/var\/log\/openvpn-8081.log\nmode                  server\npersist-key\npersist-tun\nport                  8081\nproto                 tcp6-server\nreneg-sec             86400\nscript-security       2\nstatus                \/var\/run\/openvpn\/status-8081\ntls-server\ntopology              subnet\nup                    \/etc\/openvpn\/start_vpn.sh\nverb                  1\nwritepid              \/var\/run\/openvpn\/server-8081.pid\n\n# Topologie des VPN und Default-Gateway\npush \"topology subnet\"\npush \"route-gateway 192.168.12.1\"\npush \"tun-ipv6\"\npush \"route-ipv6 fd00:0:0:2::\/64\"\n# Routen zum internen Netzwerk setzen\npush \"route 192.168.2.0 255.255.255.0\"<\/code><\/pre>\n\n\n\n<p>We shall now look at some configuration parameters and their meaning:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>cert<\/strong>, <strong>key<\/strong>: The location of the server certificate and the server key has to be listed.<\/li>\n\n\n\n<li><strong>ca<\/strong>: The location of the certificate authority certificate has to be listed.<\/li>\n\n\n\n<li><strong>crl-verify<\/strong>: This point to a certificate revocation list and contains the certificates that once were issued for devices that have been retired meanwhile or for users that only needed a temporary VPN access .<\/li>\n\n\n\n<li><strong>dev<\/strong>: This determines the tun device that shall be used for the connection. I recommend using dedicated tun devices for all VPNs rather than having them randomly assigned during start-up.<\/li>\n\n\n\n<li><strong>ifconfig<\/strong>, <strong>ifconfig-pool<\/strong>: This determines the IPv4 address of the server and the pool from which IPv4 addresses are granted to the clients. I decided to use a different \/24 network for each VPN configuration, that is, the networks <strong>192.168.<em>10<\/em>.0\/24<\/strong>, <strong>192.168.<em>11<\/em>.0\/24<\/strong>, <strong>192.168.<em>12<\/em>.0\/24<\/strong>, and <strong>192.168.<em>13<\/em>.0\/24<\/strong>. However, I decided not to use the full IP address range for dynamic allocation as I have some VPN clients (smartphones, notebooks) which get a dedicated client address so that I can easily tweak settings on the Linux server for those clients. These clients have a small, dedicated configuration file in the folder named in <strong>client-config-dir<\/strong>. Such a dedicated configuration can be used to allocate the same IP address to a certain VPN client.<\/li>\n\n\n\n<li><strong>ifconfig-ipv6<\/strong>: The first parameter is the IPv6 address of the server, and the second IPv6 address is the one of the router to the internet; in that case, I put the SoHo router there (fd00::2:3681:c4ff:fecb:5780), see the image <a rel=\"noreferrer noopener\" href=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/IPv6-Setup-des-Routers-1024x494.jpg\" target=\"_blank\">Configuration of the internal IPv6 network<\/a>.<\/li>\n\n\n\n<li><strong>ifconfig-ipv6-pool<\/strong>: This is the pool of IPv6 addresses that are granted to the clients. I follow a similar approach as with the IPv4 networks and set up separate networks for each VPN, that is, the networks <strong>fd01:0:0:<em>a<\/em>::2\/112<\/strong>, <strong>fd01:0:0:<em>b<\/em>::2\/112<\/strong>, <strong>fd01:0:0:<em>c<\/em>::2\/112<\/strong> and <strong>fd01:0:0:<em>d<\/em>::2\/112<\/strong>. Keep in mind that the first address of the IP address pool is the one mentioned here, e.g., fd01:0:0:a:0:0:0:2, as fd01:0:0:a:0:0:0:1 is already used for the server.<\/li>\n\n\n\n<li><strong>keepalive<\/strong>: Sets the interval of ping-alive requests and its timeout. This is useful as gateways that are in between the VPN client and the VPN server might keep connections open and port allocations reserved only for some time; subsequently, they might be freed up. Ideally, you want to use the longest time periods possible as shorter periods create unnecessary traffic (and might eat up the data volume of mobile clients).<\/li>\n\n\n\n<li><strong>port<\/strong>: While the standard port for <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> is 1194, with more than one VPN you are better advised to use different, dedicated ports that are not used by other service on your server.<\/li>\n\n\n\n<li><strong>proto<\/strong>: This determines the protocol used and is either <strong>udp6<\/strong> or <strong>tcp6-server<\/strong>. The &#8220;<strong>6<\/strong>&#8221; in both arguments indicates that the service shall be provided <strong>both<\/strong> on the <strong>IPv4<\/strong> as well as on the <strong>IPv6<\/strong> address. Leaving the &#8220;<strong>6<\/strong>&#8221; away <strong>only<\/strong> provides the service on the <strong>IPv4<\/strong> address.<\/li>\n\n\n\n<li><strong style=\"color: initial;\">push &#8220;redirect-gateway def1 bypass-dhcp&#8221;<\/strong><span style=\"color: initial;\"> tells the VPN client to bypass the VPN for DHCP queries. Otherwise, the client machine gets stuck when the DHCP lease on the client side terminates.<\/span><\/li>\n\n\n\n<li><strong>push &#8220;route-ipv6 2000::\/3&#8221;<\/strong> tells the VPN client machine to use the VPN for all IPv6 addresses that start with &#8220;2000::\/3&#8221;, and those are currently all routable IPv6 addresses [<a rel=\"noreferrer noopener\" href=\"https:\/\/whstatic.1and1.com\/help\/CloudServer\/EN-US\/d857940.html\" target=\"_blank\">2<\/a>].<\/li>\n\n\n\n<li><strong>push &#8220;dhcp-option DNS 8.8.8.8&#8221;<\/strong> and <strong>push &#8220;dhcp-option DNS 8.8.4.4&#8221;<\/strong> set <a rel=\"noreferrer noopener\" href=\"https:\/\/www.google.com\/\" target=\"_blank\">Google<\/a>&#8216;s DNS servers for the VPN client machine and so gives us an excellent and fast service.<\/li>\n\n\n\n<li><strong>reneg-sec<\/strong>: The specified 86400 seconds re-negotiate new encryption keys only once per day. For security reasons, a lower time period would be better, but some countries have put in efforts to detect and block encrypted communication, and this detection happens though the key exchange which seems to have a characteristic bit pattern [<a rel=\"noreferrer noopener\" href=\"https:\/\/link.springer.com\/chapter\/10.1007\/978-3-642-35795-4_56\" target=\"_blank\">6<\/a>]; therefore, a longer period has been set here.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"client-configuration\">OpenVPN Client Configuration<\/h3>\n\n\n\n<p>The generation of client configuration files is explained in [<a rel=\"noreferrer noopener\" href=\"https:\/\/openvpn.net\/community-resources\/how-to\/#setting-up-your-own-certificate-authority-ca-and-generating-certificates-and-keys-for-an-openvpn-server-and-multiple-clients\" target=\"_blank\">11<\/a>], and there are numerous guidelines in the internet. Therefore, I just want to give 2 examples and briefly point out some useful considerations.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"udp-based-vpn-full-tunneling-1\">UDP-based VPN, full tunneling<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># Konfigurationsdatei f\u00fcr den openVPN-Client auf ...\n\nclient\ndev              tun\nexplicit-exit-notify\nhand-window      90\nkeepalive        10 60\nnobind\npersist-key\npersist-tun\nproto            udp\nremote           caipirinha.spdns.org 1194\nremote-cert-tls  server\nreneg-sec        86400\nscript-security  2\nverb             1\n\n&lt;ca&gt;\n-----BEGIN CERTIFICATE-----\nMIIE2D...NNmlTg=\n-----END CERTIFICATE-----\n&lt;\/ca&gt;\n\n&lt;cert&gt;\n-----BEGIN CERTIFICATE-----\nMIIFJj...nbuzbI=\n-----END CERTIFICATE-----\n&lt;\/cert&gt;\n\n&lt;key&gt;\n-----BEGIN PRIVATE KEY-----\nMIIEvA...QcO+Q==\n-----END PRIVATE KEY-----\n&lt;\/key&gt;<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"tcp-based-vpn-full-tunneling-1\">TCP-based VPN, full tunneling<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># Konfigurationsdatei f\u00fcr den openVPN-Client auf ...\n\nclient\ndev              tun\nhand-window      90\nkeepalive        10 60\nnobind\npersist-key\npersist-tun\nproto            tcp\nremote           caipirinha.spdns.org 8080\nremote-cert-tls  server\nreneg-sec        86400\nscript-security  2\nverb             1\n\n&lt;ca&gt;\n-----BEGIN CERTIFICATE-----\nMIIE2D...NNmlTg=\n-----END CERTIFICATE-----\n&lt;\/ca&gt;\n\n&lt;cert&gt;\n-----BEGIN CERTIFICATE-----\nMIIFJj...nbuzbI=\n-----END CERTIFICATE-----\n&lt;\/cert&gt;\n\n&lt;key&gt;\n-----BEGIN PRIVATE KEY-----\nMIIEvA...QcO+Q==\n-----END PRIVATE KEY-----\n&lt;\/key&gt;<\/code><\/pre>\n\n\n\n<p>The following points proved to be useful for me:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rather than using separate files for the <strong>ca<\/strong>, the <strong>certificate<\/strong>, and the <strong>key<\/strong> of the client, all information can actually be packed into one file which then gives a complete configuration of the client. This eases the installation on mobile clients (smartphones, tablets) as you do not have to consider path names on the target device. For security reasons, the respective code blocks are not printed here.<\/li>\n\n\n\n<li>It is possible to use several <strong>remote<\/strong> statements. You can refer to different servers (if the client configuration is suitable for the servers) or you can name the very same server with different ports. On my server, I have different ports open which all point to the very same 4 different server processes. The reason is that sometimes, the dedicated <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> port 1194 is blocked in some geographies, but other ports might still work. In that case, you have to ensure that connections coming to all these ports are mapped back to the port of the server process. And you might include the statement <strong>remote-random<\/strong> so that one connection of the ones listed is chosen randomly.<\/li>\n\n\n\n<li>On the client, is it normally not necessary to bind the <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> process to a certain tun device or a certain port, different from the VPN server.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"further-improvements\">Further Improvements (OpenVPN)<\/h3>\n\n\n\n<p>Different network conditions might require tweaking one or the other parameters of the <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> service. [<a rel=\"noreferrer noopener\" href=\"https:\/\/haydenjames.io\/improving-openvpn-performance-and-throughput\/\" target=\"_blank\">8<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/hamy.io\/post\/0003\/optimizing-openvpn-throughput\/\" target=\"_blank\">9<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/community.openvpn.net\/openvpn\/wiki\/Gigabit_Networks_Linux\" target=\"_blank\">10<\/a>] contain some indications, especially with respect to different hardware and network conditions.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"dedicated-configurations\">Dedicated Configurations<\/h4>\n\n\n\n<p>As mentioned above, the <strong>client-config-dir<\/strong> directive can be used to refer to a folder that contains configurations for dedicated devices. An example is the file <strong>\/etc\/openvpn\/conf-1194\/Gabriel-SM960F<\/strong>. It contains the content:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Spezielle Konfigurationsdatei f\u00fcr Gabriels Galaxy Note 9 (gabriel-SM-N960F)\n#\n\nifconfig-push      192.168.10.251  255.255.255.0\nifconfig-ipv6-push fd01:0:0:a:0:0:1:fb\/111 fd01:0:0:a::1<\/code><\/pre>\n\n\n\n<p>This file makse the device with the client certificate named <strong>gabriel-SM-N960F<\/strong> always receive the same IP addresses, namely <strong>192.168.10.251<\/strong> (IPv4) and <strong>fd01:0:0:a:0:0:1:fb<\/strong> (IPv6). The name of the file must exactly match the VPN client&#8217;s common name (CN) that was defined when the client certificate was created [<a rel=\"noreferrer noopener\" href=\"http:\/\/wiki.integrator.com.br\/index.php?title=Instalando_e_configurando_o_OpenVPN\" target=\"_blank\">5<\/a>].<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">WireGuard Server Configuration<\/h3>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a> is a new and promising VPN protocol [<a rel=\"noreferrer noopener\" href=\"https:\/\/restoreprivacy.com\/vpn\/wireguard-vs-openvpn\/\" target=\"_blank\">15<\/a>] which is not yet as widespread as <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a>; it may therefore &#8220;escape&#8221; censorship authorities easier than <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> which can be detected by statistical analysis [<a rel=\"noreferrer noopener\" href=\"https:\/\/link.springer.com\/chapter\/10.1007\/978-3-642-35795-4_56\" target=\"_blank\">16<\/a>]. The setup of the server is described in [<a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/quickstart\/\" target=\"_blank\">12<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/stanislas.blog\/2019\/01\/how-to-setup-vpn-server-wireguard-nat-ipv6\/\" target=\"_blank\">13<\/a>], a more complex configuration is described in [<a rel=\"noreferrer noopener\" href=\"https:\/\/wiki.archlinux.org\/title\/WireGuard\" target=\"_blank\">19<\/a>]. A big advantage of <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a> is also that the code base is very lean, and hence performance on any given platform is higher than with <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a>.<\/p>\n\n\n\n<p>I personally find it unusual that you have to list the clients in the server configuration file rather than just having a general server configuration where any number of allowed clients can connect to. On my Linux server caipirinha.spdns.org, the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a> server configuration contains of 3 files:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\/etc\/wireguard\/wg_caipirinha_public.key<\/strong> is the <em>public<\/em> key of the service (the generation is described in [<a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/quickstart\/\" target=\"_blank\">12<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/stanislas.blog\/2019\/01\/how-to-setup-vpn-server-wireguard-nat-ipv6\/\" target=\"_blank\">13<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/wiki.archlinux.org\/title\/WireGuard\" target=\"_blank\">19<\/a>]).<\/li>\n\n\n\n<li><strong>\/etc\/wireguard\/wg_caipirinha_private.key<\/strong> is the <em>private<\/em> key of the service (the generation is described in [<a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/quickstart\/\" target=\"_blank\">12<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/stanislas.blog\/2019\/01\/how-to-setup-vpn-server-wireguard-nat-ipv6\/\" target=\"_blank\">13<\/a>], [<a rel=\"noreferrer noopener\" href=\"https:\/\/wiki.archlinux.org\/title\/WireGuard\" target=\"_blank\">19<\/a>]).<\/li>\n\n\n\n<li><strong>\/etc\/wireguard\/wg0.conf<\/strong> is the configuration file (the network device is named &#8220;wg0&#8221; on my machine).<\/li>\n<\/ul>\n\n\n\n<p>Similar to the <a rel=\"noreferrer noopener\" href=\"https:\/\/graphviz.org\/\" target=\"_blank\">openvpn<\/a> configurations described above, I spent a dedicated IPv4 and IPv6 subnet for the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a> server, in this case <strong>192.168.14.0\/24<\/strong> and <strong>fd01:0:0:e::\/64<\/strong>. The configuration file <strong>\/etc\/wireguard\/wg0.conf<\/strong> is easy to understand and contains important parameters that shall be discussed below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Interface]\nAddress = 192.168.14.1\/24,fd01:0:0:e::1\/64\nListenPort = 44576\nPrivateKey = SHo...\n\n&#91;Peer]\nPublicKey = pjp2PEboXA4RJhVoybXKuicNkz4XDZaW+c9yLtJq1gE=\nAllowedIPs = 192.168.14.2\/32,fd01:0:0:e::2\/128\nPersistentKeepalive = 30\n...\n&#91;Peer]\nPublicKey = fcEcFYQ6cOqe7H9L2PvkM78mkKottJLnKwiqp4WO91s=\nAllowedIPs = 192.168.14.7\/32,fd01:0:0:e::7\/128\nPersistentKeepalive = 30\n...<\/code><\/pre>\n\n\n\n<p>The section <strong>[Interface]<\/strong> describes the server setup:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Address<\/strong> lists the server&#8217;s IPv4 and IPv6 addresses.<\/li>\n\n\n\n<li><strong>ListenPort<\/strong> is the UDP port on which the service will listen.<\/li>\n\n\n\n<li><strong>PrivateKey<\/strong> is the private server key (can be read from the file <strong>\/etc\/wireguard\/wg_caipirinha_private.key<\/strong>). For security reasons, the key has only been displayed partly here.<\/li>\n<\/ul>\n\n\n\n<p>Each section <strong>[Peer]<\/strong> lists a possible client configuration. If you want to enable 10 clients on your server, you therefore need 10 such sections.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>PublicKey<\/strong> is the public key of the client.<\/li>\n\n\n\n<li><strong>AllowedIPs<\/strong> lists the IPv4 and IPv6 addresses which will be allocated to the client upon connection.<\/li>\n\n\n\n<li><strong>PersistentKeepalive<\/strong> configures the time in seconds after which &#8220;keep-alive packets&#8221; will be exchanged between the server and the client. This helps to keep connection settings on gateways that are in between the VPN client and the VPN server open; often firewalls and routers in between might otherwise delete the connection from their tables. A value of 25&#8230;30 is recommended.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">WireGuard Client Configuration<\/h3>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a> clients exist for all major operating systems. I would like to show a Windows 10 configuration that I set up on one of my notebooks according to [<a rel=\"noreferrer noopener\" href=\"https:\/\/serversideup.net\/how-to-configure-a-wireguard-windows-10-vpn-client\/\" target=\"_blank\">14<\/a>].<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"661\" height=\"518\" src=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/WireGuard-Windows-Client.jpg\" alt=\"\" class=\"wp-image-761\" srcset=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/WireGuard-Windows-Client.jpg 661w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/WireGuard-Windows-Client-300x235.jpg 300w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><figcaption class=\"wp-element-caption\">WireGuard Windows 10 Client Configuration<\/figcaption><\/figure>\n\n\n\n<p>As we can see, I also named the respective network interface on the client <strong>wg0<\/strong>, but you can use any other name, too. The detailed configuration of the only client connection is also easy to understand:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Interface]\nPrivateKey = 2B2...\nAddress = 192.168.14.7\/32, fd01:0:0:e::7\/128\nDNS = 192.168.14.1, fd01:0:0:e::1\n\n&#91;Peer]\nPublicKey = GvgCag5cvRaE18YUkAd+q\/NSOb54JYvXhylm1oz8OxI=\nAllowedIPs = 0.0.0.0\/0, ::\/0\nEndpoint = caipirinha.spdns.org:44576<\/code><\/pre>\n\n\n\n<p>The section <strong>[Interface]<\/strong> describes the client setup:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>PrivateKey<\/strong> is the private key of the client which is generated in the application itself [<a rel=\"noreferrer noopener\" href=\"https:\/\/serversideup.net\/how-to-configure-a-wireguard-windows-10-vpn-client\/\" target=\"_blank\">14<\/a>]. For security reasons, the key has only been displayed partly here.<\/li>\n\n\n\n<li><strong>Address<\/strong> lists the client&#8217;s IPv4 and IPv6 addresses.<\/li>\n\n\n\n<li><strong>DNS<\/strong> lists the DNS servers which shall be used when the VPN connection is active. In this case, the Linux server caipirinha.spdns.org has a DNS service running, hence I listed the server IPv4 and IPv6 addresses here. You might also use Google&#8217;s DNS with the IPv4 addresses 8.8.8.8, 8.8.4.4, for example. It is important to list the DNS servers as the ones that you were using before the VPN was established (e.g., the router&#8217;s IP like 192.168.4.1) might no longer be accessible after the VPN has been established.<\/li>\n<\/ul>\n\n\n\n<p>The section <strong>[Peer]<\/strong> contains information related to the server.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>PublicKey<\/strong> is the public key of the server which is located on the server in the file <strong>\/etc\/wireguard\/wg_caipirinha_public.key<\/strong>.<\/li>\n\n\n\n<li><strong>AllowedIPs<\/strong> is set to <strong>0.0.0.0\/0, ::\/0<\/strong> on this client which means that <em>all<\/em> traffic shall be sent via the VPN (fully tunneling VPN). Here, you have the chance to move from a fully tunneling VPN to a split VPN by listing subnets like <strong>192.168.2.0\/24<\/strong>, for example.<\/li>\n\n\n\n<li><strong>Endpoint<\/strong> lists the server FQDN and the port to which the client shall connect to.<\/li>\n<\/ul>\n\n\n\n<p>In a similar way, I set up another client on an Android smartphone using the official <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.wireguard.android\">WireGuard \u2013 Apps bei Google Play<\/a>, following the configuration model at [<a rel=\"noreferrer noopener\" href=\"https:\/\/heg.ge\/dualstack-vpn-mit-wireguard\/\" target=\"_blank\">23<\/a>].<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"360\" height=\"514\" src=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/WireGuard-auf-einem-Android-Telefon-3.jpg\" alt=\"\" class=\"wp-image-1442\" srcset=\"https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/WireGuard-auf-einem-Android-Telefon-3.jpg 360w, https:\/\/caipirinha.spdns.org\/wp\/wp-content\/uploads\/WireGuard-auf-einem-Android-Telefon-3-210x300.jpg 210w\" sizes=\"auto, (max-width: 360px) 100vw, 360px\" \/><figcaption class=\"wp-element-caption\">WireGuard Android Client Configuration<\/figcaption><\/figure>\n\n\n\n<p>Let&#8217;s see how that works out in reality. For the experiment, I am in Brazil and connect to my Linux server caipirinha.spdns.org in Germany with the configurations described above. Once, the connection has been established, I do a traceroute in Windows to <a rel=\"noreferrer noopener\" href=\"https:\/\/www.google.com\" target=\"_blank\">www.google.com<\/a> in IPv4 and IPv6:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>C:\\Users\\Dell&gt;tracert www.google.com\n\nRoutenverfolgung zu www.google.com &#91;142.250.185.68]\n\u00fcber maximal 30 Hops:\n\n  1   235 ms   236 ms   236 ms  CAIPIRINHA &#91;192.168.14.1]\n  2   241 ms   238 ms   238 ms  Router-EZ &#91;192.168.2.1]\n  3   259 ms   248 ms   249 ms  fra1813aihr002.versatel.de &#91;62.214.63.145]\n  4   250 ms   249 ms   248 ms  62.214.38.105\n  5   249 ms   247 ms   249 ms  72.14.204.149\n  6   249 ms   250 ms   251 ms  72.14.204.148\n  7   249 ms   249 ms   248 ms  108.170.236.175\n  8   251 ms   249 ms   250 ms  142.250.62.151\n  9   248 ms   247 ms   247 ms  fra16s48-in-f4.1e100.net &#91;142.250.185.68]\n\nAblaufverfolgung beendet.\n\nC:\\Users\\Dell&gt;tracert -6 www.google.com\n\nRoutenverfolgung zu www.google.com &#91;2a00:1450:4001:829::2004]\n\u00fcber maximal 30 Hops:\n\n  1   235 ms   235 ms   235 ms  fd01:0:0:e::1\n  2   239 ms   239 ms   237 ms  2001:16b8:30b3:f100:3681:c4ff:fecb:5780\n  3   249 ms   249 ms   247 ms  2001:1438::62:214:63:145\n  4   248 ms   249 ms   247 ms  2001:1438:0:1::4:302\n  5   250 ms   248 ms   248 ms  2001:1438:1:1001::1\n  6   250 ms   249 ms   248 ms  2001:1438:1:1001::2\n  7   252 ms   250 ms   249 ms  2a00:1450:8163::1\n  8   250 ms   249 ms   250 ms  2001:4860:0:1::5894\n  9   248 ms   250 ms   251 ms  2001:4860:0:1::5009\n 10   250 ms   249 ms   249 ms  fra24s06-in-x04.1e100.net &#91;2a00:1450:4001:829::2004]\n\nAblaufverfolgung beendet.\n\nC:\\Users\\Dell&gt;<\/code><\/pre>\n\n\n\n<p>We can see a couple of interesting points:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The latency from Brazil to my server is already &gt; 200 ms, that is not a very competitive connection.<\/li>\n\n\n\n<li>Despite the fact that between my Linux server caipirinha.spdns.org and Google, there are a range of machines, that connections has quite a low (additional) latency.<\/li>\n<\/ul>\n\n\n\n<p>Let&#8217;s now switch off the VPN and do a traceroute to <a rel=\"noreferrer noopener\" href=\"https:\/\/www.google.com\" target=\"_blank\">www.google.com<\/a> directly from the local ISP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>C:\\Users\\Dell&gt;tracert www.google.com\n\nRoutenverfolgung zu www.google.com &#91;172.217.29.100]\n\u00fcber maximal 30 Hops:\n\n  1    &lt;1 ms    &lt;1 ms    &lt;1 ms  fritz.box &#91;192.168.4.1]\n  2     1 ms    &lt;1 ms    &lt;1 ms  192.168.100.1\n  3     4 ms     4 ms     3 ms  179-199-160-1.user.veloxzone.com.br &#91;179.199.160.1]\n  4     5 ms     5 ms     4 ms  100.122.52.96\n  5    12 ms     6 ms     5 ms  100.122.25.245\n  6    11 ms    11 ms    11 ms  100.122.17.180\n  7    12 ms    12 ms    12 ms  100.122.18.52\n  8    12 ms    11 ms    11 ms  72.14.218.158\n  9    14 ms    13 ms    14 ms  108.170.248.225\n 10    15 ms    14 ms    14 ms  142.250.238.235\n 11    13 ms    13 ms    13 ms  gru09s19-in-f100.1e100.net &#91;172.217.29.100]\n\nAblaufverfolgung beendet.<\/code><\/pre>\n\n\n\n<p>For this test, only IPv4 was possible as I did not have IPv6 connection at the Ethernet port where my notebook was connected to. The overall connection is much faster, and we can clearly identify that it uns in the Brazilian internet (&#8220;179-199-160-1.user.veloxzone.com.br&#8221;).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Further Improvements (WireGuard)<\/h3>\n\n\n\n<p>A range of graphical user interfaces (GUIs) for the configuration of <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a> have come up that seek to overcome the need to deal with various configuration files on the server and the client side and align public keys and IP addresses. [<a rel=\"noreferrer noopener\" href=\"https:\/\/goneuland.de\/wireguard-guis-im-vergleich\/\" target=\"_blank\">17<\/a>] compares some GUIs for <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/\" target=\"_blank\">WireGuard<\/a>, [<a rel=\"noreferrer noopener\" href=\"https:\/\/adminforge.de\/linux-allgemein\/vpn\/wireguard-vpn-server-mit-web-interface-einrichten\/\" target=\"_blank\">18<\/a>] shows a further possibility.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"configuring-network-address-translation-nat\">Configuring Network Address Translation (NAT)<\/h3>\n\n\n\n<p>Additionally, to the configuration of the VPNs (and their respective start on the VPN server), we need to set up network address translation so that connections from the VPN networks are translated to the SoHo network. This is done with the sequence:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>readonly STD_IF='eth0'\n\u2026\niptables -t nat -F\niptables -t nat -A POSTROUTING -s 192.168.10.0\/24 -o ${STD_IF} -j MASQUERADE\niptables -t nat -A POSTROUTING -s 192.168.11.0\/24 -o ${STD_IF} -j MASQUERADE\niptables -t nat -A POSTROUTING -s 192.168.12.0\/24 -o ${STD_IF} -j MASQUERADE\niptables -t nat -A POSTROUTING -s 192.168.13.0\/24 -o ${STD_IF} -j MASQUERADE\niptables -t nat -A POSTROUTING -s 192.168.14.0\/24 -o ${STD_IF} -j MASQUERADE\n\u2026\n\n# Setup the NAT table for the VPNs.\nip6tables -t nat -F\nip6tables -t nat -A POSTROUTING -s fd01:0:0:a::\/64 -o ${STD_IF} -j MASQUERADE\nip6tables -t nat -A POSTROUTING -s fd01:0:0:b::\/64 -o ${STD_IF} -j MASQUERADE\nip6tables -t nat -A POSTROUTING -s fd01:0:0:c::\/64 -o ${STD_IF} -j MASQUERADE\nip6tables -t nat -A POSTROUTING -s fd01:0:0:d::\/64 -o ${STD_IF} -j MASQUERADE\nip6tables -t nat -A POSTROUTING -s fd01:0:0:e::\/64 -o ${STD_IF} -j MASQUERADE\n...<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>The VPN configuration mentioned above shows how to set up different VPNs that allow dual stack operations on a Linux server. Thus, VPN clients can initiate connections in IPv4 or IPv6 mode using the assigned IP addresses from a private address space; the configured <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Network_address_translation\" target=\"_blank\">network address translation<\/a> (<a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Network_address_translation\" target=\"_blank\">NAT<\/a>) translates the connections to a real-world IP address on the server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"outlook\">Outlook<\/h2>\n\n\n\n<p>The VPN server itself can also act as VPN client itself, and so, the connection from the original VPN client can be forwarded via other VPNs to other countries allowing the original VPN client to appear in different geographies depending upon the destination address of its outgoing connection. This can be useful in order to circumvent geo-blocking of media content, for example.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"sources\">Sources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Unique_local_address\" target=\"_blank\">1<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Unique_local_address\" target=\"_blank\">Unique local address<\/a> [Wikipedia]<\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/whstatic.1and1.com\/help\/CloudServer\/EN-US\/d857940.html\" target=\"_blank\">2<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/whstatic.1and1.com\/help\/CloudServer\/EN-US\/d857940.html\" target=\"_blank\">IPv6: Basics<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/IPv6_address#Stateless_address_autoconfiguration\" target=\"_blank\">3<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/IPv6_address#Stateless_address_autoconfiguration\" target=\"_blank\">Stateless address autoconfiguration<\/a> (SLAAC)<\/li>\n\n\n\n<li><s>[<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/OpenVPN\/easy-rsa-old\/blob\/master\/easy-rsa\/2.0\/pkitool\" target=\"_blank\">4<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/OpenVPN\/easy-rsa-old\/blob\/master\/easy-rsa\/2.0\/pkitool\" target=\"_blank\">OpenVPN \/ easy-rsa-old<\/a> [Github]<\/s> (superseded)<\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"http:\/\/wiki.integrator.com.br\/index.php?title=Instalando_e_configurando_o_OpenVPN\" target=\"_blank\">5<\/a>] = <a rel=\"noreferrer noopener\" href=\"http:\/\/wiki.integrator.com.br\/index.php?title=Instalando_e_configurando_o_OpenVPN\" target=\"_blank\">Instalando e configurando o OpenVPN<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/link.springer.com\/chapter\/10.1007\/978-3-642-35795-4_56\" target=\"_blank\">6<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/link.springer.com\/chapter\/10.1007\/978-3-642-35795-4_56\" target=\"_blank\">OpenVPN Traffic Identification Using Traffic Fingerprints and Statistical Characteristics<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/caipirinha.spdns.org\/wp\/?p=56\" target=\"_blank\">7<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/caipirinha.spdns.org\/wp\/?p=56\" target=\"_blank\">Internet Censorship in China<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/haydenjames.io\/improving-openvpn-performance-and-throughput\/\" target=\"_blank\">8<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/haydenjames.io\/improving-openvpn-performance-and-throughput\/\" target=\"_blank\">Improving OpenVPN performance and throughput<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/hamy.io\/post\/0003\/optimizing-openvpn-throughput\/\" target=\"_blank\">9<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/hamy.io\/post\/0003\/optimizing-openvpn-throughput\/\" target=\"_blank\">Optimizing OpenVPN Throughput<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/community.openvpn.net\/openvpn\/wiki\/Gigabit_Networks_Linux\" target=\"_blank\">10<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/community.openvpn.net\/openvpn\/wiki\/Gigabit_Networks_Linux\" target=\"_blank\">Optimizing performance on gigabit networks<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/openvpn.net\/community-resources\/how-to\/#setting-up-your-own-certificate-authority-ca-and-generating-certificates-and-keys-for-an-openvpn-server-and-multiple-clients\" target=\"_blank\">11<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/openvpn.net\/community-resources\/how-to\/#setting-up-your-own-certificate-authority-ca-and-generating-certificates-and-keys-for-an-openvpn-server-and-multiple-clients\" target=\"_blank\">Setting up your own Certificate Authority (CA) and generating certificates and keys for an OpenVPN server and multiple clients<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/quickstart\/\" target=\"_blank\">12<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/www.wireguard.com\/quickstart\/\" target=\"_blank\">WireGuard Quick Start<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/stanislas.blog\/2019\/01\/how-to-setup-vpn-server-wireguard-nat-ipv6\/\" target=\"_blank\">13<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/stanislas.blog\/2019\/01\/how-to-setup-vpn-server-wireguard-nat-ipv6\/\" target=\"_blank\">How to setup a VPN server using WireGuard (with NAT and IPv6)<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/serversideup.net\/how-to-configure-a-wireguard-windows-10-vpn-client\/\" target=\"_blank\">14<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/serversideup.net\/how-to-configure-a-wireguard-windows-10-vpn-client\/\" target=\"_blank\">How to configure a WireGuard Windows 10 VPN client<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/restoreprivacy.com\/vpn\/wireguard-vs-openvpn\/\" target=\"_blank\">15<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/restoreprivacy.com\/vpn\/wireguard-vs-openvpn\/\" target=\"_blank\">WireGuard vs OpenVPN: 7 Big Difference<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/link.springer.com\/chapter\/10.1007\/978-3-642-35795-4_56\" target=\"_blank\">16<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/link.springer.com\/chapter\/10.1007\/978-3-642-35795-4_56\" target=\"_blank\">OpenVPN Traffic Identification Using Traffic Fingerprints and Statistical Characteristics<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/goneuland.de\/wireguard-guis-im-vergleich\/\" target=\"_blank\">17<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/goneuland.de\/wireguard-guis-im-vergleich\/\" target=\"_blank\">Wireguard GUIs im Vergleich<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/adminforge.de\/linux-allgemein\/vpn\/wireguard-vpn-server-mit-web-interface-einrichten\/\" target=\"_blank\">18<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/adminforge.de\/linux-allgemein\/vpn\/wireguard-vpn-server-mit-web-interface-einrichten\/\" target=\"_blank\">WireGuard VPN Server mit Web Interface einrichten<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/wiki.archlinux.org\/title\/WireGuard\" target=\"_blank\">19<\/a>] = <a rel=\"noreferrer noopener\" href=\"https:\/\/wiki.archlinux.org\/title\/WireGuard\" target=\"_blank\">WireGuard [ArchWiki]<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/easy-rsa.readthedocs.io\/en\/latest\/\" target=\"_blank\">20<\/a>] = <a href=\"https:\/\/easy-rsa.readthedocs.io\/en\/latest\/\">Home &#8211; Easy RSA (easy-rsa.readthedocs.io)<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/wiki.archlinux.org\/title\/Easy-RSA#top-page\" target=\"_blank\">21<\/a>] = <a href=\"https:\/\/wiki.archlinux.org\/title\/Easy-RSA#top-page\">Easy-RSA &#8211; ArchWiki (archlinux.org)<\/a><\/li>\n\n\n\n<li>[<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/OpenVPN\/easy-rsa\" target=\"_blank\">22<\/a>] = <a href=\"https:\/\/github.com\/OpenVPN\/easy-rsa\">GitHub &#8211; OpenVPN\/easy-rsa: easy-rsa &#8211; Simple shell based CA utility<\/a><\/li>\n\n\n\n<li>[<a href=\"https:\/\/heg.ge\/dualstack-vpn-mit-wireguard\/\" target=\"_blank\" rel=\"noreferrer noopener\">23<\/a>] = <a href=\"https:\/\/heg.ge\/dualstack-vpn-mit-wireguard\/\">DualStack VPN mit Wireguard \u2013 sebastian heg.ge<\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This blog post explains how I set up dual stack (IPv4, IPv6) virtual private networks (VPN) with the open-source packages openvpn and WireGuard on my Linux server caipirinha.spdns.org. Clients (smartphones, tablets, notebooks) which connect to my server will be supplied with a dual stack VPN connections and can therefore use both IPv4 as well as IPv6 connections via the Linux server to the internet.<\/p>\n","protected":false},"author":1,"featured_media":760,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[35],"tags":[97,98,100],"class_list":["post-734","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-it","tag-openvpn","tag-vpn","tag-wireguard"],"_links":{"self":[{"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/734","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=734"}],"version-history":[{"count":22,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/734\/revisions"}],"predecessor-version":[{"id":1566,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/posts\/734\/revisions\/1566"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=\/wp\/v2\/media\/760"}],"wp:attachment":[{"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=734"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/caipirinha.spdns.org\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}