2019-02-15 01:31:21 +01:00
|
|
|
<!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+01:00"/>
|
2019-02-15 01:36:23 +01:00
|
|
|
<meta property="article:modified_time" content="2019-02-15T01:35:32+01:00"/>
|
2019-02-15 01:31:21 +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 [
|
|
|
|
<time datetime="2019-02-14T21:38:28+01:00">2019-02-14</time>
|
|
|
|
]
|
|
|
|
Tags [
|
|
|
|
<a href="https://blog.tastytea.de/tags/wireguard/">wireguard</a>
|
|
|
|
<a href="https://blog.tastytea.de/tags/vpn/">vpn</a>
|
|
|
|
]
|
|
|
|
</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’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’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’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 > 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"><PRIVATE KEY OF server1></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"><PUBLIC KEY OF server2></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"><PUBLIC KEY OF client1a></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"><PUBLIC KEY OF client1b></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"><PRIVATE KEY OF server2></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"><PUBLIC KEY OF server1></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"><PUBLIC KEY OF client2a></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"><PRIVATE KEY OF client1a></span>
|
|
|
|
|
|
|
|
<span class="k">[Peer]</span>
|
|
|
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF server1></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"><PRIVATE KEY OF client1b></span>
|
|
|
|
|
|
|
|
<span class="k">[Peer]</span>
|
|
|
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF server1></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"><PRIVATE KEY OF client2a></span>
|
|
|
|
|
|
|
|
<span class="k">[Peer]</span>
|
|
|
|
<span class="na">PublicKey</span> <span class="o">=</span> <span class="s"><PUBLIC KEY OF server2></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">⇧︎</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">
|
|
|
|
© 2019 — 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>
|