<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://www.forshee.me/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.forshee.me/" rel="alternate" type="text/html" /><updated>2022-11-11T04:05:37+00:00</updated><id>https://www.forshee.me/feed.xml</id><title type="html">Seth Forshee’s Blog</title><subtitle>Personal blog of Seth Forshee.</subtitle><author><name>Seth Forshee</name></author><entry><title type="html">EdgeRouter: Accept OpenVPN Connections on Multiple Ports</title><link href="https://www.forshee.me/edgerouter-accept-openvpn-connections-on-multiple-ports/" rel="alternate" type="text/html" title="EdgeRouter: Accept OpenVPN Connections on Multiple Ports" /><published>2016-09-28T00:00:00+00:00</published><updated>2016-09-28T00:00:00+00:00</updated><id>https://www.forshee.me/edgerouter-accept-openvpn-connections-on-multiple-ports</id><content type="html" xml:base="https://www.forshee.me/edgerouter-accept-openvpn-connections-on-multiple-ports/">&lt;p&gt;Since different networks frequently have different restrictions on what ports
are allowed to access the internet, it’s useful to have OpenVPN listening on 
multiple ports for incoming connections. However OpenVPN does not support 
listening on multiple ports from a single instance of the server. The usual 
advice is to run separate instances of OpenVPN for each port.&lt;/p&gt;

&lt;p&gt;This has some obvious disadvantages - more configurations to manage, more 
subnets, more firewall rules, etc. Fortunately there’s another way we can do 
this, by having the router translate the destination port for incoming packets
to a different port, commonly called &lt;em&gt;port forwarding&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The Ubiquiti EdgeRouter products offer two different configuration interfaces 
for setting this up, &lt;em&gt;destination NAT&lt;/em&gt; (&lt;em&gt;DNAT&lt;/em&gt;) and &lt;em&gt;port forwarding&lt;/em&gt;. I’ve 
chosen to use DNAT, simply because I wanted to play around with the NAT 
functionality.&lt;/p&gt;

&lt;h2 id=&quot;which-ports&quot;&gt;Which Ports?&lt;/h2&gt;

&lt;p&gt;Before starting we need to know which ports we want OpenVPN to listen on. This 
will vary depending on the situation. I’m going to assume a typical home user 
who wants to be able to access their home network from various locations and who 
does not run a public facing web server from their network.&lt;/p&gt;

&lt;p&gt;Any network which allows general web access must allow clients to establish 
connections over TCP ports 80 and 443, which respectively are the standard ports 
for HTTP and HTTPS. Therefore setting up OpenVPN to listen on these ports will 
allow access from practically any network. In this example I’ll assume that 
OpenVPN is listening on TCP port 443 and we want to also forward connections on 
port 80.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-dnat&quot;&gt;Setting Up DNAT&lt;/h2&gt;

&lt;p&gt;The instructions here assume that you already have OpenVPN up and running on the 
EdgeRouter. Please see
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-5-openvpn-setup/&quot;&gt;here&lt;/a&gt;
for more information about OpenVPN setup. That post also notes a pitfall of 
running OpenVPN on port 443 and how to handle it.&lt;/p&gt;

&lt;p&gt;The following commands set up a DNAT rule to forward incoming connections on 
port 80 to port 443.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit service nat rule &amp;lt;rule-number&amp;gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;description &lt;span class=&quot;s2&quot;&gt;&quot;Port forward for OpenVPN&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set type &lt;/span&gt;destination
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;inbound-interface &amp;lt;wan-iface&amp;gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;destination port 80
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;inside-address port 443
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;protocol tcp&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Fill in the rule number and the WAN interface. The rule number is only going to 
be significant if you have other DNAT rules, as rules will be executed 
sequentially.  I found
&lt;a href=&quot;https://help.ubnt.com/hc/en-us/articles/204976494-EdgeMAX-Add-source-NAT-rules&quot;&gt;this article&lt;/a&gt; 
from Ubiquiti which states that source/masquerade NAT rules must be numbered 
5000 or higher, but I didn’t find anything stating a similar limitation on the 
number of DNAT rules. It’s probably a good idea to leave some space in case you 
later need to insert rules before this one, so something like 100 should be 
fine. You can always change the rule number later by copying the rule to a new 
one and deleting the original.&lt;/p&gt;

&lt;p&gt;After committing these changes it will be possible to connect to OpenVPN on both 
TCP ports 80 and 443. You might think that the firewall rules need updates to 
allow incoming TCP connections on port 80, but this isn’t the case. DNAT happens 
before the firewall, so a rule is only needed for the translated address.&lt;/p&gt;

&lt;h2 id=&quot;limitations&quot;&gt;Limitations&lt;/h2&gt;

&lt;p&gt;There is one significant limitation to this approach - it’s not possible to 
forward TCP connections to a UDP port, or vice versa, since they are different 
protocols. If you wish to accept both TCP and UDP connections it is necessary to 
run two OpenVPN instances. In that case the rule above can be modified to 
specify &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tcp_udp&lt;/code&gt; for the protocol so that connections using either protocol 
will be forwarded.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="edgerouter" /><category term="networking" /><summary type="html">Since different networks frequently have different restrictions on what ports are allowed to access the internet, it’s useful to have OpenVPN listening on multiple ports for incoming connections. However OpenVPN does not support listening on multiple ports from a single instance of the server. The usual advice is to run separate instances of OpenVPN for each port.</summary></entry><entry><title type="html">Fixing 256-color Support with tmux in terminator</title><link href="https://www.forshee.me/fixing-256-color-support-in-tmux-with-terminator/" rel="alternate" type="text/html" title="Fixing 256-color Support with tmux in terminator" /><published>2016-05-26T00:00:00+00:00</published><updated>2016-05-26T00:00:00+00:00</updated><id>https://www.forshee.me/fixing-256-color-support-in-tmux-with-terminator</id><content type="html" xml:base="https://www.forshee.me/fixing-256-color-support-in-tmux-with-terminator/">&lt;p&gt;I use &lt;a href=&quot;http://gnometerminator.blogspot.com/p/introduction.html&quot;&gt;terminator&lt;/a&gt; for 
my terminal emulator. Generally everything works well, but one problem has been 
bothering me recently. My vim color scheme shows up fine in terminator but not 
from tmux within terminator. Everything is okay when using tmux in 
gnome-terminal though, so it seems to be the combination of tmux and terminator 
that is problematic.&lt;/p&gt;

&lt;p&gt;After a little digging I found out that this is due to terminator setting 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TERM=xterm&lt;/code&gt; in the environment, causing tmux to think that the terminal doesn’t 
support 256 colors. This is easily verified by the fact that running 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TERM=xterm-256color tmux&lt;/code&gt; fixes the issue.&lt;/p&gt;

&lt;p&gt;If terminator supports 256 colors, why is it setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TERM&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xterm&lt;/code&gt; instead 
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xterm-256color&lt;/code&gt;? I didn’t really dig into it, but the gory details are 
&lt;a href=&quot;https://bugzilla.gnome.org/show_bug.cgi?id=640940&quot;&gt;here&lt;/a&gt; for anyone who is 
interested. The tl;dr is that it doesn’t look like it will get fixed soon.&lt;/p&gt;

&lt;p&gt;But since the terminal really does support 256 colors, a simple workaround is to 
just override &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TERM&lt;/code&gt; in the environment. This should only be done for terminator 
though, we don’t want to mess with the variable as set by other terminal 
emulators.&lt;/p&gt;

&lt;p&gt;This can be done in the terminator configuration. It’s part of the profile 
settings though, so if you have more than one profile it needs to be done for 
each one.&lt;/p&gt;

&lt;p&gt;In the gui you can open the preferences and navigate to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Profiles -&amp;gt; &amp;lt;profile&amp;gt; 
-&amp;gt; Command&lt;/code&gt;. Check the box to run a custom command then enter 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TERM=xterm-256color bash -l&lt;/code&gt; as the custom command (assuming you use bash, if 
not substitute your shell). Or open &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.config/terminator/config&lt;/code&gt; and add this 
line to each profile:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;custom_command = TERM=xterm-256color bash -l
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Newly launched terminator windows will have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TERM=xterm-256color&lt;/code&gt;.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="Linux" /><summary type="html">I use terminator for my terminal emulator. Generally everything works well, but one problem has been bothering me recently. My vim color scheme shows up fine in terminator but not from tmux within terminator. Everything is okay when using tmux in gnome-terminal though, so it seems to be the combination of tmux and terminator that is problematic.</summary></entry><entry><title type="html">Ubiquiti EdgeRouter Lite Setup Part 6: Odds and Ends</title><link href="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-6-odds-and-ends/" rel="alternate" type="text/html" title="Ubiquiti EdgeRouter Lite Setup Part 6: Odds and Ends" /><published>2016-03-22T00:00:00+00:00</published><updated>2016-03-22T00:00:00+00:00</updated><id>https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-6-odds-and-ends</id><content type="html" xml:base="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-6-odds-and-ends/">&lt;p&gt;In this final post on configuring the ERL we’ll cover some miscellaneous items
that don’t warrant a full post on their own. See
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-1-the-basics/&quot;&gt;part 1&lt;/a&gt;
for a list of all posts in this series.&lt;/p&gt;

