blog/public/posts/wireguard-vpn-with-2-or-mor.../index.html

300 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>WireGuard VPN with 2 or more subnets | tastyteablog</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="description" content="How to connect 2 subnets with WireGuard." />
<meta name="author" content="tastytea" />
<meta property="og:title" content="WireGuard VPN with 2 or more subnets" />
<meta property="og:description" content="How to connect 2 subnets with WireGuard." />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://blog.tastytea.de/posts/wireguard-vpn-with-2-or-more-subnets/" />
<meta property="article:published_time" content="2019-02-14T21:38:28&#43;01:00"/>
<meta property="article:modified_time" content="2019-02-15T01:38:40&#43;01:00"/>
<meta name="generator" content="Hugo 0.54.0" />
<link href="https://blog.tastytea.de/index.xml" rel="alternate" type="application/rss+xml" title="tastyteablog Feed" />
<link rel="shortcut icon" href="https://blog.tastytea.de/img/favicon.png" type="image/png" />
<!--[if lte IE 8]>
<link rel="stylesheet" href="https://blog.tastytea.de/assets/style-compat.css" />
<![endif]-->
<!--[if gt IE 8]><!-->
<link rel="stylesheet" href="https://blog.tastytea.de/assets/style.css" />
<!--<![endif]-->
</head>
<body>
<div class="pure-g">
<div class="pure-u-1-24 pure-u-md-5-24"></div>
<div class="pure-u-22-24 pure-u-md-14-24">
<div class="navigation-header">
<div class="pure-menu pure-menu-horizontal">
<a class="pure-menu-heading pure-menu-link" href="/">
tastyteablog
</a>
<ul class="pure-menu-list pull-end navigation-header-subtitle">
<li class="pure-menu-item pure-menu-disabled">I write things here.</li>
</ul>
</div>
</div>
<div class="navigation-content">
<div class="pure-menu pure-menu-horizontal">
<ul class="pure-menu-list">
<li class="pure-menu-item">
<a class="pure-menu-link" href="/posts/">Posts</a>
</li>
<li class="pure-menu-item">
<a class="pure-menu-link" href="/tags/">Tags</a>
</li>
<li class="pure-menu-item">
<a class="pure-menu-link" href="/index.xml">RSS</a>
</li>
</ul>
</div>
</div>
<div>
<div>
<h1 class="post-title">WireGuard VPN with 2 or more subnets</h1>
<div class="post-meta">
Date &#x5b;
<time datetime="2019-02-14T21:38:28&#43;01:00">2019-02-14</time>
&#x5d;
Tags &#x5b;
<a href="https://blog.tastytea.de/tags/wireguard/">wireguard</a>
<a href="https://blog.tastytea.de/tags/vpn/">vpn</a>
&#x5d;
</div>
</div>
<div><div class="paragraph">
<p>I wanted to create a <a href="https://en.wikipedia.org/wiki/WireGuard">WireGuard</a> VPN with
2 subnets in different physical places, each with their own server. I couldn&#8217;t
find an example how to do that, so I wrote this one.</p>
</div>
<div class="sect1">
<h2 id="_introduction">Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>I&#8217;m going to use the IP range <code>fd69::/48</code> for the VPN, <code>fd69:0:0:1::/64</code> for
subnet 1 and <code>fd69:0:0:2::/64</code> for subnet 2. I&#8217;m going to call the server of
subnet 1 <code>server1</code>, its first client <code>client1a</code>, the second one <code>client1b</code> and
so on.</p>
</div>
<div class="paragraph">
<p>All clients in subnet 1 will connect to <code>server1</code> and all clients in subnet 2
will connect to <code>server2</code>. <code>server1</code> and <code>server2</code> will be connected. If
<code>client1a</code> wants to connect to <code>client2a</code>, the route will be:
<code>client1a → server1 → server2 → client2a</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_preparations">Preparations</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="https://www.wireguard.com/install/">Install WireGuard</a>, create <code>/etc/wireguard</code>
and generate a key-pair on each participating peer.</p>
</div>
<div class="listingblock">
<div class="content">
<pre><div class="highlight"><pre class="chroma"><code class="language-sh" data-lang="sh">mkdir /etc/wireguard
<span class="nb">cd</span> /etc/wireguard
<span class="nb">umask</span> <span class="m">077</span>
wg genkey <span class="p">|</span> tee privatekey <span class="p">|</span> wg pubkey &gt; publickey</code></pre></div></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_configure_servers">Configure servers</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="title"><code>server1:/etc/wireguard/wg0.conf</code>:</div>
<div class="content">
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="c1"># This peer</span>
<span class="k">[Interface]</span>
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:1::1/48</span>
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s">&lt;PRIVATE KEY OF server1&gt;</span>
<span class="na">ListenPort</span> <span class="o">=</span> <span class="s">51820</span>
<span class="c1"># Server of subnet 2</span>
<span class="k">[Peer]</span>
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s">&lt;PUBLIC KEY OF server2&gt;</span>
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server2:51820</span>
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:2::/64</span>
<span class="c1"># Clients of subnet 1</span>
<span class="k">[Peer]</span>
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s">&lt;PUBLIC KEY OF client1a&gt;</span>
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:1::a/128</span>
<span class="k">[Peer]</span>
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s">&lt;PUBLIC KEY OF client1b&gt;</span>
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:1::b/128</span></code></pre></div></pre>
</div>
</div>
<div class="listingblock">
<div class="title"><code>server2:/etc/wireguard/wg0.conf</code>:</div>
<div class="content">
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="c1"># This peer</span>
<span class="k">[Interface]</span>
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:2::1/48</span>
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s">&lt;PRIVATE KEY OF server2&gt;</span>
<span class="na">ListenPort</span> <span class="o">=</span> <span class="s">51820</span>
<span class="c1"># Server of subnet 1</span>
<span class="k">[Peer]</span>
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s">&lt;PUBLIC KEY OF server1&gt;</span>
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server1:51820</span>
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:1::/64</span>
<span class="c1"># Clients of subnet 2</span>
<span class="k">[Peer]</span>
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s">&lt;PUBLIC KEY OF client2a&gt;</span>
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69:0:0:2::a/128</span></code></pre></div></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_configure_clients">Configure clients</h2>
<div class="sectionbody">
<div class="listingblock">
<div class="title"><code>client1a:/etc/wireguard/wg0.conf</code>:</div>
<div class="content">
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="k">[Interface]</span>
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:1::a/48</span>
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s">&lt;PRIVATE KEY OF client1a&gt;</span>
<span class="k">[Peer]</span>
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s">&lt;PUBLIC KEY OF server1&gt;</span>
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server1:51820</span>
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69::/48</span>
<span class="na">PersistentKeepalive</span> <span class="o">=</span> <span class="s">25</span></code></pre></div></pre>
</div>
</div>
<div class="listingblock">
<div class="title"><code>client1b:/etc/wireguard/wg0.conf</code>:</div>
<div class="content">
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="k">[Interface]</span>
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:1::b/48</span>
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s">&lt;PRIVATE KEY OF client1b&gt;</span>
<span class="k">[Peer]</span>
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s">&lt;PUBLIC KEY OF server1&gt;</span>
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server1:51820</span>
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69::/48</span>
<span class="na">PersistentKeepalive</span> <span class="o">=</span> <span class="s">25</span></code></pre></div></pre>
</div>
</div>
<div class="listingblock">
<div class="title"><code>client2a:/etc/wireguard/wg0.conf</code>:</div>
<div class="content">
<pre><div class="highlight"><pre class="chroma"><code class="language-cfg" data-lang="cfg"><span class="k">[Interface]</span>
<span class="na">Address</span> <span class="o">=</span> <span class="s">fd69:0:0:2::a/48</span>
<span class="na">PrivateKey</span> <span class="o">=</span> <span class="s">&lt;PRIVATE KEY OF client2a&gt;</span>
<span class="k">[Peer]</span>
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s">&lt;PUBLIC KEY OF server2&gt;</span>
<span class="na">Endpoint</span> <span class="o">=</span> <span class="s">server1:51820</span>
<span class="na">AllowedIPs</span> <span class="o">=</span> <span class="s">fd69::/48</span>
<span class="na">PersistentKeepalive</span> <span class="o">=</span> <span class="s">25</span></code></pre></div></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>AllowedIPs</code> setting acts as a routing table. When a peer tries to send a
packet to an IP, it will check <code>AllowedIPs</code>, and if the IP appears in the list,
it will send it through the WireGuard interface.</p>
</div>
<div class="paragraph">
<p>The <code>PersistentKeepalive</code> setting ensures that the connection is maintained and
that the peer continues to be reachable, even behind a NAT.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_start_vpn">Start VPN</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Run <code>wg-quick up wg0</code> on each peer.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_further_reading">Further reading</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The article <a href="https://www.stavros.io/posts/how-to-configure-wireguard/">How to easily configure WireGuard</a>
by Stavros Korokithakis helped me a great deal in understanding WireGuard.</p>
</div>
</div>
</div>
</div>
</div>
<div class="footer-content">
<div class="pure-menu pure-menu-horizontal">
<ul class="pure-menu-list">
<li class="pure-menu-item">
<a class="pure-menu-link" href="https://tastytea.de/">Website</a>
</li>
<li class="pure-menu-item">
<a class="pure-menu-link" href="https://schlomp.space/tastytea">Sourcecode</a>
</li>
<li class="pure-menu-item">
<a class="pure-menu-link" href="https://likeable.space/users/tastytea">Fediverse</a>
</li>
<li class="pure-menu-item">
<a href="https://blog.tastytea.de/index.xml" class="pure-menu-link">RSS</a>
</li>
<li class="pure-menu-item">
<a class="pure-menu-link" id="btn-gototop">
<span class="fixup">&#x21e7;&#xfe0e;</span>
</a>
</li>
</ul>
</div>
<div class="pure-menu pure-menu-horizontal">
<ul class="pure-menu-list">
<li class="pure-menu-item pure-menu-disabled">
&copy; 2019 &mdash; CC BY-NC 4.0
</li>
</ul>
</div>
</div>
<script>
function setElementsClass(selector, value) {
Array.prototype.forEach.call(
document.querySelectorAll(selector),
function(elem) { elem.className = value; }
);
}
setElementsClass('img', 'pure-img');
setElementsClass('table', 'pure-table');
function onResize() {
setElementsClass(
'.pure-menu', document.documentElement.clientWidth >= 568 ?
'pure-menu pure-menu-horizontal' : 'pure-menu'
);
}
onResize();
window.addEventListener('resize', onResize);
document.getElementById('btn-gototop').addEventListener('click', function() {
function scroll() {
if (window.pageYOffset > 0) { setTimeout(scroll, 8); }
window.scroll(0, window.pageYOffset - 128);
}
scroll();
});
</script>
</div>
<div class="pure-u-1-24 pure-u-md-5-24"></div>
</div>
</body>
</html>