tastyteablog https://blog.tastytea.de/ Recent content on tastyteablog Hugo 0.54.0 -- gohugo.io en tastytea@tastytea.de (tastytea) tastytea@tastytea.de (tastytea) CC BY-NC 4.0 Thu, 14 Feb 2019 21:38:28 +0100 WireGuard VPN with 2 or more subnets https://blog.tastytea.de/posts/wireguard-vpn-with-2-or-more-subnets/ Thu, 14 Feb 2019 21:38:28 +0100 tastytea@tastytea.de (tastytea) https://blog.tastytea.de/posts/wireguard-vpn-with-2-or-more-subnets/ <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> Using AsciiDoc(tor) with Gitea https://blog.tastytea.de/posts/using-asciidoc-with-gitea/ Sat, 26 Jan 2019 13:03:36 +0100 tastytea@tastytea.de (tastytea) https://blog.tastytea.de/posts/using-asciidoc-with-gitea/ <div class="paragraph"> <p>In this blogpost I describe what I did to get AsciiDoc support into <a href="https://gitea.io/">Gitea</a>. If you want more than syntax highlighting and basic formatting, Gitea has to be patched unfortunately(this <a href="https://github.com/go-gitea/gitea/issues/4935">issue</a> has already been reported). But I think most people will only need to edit 1 configuration file and are done.</p> </div> <div class="sect1"> <h2 id="_asciidoctor_or_asciidoc">Asciidoctor or AsciiDoc?</h2> <div class="sectionbody"> <div class="paragraph"> <p><a href="https://asciidoctor.org/">Asciidoctor</a> has inbuilt support for <a href="https://highlightjs.org/">highlight.js</a>, the solution Gitea uses and is therefore the best choice in most scenarios. If you can&#8217;t or don&#8217;t want to use it you can use <a href="http://asciidoc.org/">AsciiDoc</a>.</p> </div> <div class="paragraph"> <p>Add the following section to <code>conf/app.ini</code> in your Gitea path. The change causes <code>.adoc</code> files to be rendered with asciidoctor.</p> </div> <div class="listingblock"> <div class="content"> <pre><div class="highlight"><pre class="chroma"><code class="language-ini" data-lang="ini"><span class="k">[markup.asciidoc]</span> <span class="na">ENABLED</span> <span class="o">=</span> <span class="s">true</span> <span class="c1">; List of file extensions that should be rendered by an external command</span> <span class="na">FILE_EXTENSIONS</span> <span class="o">=</span> <span class="s">.adoc,.asciidoc</span> <span class="c1">; External command to render all matching extensions</span> <span class="na">RENDER_COMMAND</span> <span class="o">=</span> <span class="s">&#34;asciidoctor --backend=html5 --no-header-footer --attribute source-highlighter=highlightjs --out-file=- -&#34;</span> <span class="c1">; Don&#39;t pass the file on STDIN, pass the filename as argument instead.</span> <span class="na">IS_INPUT_FILE</span> <span class="o">=</span> <span class="s">false</span></code></pre></div></pre> </div> </div> <div class="paragraph"> <p>If you want to use asciidoc instead the command would be: <code>asciidoc --backend=xhtml11 --no-header-footer --attribute source-highlighter=highlight --out-file=- -</code>. I would choose the <code>xhtml11</code> backend because it is the only one that encloses code snippets with <code>&lt;code&gt;</code> tags. Instead of <a href="http://www.andre-simon.de/doku/highlight/en/highlight.html">highlight</a> you can use <a href="http://www.gnu.org/software/src-highlite/">source-highlight</a> or <a href="http://pygments.org/">Pygments</a>.</p> </div> <div class="paragraph"> <p>If you use asciidoctor and don&#8217;t need tables or other fancy stuff you&#8217;re now done! If you use asciidoc, you&#8217;ll have to patch Gitea to get syntax highlighting.</p> </div> </div> </div> <div class="sect1"> <h2 id="_patching_gitea">Patching Gitea</h2> <div class="sectionbody"> <div class="paragraph"> <p>The sanitizer strips almost all attributes from HTML-tags, as a security precaution. I&#8217;ve added exceptions for:</p> </div> <div class="ulist"> <ul> <li> <p><code>class</code> attributes on all the tags Asciidoctor introduces,</p> </li> <li> <p>Numerous attributes on <code>table</code> tags,</p> </li> <li> <p><code>align</code> and <code>valign</code> on <code>td</code> tags,</p> </li> <li> <p><code>style</code> attributes on <code>span</code> tags, but only if they contain nothing more than color and font definitions.</p> </li> </ul> </div> <div class="paragraph"> <p>If you use Asciidoctor with highlight.js output, you don&#8217;t need to allow <code>style</code> attributes, if you don&#8217;t use tables you can omit the lines that deal with them and the <code>class</code> exception is only useful if you add custom CSS to use them.</p> </div> <div class="paragraph"> <p>Apply the patch with <code>patch -p1 &lt; gitea_relax-sanitizer.patch</code>.</p> </div> <div class="listingblock"> <div class="content"> <pre><div class="highlight"><pre class="chroma"><code class="language-diff" data-lang="diff"><span class="gh">diff -ur a/modules/markup/sanitizer.go b/modules/markup/sanitizer.go </span><span class="gh"></span><span class="gd">--- a/modules/markup/sanitizer.go 2019-01-26 16:04:56.014108339 +0100 </span><span class="gd"></span><span class="gi">+++ b/modules/markup/sanitizer.go 2019-01-26 16:03:21.776401012 +0100 </span><span class="gi"></span><span class="gu">@@ -38,6 +38,16 @@ </span><span class="gu"></span> // Custom URL-Schemes sanitizer.policy.AllowURLSchemes(setting.Markdown.CustomURLSchemes...) <span class="gi">+ // Allow style on span tags </span><span class="gi">+ sanitizer.policy.AllowAttrs(&#34;style&#34;).Matching(regexp.MustCompile(`^(background-)?color:[^;]+(; ?font[^;]+)?;?$`)).OnElements(&#34;span&#34;) </span><span class="gi">+ </span><span class="gi">+ // Allow class attribute </span><span class="gi">+ sanitizer.policy.AllowAttrs(&#34;class&#34;).OnElements(&#34;code&#34;, &#34;pre&#34;, &#34;span&#34;, &#34;div&#34;, &#34;p&#34;, &#34;table&#34;, &#34;td&#34;) </span><span class="gi">+ </span><span class="gi">+ // Allow table attributes </span><span class="gi">+ sanitizer.policy.AllowAttrs(&#34;width&#34;, &#34;frame&#34;, &#34;rules&#34;, &#34;cellspacing&#34;, &#34;cellpadding&#34;).OnElements(&#34;table&#34;) </span><span class="gi">+ sanitizer.policy.AllowAttrs(&#34;width&#34;).OnElements(&#34;col&#34;) </span><span class="gi">+ sanitizer.policy.AllowAttrs(&#34;align&#34;, &#34;valign&#34;).OnElements(&#34;td&#34;) </span><span class="gi"></span> }) } </code></pre></div></pre> </div> </div> </div> </div> <div class="sect1"> <h2 id="_tables_without_borders">Tables without borders</h2> <div class="sectionbody"> <div class="paragraph"> <p>I used tables without borders in a manpage I wrote for the list of options. Gitea insist on drawing borders around them, so I had to create a custom CSS snippet.</p> </div> <div class="paragraph"> <p>In your Gitea directory, create <code>custom/templates/custom/header.tmpl</code>.</p> </div> <div class="listingblock"> <div class="content"> <pre><div class="highlight"><pre class="chroma"><code class="language-css" data-lang="css"><span class="o">&lt;</span><span class="nt">style</span><span class="o">&gt;</span> <span class="c">/* Additions for asciidoc */</span> <span class="p">.</span><span class="nc">markdown</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="nt">code</span><span class="o">)</span> <span class="nt">table</span><span class="p">.</span><span class="nc">frame-none</span> <span class="p">{</span> <span class="k">border</span><span class="p">:</span> <span class="mi">0</span> <span class="cp">!important</span><span class="p">;</span> <span class="p">}</span> <span class="p">.</span><span class="nc">markdown</span><span class="p">:</span><span class="nd">not</span><span class="o">(</span><span class="nt">code</span><span class="o">)</span> <span class="nt">table</span><span class="p">.</span><span class="nc">grid-none</span> <span class="o">*</span> <span class="p">{</span> <span class="k">border</span><span class="p">:</span> <span class="mi">0</span> <span class="cp">!important</span><span class="p">;</span> <span class="p">}</span> <span class="o">&lt;/</span><span class="nt">style</span><span class="o">&gt;</span></code></pre></div></pre> </div> </div> </div> </div>