&lt;h2 id=&quot;dynamic-dns&quot;&gt;Dynamic DNS&lt;/h2&gt;

&lt;p&gt;The ERL can automatically update your IP address with a number of dynamic DNS
providers. I’m using the following configuration with DNS-O-Matic:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;show service dns dynamic 
&lt;span class=&quot;go&quot;&gt; interface eth0.2 {
     service dyndns {
         host-name all.dnsomatic.com
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;         login &amp;lt;username&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;         password &amp;lt;password&amp;gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;         server updates.dnsomatic.com
     }
 }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;static-dhcp-mappings&quot;&gt;Static DHCP Mappings&lt;/h2&gt;

&lt;p&gt;Sometimes it’s useful to assign known IPv4 addresses to specific machines. This
example demonstrates how to set this up.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit service dhcp-server shared-network-name &amp;lt;name&amp;gt; subnet &amp;lt;subnet&amp;gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;static-mapping &amp;lt;name&amp;gt; mac-address &amp;lt;mac-address&amp;gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;static-mapping &amp;lt;name&amp;gt; ip-address &amp;lt;ip-address&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;changing-the-host-name&quot;&gt;Changing the Host Name&lt;/h2&gt;

&lt;p&gt;The default host name for the ERL is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ubnt&lt;/code&gt;, but this can be easily changed.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;system host-name &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;google-fiber&quot;&gt;Google Fiber&lt;/h2&gt;

&lt;p&gt;According to the information available on various forums and blogs, in order to
get maximum performance when using the ERL in place of the Google Fiber network
box traffic in and out of the WAN interface must be tagged for VLAN 2 and have
the VLAN priority set to 3, and hardware offloading should be enabled. I’ve
never tried using the ERL with any other configuration, but I can confirm that
I’m seeing &lt;a href=&quot;http://speedtest.dslreports.com/speedtest/3203290&quot;&gt;good speeds&lt;/a&gt;
with this configuration.&lt;/p&gt;

&lt;p&gt;To apply these settings, delete most other settings from the WAN interface
(besides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;duplex auto&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;speed auto&lt;/code&gt;) and do the following:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit interfaces ethernet &amp;lt;iface&amp;gt; vif 2
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;description &lt;span class=&quot;s2&quot;&gt;&quot;Google Fiber&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;address dhcp
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;egress-qos 0:3
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;system offload ipv4 forwarding &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;system offload ipv4 vlan &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;system offload ipv6 forwarding &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;system offload ipv6 vlan &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You’ll also need to apply your IPv6 prefix delegation settings to the virtual
interface.&lt;/p&gt;

&lt;h2 id=&quot;staying-up-to-date&quot;&gt;Staying Up to Date&lt;/h2&gt;

&lt;p&gt;It’s a good idea to keep your router firmware up to date to ensure that you
have all the latest security fixes. I haven’t found any way to receive emails
or similar when new firmware is made available, but firmware announcements are
posted to the
&lt;a href=&quot;http://community.ubnt.com/t5/EdgeMAX-Updates-Blog/bg-p/Blog_EdgeMAX&quot;&gt;EdgeMax Updates Blog&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In my opinion Ubiquiti’s EdgeRouter Lite is a very nice step up from the
typical home or small office router for those who want more control over their
networks. These posts have described configuration of some of the most common
features needed for a basic home or small office network.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="edgerouter" /><category term="networking" /><summary type="html">In this final post on configuring the ERL we’ll cover some miscellaneous items that don’t warrant a full post on their own. See part 1 for a list of all posts in this series.</summary></entry><entry><title type="html">Ubiquiti EdgeRouter Lite Setup Part 5: OpenVPN Setup</title><link href="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-5-openvpn-setup/" rel="alternate" type="text/html" title="Ubiquiti EdgeRouter Lite Setup Part 5: OpenVPN Setup" /><published>2016-03-16T00:00:00+00:00</published><updated>2016-03-16T00:00:00+00:00</updated><id>https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-5-openvpn-setup</id><content type="html" xml:base="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-5-openvpn-setup/">&lt;p&gt;In previous posts we’ve covered everything required to set up a network with
multiple VLANs and IPv6 (see &lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-1-the-basics/&quot;&gt;part 1&lt;/a&gt; for a list of all posts in this
series). Today we’re going to talk about setting up an OpenVPN server on the ERL.&lt;/p&gt;

&lt;p&gt;If you aren’t familiar with VPNs, think of them as encrypted tunnels used to
connect computers over the internet. Common uses for VPNs include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Providing privacy while using public networks, especially open public wifi
hotspots.&lt;/li&gt;
  &lt;li&gt;Enabling secure, remote access to LANs, connecting remote networks.
Corporations often use this to allow employees to access the corporate
network remotely.&lt;/li&gt;
  &lt;li&gt;Connecting networks in multiple, fixed locations. For example a business with
multiple offices might use this to securely connect together the various
office networks via the internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The VPN setup described here can be used for the first two use cases above but
not for the third.&lt;/p&gt;

&lt;p&gt;There are several protocols which can be used to set up a VPN, including
&lt;a href=&quot;https://en.wikipedia.org/wiki/Point-to-Point_Tunneling_Protocol&quot;&gt;PPTP&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Layer_2_Tunneling_Protocol&quot;&gt;L2TP&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/Secure_Socket_Tunneling_Protocol&quot;&gt;SSTP&lt;/a&gt;, and
&lt;a href=&quot;https://en.wikipedia.org/wiki/OpenVPN&quot;&gt;OpenVPN&lt;/a&gt;. I’ve chosen OpenVPN here
because it’s secure, flexible, and open source. The paticular configuration is
very specific to my needs and level of paranioa. Consult the
&lt;a href=&quot;https://openvpn.net/index.php/open-source/documentation.html&quot;&gt;OpenVPN documentation&lt;/a&gt;
to help you modify this setup for your needs.&lt;/p&gt;

&lt;h2 id=&quot;generating-certificates&quot;&gt;Generating Certificates&lt;/h2&gt;

&lt;p&gt;OpenVPN uses public key cryptography in essentially the same way it’s used to
make secure connections to websites. This means we need a public key
infrastructure capable of generating signed public/private key pairs, which in
turn means we need to create our own certificate authority (CA). There’s a
script on the ERL to help us do that.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; /usr/lib/ssl/misc
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;./CA.sh &lt;span class=&quot;nt&quot;&gt;-newca&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You’ll be asked a number of questions during the process, and skipping them may
cause it to fail. Just answer the best you can. This is going to happen several
times while setting up the certificates.&lt;/p&gt;

&lt;p&gt;If you supply a password here, make sure you remember it. You’re going to need
it! Of course if you forget it you can always start the process over again at
the beginning.&lt;/p&gt;

&lt;p&gt;Once this completes you’ll have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;demoCA&lt;/code&gt; directory containing a number of
files. The important ones are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cakey.pem&lt;/code&gt;, which is the private key for your
CA, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cacert.pem&lt;/code&gt;, which is the public key.&lt;/p&gt;

&lt;p&gt;Next we’ll generate a public/private keypair for the OpenVPN server.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;./CA.sh &lt;span class=&quot;nt&quot;&gt;-newreq&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;./CA.sh &lt;span class=&quot;nt&quot;&gt;-sign&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will generate two files, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newkey.pem&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;newcert.pem&lt;/code&gt;, which are
respectively the private and public halves of your server certificate.&lt;/p&gt;

&lt;p&gt;Now we’re going to move all of these key files to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/config/auth/&lt;/code&gt;. This will
ensure that they’re preserved across firmware upgrades and include in your
configuration backups.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cp &lt;/span&gt;demoCA/cacert.pem demoCA/private/cakey.pem /config/auth
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mv &lt;/span&gt;newcert.pem /config/auth/host.pem
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mv &lt;/span&gt;newkey.pem /config/auth/host.key&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next we’ll generate a Diffie-Hellman parameter file. This will allow clients
and the server to generate shared session keys without ever having to transmit
that key over the internet, so even if someone compromised the server
certificate they would be unable to decrypt session traffic. I use a key size
of 2048, though 1024 is more common and probably safe (though I don’t claim to
be a crypto expert).&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;openssl dhparam &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; /config/auth/dhp.pem &lt;span class=&quot;nt&quot;&gt;-2&lt;/span&gt; 2048&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is going to take a while, so go get a cup of your favorite beverage. No
need to hurry.&lt;/p&gt;

