213 lines
16 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="/bootstrap-4.4.1.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="https://router7.org/sass/sidebar.css">
<title>router7: installation</title>
</head>
<body>
<div id="content">
<div class="container">
<div class="row">
<div class="col-md-10"><nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">router7</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav ml-auto">
<a class="nav-item nav-link " href="/">Home </a>
<a class="nav-item nav-link " href="/architecture/">Architecture </a>
<a class="nav-item nav-link active" href="/installation/">Installation <span class="sr-only">(current)</span></a>
<a class="nav-item nav-link " href="https://github.com/rtr7/router7">GitHub </a>
</div>
</div>
</nav>
<h1 id="installation">Installation</h1>
<p>Connect your serial adapter (<a href="https://pcengines.ch/usbcom1a.htm">usbcom1a</a> works well if you dont have one already) to the apu2c4 and start a program to use it, e.g. <code>screen /dev/ttyUSB0 115200</code>. Then, power on the apu2c4 and configure it to do PXE boot:</p>
<ul>
<li>Press <code>F10</code> to enter the boot menu</li>
<li>Press <code>3</code> to enter setup</li>
<li>Press <code>n</code> to enable network boot</li>
<li>Press <code>c</code> to move mSATA to the top of the boot order</li>
<li>Press <code>e</code> to move iPXE to the top of the boot order</li>
<li>Press <code>s</code> to save configuration and exit</li>
</ul>
<p>Connect a network cable on <code>net0</code>, the port closest to the serial console port:</p>
<p><img src="https://raw.githubusercontent.com/rtr7/router7/master/devsetup.jpg"
width="800" alt="router7 development setup"></p>
<p>Next, create a router7 gokrazy instance (see <a href="https://gokrazy.org/quickstart/">gokrazy
quickstart</a> if youre unfamiliar with gokrazy):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>go install github.com/gokrazy/tools/cmd/gok@main
</span></span><span style="display:flex;"><span>go install github.com/rtr7/tools/cmd/...@latest
2022-10-17 17:52:15 +02:00
</span></span><span style="display:flex;"><span>mkdir /tmp/recovery
</span></span><span style="display:flex;"><span>gok -i router7 new
</span></span><span style="display:flex;"><span>gok -i router7 edit
</span></span></code></pre></div><p>Change the config until you have the following fields set:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;Hostname&#34;</span>: <span style="color:#e6db74">&#34;router7&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;Packages&#34;</span>: [
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;github.com/gokrazy/fbstatus&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;github.com/gokrazy/hello&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;github.com/gokrazy/serial-busybox&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;github.com/gokrazy/breakglass&#34;</span>
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;github.com/rtr7/router7/cmd/...&#34;</span>
</span></span><span style="display:flex;"><span> ],
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;SerialConsole&#34;</span>: <span style="color:#e6db74">&#34;ttyS0,115200&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;GokrazyPackages&#34;</span>: [
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;github.com/gokrazy/gokrazy/cmd/ntp&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#e6db74">&#34;github.com/gokrazy/gokrazy/cmd/randomd&#34;</span>
</span></span><span style="display:flex;"><span> ],
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;KernelPackage&#34;</span>: <span style="color:#e6db74">&#34;github.com/rtr7/kernel&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;FirmwarePackage&#34;</span>: <span style="color:#e6db74">&#34;github.com/rtr7/kernel&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;EEPROMPackage&#34;</span>: <span style="color:#e6db74">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Then, build an image:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>GOARCH<span style="color:#f92672">=</span>amd64 gok -i router7 overwrite <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --boot /tmp/recovery/boot.img <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --mbr /tmp/recovery/mbr.img <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --root /tmp/recovery/root.img
</span></span></code></pre></div><p>And serve the image for netboot installation:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>rtr7-recover <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --boot /tmp/recovery/boot.img <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --mbr /tmp/recovery/mbr.img <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span> --root /tmp/recovery/root.img
</span></span></code></pre></div><p>Specifically, <code>rtr7-recover</code>:</p>
<ul>
<li>trigger a reset <a href="#rebootor">if a Teensy with the rebootor firmware is attached</a></li>
<li>serve a DHCP lease to all clients which request PXE boot (i.e., your apu2c4)</li>
<li>serve via TFTP:
<ul>
<li>the PXELINUX bootloader</li>
<li>the router7 kernel</li>
<li>an initrd archive containing the rtr7-recovery-init program and mke2fs</li>
</ul>
</li>
<li>serve via HTTP the boot and root images</li>
<li>optionally serve via HTTP a backup.tar.gz image containing files for <code>/perm</code> (e.g. for moving to new hardware, rolling back corrupted state, or recovering from a disk failure)</li>
<li>exit once the router successfully wrote the images to disk</li>
</ul>
<h2 id="configuration">Configuration</h2>
<h3 id="interfaces">Interfaces</h3>
<p>The <code>/perm/interfaces.json</code> configuration file will be <a href="https://github.com/rtr7/tools/blob/57c2cdc3b629d2fbd13564ae37f6282f6ee8427f/cmd/rtr7-recovery-init/recoveryinit.go#L320">automatically created</a> if it is not present when you run the first recovery.</p>
<p>Example:</p>
2022-10-17 17:52:15 +02:00
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;interfaces&#34;</span>: [
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;hardware_addr&#34;</span>: <span style="color:#e6db74">&#34;12:34:56:78:9a:b0&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;lan0&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;addr&#34;</span>: <span style="color:#e6db74">&#34;192.168.0.1/24&#34;</span>
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;hardware_addr&#34;</span>: <span style="color:#e6db74">&#34;12:34:56:78:9a:b2&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;uplink0&#34;</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> ]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Schema: see <a href="https://github.com/rtr7/router7/blob/f86e20be5305fc0e7e77421e0f2abde98a84f2a7/internal/netconfig/netconfig.go#L183"><code>InterfaceConfig</code></a></p>
<h3 id="port-forwarding">Port Forwarding</h3>
<p>The <code>/perm/portforwardings.json</code> configuration file can be created to define port forwarding rules.</p>
<p>Example:</p>
2022-10-17 17:52:15 +02:00
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;forwardings&#34;</span>: [
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;proto&#34;</span>: <span style="color:#e6db74">&#34;tcp&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;port&#34;</span>: <span style="color:#e6db74">&#34;22&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;dest_addr&#34;</span>: <span style="color:#e6db74">&#34;10.0.0.10&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;dest_port&#34;</span>: <span style="color:#e6db74">&#34;22&#34;</span>
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;proto&#34;</span>: <span style="color:#e6db74">&#34;tcp&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;port&#34;</span>: <span style="color:#e6db74">&#34;80&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;dest_addr&#34;</span>: <span style="color:#e6db74">&#34;10.0.0.10&#34;</span>,
</span></span><span style="display:flex;"><span> <span style="color:#f92672">&#34;dest_port&#34;</span>: <span style="color:#e6db74">&#34;80&#34;</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> ]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Schema: see <a href="https://github.com/rtr7/router7/blob/f86e20be5305fc0e7e77421e0f2abde98a84f2a7/internal/netconfig/netconfig.go#L431"><code>portForwardings</code></a></p>
<h2 id="updates">Updates</h2>
<p>Run e.g. <code>rtr7-safe-update -updates_dir=$HOME/router7/updates</code> to:</p>
<ul>
<li>verify the router currently has connectivity, abort the update otherwise</li>
<li>download a backup archive of <code>/perm</code></li>
<li>build a new image</li>
<li>update the router</li>
<li>wait until the router restored connectivity, roll back the update using <code>rtr7-recover</code> otherwise</li>
</ul>
<p>The update step uses kexec to reduce the downtime to approximately 15 seconds.</p>
<h2 id="manual-recovery">Manual Recovery</h2>
<p>Given <code>rtr7-safe-update</code>s safeguards, manual recovery should rarely be required.</p>
<p>To manually roll back to an older image, invoke <code>rtr7-safe-update</code> via the
<code>recover.bash</code> script in the image directory underneath <code>-updates_dir</code>, e.g.:</p>
2022-10-17 17:52:15 +02:00
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>% cd ~/router7/updates/2018-07-03T17:33:52+02:00
</span></span><span style="display:flex;"><span>% ./recover.bash
</span></span></code></pre></div><h2 id="rebootor">Teensy rebootor</h2>
<p>The cheap and widely-available <a href="https://www.pjrc.com/store/teensypp.html">Teensy++ USB development board</a> comes with a firmware called rebootor, which is used by the <a href="https://www.pjrc.com/teensy/loader_cli.html"><code>teensy_loader_cli</code></a> program to perform hard resets.</p>
<p>This setup can be used to programmatically reset the apu2c4 (from <code>rtr7-recover</code>) by connecting the Teensy++ to the <a href="http://pcengines.ch/pdf/apu2.pdf">apu2c4s reset pins</a>:</p>
<ul>
<li>connect the Teensy++s <code>GND</code> pin to the apu2c4 J2s pin 4 (<code>GND</code>)</li>
<li>connect the Teensy++s <code>B7</code> pin to the apu2c4 J2s pin 5 (<code>3.3V</code>, resets when pulled to <code>GND</code>)</li>
</ul>
<p>You can find a working rebootor firmware .hex file at <a href="https://github.com/PaulStoffregen/teensy_loader_cli/issues/38">https://github.com/PaulStoffregen/teensy_loader_cli/issues/38</a></p>
<h2 id="prometheus">Prometheus</h2>
<p>See <a href="https://github.com/rtr7/router7/tree/master/contrib/prometheus">https://github.com/rtr7/router7/tree/master/contrib/prometheus</a> for example
configuration files, and install the <a href="https://grafana.com/dashboards/8288">router7 Grafana
Dashboard</a>.</p>
<hr>
<p class="small">
© 2018 Michael Stapelberg and contributors
</p>
</div>
<div class="col-md-2">
<aside class="bd-toc">
<nav id="TableOfContents">
<ul>
<li><a href="#configuration">Configuration</a>
<ul>
<li><a href="#interfaces">Interfaces</a></li>
<li><a href="#port-forwarding">Port Forwarding</a></li>
</ul>
</li>
<li><a href="#updates">Updates</a></li>
<li><a href="#manual-recovery">Manual Recovery</a></li>
<li><a href="#rebootor">Teensy rebootor</a></li>
<li><a href="#prometheus">Prometheus</a></li>
</ul>
</nav>
</aside>
</div>
</div>
</div>
</div>
<script src="/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="/popper-1.16.0.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="/bootstrap-4.4.1.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
</body>
</html>