&lt;p&gt;Once that’s completed you’ll need keys for clients, preferably one set per
client.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;./CA.sh &lt;span class=&quot;nt&quot;&gt;-newreq&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;./CA.sh &lt;span class=&quot;nt&quot;&gt;-sign&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mv &lt;/span&gt;newcert.pem /config/auth/client1.pem
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mv &lt;/span&gt;newkey.pem /config/auth/client1.key&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;At this point I note that some other guides state that you should remove the
password from your client key files. I honestly can’t remember whether or not I
did this, or maybe I just didn’t supply a password for the client certificates.
Anyway, here’s the command to do this if you’re having issues because the
client keys have a password, or if you’re just getting annoyed at entering the
password each time you connect:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;openssl rsa &lt;span class=&quot;nt&quot;&gt;-in&lt;/span&gt; client1.key &lt;span class=&quot;nt&quot;&gt;-out&lt;/span&gt; client1_nopass.key&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You’ll need to copy the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.pem&lt;/code&gt; files to the respective clients to allow them to
make connections.&lt;/p&gt;

&lt;h2 id=&quot;openvpn-server-setup&quot;&gt;OpenVPN Server Setup&lt;/h2&gt;

&lt;p&gt;Now it’s time to set up the OpenVPN server on the ERL. This is done by creating
a new interface. You’ll also need a new IPv4 subnet for the VPN; I use
192.168.200.0/24 here.&lt;/p&gt;

&lt;p&gt;You’ll also need to make decisions about which port to use, whether to use tcp
or udp, which routes to push, etc. For this example I’ll use tcp on port 443,
which sort of disguises the traffic as normal SSL (useful because SSL
connections are never blocked by network admins). I’ll push a route to allow
communication with clients in the office network.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: As pointed out in the comments port 443 conflicts with using SSL for 
the web gui. Your options to solve this are to either use a different port for 
the web interface (the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;serivce gui https-port&lt;/code&gt; setting controls this) or a 
different port for the VPN.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit interfaces openvpn vtun0
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;description OpenVPN
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;mode server
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;local-port 443
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;protocol tcp-passive
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;server subnet 192.168.200.0/24
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;server topology subnet
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;server push-route 192.168.103.0/24
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;tls ca-cert-file /config/auth/cacert.pem
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;tls cert-file /config/auth/host.pem
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;tls dh-file /config/auth/dhp.pem
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;tls key-file /config/auth/host.key&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;firewall-setup&quot;&gt;Firewall Setup&lt;/h2&gt;

&lt;p&gt;Now we need to set up a firewall zone for the VPN and write rules for this
zone. In this setup the VPN is really just an extension of the office LAN, so
for the most part we can just reuse the same rules used for the office LAN
zone. There are a handful of cases where this isn’t possible though:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;WAN to local: A rule is needed here to allow incoming tcp connections on port 443.&lt;/li&gt;
  &lt;li&gt;VPN to office LAN: All traffic is allowed.&lt;/li&gt;
  &lt;li&gt;Office LAN to VPN: All traffic is allowed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer back to
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup/&quot;&gt;part 2&lt;/a&gt;
for help setting up the firewall.&lt;/p&gt;

&lt;h2 id=&quot;final-steps-and-testing&quot;&gt;Final Steps and Testing&lt;/h2&gt;

&lt;p&gt;The OpenVPN server hands out IP addresses to clients, so there’s no need to set
up DHCP for the VPN subnet. You may or may not want to set up DNS to listen on
the vtun0 interface, depending on your needs.&lt;/p&gt;

&lt;p&gt;Now it’s time to save everything and try it out.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;commit
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;save&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You’ll need to configure your client machine(s) to connect using the client
certificate(s) we generated earlier. The steps for doing this vary depending on
your OS; please consult the
&lt;a href=&quot;https://openvpn.net/index.php/open-source/documentation.html&quot;&gt;OpenVPN documentation&lt;/a&gt;
for help.&lt;/p&gt;

&lt;p&gt;For testing it’s ideal to try and connect from outside your network, e.g. by
tethering to a phone. But for this setup it’s also possible to test by trying
to use the VPN to access the office LAN from the home LAN. Just be sure you’ve
set up firewall rules to allow clients on the home LAN to connect to the
OpenVPN server on the router.&lt;/p&gt;

&lt;h2 id=&quot;hardening&quot;&gt;Hardening&lt;/h2&gt;

&lt;p&gt;This section isn’t essential, but I do recommend it.&lt;/p&gt;

&lt;p&gt;The
&lt;a href=&quot;https://community.openvpn.net/openvpn/wiki/Hardening&quot;&gt;OpenVPN hardening page&lt;/a&gt;
covers various ways to improve the security of OpenVPN. It’s useful to read
through these. The only one that I’m going to cover here is TLS auth.&lt;/p&gt;

&lt;p&gt;The TLS auth option is pretty cool. It makes it so that the OpenVPN server will
not respond to packets unless those packets have a valid signature from a
pre-shared key. This makes it so that someone doing a port scan of your public
IP address will not see that the OpenVPN port is accepting connections. It also
provides other benefits described on the hardening page.&lt;/p&gt;

&lt;p&gt;Setting this up is pretty simple. First you need to generate the pre-shared
key.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;go&quot;&gt;  
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;openvpn &lt;span class=&quot;nt&quot;&gt;--genkey&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--secret&lt;/span&gt; ta.key  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next, copy the key to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/config/auth&lt;/code&gt; on the ERL and to all client machines.
Then set up the OpenVPN server to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--tls-auth&lt;/code&gt; option.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;go&quot;&gt;  
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;interfaces openvpn vtun0 openvpn-option &lt;span class=&quot;s2&quot;&gt;&quot;--tls-auth /config/auth/openvpn/ta.key 0&quot;&lt;/span&gt;  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;commit  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;save  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Finally, configure clients to pass the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--tls-auth ta.key 1&lt;/code&gt; option to OpenVPN.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update 2016-12-30:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Since writing this post I’ve employed a few addtional hardening options for 
OpenVPN:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Drop root privileges after OpenVPN initialization. This is done by passing the 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--user nobody --group nogroup&lt;/code&gt; options to OpenVPN. Additionally the 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--persist-key --persist-tun&lt;/code&gt; options should be used to avoid the need for 
privileges on soft restart.&lt;/li&gt;
  &lt;li&gt;Use AES256 for the cipher and SHA256 for the message digest instead of the 
defaults (Blowfish/SHA1). Note that this may impact performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the following commands to enable these options.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;go&quot;&gt;  
&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit interfaces openvpn vtun0
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;openvpn-option &lt;span class=&quot;s2&quot;&gt;&quot;--user nobody&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;openvpn-option &lt;span class=&quot;s2&quot;&gt;&quot;--group nogroup&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;openvpn-option &lt;span class=&quot;nt&quot;&gt;--persist-key&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;openvpn-option &lt;span class=&quot;nt&quot;&gt;--persist-tun&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;encryption aes256
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set hash &lt;/span&gt;sha256
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;commit  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;save  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You will also need to set the cipher and message digest appropriately in your 
client configuration.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In this post we’ve covered one fairly common scenario for setting up an OpenVPN
server on the ERL. OpenVPN is incredibly flexible though, so if your needs
aren’t completely covered by this guide there’s a pretty good chance that you
just need to tweak the configuration.&lt;/p&gt;

&lt;p&gt;The next post will wrap up this series by covering various useful
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-6-odds-and-ends/&quot;&gt;odds and ends&lt;/a&gt;
that we haven’t touched on yet.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="edgerouter" /><category term="networking" /><summary type="html">In previous posts we’ve covered everything required to set up a network with multiple VLANs and IPv6 (see part 1 for a list of all posts in this series). Today we’re going to talk about setting up an OpenVPN server on the ERL.</summary></entry><entry><title type="html">Ubiquiti EdgeRouter Lite Setup Part 4: IPv6 Setup</title><link href="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-4-ipv6-setup/" rel="alternate" type="text/html" title="Ubiquiti EdgeRouter Lite Setup Part 4: IPv6 Setup" /><published>2016-03-08T00:00:00+00:00</published><updated>2016-03-08T00:00:00+00:00</updated><id>https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-4-ipv6-setup</id><content type="html" xml:base="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-4-ipv6-setup/">&lt;p&gt;At this point we’ve done
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-1-the-basics/&quot;&gt;basic setup&lt;/a&gt;
of the ERL, configured a
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup/&quot;&gt;zone-based firewall&lt;/a&gt;
and set up flexible network partitioning using
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-3-vlan-setup/&quot;&gt;VLANs&lt;/a&gt;.
But we’re still only supplying an IPv4 network to clients. In this post we’re
going to learn about deploying IPv6.&lt;/p&gt;

&lt;p&gt;To my knowledge DHCPv6 prefix delegation is widely supported among ISPs that
provide native IPv6. That’s what I describe here; check with your ISP for
specifics about using IPv6 on their network.&lt;/p&gt;

&lt;p&gt;If your ISP doesn’t support IPv6 at all a good option is a 6to4 service like
&lt;a href=&quot;https://tunnelbroker.net&quot;&gt;tunnelbroker.net&lt;/a&gt;. I won’t describe setting that up
here, but instructions can be found
&lt;a href=&quot;https://help.ubnt.com/hc/en-us/articles/204976104-EdgeMAX-IPv6-Tunnel&quot;&gt;elsewhere&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;dhcpv6-and-prefix-delegation&quot;&gt;DHCPv6 and Prefix Delegation&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://tools.ietf.org/html/rfc3633&quot;&gt;RFC 3633&lt;/a&gt; defines a mechanism by which
&lt;a href=&quot;https://en.wikipedia.org/wiki/DHCPv6&quot;&gt;DHCPv6&lt;/a&gt; can be used to delegate a
network address prefix to a network. This is known as
&lt;a href=&quot;https://en.wikipedia.org/wiki/Prefix_delegation&quot;&gt;prefix delegation&lt;/a&gt;. The
router can then assign addresses to clients within the network using either
DHCPv6 or
&lt;a href=&quot;https://en.wikipedia.org/wiki/IPv6_address#Stateless_address_autoconfiguration&quot;&gt;stateless address autoconfiguraton&lt;/a&gt;
(SLAAC). With SLAAC the router advertises a prefix to clients, and clients pick
their own address within that network. This example will use SLAAC.&lt;/p&gt;

&lt;h2 id=&quot;wan-setup&quot;&gt;WAN Setup&lt;/h2&gt;

&lt;p&gt;The first step in configuring the ERL is to set up the WAN interface to request
a prefix via DHCPv6. Our network is divided into multiple LANs, so we’ll divide
up the assigned prefix into smaller networks that can be advertised on each
lan, assigning the ::1 address in each network to the virtual interface in the
ERL.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit interfaces ethernet eth0
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd rapid-commit &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 prefix-length /56
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.1 service slaac
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.1 prefix-id 1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.1 host-address ::1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.2 service slaac
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.2 prefix-id 2
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.2 host-address ::1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.3 service slaac
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.3 prefix-id 3
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;dhcpv6-pd pd 1 interface eth2.3 host-address ::1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The prefix length is determined by your ISP, so you will need to check with
them to determine the correct value.&lt;/p&gt;

&lt;h2 id=&quot;lan-setup&quot;&gt;LAN Setup&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: There is a much simpler way to get router advertisements on your LANs 
than what I described in my original instructions. Simply do this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit interfaces ethernet eth2 vif 1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 address autoconf
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 dup-addr-detect-transmits 1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I can’t recall now why I didn’t do it this way originally. Possibly it’s a 
legacy of having previously used a 6to4 tunnel. Anyway, I’d suggest you try this 
first, and refer to the original instructions (below) only if you need to 
customize the router advertisements.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Original Instructions&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Now each vif must be configured to advertise its assigned IPv6 prefix to
clients.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit interfaces ethernet eth2 vif 1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 dup-addr-detect-transmits 1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert cur-hop-limit 64
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert link-mtu 0
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert managed-flag &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert max-interval 600
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert other-config-flag &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert prefix ::/64 autonomous-flag &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert prefix ::/64 on-link-flag &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert prefix ::/64 valid-lifetime 2592000
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert reachable-time 0
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert retrans-timer 0
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;ipv6 router-advert sent-advert &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Again here the size of your prefix may depend on the size of the prefix
assigned by your ISP. Since my ISP assigns a /56 prefix I have 256 /64 networks
that I can assign to my subnets.&lt;/p&gt;

&lt;p&gt;Repeat these steps for the other virtual interfaces on eth2.&lt;/p&gt;

&lt;h2 id=&quot;potential-problems&quot;&gt;Potential Problems&lt;/h2&gt;

&lt;p&gt;When I was originally playing with this I found that either the ERL or 
my ISP or both were a bit finicky when it came to making IPV6 changes on 
the ERL. Here are a few tips for some scenaios I encountered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you’re replacing a router supplied by your ISP it may have already 
requested a prefix, and your ISP may not allow the ERL to request a 
prefix until that lease has expired. If you’re having trouble getting 
a prefix and nothing seems to be working, you might just need to wait.&lt;/li&gt;
  &lt;li&gt;In some cases the ERL seemed to get a bit confused after I changed 
some IPv6-related settings. Rebooting the ERL always cleared this up.&lt;/li&gt;
  &lt;li&gt;I ended up with cases where, after changing the prefixes I was assigning to
my LANs, clients ended up with IPv6 addresses in both the old and new
prefixes. Disconnecting then reconnecting clients to the network generally
straightened things out. If all else fails you can always reboot the
client.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Hopefully you find these instructions helpful, but if your situation 
turns out to be different from mine there’s a lot of information to be 
found in forums. Just fire up your favorite search engine and you’re 
likely to find others who have already solved your problems.&lt;/p&gt;

&lt;p&gt;At this point we’ve covered everything for a reasonably complete network 
setup. From here we’ll start exploring some more specialized topics, 
starting with setting up an
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-5-openvpn-setup/&quot;&gt;OpenVPN server&lt;/a&gt;
on the ERL.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="edgerouter" /><category term="networking" /><summary type="html">At this point we’ve done basic setup of the ERL, configured a zone-based firewall and set up flexible network partitioning using VLANs. But we’re still only supplying an IPv4 network to clients. In this post we’re going to learn about deploying IPv6.</summary></entry><entry><title type="html">Ubiquiti EdgeRouter Lite Setup Part 3: VLAN Setup</title><link href="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-3-vlan-setup/" rel="alternate" type="text/html" title="Ubiquiti EdgeRouter Lite Setup Part 3: VLAN Setup" /><published>2016-03-04T00:00:00+00:00</published><updated>2016-03-04T00:00:00+00:00</updated><id>https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-3-vlan-setup</id><content type="html" xml:base="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-3-vlan-setup/">&lt;p&gt;Those who have followed along with parts &lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-1-the-basics/&quot;&gt;1&lt;/a&gt; and &lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup/&quot;&gt;2&lt;/a&gt; of this series should now have an ERL configuration with one WAN and one LAN interface and a zone-based firewall. Let’s take another look at our example network configuration diagram.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.forshee.me/assets/article_images/ubiquiti-edgerouter-lite-setup-part-1-the-basics/network-topolgy.png&quot; alt=&quot;Example network configuration&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Rather than the single LAN we have now, this shows separate home and office LANs. It also shows a wireless AP which will supply wireless networks for both LANs.&lt;/p&gt;

&lt;p&gt;One way to separate the home and office networks would be to put them on different interfaces of the ERL, e.g. the home LAN on eth1 and the office LAN on eth2. This would work but has a some disadvantages - reconfiguring the network might involve rewiring, and each network needs its own wireless AP.&lt;/p&gt;

&lt;p&gt;A more flexible option is to use &lt;a href=&quot;https://en.wikipedia.org/wiki/Virtual_LAN&quot;&gt;virtual LANs&lt;/a&gt; (VLANs). With VLANs the networking equipment provides a logical separation of networks which can easily be reconfigured in software. A single interconnect can carry traffic for multiple VLANs using &lt;a href=&quot;https://en.wikipedia.org/wiki/IEEE_802.1Q&quot;&gt;802.1q VLAN tagging&lt;/a&gt;, which allows deploying a single AP which serves wireless networks for both LANs or even multiple APs throughout the building all serving multiple wireless networks.&lt;/p&gt;

&lt;p&gt;Using VLANs does require that at least some of your other networking equipment support VLANs. In a small network a single managed switch is sufficient, and wireless APs need to support defining multiple SSIDs with VLAN tagging.&lt;/p&gt;

&lt;p&gt;In this post we’ll learn how to set up VLANs on the ERL. A VLAN deployment will also require configuring switches and wireless APs, but exactly how to do this is hardware-specific and thus will not be covered here.&lt;/p&gt;

&lt;h2 id=&quot;adding-vlans&quot;&gt;Adding VLANs&lt;/h2&gt;

&lt;p&gt;A VLAN is created by adding a virtual interfaces or &lt;em&gt;vif&lt;/em&gt; to one of the physical interfaces. For our network we’ll define three VLANs. Each VLAN will need its own pool of addresses to assign to clients. For this example we’ll use:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;VLAN 1&lt;/strong&gt;: Management network. This is the network used for communication between the network hardware. Subnet: 192.168.101.0/24.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;VLAN 2&lt;/strong&gt;: Home network. Subnet: 192.168.102.0/24.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;VLAN 3&lt;/strong&gt;: Office network. Subnet: 192.168.103.0/24.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;vlan-configuration&quot;&gt;VLAN Configuration&lt;/h4&gt;

&lt;p&gt;We’ll configure the management LAN as an example. First we need to add the vif to eth2:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit interfaces ethernet eth2
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;vif 1 description &lt;span class=&quot;s2&quot;&gt;&quot;Management VLAN&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;vif 1 address 192.168.101.1/24
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next, set up DHCP and DNS for this network.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit service dhcp-server shared-network-name mgmt
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;authoritative disable
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;subnet 192.168.101.0/24 default-router 192.168.101.1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;subnet 192.168.101.0/24 dns-server 192.168.101.1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;subnet 192.168.101.0/24 lease 86400
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;subnet 192.168.101.0/24 start 192.168.101.150 stop 192.168.101.254
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service dns forwarding listen-on eth2.1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Repeat this procedure for the home and office VLANs.&lt;/p&gt;

&lt;h4 id=&quot;firewall-rules&quot;&gt;Firewall Rules&lt;/h4&gt;

&lt;p&gt;Firewall rules and zone policy also need to be defined for the management zone. I won’t cover this in detail here; refer to &lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup/&quot;&gt;part 2&lt;/a&gt; for guidance.&lt;/p&gt;

&lt;h4 id=&quot;deleting-the-old-configuration&quot;&gt;Deleting the Old Configuration&lt;/h4&gt;

&lt;p&gt;Once the VLAN configuration has been verified to be working with other networking equipment, much of the old configuration for the LAN is likely no longer needed. It should be safe to delete the IP address for eth2 and the DHCP settings, DNS settings, and zone policy for the old LAN network. Any firewall rulesets that are no longer used can also be deleted. Make sure that you delete only the rules for the eth2 interface itself and not for its VLANs. Also be sure that the firewall rules allow access to the router configuration from at least one of the VLANs, otherwise you may find yourself locked out!&lt;/p&gt;

&lt;h2 id=&quot;guestiot-vlan&quot;&gt;Guest/IoT VLAN&lt;/h2&gt;

&lt;p&gt;Though this isn’t included in the example network we’re setting up, it’s definitely worth mentioning.&lt;/p&gt;

&lt;p&gt;Setting up isolated wireless networks for guests and/or internet of things (IoT) devices is a really good idea. Guests could be bringing compromised devices into your network, and IoT devices are infamous for their poor security practices. Unless you have a specific reason that the device needs to be on the same network as your other machines (e.g. a wireless printer) it’s better to put them on an isolated network.&lt;/p&gt;

&lt;p&gt;Using the information above it is strightforward to add one or more additional VLANs for these devices. Set up the vlan similarly to the one above, set up DHCP with an unused range of IPv4 addresses, add a new firewal zone for the network, and configure the firewall so that all trafic to and from the zone is dropped except for WAN traffic. Pro tip: If the default action for your zones is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drop&lt;/code&gt; you don’t actually need to explicitly add rules to drop traffic between two zones.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;That’s it for our brief overview of setting up VLANs on the ERL. In part 4 we’ll talk about deploying &lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-4-ipv6-setup/&quot;&gt;IPv6&lt;/a&gt; on the ERL.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="edgerouter" /><category term="networking" /><summary type="html">Those who have followed along with parts 1 and 2 of this series should now have an ERL configuration with one WAN and one LAN interface and a zone-based firewall. Let’s take another look at our example network configuration diagram.</summary></entry><entry><title type="html">Ubiquiti EdgeRouter Lite Setup Part 2: Firewall Setup</title><link href="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup/" rel="alternate" type="text/html" title="Ubiquiti EdgeRouter Lite Setup Part 2: Firewall Setup" /><published>2016-03-02T00:00:00+00:00</published><updated>2016-03-02T00:00:00+00:00</updated><id>https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup</id><content type="html" xml:base="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup/">&lt;p&gt;In &lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-1-the-basics/&quot;&gt;part 1&lt;/a&gt;
we covered the basics of setting up the ERL for one WAN interface and one LAN 
interface with a basic firewall on the WAN interface. But isolating our internal 
networks against bad actors on the outside is one of the most important 
functions of a router, so let’s explore a more robust firewall configuration.&lt;/p&gt;

&lt;h2 id=&quot;acl-vs-zone-based-firewall&quot;&gt;ACL vs. Zone Based Firewall&lt;/h2&gt;

&lt;p&gt;The default firewall setup on the ERL (and the only one supported via the web 
client) allows defining firewalls as sets of ACL rules on a per-interface and 
per-direction basis. But the ERL also supports zone-based firewalls, which work 
by dividing your network into zones and matching rules based on source and 
destination zones. For a pretty thorough comparison of ACL versus zone-based 
firewall, I suggest going 
&lt;a href=&quot;https://www.nnbfn.net/2011/06/per-interface-vs-zone-based-firewall/&quot;&gt;here&lt;/a&gt;. The 
basic idea behind a zone-based firewall is as follows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You define zones for your network. A common set of zones might be WAN, LAN, 
and DMZ.&lt;/li&gt;
  &lt;li&gt;You assign one or more interfaces to each zone.&lt;/li&gt;
  &lt;li&gt;You set up rules which match based on source and destination zones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While an ACL firewall can be easier to set up for simple networks such as the 
one in this example, a zone-based firewall is conceptually simpler (in my 
opinion at least) and less susceptible to the sorts of mistakes that can open up 
your network to the outside.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-a-zone-based-firewall&quot;&gt;Setting Up a Zone Based Firewall&lt;/h2&gt;

&lt;p&gt;The approach I’ve taken is based on
&lt;a href=&quot;https://help.ubnt.com/hc/en-us/articles/204952154-EdgeMAX-Zone-Policy-CLI-Example&quot;&gt;this article&lt;/a&gt;, 
and I recommend reading it before proceeding. The link to the example 
configuration file in that article is broken however, luckily someone was kind 
enough to post a copy 
&lt;a href=&quot;https://gist.github.com/cimnine/9b9dc854a43702f953ea&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s convert the firewall we created in
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-1-the-basics/&quot;&gt;part 1&lt;/a&gt;
to a roughly equivalent zone-based firewall. In the end the result will in fact 
be much more robust than the ACL firewall.&lt;/p&gt;

&lt;h4 id=&quot;define-zones-and-allowed-connections&quot;&gt;Define Zones and Allowed Connections&lt;/h4&gt;

&lt;p&gt;The first step is to determine what our zones are and what connections will be 
permited for each pair of source and destination zones.&lt;/p&gt;

&lt;p&gt;In this simple setup we have a &lt;em&gt;WAN&lt;/em&gt; zone for the connection to the internet and 
a &lt;em&gt;LAN&lt;/em&gt; zone for our internal LAN. We also need to define one more zone, named 
&lt;em&gt;local&lt;/em&gt;, for connections to the router itself (DHCP, DNS, ssh, etc.).&lt;/p&gt;

&lt;p&gt;Three zones gives us six &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;source&amp;gt;,&amp;lt;destination&amp;gt;&lt;/code&gt; zone pairs. A reasonable 
initial set of rules for traffic to allow between the zones is:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;WAN to LAN&lt;/strong&gt;: Allow only traffic for established connections.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;WAN to local&lt;/strong&gt;: Allow only traffic for established connections.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;LAN to WAN&lt;/strong&gt;: Drop invalid state packets, allow all other traffic.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;LAN to local&lt;/strong&gt;: Allow traffic for established connections. Also allow new 
ICMP, DHCP, DNS, ssh, and HTTP/HTTPS connections.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;local to WAN&lt;/strong&gt;: Drop invalid state packets, allow all other traffic.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;local to LAN&lt;/strong&gt;: Drop invalid state packets, allow all other traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;create-firewall-rulesets&quot;&gt;Create Firewall Rulesets&lt;/h4&gt;

&lt;p&gt;Now we need to translate the list of permissible traffic into firewall rules.&lt;/p&gt;

&lt;p&gt;The article linked to above suggests defining two sets of rules for every 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;source&amp;gt;,&amp;lt;destination&amp;gt;&lt;/code&gt; pair, using the naming convention 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;source&amp;gt;-&amp;lt;destination&amp;gt;&lt;/code&gt; for IPv4 and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;source&amp;gt;-&amp;lt;destination&amp;gt;-6&lt;/code&gt; for IPv6. I 
generally follow this suggestion, but it results in quite a few identical 
rulesets, as you can see from the list above. Therefore I define a few 
“standard” rulesets for these rather than having redundant rules. Let’s write 
these rulesets first.&lt;/p&gt;

&lt;p&gt;The most basic of these is what I call the &lt;em&gt;allow established, drop invalid&lt;/em&gt; 
ruleset. For performance reasons these rules form the basis of all rulesets, but 
often they are the only rules needed. The following commands in the CLI will 
create this ruleset for IPv4.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit firewall name allow-est-drop-inv
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;default-action drop
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;enable-default-log
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 1 action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 1 state established &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 1 state related &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 2 action drop
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 2 log &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 2 state invalid &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We need an equivalent rule for IPv6, but here we need to additionally allow ICMP 
connections.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit firewall ipv6-name allow-est-drop-inv-6
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;default-action drop
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;enable-default-log
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 1 action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 1 state established &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 1 state related &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 2 action drop
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 2 log &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 2 state invalid &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 100 action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 100 protocol ipv6-icmp
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The other repeated case we have is the &lt;em&gt;allow all connections&lt;/em&gt; ruleset. To save 
some typing we can start off by making a copy of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allow-est-drop-invalid&lt;/code&gt; 
rulesets, then simply change the default action to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accept&lt;/code&gt; and disable logging 
for the default rule.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit firewall
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;copy name allow-est-drop-inv to name allow-all
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;name allow-all default-action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;delete name allow-all enable-default-log
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Repeat these steps to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allow-all-6&lt;/code&gt; ruleset.&lt;/p&gt;

&lt;p&gt;We have only one ruleset left to create now, for connections from the LAN to the 
router. For IPv4 this looks like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit firewall
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;copy name allow-est-drop-inv to name lan-local
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit name lan-local
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 100 action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 100 protocol icmp
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 200 description &lt;span class=&quot;s2&quot;&gt;&quot;Allow HTTP/HTTPS&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 200 action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 200 destination port 80,443
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 200 protocol tcp
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 600 description &lt;span class=&quot;s2&quot;&gt;&quot;Allow DNS&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 600 action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 600 destination port 53
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 600 protocol tcp_udp
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 700 description &lt;span class=&quot;s2&quot;&gt;&quot;Allow DHCP&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 700 action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 700 destination port 67,68
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 700 protocol udp
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 800 description &lt;span class=&quot;s2&quot;&gt;&quot;Allow SSH&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 800 action accept
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 800 destination port 22
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;rule 800 protocol tcp
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This should be done for IPv6 as well. Keep in mind that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allow-est-drop-inv-6&lt;/code&gt; 
already includes a rule for ICMP.&lt;/p&gt;

&lt;h4 id=&quot;set-up-zones&quot;&gt;Set Up Zones&lt;/h4&gt;

&lt;p&gt;Now that we have our rulesets, we need to tell the router about our zones, which 
interfaces belong to each zone, and which rulesets to apply for traffic 
originating from other zones. This information goes in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zone-policy&lt;/code&gt; stanza 
of the configuration, with one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zone&lt;/code&gt; stanza for each zone of our network.&lt;/p&gt;

&lt;p&gt;Let’s start by creating a local zone.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;edit zone-policy zone &lt;span class=&quot;nb&quot;&gt;local&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Each zone has a default action, which must be either &lt;em&gt;drop&lt;/em&gt; or &lt;em&gt;reject&lt;/em&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;default-action drop&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next specify which interface(s) are in this zone. Normally this would be a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set 
interface &amp;lt;iface&amp;gt;&lt;/code&gt; command, but the local zone is a bit different:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;local-zone&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we must create &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from &amp;lt;zone&amp;gt;&lt;/code&gt; stanzas to specify which rulesets to apply for 
traffic from the specified zone to the local zone.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;from WAN firewall name allow-est-drop-inv
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;from WAN firewall ipv6-name allow-est-drop-inv-6
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;from LAN firewall name lan-local
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;from LAN firewall ipv6-name lan-local-6
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;top&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Repeat this procedure for the LAN and WAN zones.&lt;/p&gt;

&lt;h4 id=&quot;delete-existing-wan-rules&quot;&gt;Delete Existing WAN Rules&lt;/h4&gt;

&lt;p&gt;If you’ve been following along you will already have some ACL rules applied to 
the WAN interface. It’s time to delete those.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;delete interfaces ethernet eth0 firewall
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;delete firewall name WAN_IN
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;delete firewall name WAN_LOCAL&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h4 id=&quot;apply-changes&quot;&gt;Apply Changes&lt;/h4&gt;

&lt;p&gt;Now it’s time to cross your fingers and commit the load of changes we just made. 
If you’ve made any mistakes the CLI will let you know, and you can correct them 
and commit again. Don’t forget to save your changes and back them up once 
everything is working!&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Setting up a zone-based firewall on the EdgeRouter is a bit of work, but for me 
the conceptual simplicity and inherent protection against mistakes make it 
worthwhile.&lt;/p&gt;

&lt;p&gt;In
&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-3-vlan-setup/&quot;&gt;part 3&lt;/a&gt;
we’ll talk about setting up VLANs.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="edgerouter" /><category term="networking" /><summary type="html">In part 1 we covered the basics of setting up the ERL for one WAN interface and one LAN interface with a basic firewall on the WAN interface. But isolating our internal networks against bad actors on the outside is one of the most important functions of a router, so let’s explore a more robust firewall configuration.</summary></entry><entry><title type="html">Ubiquiti EdgeRouter Lite Setup Part 1: The Basics</title><link href="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-1-the-basics/" rel="alternate" type="text/html" title="Ubiquiti EdgeRouter Lite Setup Part 1: The Basics" /><published>2016-03-01T00:00:00+00:00</published><updated>2016-03-01T00:00:00+00:00</updated><id>https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-1-the-basics</id><content type="html" xml:base="https://www.forshee.me/ubiquiti-edgerouter-lite-setup-part-1-the-basics/">&lt;p&gt;A few months back I picked up an &lt;a href=&quot;https://www.ubnt.com/edgemax/edgerouter-lite/&quot;&gt;Ubiquiti EdgeRouter Lite&lt;/a&gt; as I started the process of upgrading some of the aging network equipment in my home. So far I’m finding this to be a very substantial upgrade to the typical consumer-grade home networking equipment at a reasonable price. Getting this device configured was a bit of work though, so I’m documenting what a learned here - mostly for my reference, but also in case it proves useful to anyone else.&lt;/p&gt;

&lt;p&gt;Please note that for the most part I’m writing this from memory, so there may be mistakes. Since my ERL is currently in use I haven’t been able to validate the configuration steps I provide. If you see mistakes, have problems with any of the steps, or have suggestions for better ways to do things please let me know.&lt;/p&gt;

&lt;p&gt;For reference I’ll maintain a collection of links to all my posts about EdgeRouter Lite configuration here, updating it as new posts are added.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-1-the-basics/&quot;&gt;Part 1: The Basics&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup/&quot;&gt;Part 2: Firewall Setup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-3-vlan-setup/&quot;&gt;Part 3: VLAN Setup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-4-ipv6-setup/&quot;&gt;Part 4: IPv6 Setup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-5-openvpn-setup/&quot;&gt;Part 5: OpenVPN Setup&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-6-odds-and-ends/&quot;&gt;Part 6: Odds and Ends&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;about-the-edgerouter-lite&quot;&gt;About the EdgeRouter Lite&lt;/h2&gt;

&lt;p&gt;If all you’re familiar with is the standard consumer home networking equipment, it may take a bit of reorienting to understand the role of the ERL. In consumer parlance a &lt;em&gt;router&lt;/em&gt; is typically a combination of a router (connects networks together), a switch (connects machines within a network), and a wireless access point (allows wireless clients to connect to the network). The ERL serves only the router function, but it does this with better performance, more flexibility, and (hopefully) better reliability than consumer equipment. It also has a decent CLI, which will be used for almost all the configuration examples in these posts.&lt;/p&gt;

&lt;h2 id=&quot;network-configuration&quot;&gt;Network Configuration&lt;/h2&gt;

&lt;p&gt;The typical home network consists of just a single network. I work from home though, and I keep my office network separated from our home network to protect my work assets from any potential compromise of my home network. Previously this was done by attaching a second NAT router with firewall behind the router that connected my home from the internet. With the ERL (in combination with a managed switch) I can instead use VLANs to separate my networks for something that looks more like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.forshee.me/assets/article_images/ubiquiti-edgerouter-lite-setup-part-1-the-basics/network-topolgy.png&quot; alt=&quot;Example network configuration&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In these posts we’ll gradually work towards setting up the EdgeRouter Lite for this setup.&lt;/p&gt;

&lt;h2 id=&quot;initial-erl-setup-via-the-web-ui&quot;&gt;Initial ERL Setup via the Web UI&lt;/h2&gt;

&lt;p&gt;Consult the &lt;a href=&quot;http://dl.ubnt.com/guides/edgemax/EdgeRouter_Lite_UG.pdf&quot;&gt;EdgeRouter Lite User Guide&lt;/a&gt; for information on accessing the EdgeOS configuration interface for the first time. Bascially, the steps are: connect a machine to the eth0 port on the ERL, manually configure your machine to have an address in the 192.168.1.x subnet, then point your web browser at 192.168.1.1. This will bring up the configuration interface in your browser.&lt;/p&gt;

&lt;p&gt;While I prefer the CLI for most of my configuration, the ERL’s web interface contains a handful of wizards for common setups. If you wish to use one of the wizards it is important that this be the first configuration step you perform, as any change to the configuration at all seems to make the ERL insist that you reset to the default configuration before using the wizard.&lt;/p&gt;

&lt;p&gt;Once this is done and the ERL reboots, it is imperative that your next step is to change the default password, or better yet add a new user and delete the default user altogether.&lt;/p&gt;

&lt;h2 id=&quot;using-the-cli&quot;&gt;Using the CLI&lt;/h2&gt;

&lt;p&gt;You can access the CLI either within the web UI or over ssh (my preferred method). The OS on the ERL is called EdgeOS and is based on Vyatta, so if you’re familiar with Vyatta the EdgeOS CLI will be familiar. You’ll probably want to consult the &lt;a href=&quot;https://dl.ubnt.com/guides/edgemax/EdgeOS_UG.pdf&quot;&gt;EdgeOS User Guide&lt;/a&gt; to get familiar with the CLI (refer to Appendix A), but I’ll mention a few of the basics here.&lt;/p&gt;

&lt;p&gt;Once logged into the CLI you’re presented with a shell in a Debian-based environment. The first thing to know is that at any time typing ? will bring up context-sensitive help about valid commands and syntax. Typing ? a second time will show more detailed help. The shell also includes context-sensitive tab completion.&lt;/p&gt;

&lt;p&gt;There is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show&lt;/code&gt; command which can be used to display information about the system. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show interfaces&lt;/code&gt; displays information about the network interfaces in the system.&lt;/p&gt;

&lt;p&gt;To make changes to the configuration you must enter configuration mode by entering the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;configure&lt;/code&gt; command. Configuration mode has &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set&lt;/code&gt; commands for displaying and modifying configuration variables, respectively, along with an assortment of other commands.&lt;/p&gt;

&lt;p&gt;The configuration itself is hierarchical, with sections which may contain settings or subsections. For example there is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interfaces&lt;/code&gt; section which holds the configurations for network interfaces and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;firewall&lt;/code&gt; section which contains the firewall rules.&lt;/p&gt;

&lt;p&gt;Changes made while in configuration mode are staged until they are committed with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;commit&lt;/code&gt; command, at which point they go into effect, or they can be discarded using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;discard&lt;/code&gt; command. To save the changes to the default configuration use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;save&lt;/code&gt; command, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit&lt;/code&gt; command will return to operational mode. The default configuration is stored in a plain text file at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/config/config.boot&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-wanlan-using-the-cli&quot;&gt;Setting Up WAN+LAN Using the CLI&lt;/h2&gt;

&lt;p&gt;My setup uses eth0 to connect to the internet and eth2 for my LANs. We’ll start with a basic setup to provide NAT and a basic firewall on the WAN interface and a single network on the LAN interface.&lt;/p&gt;

&lt;p&gt;First, let’s set up the firewall to only allow established connections into the network. We’ll go into more details about firewall setup in the next post, but for now note thatt we actually create two sets of rules. One is named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WAN_IN&lt;/code&gt; and applies to packets coming in the WAN interface destined for other interfaces, and the other is named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WAN_LOCAL&lt;/code&gt; and applies to packets coming in the WAN interface destined for the router itself.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ configure
# set firewall all-ping enable
# set firewall broadcast-ping disable
# set firewall ipv6-receive-redirects disable
# set firewall ipv6-src-route disable
# set firewall ip-src-route disable
# set firewall log-martians enable
# set firewall receive-redirects disable
# set firewall send-redirects enable
# set firewall source-validation disable
# set firewall syn-cookies enable
# set firewall name WAN_IN default-action drop
# set firewall name WAN_IN enable-default-log
# set firewall name WAN_IN rule 1 action accept
# set firewall name WAN_IN rule 1 description &quot;Allow established connections&quot;
# set firewall name WAN_IN rule 1 state established enable
# set firewall name WAN_IN rule 1 state related enable
# set firewall name WAN_IN rule 2 action drop
# set firewall name WAN_IN rule 2 log enable
# set firewall name WAN_IN rule 2 description &quot;Drop invalid state&quot;
# set firewall name WAN_IN rule 2 state invalid enable
# set firewall name WAN_LOCAL default-action drop
# set firewall name WAN_LOCAL enable-default-log
# set firewall name WAN_LOCAL rule 1 action accept
# set firewall name WAN_LOCAL rule 1 description &quot;Allow established connections&quot;
# set firewall name WAN_LOCAL rule 1 state established enable
# set firewall name WAN_LOCAL rule 1 state related enable
# set firewall name WAN_LOCAL rule 2 action drop
# set firewall name WAN_LOCAL rule 2 log enable
# set firewall name WAN_LOCAL rule 2 description &quot;Drop invalid state&quot;
# set firewall name WAN_LOCAL rule 2 state invalid enable&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Next, set up eth0 as the WAN interface and set up NAT.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;interfaces ethernet eth0 description WAN
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;interfaces ethernet eth0 address dhcp
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;interfaces ethernet eth0 firewall &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;name WAN_IN
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;interfaces ethernet eth0 firewall &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;name WAN_LOCAL
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service nat rule 5010 description &lt;span class=&quot;s2&quot;&gt;&quot;Masquerade for WAN&quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service nat rule 5010 outbound-interface eth0
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service nat rule 5010 &lt;span class=&quot;nb&quot;&gt;type &lt;/span&gt;masquerade&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Finally, set up eth2 as the LAN interface with DHCP, and listen for DNS queries for clients on this network.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;interfaces ethernet eth2 description LAN
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;interfaces ethernet eth2 address 192.168.1.1/24
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service dhcp-server disabled &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service dhcp-server shared-network-name LAN authoritative &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 default-router 192.168.1.1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 dns-server 192.168.1.1
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 lease 86400
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service dhcp-server shared-network-name LAN subnet 192.168.1.0/24 start 192.168.1.150 stop 192.168.1.254
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;service dns forwarding listen-on eth2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now commit and save the changes.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;commit
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;save
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;backing-up-and-restoring-your-configuration&quot;&gt;Backing Up and Restoring Your Configuration&lt;/h2&gt;

&lt;p&gt;Once you have something that’s working it’s important to back up the configuration file. It’s possible to save the configuration to another host using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;save&lt;/code&gt; command, but this is one case where I prefer to use the web UI. Once logged in, click on the &lt;em&gt;System&lt;/em&gt; button on the bottom of the screen, find the &lt;em&gt;Back Up Config&lt;/em&gt; section, and click the &lt;em&gt;Download&lt;/em&gt; button. The configuration can be restored from a backup here as well.&lt;/p&gt;

&lt;p&gt;The EdgeRouter supports revisioning of the configuration, but I prefer to just store revisions in my own git repository. More information about managing the config file can be found &lt;a href=&quot;https://help.ubnt.com/hc/en-us/articles/204960084-EdgeMAX-Manage-the-configuration-file&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;key-based-ssh-login&quot;&gt;Key-Based SSH Login&lt;/h2&gt;

&lt;p&gt;It’s more convenient and more secure to log into ssh using public key authentication than with password authentication. I’ll assume you’re already familiar with key-based authentication, if not a quick search should turn up plenty of resources.&lt;/p&gt;

&lt;p&gt;The first step is to copy your ssh public key to the ERL. For example, using scp on your local machine:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;scp ~/.ssh/id_rsa.pub &amp;lt;ip-of-erl&amp;gt;:/tmp  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After this you need to associate the public key with your user on the ERL. Log into the ERL and run these commands:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;configure  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;loadkey &amp;lt;user&amp;gt; /tmp/id_rsa.pub  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;commit  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;save  
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In theory this should be all that is needed, but I had to do one additional manual step. For some reason my home directory and some of its contents were owned by uid 1000, which was not the id of my user. Key-based ssh login would not work until I fixed this. On the ERL run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo chown&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-R&lt;/span&gt; &amp;lt;user&amp;gt; /home/&amp;lt;user&amp;gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now you should be able to log out and then log back in using your ssh key.&lt;/p&gt;

&lt;p&gt;That’s it for part 1. In &lt;a href=&quot;/ubiquiti-edgerouter-lite-setup-part-2-firewall-setup/&quot;&gt;part 2&lt;/a&gt; we’ll go into detail about setting up the firewall.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="edgerouter" /><category term="networking" /><summary type="html">A few months back I picked up an Ubiquiti EdgeRouter Lite as I started the process of upgrading some of the aging network equipment in my home. So far I’m finding this to be a very substantial upgrade to the typical consumer-grade home networking equipment at a reasonable price. Getting this device configured was a bit of work though, so I’m documenting what a learned here - mostly for my reference, but also in case it proves useful to anyone else.</summary></entry><entry><title type="html">Container Mounts in Ubuntu 16.04</title><link href="https://www.forshee.me/container-mounts-in-ubuntu-1604/" rel="alternate" type="text/html" title="Container Mounts in Ubuntu 16.04" /><published>2016-02-22T21:26:00+00:00</published><updated>2016-02-22T21:26:00+00:00</updated><id>https://www.forshee.me/container-mounts-in-ubuntu-1604</id><content type="html" xml:base="https://www.forshee.me/container-mounts-in-ubuntu-1604/">&lt;p&gt;Something I’ve been working on for a while now is mounting select filesystems from within unprivileged (i.e. user namespace) containers. Though I’m still working on getting this into upstream Linux, support for mounting fuse and ext4 was recently merged as an opt-in feature in the xenial kernel. The instructions below will help you get started if you’d like to give this a try.&lt;/p&gt;

&lt;p&gt;But first a word of warning: &lt;strong&gt;this feature is experimental&lt;/strong&gt;. As far as I know it should be stable, but there are known security concerns, specifically with mounting ext2/3/4 volumes&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.  It should only be enabled in trusted environments where potentially malicious users do not have shell access to your system.&lt;/p&gt;

&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;/h2&gt;

&lt;p&gt;In order to use this feature, you will need a 4.4.0-6.21 or later kernel in Ubuntu xenial. To follow these instructions you will also need to have lxd installed (help for this can be found &lt;a href=&quot;https://linuxcontainers.org/lxd/getting-started-cli/&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;p&gt;The first thing you need to do is flip the module parameters to enable user namespace mounts for fuse and/or ext4.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;Y | &lt;span class=&quot;nb&quot;&gt;sudo tee&lt;/span&gt; /sys/module/fuse/parameters/userns_mounts
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;Y | &lt;span class=&quot;nb&quot;&gt;sudo tee&lt;/span&gt; /sys/module/ext4/parameters/userns_mounts&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;A lxd container running under the default profile will not have the device nodes needed for mounting (/dev/fuse for fuse and some block device for ext4, e.g.  /dev/loop0) and will not be permitted to mount by AppArmor. We need to create a lxd profile which will include the device nodes and run the container without AppArmor confinement. This will be used on top of the lxd default profile.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lxc profile create nsmount
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lxc profile &lt;span class=&quot;nb&quot;&gt;set &lt;/span&gt;nsmount raw.lxc lxc.aa_profile&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;unconfined
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lxc profile device add nsmount fuse unix-char &lt;span class=&quot;nv&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/fuse
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lxc profile device add nsmount loop0 unix-block &lt;span class=&quot;nv&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/loop0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now create a new container using this profile.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lxc launch ubuntu u1 &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; default &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; nsmount  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;testing-it-out&quot;&gt;Testing it out&lt;/h2&gt;

&lt;p&gt;Let’s try fuse first. Launch a shell in your new container:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lxc &lt;span class=&quot;nb&quot;&gt;exec &lt;/span&gt;u1 &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; /bin/bash&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Inside the container we can create an ext2 filesystem and mount it using fuseext2, adding the ‘-o force’ option to make the mount read/write.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;fuseext2
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/zero &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ext2.img &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1M &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;8
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mkfs.ext2 ext2.img
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; mount
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;fuseext2 ext2.img mount &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; force  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can now browse and modify the filesystem. To unmount run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;fusermount &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; mount&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For ext4 we’ll create the filesystem outside of the container and set this as the backing store for /dev/loop0.  If loop0 is already in use you can pick another loop device, in which case you’ll also need to modify the nsmout lxd profile to make that device available in the container.&lt;/p&gt;

&lt;p&gt;Back in the host run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/zero &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ext4.img &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1M &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;8
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mkfs.ext4 ext4.img
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;losetup /dev/loop0 ext4.img  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then back in the container run:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-console&quot; data-lang=&quot;console&quot;&gt;&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; mount
&lt;span class=&quot;gp&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;mount /dev/loop0 mount  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This filesystem can be unmounted in the usual way.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;The known security concern is that a malicious user could provide a crafted filesystem to exploit bugs in the in-kernel filesystem parsing code, or the user could change the backing store at runtime. Either of these could lead to kernel crashes or worse. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>Seth Forshee</name></author><summary type="html">Something I’ve been working on for a while now is mounting select filesystems from within unprivileged (i.e. user namespace) containers. Though I’m still working on getting this into upstream Linux, support for mounting fuse and ext4 was recently merged as an opt-in feature in the xenial kernel. The instructions below will help you get started if you’d like to give this a try.</summary></entry><entry><title type="html">Introduction to Creating DKMS Packages for Ubuntu, Part 2</title><link href="https://www.forshee.me/introduction-to-creating-dkms-packages_16/" rel="alternate" type="text/html" title="Introduction to Creating DKMS Packages for Ubuntu, Part 2" /><published>2012-03-16T14:02:00+00:00</published><updated>2012-03-16T14:02:00+00:00</updated><id>https://www.forshee.me/introduction-to-creating-dkms-packages_16</id><content type="html" xml:base="https://www.forshee.me/introduction-to-creating-dkms-packages_16/">&lt;p&gt;The DKMS framework makes it easy to create and distribute an out-of-tree kernel module, as demonstrated in &lt;a href=&quot;/introduction-to-creating-dkms-packages/&quot;&gt;part 1&lt;/a&gt;. However, the process is rather manual (read: error prone) for packages that will be updated regularly. This post is going to look at a way to set up the debian packaging components to make updating easier. A basic familiarity with debian packaging is assumed.&lt;/p&gt;

&lt;p&gt;As an example, we’ll use an updated version of the apple-gmux-dkms source tree from part 1, which can be donwloaded &lt;a href=&quot;http://kernel.ubuntu.com/~sforshee/dkms-demo/apple-gmux-dkms-0.2.tar.gz&quot;&gt;here&lt;/a&gt;. This time it’s not necessary to extract it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/src&lt;/code&gt;; just extract it to wherever you like in your home directory.&lt;/p&gt;

&lt;p&gt;The layout of the files has changed a little bit. The source file and makefile are still in the root of the tree, but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dkms.conf&lt;/code&gt; has been moved into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;debian&lt;/code&gt; directory and renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apple-gmux-dkms.dkms.in&lt;/code&gt;. We’ll talk more about this file later. Most of the remaining files are the typical debian packaging boilerplate; examining these files is left as an exercise for the reader. The one file we will take a closer look at is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;debian/rules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The first item of note in the rules file is that it grabs the version number for the package from the changelog with the following.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-make&quot; data-lang=&quot;make&quot;&gt;&lt;span class=&quot;nv&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;shell&lt;/span&gt; dpkg-parsechangelog | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'^Version:'&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;cut&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f2&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;cut&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d-&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f1&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;)&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This eliminates the error-prone process of making sure the version gets updated throughout the package by making the changelog the canonical location for the version number. Towards that end, the rules file also has a rule to auto-generate the DKMS configuration file, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;debian/apple-gmux-dkms.dkms&lt;/code&gt;, from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apple-gmux-dkms.dkms.in&lt;/code&gt;. This file is identical to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dkms.conf&lt;/code&gt; file used in part 1, except that the version number has been replaced by the string &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@VERSION@&lt;/code&gt;. A sed command is used to generate the config file with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@VERSION@&lt;/code&gt; replaced by the actual version number.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-make&quot; data-lang=&quot;make&quot;&gt;&lt;span class=&quot;nl&quot;&gt;debian/apple-gmux-dkms.dkms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;debian/apple-gmux-dkms.dkms.in  &lt;/span&gt;
    &lt;span class=&quot;err&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;s/@VERSION@/$(version)/g&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$&amp;lt;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$@&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The other item worth noting is that there’s a DKMS debhelper, dh_dkms, which makes setting up the rules file a breeze when used along with the dh helper (for more information about the dh helper consult the &lt;a href=&quot;http://manpages.ubuntu.com/manpages/precise/man1/dh.1.html&quot;&gt;man page&lt;/a&gt;). We just need a rule to let dh do its thing:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-make&quot; data-lang=&quot;make&quot;&gt;&lt;span class=&quot;nl&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;  
    &lt;span class=&quot;err&quot;&gt;dh&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;$@&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Then we need to override a few of the debhelper commands to install files for the DKMS package and to invoke dh_dkms. We also need to clean up the auto-generated DKMS configuration file, and since we’re not actually building anything to generate the package we override the build command to do nothing. This leaves us with the following override rules.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-make&quot; data-lang=&quot;make&quot;&gt;&lt;span class=&quot;nl&quot;&gt;override_dh_clean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;dh_clean&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;debian/apple-gmux-dkms.dkms&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;override_dh_auto_build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;:&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;override_dh_auto_install&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;debian/apple-gmux-dkms.dkms&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;dh_install&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;apple-gmux.c&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;Makefile&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;/usr/src/apple-gmux-$(version)/&lt;/span&gt;
        &lt;span class=&quot;err&quot;&gt;dh_dkms&lt;/span&gt;

&lt;span class=&quot;nl&quot;&gt;override_dh_auto_install_indep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;debian/apple-gmux-dkms.dkms&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That’s it! Now you can build the binary and source packages with the usual debian packaging commands. When it comes time to update the package, you only need to update the version number in the changelog to get it updated throughout the package.&lt;/p&gt;</content><author><name>Seth Forshee</name></author><category term="Linux" /><category term="dkms" /><summary type="html">The DKMS framework makes it easy to create and distribute an out-of-tree kernel module, as demonstrated in part 1. However, the process is rather manual (read: error prone) for packages that will be updated regularly. This post is going to look at a way to set up the debian packaging components to make updating easier. A basic familiarity with debian packaging is assumed.</summary></entry></feed>