<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>General Networking on 0x2142 | Networking Nonsense</title>
    <link>https://0x2142.com/categories/general-networking/</link>
    <description>Recent content in General Networking on 0x2142 | Networking Nonsense</description>
    <image>
      <title>0x2142 | Networking Nonsense</title>
      <url>https://0x2142.com/logo.jpg</url>
      <link>https://0x2142.com/logo.jpg</link>
    </image>
    <generator>Hugo -- 0.143.1</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 18 Apr 2024 12:00:00 +0000</lastBuildDate>
    <atom:link href="https://0x2142.com/categories/general-networking/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>[How To] Set up Cisco Modeling Labs (CML) on Proxmox</title>
      <link>https://0x2142.com/how-to-setup-cml-on-proxmox/</link>
      <pubDate>Thu, 18 Apr 2024 12:00:00 +0000</pubDate>
      <guid>https://0x2142.com/how-to-setup-cml-on-proxmox/</guid>
      <description>In this blog post, we&amp;rsquo;ll walk through how to set up &amp;amp; install Cisco Modeling Labs (CML) on Proxmox</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Ajpi_vVTtLc?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>With a lot of the recent nonsense going on after VMware was acquired last year, I&rsquo;m seeing people start to look for ESX alternatives - especially for home labs. In fact, I also just <a href="https://www.youtube.com/watch?v=MS4ERrvG9eM">migrated</a> my home lab from ESX to Proxmox.</p>
<p>One of the things I needed to keep running was Cisco Modeling Labs (CML). I often use CML to build quick virtual topologies for testing things, so it was important for me that it worked on Proxmox.</p>
<p>It&rsquo;s worth noting that Proxmox isn&rsquo;t an officially supported platform. The <a href="https://developer.cisco.com/docs/modeling-labs/#!system-requirements">docs</a> state that only bare metal &amp; VMware platforms are supported.</p>
<p>That being said, I&rsquo;m happy to say that Proxmox has worked just fine for me - it just needed a few tweaks. Though just be warned that you may still run into issues and it is technically an unsupported configuration.</p>
<p>In the post below, I&rsquo;ll share the steps that I used to get CML up &amp; running on Proxmox.</p>
<hr>
<h2 id="prerequisites">Prerequisites</h2>
<p>To start with, we&rsquo;ll need a few things:</p>
<ul>
<li>A server running Proxmox
<ul>
<li>I&rsquo;m currently using version 8.1.3</li>
</ul>
</li>
<li>A CML install ISO, found <a href="https://software.cisco.com/download/home/286193282/type/286326381/release/2.6.1">here</a>
<ul>
<li>We&rsquo;ll be using version 2.6.1 for this guide</li>
</ul>
</li>
<li>CML&rsquo;s reference platform ISO, also found at the link above</li>
</ul>
<p>Our Proxmox machine will still need enough resources to build a VM with the minimum requirements listed <a href="https://developer.cisco.com/docs/modeling-labs/#!system-requirements">here</a>.</p>
<p>The CML &amp; refplat ISOs should be placed into a Proxmox ISO storage location.</p>
<h2 id="creating-the-vm">Creating the VM</h2>
<p>Next we can get to the fun part: Setting up the VM in Proxmox.</p>
<p>We&rsquo;ll first locate a node in Proxmox to place our VM. Then right-click that node &amp; select <strong>Create VM</strong>:</p>
<p><img alt="new-vm" loading="lazy" src="/how-to-setup-cml-on-proxmox/new-vm.png#center"></p>
<p>Then, we&rsquo;ll give our VM a name &amp; ID. I&rsquo;ve named mine <strong>CML</strong>:</p>
<p><img alt="vm-general" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-general.png#center"></p>
<p>On the next page, we can select our CML ISO from the correct storage device. We can leave the Guest OS as <strong>Linux</strong> and <strong>6.x - 2.6 Kernel</strong>:</p>
<p><img alt="vm-os" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-os.png#center"></p>
<p>Next, we&rsquo;ll need to make some minor adjustments on the <strong>System</strong> tab.</p>
<p>The default BIOS will likely be set to <strong>Default (SeaBIOS)</strong>. We&rsquo;ll change that to <strong>OVMF (UEFI)</strong>, which will also give us a few additional options.</p>
<p>We&rsquo;ll keep <strong>Add EFI Disk</strong> checked, and select a storage location for that EFI disk.</p>
<p><img alt="vm-system" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-system.png#center"></p>
<p>On the <strong>Disks</strong> tab, feel free to increase the size of the VM disk. While 32GB is the minimum required, you&rsquo;ll likely want more than that. I&rsquo;ve increased mine to 50G for now. Keep the image format as <strong>QEMU</strong>.</p>
<p>We&rsquo;ll also want to update the <strong>Async IO</strong> setting to <strong>native</strong>. This is hidden under the <strong>Advanced</strong> settings:</p>
<p><img alt="vm-disk" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-disk.png#center"></p>
<p>On the <strong>CPU</strong> tab, we&rsquo;ll update the core count to a minimum of 4 per the requirements. Of course, you&rsquo;re welcome to increase this as needed.</p>
<p>More importantly however, we&rsquo;ll need to set the CPU <strong>type</strong> to <strong>host</strong>. This allows the VM to use the underlying nested virtualization features:</p>
<p><img alt="vm-cpu" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-cpu.png#center"></p>
<p>Next we can assign memory to our VM.</p>
<p>The requirements state a minimum of 8GB, however this will likely only accommodate simpler labs. Some individual CML nodes require more than that to start.</p>
<p>In my case, I&rsquo;ll start with 32GB - and we can always increase this later:</p>
<p><img alt="vm-memory" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-memory.png#center"></p>
<p>Lastly, on the <strong>Network</strong> tab, no changes are necessary. Of course, you can assign a VLAN if needed.</p>
<p><img alt="vm-network" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-network.png#center"></p>
<p>After that, we can head over to the <strong>Confirm</strong> tab &amp; finish up the wizard.</p>
<h2 id="add-refplat-iso">Add Refplat ISO</h2>
<p>Next, we&rsquo;ll need to make sure our reference platform ISO is connected to the VM.</p>
<p>We&rsquo;ll head over to the VM&rsquo;s hardware tab, then click <strong>Add</strong> and select <strong>CD/DVD Drive</strong>:</p>
<p><img alt="vm-add-cdrom" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-add-cdrom.png#center"></p>
<p>Then we&rsquo;ll select the appropriate ISO storage, and pick our refplat ISO file:</p>
<p><img alt="vm-add-refplat" loading="lazy" src="/how-to-setup-cml-on-proxmox/vm-add-refplat.png#center"></p>
<h2 id="install-cml">Install CML</h2>
<p>Once that&rsquo;s done, we can go ahead and power on our VM &amp; pop open the console!</p>
<p>If you&rsquo;ve installed CML previously on another platform, this process is just the same.</p>
<p><img alt="con-install" loading="lazy" src="/how-to-setup-cml-on-proxmox/con-install.png#center"></p>
<p>At boot, we&rsquo;ll select <strong>Install CML</strong>.</p>
<p>After a moment &amp; a few screens, we&rsquo;ll start the system configuration.</p>
<p>First, we&rsquo;ll input a system hostname:</p>
<p><img alt="con-hostname" loading="lazy" src="/how-to-setup-cml-on-proxmox/con-hostname.png#center"></p>
<p>Then, we&rsquo;ll input credentials for the system management user.</p>
<blockquote>
<p>Note: This user isn&rsquo;t used to log into the CML software. Rather, it&rsquo;s used for system administration tasks via the <a href="https://cockpit-project.org/">Cockpit UI</a>, such as: Installing updates, checking logs, joining a domain, or powering off / rebooting the system.</p></blockquote>
<p><img alt="con-sysadmin" loading="lazy" src="/how-to-setup-cml-on-proxmox/con-sysadmin.png#center"></p>
<p>After that, we can configure our CML admin user:</p>
<p><img alt="con-cmladmin" loading="lazy" src="/how-to-setup-cml-on-proxmox/con-cmladmin.png#center"></p>
<p>Next we have our network config. By default, CML will prompt to use DHCP, but we&rsquo;ll likely want to change this to a static IP assignment:</p>
<p><img alt="con-networktype" loading="lazy" src="/how-to-setup-cml-on-proxmox/con-networktype.png#center"></p>
<p><img alt="con-staticip" loading="lazy" src="/how-to-setup-cml-on-proxmox/con-staticip.png#center"></p>
<p>After that, CML will prompt us to confirm our settings - then it will begin the installation. Since a lot of the VM images come from the reference platform ISO, this process may take a while as each of those images are copied over to the system.</p>
<p>When CML is ready, we&rsquo;ll see something similar on the console telling us how to reach the web UI:</p>
<p><img alt="con-alldone" loading="lazy" src="/how-to-setup-cml-on-proxmox/con-alldone.png#center"></p>
<p>Again for reference, the main UI is reachable at <code>https://&lt;CML IP&gt;</code> and the Cockpit management UI is at <code>https://&lt;CML IP&gt;:9090</code>.</p>
<p>At this point, we can log in &amp; start building labs!</p>
<hr>
<p>The process for setting up CML on Proxmox isn&rsquo;t super crazy, but there are just a few tweaks that need to be made during setup. I wrote this hoping that if anyone else out there is trying to set this up, maybe it would help.</p>
<p>As always, Thanks for reading!</p>
]]></content:encoded>
    </item>
    <item>
      <title>[Quick Fix] Nexus 9k &amp; Ansible: &#34;Request without namespace and filter is an unsupported operation&#34;</title>
      <link>https://0x2142.com/quick-fix-nexus-9k-ansible-netconf/</link>
      <pubDate>Wed, 31 Jan 2024 23:01:48 +0000</pubDate>
      <guid>https://0x2142.com/quick-fix-nexus-9k-ansible-netconf/</guid>
      <description>A quick blog post on how to fix an error with Ansible and Cisco Nexus 9k via NETCONF: &amp;ldquo;Request without namespace and filter is an unsupported operation&amp;rdquo;</description>
      <content:encoded><![CDATA[<p>Hey there everyone, I hope you&rsquo;ve had a great start to the year so far!</p>
<p>In this blog post, I wanted to spend just a few minutes going over how to solve an issue one of my peers ran into recently.</p>
<h2 id="the-issue">The Issue</h2>
<p>Let&rsquo;s say we were trying to use Ansible to update the interface admin state on a Cisco Nexus switch. In this case, I&rsquo;m using a virtual Nexus 9000 which is running NX-OS version 10.2(6).</p>
<p>This switch has a loopback interface (lo100), which we want to disable.</p>
<p>Reading the <a href="https://docs.ansible.com/ansible/latest/collections/ansible/netcommon/netconf_config_module.html#examples">Ansible documentation</a> for the NETCONF module, we might assume that the following would be enough to get the job done:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="nt">name </span><span class="p">:</span><span class="w"> </span><span class="l">NX-OS Interface Updates</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">hosts</span><span class="p">:</span><span class="w"> </span><span class="l">all</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">connection</span><span class="p">:</span><span class="w"> </span><span class="l">netconf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">gather_facts</span><span class="p">:</span><span class="w"> </span><span class="kc">no</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">tasks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Update Interface State</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">ansible.netcommon.netconf_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">content</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">            &lt;config&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">              &lt;System xmlns=&#34;http://cisco.com/ns/yang/cisco-nx-os-device&#34;&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                &lt;intf-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                  &lt;lb-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                    &lt;LbRtdIf-list&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                      &lt;id&gt;lo100&lt;/id&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                      &lt;adminSt&gt;down&lt;/adminSt&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                    &lt;/LbRtdIf-list&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                  &lt;/lb-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                &lt;/intf-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">              &lt;/System&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">            &lt;/config&gt;</span><span class="w">
</span></span></span></code></pre></div><p>However, once we run that playbook, we&rsquo;ll get an error back:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="o">(</span>ansible<span class="o">)</span> matt@ansible-dev:~/ansible/nxos$ ansible-playbook nx-update-interface.yaml -i inventory.yml
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">PLAY <span class="o">[</span>NX-OS Interface Updates<span class="o">]</span> **********************************************************************************************************
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">TASK <span class="o">[</span>Update Interface State<span class="o">]</span> ***********************************************************************************************************
</span></span><span class="line"><span class="cl">fatal: <span class="o">[</span>10.122.2.229<span class="o">]</span>: FAILED! <span class="o">=</span>&gt; <span class="o">{</span><span class="s2">&#34;changed&#34;</span>: false, <span class="s2">&#34;msg&#34;</span>: <span class="s2">&#34;Request without namespace and filter is an unsupported operation&#34;</span><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">PLAY RECAP ******************************************************************************************************************************
</span></span><span class="line"><span class="cl">10.122.2.229               : <span class="nv">ok</span><span class="o">=</span><span class="m">0</span>    <span class="nv">changed</span><span class="o">=</span><span class="m">0</span>    <span class="nv">unreachable</span><span class="o">=</span><span class="m">0</span>    <span class="nv">failed</span><span class="o">=</span><span class="m">1</span>    <span class="nv">skipped</span><span class="o">=</span><span class="m">0</span>    <span class="nv">rescued</span><span class="o">=</span><span class="m">0</span>    <span class="nv">ignored</span><span class="o">=</span><span class="m">0</span>
</span></span></code></pre></div><h2 id="the-fix">The Fix</h2>
<p>Luckily, this has an easy solution.</p>
<p>According to the Cisco <a href="https://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus9000/sw/93x/progammability/guide/b-cisco-nexus-9000-series-nx-os-programmability-guide-93x/b-cisco-nexus-9000-series-nx-os-programmability-guide-93x_chapter_0100110.html#id_72426">NX-OS Documentation</a>, there was a change in version 9.3(1) that requires a filter to be sent along with any GET or GET-CONFIG request.</p>
<p>But wait - aren&rsquo;t we updating the config via an EDIT-CONFIG request? We shouldn&rsquo;t need to send a filter, since it&rsquo;s not a GET or GET-CONFIG, right?</p>
<p>Well because of the way Ansible works, we actually send two GET-CONFIG requests along with our EDIT-CONFIG. One <a href="https://github.com/ansible-collections/ansible.netcommon/blob/95d2f6bd66ce5841d951b26790298cf97e3d591b/plugins/modules/netconf_config.py#L622">before</a> the change, and another one <a href="https://github.com/ansible-collections/ansible.netcommon/blob/95d2f6bd66ce5841d951b26790298cf97e3d591b/plugins/modules/netconf_config.py#L673">after</a> making the change.</p>
<p>These are used to validate that we actually updated the config. Ansible uses these two GET-CONFIG requests to compare &amp; see if there is actually any difference between the two.</p>
<p>So to address our error above - when we send our config change in Ansible, we also need to include the get_filter parameter. This will give Ansible a NETCONF filter use when it issues the GET-CONFIG requests to validate our changes.</p>
<p>In our case, that GET-CONFIG filter could look something like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;System</span> <span class="na">xmlns=</span><span class="s">&#34;http://cisco.com/ns/yang/cisco-nx-os-device&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;intf-items&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;lb-items&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;LbRtdIf-list&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&lt;id&gt;</span>lo100<span class="nt">&lt;/id&gt;</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&lt;adminSt/&gt;</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&lt;/LbRtdIf-list&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&lt;/lb-items&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&lt;/intf-items&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/System&gt;</span>
</span></span></code></pre></div><p>That filter would pull back just the admin state for our lo100 interface, which then Ansible could use to compare after we issue our request to disable the interface.</p>
<p>For what it&rsquo;s worth, we don&rsquo;t necessarily have to be that specific with our filter. We just need to ensure that whatever config returned by the filter would also include the section we intend to change.</p>
<p>So for example, we could actually just filter by System and this would still work:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-xml" data-lang="xml"><span class="line"><span class="cl"><span class="nt">&lt;System</span> <span class="na">xmlns=</span><span class="s">&#34;http://cisco.com/ns/yang/cisco-nx-os-device&#34;</span><span class="nt">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="nt">&lt;/System&gt;</span>
</span></span></code></pre></div><p>The main difference here is that the switch would return a much larger amount of data, which then Ansible would also need to process to detect the change. So for efficiency &amp; accuracy, it&rsquo;s probably still helpful to keep our get_filter scoped to a reasonably narrow amount.</p>
<p>With all that covered, here&rsquo;s the example of our final playbook with the new filter:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="nt">name </span><span class="p">:</span><span class="w"> </span><span class="l">NX-OS Interface Updates</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">hosts</span><span class="p">:</span><span class="w"> </span><span class="l">all</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">connection</span><span class="p">:</span><span class="w"> </span><span class="l">netconf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">gather_facts</span><span class="p">:</span><span class="w"> </span><span class="kc">no</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">tasks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Update Interface State</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">ansible.netcommon.netconf_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">get_filter</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">          &lt;System xmlns=&#34;http://cisco.com/ns/yang/cisco-nx-os-device&#34;&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                &lt;intf-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                  &lt;lb-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                    &lt;LbRtdIf-list&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                      &lt;id&gt;lo100&lt;/id&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                      &lt;adminSt/&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                    &lt;/LbRtdIf-list&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                  &lt;/lb-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                &lt;/intf-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">              &lt;/System&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">content</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">            &lt;config&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">              &lt;System xmlns=&#34;http://cisco.com/ns/yang/cisco-nx-os-device&#34;&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                &lt;intf-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                  &lt;lb-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                    &lt;LbRtdIf-list&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                      &lt;id&gt;lo100&lt;/id&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                      &lt;adminSt&gt;down&lt;/adminSt&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                    &lt;/LbRtdIf-list&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                  &lt;/lb-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">                &lt;/intf-items&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">              &lt;/System&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">            &lt;/config&gt;</span><span class="w">
</span></span></span></code></pre></div><p>And, if we try to run the playbook again:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="o">(</span>ansible<span class="o">)</span> matt@ansible-dev:~/ansible/nxos$ ansible-playbook nx-update-interface.yaml -i inventory.yml
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">PLAY <span class="o">[</span>NX-OS Interface Updates<span class="o">]</span> **********************************************************************************************************
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">TASK <span class="o">[</span>Update Interface State<span class="o">]</span> ***********************************************************************************************************
</span></span><span class="line"><span class="cl">changed: <span class="o">[</span>10.122.2.229<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">PLAY RECAP ******************************************************************************************************************************
</span></span><span class="line"><span class="cl">10.122.2.229               : <span class="nv">ok</span><span class="o">=</span><span class="m">1</span>    <span class="nv">changed</span><span class="o">=</span><span class="m">1</span>    <span class="nv">unreachable</span><span class="o">=</span><span class="m">0</span>    <span class="nv">failed</span><span class="o">=</span><span class="m">0</span>    <span class="nv">skipped</span><span class="o">=</span><span class="m">0</span>    <span class="nv">rescued</span><span class="o">=</span><span class="m">0</span>    <span class="nv">ignored</span><span class="o">=</span><span class="m">0</span>
</span></span></code></pre></div><p>That looks much better!</p>
<hr>
<p>Thanks so much for reading this blog post. I really hope it was helpful to you!</p>
<p>If you found value in this, please let me know! Feel free to leave me a comment below, or follow me on <a href="https://www.youtube.com/@0x2142">YouTube</a>!</p>
<p>Oh, and for those of you on Mastodon - You can find me at <a href="https://0x2142.com/@matt">@matt@0x2142.com</a>.</p>
<p>Thanks again!</p>
]]></content:encoded>
    </item>
    <item>
      <title>[How To] Protect Your Home Network with Mullvad VPN &amp; OPNsense</title>
      <link>https://0x2142.com/how-to-protect-your-home-network-with-mullvad-vpn-opnsense/</link>
      <pubDate>Tue, 29 Aug 2023 15:01:15 +0000</pubDate>
      <guid>https://0x2142.com/how-to-protect-your-home-network-with-mullvad-vpn-opnsense/</guid>
      <description>In this post, we&amp;rsquo;ll walk through how to connect an OPNsense firewall to Mullvad&amp;rsquo;s VPN service. This covers both a full tunnel &amp;amp; partial tunnel configuration.</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/9B4FW5pf2wA?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>In this post, we&rsquo;ll walk through how to connect an OPNsense firewall to Mullvad&rsquo;s wireguard VPN. This can be used in various deployments to help protect your home network traffic.</p>
<p>As a quick note, this post is not sponsored by <a href="https://mullvad.net/">Mullvad</a> - I just happen to really like their service &amp; appreciate their approach to privacy and security. In fact, they currently don&rsquo;t offer any incentives or paid promotions of their product. More info on their current policy can be found <a href="https://mullvad.net/en/help/policy-reviews-advertising-and-affiliates/">here</a>.</p>
<h1 id="creating-an-account">Creating an Account</h1>
<p>Mullvad is unique in that they don&rsquo;t really require any sign up to get started with their service. Instead, when you sign up for new service, they randomly generate an account number. That&rsquo;s it. They don&rsquo;t require any additional information from you.</p>
<p>So first we can hit their new account page <a href="https://mullvad.net/en/account/create">here</a> - then click to generate a new account number.</p>
<p><img alt="create-account" loading="lazy" src="/content/images/2023/07/create-account.png#center"></p>
<blockquote>
<p>Keep this account number somewhere safe. Mullvad has <a href="https://mullvad.net/en/account/recover/">very limited</a> ability to help you recover the account number.</p></blockquote>
<p>Once we have that, we can click the button to <strong>Add time</strong> to our account.</p>
<p>Mullvad doesn&rsquo;t support any recurring subscriptions, so that they are able to keep less data about their customers. Instead, we just add time increments in months for how long we would like to use the service. This can be anywhere from a single month up to a year.</p>
<p>In terms of payments, they do offer a number of options, including the usual PayPal/credit cards - or if you&rsquo;re truly concerned about privacy, they accept a few cryptocurrencies or you can actually mail them a cash payment as well.</p>
<p>After a payment has been made &amp; time added to the account, we can quickly jump into the configuration side of things.</p>
<h1 id="config-mullvad-side">Config: Mullvad Side</h1>
<p>First we&rsquo;ll take a quick look at the configuration required on the Mullvad VPN side of things.</p>
<p>On the left side of the account page, we&rsquo;ll click on <strong>WireGuard Configuration</strong>.</p>
<p>First we&rsquo;ll select <strong>Linux</strong> as our platform (In this context, what is selected here isn&rsquo;t really important) - and then click the button to generate WireGuard keys:</p>
<p><img alt="generate-keys" loading="lazy" src="/content/images/2023/07/generate-keys.png#center"></p>
<blockquote>
<p>Note: Alternatively, we could have generated our WireGuard keys on our OPNsense firewall - then applied them here. It&rsquo;s up to you on which method you prefer!</p></blockquote>
<p>Next, we&rsquo;ll take a look at which server(s) we would like to connect to.</p>
<p><img alt="select-server" loading="lazy" src="/content/images/2023/07/select-server.png#center"></p>
<p>When selecting a server, we have the option to pick our desired country &amp; location - as well as picking a specific server to connect to if we choose. There is also an option to select all servers - in which case the config generator will create a WireGuard configuration file for each server.</p>
<p>For the purpose of this walk through, we&rsquo;ll keep things simple &amp; only select a single server. So in the screenshot above, I&rsquo;ve selected <code>us-qas-wg-004</code>.</p>
<p>We&rsquo;ll also take a quick look at the advanced options, which give us a little flexibility if we need it. For most people, these additional options will not be necessary to change or modify.</p>
<p>We can enable <strong>Multihop</strong> functionality, so long as we only selected a single server to connect to. So if you selected the <strong>All Servers</strong> option, this won&rsquo;t be available. This allows us to specify an entry &amp; exit server for our VPN. In other words, our device would directly connect to the entry server we select - then Mullvad would tunnel our traffic across their network to the exit server, where our traffic would be decrypted &amp; forwarded out to the internet. Depending on your privacy &amp; security desires, this is a really nice option to have the ability to enable.</p>
<p>Next, we have options on what type of connection we would like &amp; which traffic to forward.</p>
<p><strong>Server connection protocol</strong> will specify whether we are using IPv4 or IPv6 between our device &amp; our VPN server. Most likely you&rsquo;ll want to leave this at IPv4, unless you have an IPv6-only internet connection (or if you just would prefer to use IPv6 anyways!).</p>
<p><strong>Tunnel traffic</strong> is how we can specify whether we would like IPv4 or IPv6 <em>client-side</em> traffic to be forwarded over the VPN. So this would depend on whether the clients on our network have IPv4 vs IPv6 connectivity, or both - and whether we prefer to only forward certain types of traffic over the VPN. I&rsquo;ll be leaving this setting as the default: <strong>Both.</strong></p>
<p>Next we can specify a custom port if we would like. By default, wireguard will use UDP port 51820 - and we probably won&rsquo;t need to change this unless the port is being blocked upstream.</p>
<p>Lastly, we also have the option to enable content blocking across the VPN. Mullvad accomplishes content filtering through DNS-level blocking - and when we finish generating a configuration file, the file will include DNS servers to use. This is okay to use if you were connecting a single client to their VPN service. However, if you&rsquo;re using a router or device like OPNsense, you would need to update the DNS on all clients on your network to make this work. This is possible by updating DHCP on our router with the new DNS server address - or configuring a DNS rewrite. We won&rsquo;t get into either of those in this post - so for now I will leave the content blocking options unchecked.</p>
<p>Once we&rsquo;re good with our configuration - we can click the <strong>Download File</strong> button. We&rsquo;ll get a standard WireGuard config file, that looks like this:</p>
<p><img alt="wireguard-config" loading="lazy" src="/content/images/2023/07/wireguard-config.png#center"></p>
<p>At this point, we&rsquo;re good to move onto the next part!</p>
<h1 id="config-opnsense-side">Config: OPNsense Side</h1>
<p>Okay, so now that we have everything ready to go on the Mullvad side - we can configure our OPNsense device.</p>
<p>Make sure you already have WireGuard installed on OPNsense. This can be done by navigating to <strong>System &gt; Firmware &gt; Plugins</strong> then searching for <strong>wireguard</strong> &amp; clicking the install button.</p>
<p>Next, we&rsquo;ll enable Wireguard by navigating to <strong>VPN &gt; Wireguard</strong> and checking the box to <strong>Enable WireGuard</strong>, then <strong>Apply</strong>.</p>
<p><img alt="enable-wireguard" loading="lazy" src="/content/images/2023/07/enable-wireguard.png#center"></p>
<p>Then we&rsquo;ll hop over to the <strong>Endpoints</strong> tab &amp; configure our Mullvad VPN peer.</p>
<p>For this part of the configuration, we&rsquo;ll just copy our public key, allowed IPs, endpoint address, and endpoint port from our Mullvad config file. In the screenshot below, I also named my endpoint with the specific Mullvad server I&rsquo;ll be connecting to:</p>
<p><img alt="mullvad-peer-config-1" loading="lazy" src="/content/images/2023/07/mullvad-peer-config-1.png#center"></p>
<p>Then we can click <strong>Save</strong> and <strong>Apply.</strong></p>
<blockquote>
<p>If you wanted multiple Mullvad servers configured, just create a new endpoint for each one. Then, make sure that you select all of the Mullvad peers on the next step below.</p></blockquote>
<p>After that, we can move over to the <strong>Local</strong> tab to define our OPNsense tunnel configuration.</p>
<p>Click the button to add a new peer, then we&rsquo;ll fill in our private key and tunnel address(es) from the Mullvad config file. Under <strong>Peers</strong>, we&rsquo;ll also select our Mullvad VPN peer that we configured just a moment ago:</p>
<p><img alt="opnsense-local-1" loading="lazy" src="/content/images/2023/07/opnsense-local-1.png#center"></p>
<blockquote>
<p>UPDATE: Looks like with a recent OPNsense update, they now require you to enter both the WireGuard private &amp; public key into the local config (shown above). In the the screenshot, I only show entering the private key - since this was all that was required at the time.
Two ways to get your public key:</p>
<ol>
<li>Log into Mullvad &amp; check the &ldquo;Devices&rdquo; tab under &ldquo;Account Management&rdquo;. This will show your device public key (They don&rsquo;t keep your private key after generating it for you, only the public).</li>
<li>If you have wireguard installed somewhere else, you can use the &ldquo;wg pubkey&rdquo; command to derive a public key from your private key. Command: <code>echo &lt;private_key&gt; | wg pubkey</code></li>
</ol></blockquote>
<blockquote>
<p>Note: By default with the configuration we&rsquo;ve applied so far, this VPN will forward ALL traffic on our network to Mullvad. If we would prefer to selectively choose which traffic to send over the VPN, we can check the box for <strong>Disable Routes</strong> - then use policy routing to forward specific things to Mullvad.
We&rsquo;ll take a look at how to do this later in the post - but for now just be aware that our current configuration will forward ALL traffic.</p></blockquote>
<p>Okay, with that all done we can click <strong>Apply</strong> and <strong>Save</strong> here as well.</p>
<p>With any luck, we can check the <strong>Status</strong> tab &amp; see that there is data being transmitted &amp; successful WireGuard handshakes:</p>
<p><img alt="wg-status" loading="lazy" src="/content/images/2023/07/wg-status.png#center"></p>
<p>However, before our clients traffic can be forwarded over the VPN, we&rsquo;ll need to create a firewall rule to permit traffic &amp; a NAT rule to translate our client addresses to our Mullvad IP.</p>
<p>We&rsquo;ll navigate to <strong>Firewall &gt; Rules &gt; WireGuard (Group)</strong>. Then we&rsquo;ll click to create a new rule.</p>
<p>Within this new rule, I&rsquo;ll update <strong>Direction</strong> to <strong>Out</strong> and change <strong>TCP/IP Version</strong> to <strong>IPv4+IPv6</strong>. I&rsquo;ll leave the source as <strong>Any:</strong></p>
<p><img alt="wgrule1" loading="lazy" src="/content/images/2023/07/wgrule1.png#center"></p>
<p>We can also leave the <strong>Destination</strong> as <strong>Any</strong>, but I&rsquo;ll update the rule to enable logging:</p>
<p><img alt="wgrule2" loading="lazy" src="/content/images/2023/07/wgrule2.png#center"></p>
<p>This rule will allow any clients behind our OPNsense firewall to reach anything on the internet.</p>
<p>Next, we&rsquo;ll have to create a NAT rule. This ensures that our client addresses on our network get appropriately translated to the tunnel IP address that Mullvad has assigned us.</p>
<p>We&rsquo;ll navigate to <strong>Firewall &gt; NAT &gt; Outbound</strong>. By default, OPNsense will be set to <strong>Automatic outbound NAT rule generation</strong>. We&rsquo;ll need to update this to <strong>Hybrid outbound NAT rule generation</strong> to allow custom NAT rules. Then we can click <strong>Save</strong> and <strong>Apply</strong>.</p>
<p><img alt="nat-before" loading="lazy" src="/content/images/2023/07/nat-before.png#center"></p>
<p>Next, we&rsquo;ll create a new <strong>Manual NAT</strong> rule, where we&rsquo;ll update our <strong>Interface</strong> to <strong>WireGuard (Group):</strong></p>
<p><img alt="nat-rule1" loading="lazy" src="/content/images/2023/07/nat-rule1.png#center"></p>
<p>Then we&rsquo;ll make sure our <strong>Translation / target</strong> is set to <strong>Interface Address</strong> - and again, I&rsquo;ll enable logging:</p>
<p><img alt="nat-rule2" loading="lazy" src="/content/images/2023/07/nat-rule2.png#center"></p>
<p>After we click save, we should have a NAT rule that looks like this:</p>
<p><img alt="nat-after" loading="lazy" src="/content/images/2023/07/nat-after.png#center"></p>
<p>At this point, we should be good to test our clients!</p>
<h1 id="testing">Testing</h1>
<p>Of course, it&rsquo;s easy enough to use one of our clients to check that we still have internet access - but how can we be sure that they&rsquo;re using the VPN?</p>
<p>The easiest way might be to check the <a href="https://mullvad.net">mullvad.net</a>, where they do have a quick validation at the top of the page:</p>
<p><img alt="mullvad-test" loading="lazy" src="/content/images/2023/07/mullvad-test.png#center"></p>
<p>So according to Mullvad, it looks like we&rsquo;re connected &amp; they even show which server we&rsquo;re connecting from.</p>
<p>We can also double check using a traceroute or tracepath command:</p>
<p><img alt="tracepath" loading="lazy" src="/content/images/2023/07/tracepath.png#center"></p>
<p>In this case, we can see that our traffic to Google hits our OPNsense gateway, then the Mullvad VPN gateway followed by another external address owned by Mullvad.</p>
<p>So based on some quick testing, it looks like we&rsquo;re all good!</p>
<h1 id="policy-routing">Policy Routing</h1>
<p>So in the above walkthrough, we configured a Mullvad VPN from our OPNsense firewall - but it is forwarding ALL of our network clients over the VPN. What about if we only wanted certain clients to use the VPN? Or all clients to use it, but only for certain destinations?</p>
<p>We can accomplish this through policy routing.</p>
<p>So the first thing we&rsquo;ll do is go back to our WireGuard config, then under the <strong>Local</strong> tab. We&rsquo;ll edit our configuration here, and check the box for <strong>Disable Routes</strong>.</p>
<p><img alt="disable-routes" loading="lazy" src="/content/images/2023/07/disable-routes.png#center"></p>
<p>By default, OPNsense / WireGuard will install routes for any IPs listed in the <strong>AllowedIPs</strong> field for each peer. In our set up, we configured <strong>0.0.0.0/0</strong> - which matches all traffic. By checking the box for <strong>Disable Routes</strong>, we prevent OPNsense from installing that default route - and instead we can manually specify our own.</p>
<blockquote>
<p>If you&rsquo;re curious to double check this, you can try hitting Mullvad&rsquo;s website after changing this setting - and it should show that you&rsquo;re no longer connected.</p></blockquote>
<p>Then, we&rsquo;ll need to set up our WireGuard configuration to use a dedicated, named interface so that we can create a static gateway.</p>
<p>We&rsquo;ll head to <strong>Interfaces &gt; Assignments</strong> - and create a new interface. From the drop-down, we&rsquo;ll select our WireGuard interface - in my case this was <code>wg1</code>. Then we can assign it a name:</p>
<p><img alt="create-interface" loading="lazy" src="/content/images/2023/07/create-interface.png#center"></p>
<p>Then click the <strong>+</strong> icon to add, and <strong>Save.</strong></p>
<p>Then we can navigate to the interface name under the <strong>Interfaces</strong> menu - and enable the new interface:</p>
<p><img alt="enable-interface" loading="lazy" src="/content/images/2023/07/enable-interface.png#center"></p>
<p>Next we can create a gateway to route traffic through. Navigate to <strong>System &gt; Gateways &gt; Single</strong>.</p>
<p>Create a new gateway &amp; give it a name. Then we&rsquo;ll enter our Mullvad VPN gateway IP address, which in my case was <code>10.64.0.1</code>. How did we find this? Well earlier when we tested our VPN connectivity - we performed a tracepath. In the output of this tracepath, our second hop (the one right after our OPNsense firewall) would be the Mullvad VPN gateway. So this is the address we&rsquo;ll use for our gateway here:</p>
<p><img alt="mullvad-gateway" loading="lazy" src="/content/images/2023/07/mullvad-gateway.png#center"></p>
<p>Then clic <strong>Save</strong> and <strong>Apply</strong>.</p>
<blockquote>
<p>Note: You may get an error here, like &ldquo;The gateway address &ldquo;10.64.0.1&rdquo; does not lie within one of the chosen interface&rsquo;s IPv4 subnets.&rdquo;
To resolve this, we&rsquo;ll temporarily change our interface address. Navigate to the WireGuard local config, and re-enter your tunnel address excluding the &ldquo;/32&rdquo;. For example, if your tunnel IP was <code>10.10.10.10/32</code>, change this to just <code>10.10.10.10</code>
You should be able to set the gateway address now. Be sure to change your tunnel IP back afterwards!</p></blockquote>
<p>Next, we&rsquo;ll create a firewall rule for each set of sources or destinations we would like to manipulate.</p>
<p>So we can navigate to <strong>Firewall &gt; Rules &gt; Floating</strong> (or select a specific interface for clients, like LAN).</p>
<p>In here, we&rsquo;ll set whichever parameters we would like to match. So for this example, let&rsquo;s say I have a client PC at <code>10.100.100.10</code> and I only want traffic to <code>8.8.8.8</code> to use Mullvad. All other traffic can use the normal internet connection &amp; not use the VPN.</p>
<p>In that case, I&rsquo;ll set my source address to <code>10.100.100.10/32</code> and my destination to <code>8.8.8.8/32</code>:</p>
<p><img alt="policy-route1" loading="lazy" src="/content/images/2023/07/policy-route1.png#center"></p>
<p>Then all we need to do is update our <strong>Gateway</strong> to use the Mullvad gateway we just created:</p>
<p><img alt="policy-route2" loading="lazy" src="/content/images/2023/07/policy-route2.png#center"></p>
<p>Now, if we hop over to our client PC - Mullvad&rsquo;s website will say that we&rsquo;re not connected to the VPN. However, we can check that traffic to 8.8.8.8 is actually being sent through Mullvad using tracepath again:</p>
<p><img alt="split-routing" loading="lazy" src="/content/images/2023/07/split-routing.png#center"></p>
<p>In the screenshot above, I also included a tracepath to 8.8.4.4, just to show that it is going through my normal internet connection &amp; not Mullvad.</p>
<p>This was just one example, but you could easily create multiple firewall rules for different sources and/or destinations to control where traffic is sent. Aliases can also be used to group sources or destinations, so that multiple can be added to a single firewall rule.</p>
<hr>
<p>Okay - I think that&rsquo;s about all I wanted to cover in this post.</p>
<p>Hope it is helpful! Feel free to leave a comment below - or follow me on <a href="https://youtube.com/@0x2142">YouTube</a> 😊</p>
]]></content:encoded>
    </item>
    <item>
      <title>[How To] Set up AdGuard Home on OPNsense</title>
      <link>https://0x2142.com/how-to-set-up-adguard-on-opnsense/</link>
      <pubDate>Fri, 09 Dec 2022 16:40:49 +0000</pubDate>
      <guid>https://0x2142.com/how-to-set-up-adguard-on-opnsense/</guid>
      <description>In this post, we&amp;rsquo;ll walk through how to install, setup, and configure AdGuard Home on OPNsense for DNS-level ad blocking.</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/7RC7q5WOYC0?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>In this post - we&rsquo;ll take a look at how to set up &amp; configure AdGuard Home on OPNsense.</p>
<p>Please note that the AdGuard Home plugin for OPNsense is a <a href="https://github.com/mimugmail/opn-repo">community built plugin</a>, and not officially supported by OPNsense.</p>
<hr>
<h2 id="whats-adguard-home-why-use-it">What&rsquo;s AdGuard Home? Why use it?</h2>
<p>Almost every website we visit these days is loaded with additional components for  advertisements, analytics, and engagement tracking. One one side, these tools can be very helpful for the company or website owner to monetize their platform and/or track &amp; understand their audience&rsquo;s interests.</p>
<p>However, it&rsquo;s also becoming more popular to want to <em>avoid</em> being tracked on every website, or reduce the amount of advertisements you see. Unfortunately, a lot of these scripts &amp; code snippets are automatically embedded in websites and most don&rsquo;t allow you to opt-out.</p>
<p>A while back, there were a few browser extensions that became popular by automatically blocking the advertisement &amp; tracking elements from loading. These were great (and still are!), but a lot of website owners have been fighting it &amp; making it harder to block their content. In addition, these types of extensions operate at your web browser level - meaning that your computer has already made a few calls out to the internet before the extension even has a chance to block something.</p>
<p>Here&rsquo;s where we&rsquo;ve started to see more ad blockers come out that operate at the network level. AdGuard Home is one of them, but you also may have seen similar packages like Pi-hole or NextDNS. These are typically packages that you install on your home network &amp; run as a local Domain Name System (DNS) server.</p>
<p>Each time your browser needs to load something from the web, the first step is figuring out what IP address to connect to. For this, the computer reaches out to it&rsquo;s configured DNS server and provides the website name (like 0x2142.com). The DNS server looks up where that lives &amp; provides the computer with the IP address (like 203.0.113.52). Then your computer can load the website by connecting to that address.</p>
<p>With a DNS-level blocker, like AdGuard Home, we can block your computer from ever trying to establish that connection. If you tried to go to a website (like 0x2142.com), and there was an embedded advertisement or tracking, AdGuard would tell your computer that the domain hosting the advertisement doesn&rsquo;t exist (usually via returning a 0.0.0.0 or NXDOMAIN response). So your browser would still be able to load the main site (0x2142.com), but it would never even try to establish a connection to the advertisement or tracking components.</p>
<p>So we gain a few benefits here - the big ones being some level of privacy &amp; reduced advertisement noise when browsing the web. But also since we block so much of that noise early in the process, your computer never has the opportunity to load that content - meaning that we also save on bandwidth usage &amp; data costs. There may also be small performance improvements since each site has less content that needs to be loaded.</p>
<p>The other bonus worth considering is security. There are quite a handful of DNS blocklists that are constantly updated with the latest malicious or suspicious domains. The quicker we can block  &amp; stop clients from potentially connecting to those domains, the better off we are!</p>
<p>Is there a down side? Yeah, of course there is! A lot of these DNS-level blockers pull from varying website blocklists - which are not always 100% accurate. So sometimes you may still see advertisements or get tracked. It&rsquo;s not a perfect system. In addition, you may also (and sometimes often) see the reverse - parts of websites being blocked that are legitimate. And there are quite a handful of websites these days that won&rsquo;t work correctly unless they can load 3rd party components. Most of the time everything will be fine, but just be aware that there may be some time spent troubleshooting &amp; manually unblocking website components.</p>
<h3 id="do-i-have-to-install-this-on-opnsense">Do I have to install this on OPNsense?</h3>
<p>Nope. AdGuard Home has a number of packages &amp; ways to get running. Check out their <a href="https://github.com/AdguardTeam/AdguardHome">GitHub</a> repo.</p>
<p>If you&rsquo;re already running OPNsense, it&rsquo;s easy to install this as an add-on package &amp; not have another system to manage. However, if you prefer to set up AdGuard (or Pi-hole, or others) elsewhere, that&rsquo;s fine too. You&rsquo;ll just need to update your client network&rsquo;s DHCP options to use the new DNS servers. See the last section below on how to do that.</p>
<p>Okay - Let&rsquo;s get started with setting this up!</p>
<h2 id="topology">Topology</h2>
<p>For the purposes of this walkthrough, we&rsquo;ll be using a fairly simple &amp; straightforward topology. A single OPNsense appliance connected to the internet via it&rsquo;s WAN port, as well as a single client PC connected via the LAN port.</p>
<p>In this setup, the OPNsense appliance is configured to provide IP address &amp; DNS information to our client PCs via DHCP.</p>
<p><img alt="topology" loading="lazy" src="/content/images/2022/12/topology.png#center"></p>
<h2 id="adding-the-community-repository-to-opnsense">Adding the Community Repository to OPNsense</h2>
<p>So by default, AdGuard Home is not included in the available plugins to download/install in OPNsense. However, someone built a community plugin repository that includes a small handful of additional packages.</p>
<p>Before we can install the AdGuard Home plugin, we will need to setup &amp; install that <a href="https://github.com/mimugmail/opn-repo">community repository</a>.</p>
<p>To do this, we&rsquo;ll need direct SSH or console access to our OPNsense appliance.</p>
<p>SSH is disabled by default, but we can enable it quickly by navigating to <strong>System &gt; Settings &gt; Administration</strong> and then scrolling down to the <strong>Secure Shell</strong> section.</p>
<p><img alt="enable-ssh-1" loading="lazy" src="/content/images/2022/12/enable-ssh-1.png#center"></p>
<p>We&rsquo;ll need to check the box for <strong>Enable Secure Shell</strong> and <strong>Permit Password Login</strong>. If you&rsquo;re logging into OPNsense with the <strong>root</strong> account, you&rsquo;ll also need to select <strong>Permit root user login</strong>.</p>
<p>Then scroll down to the bottom of the page &amp; click <strong>Save</strong>.</p>
<blockquote>
<p>Note: By default OPNsense will also have the SSH <strong>Listen Interface</strong> set to <strong>All</strong>. I would highly recommend setting this to only enable on your <strong>LAN</strong> interface
Also: If you don&rsquo;t need SSH access all the time, please remember to disable this service once you&rsquo;re finished setting this up!</p></blockquote>
<p>Okay, now that&rsquo;s enabled - we can connect to our OPNsense appliance using your preferred SSH client (like <a href="https://www.putty.org/">PuTTY</a>).</p>
<p>If you&rsquo;re using the <strong>root</strong> account, you&rsquo;ll likely be dropped into the OPNsense shell - but you can select option 8 here to access the underlying FreeBSD shell.</p>
<p>In order to install the community repository, we&rsquo;ll pull down the repository config file using the following command:</p>
<pre tabindex="0"><code>fetch -o /usr/local/etc/pkg/repos/mimugmail.conf https://www.routerperformance.net/mimugmail.conf
</code></pre><p>Then, we&rsquo;ll need to ask OPNsense to update it&rsquo;s local cache with the new repo - so it knows what packages are hosted there:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">pkg update
</span></span></code></pre></div><p>If everything is successful, you&rsquo;ll see output similar to below - which lists the <code>mimugmail</code> repository now:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">root@0xOPNsense:/home/matt <span class="c1"># pkg update</span>
</span></span><span class="line"><span class="cl">Updating OPNsense repository catalogue...
</span></span><span class="line"><span class="cl">Fetching meta.conf: 100%    <span class="m">163</span> B   0.2kB/s    00:01
</span></span><span class="line"><span class="cl">Fetching packagesite.pkg: 100%  <span class="m">229</span> KiB 234.3kB/s    00:01
</span></span><span class="line"><span class="cl">Processing entries: 100%
</span></span><span class="line"><span class="cl">OPNsense repository update completed. <span class="m">822</span> packages processed.
</span></span><span class="line"><span class="cl">Updating mimugmail repository catalogue...
</span></span><span class="line"><span class="cl">Fetching meta.conf: 100%    <span class="m">163</span> B   0.2kB/s    00:01
</span></span><span class="line"><span class="cl">Fetching packagesite.pkg: 100%   <span class="m">54</span> KiB  54.8kB/s    00:01
</span></span><span class="line"><span class="cl">Processing entries: 100%
</span></span><span class="line"><span class="cl">mimugmail repository update completed. <span class="m">177</span> packages processed.
</span></span><span class="line"><span class="cl">All repositories are up to date.
</span></span></code></pre></div><h2 id="installing-the-adguard-home-package">Installing the AdGuard Home Package</h2>
<p>Now that the additional package repository is set up, we can download &amp; install the AdGuard Home plugin via the OPNsense web interface.</p>
<p>So back in our browser, we can nagivate to: <strong>System &gt; Firmware &gt; Plugins</strong>. On this page we can search for <strong>adguard</strong> or scroll through the list to find it.</p>
<p><img alt="plugin-install" loading="lazy" src="/content/images/2022/12/plugin-install.png#center"></p>
<p>Then we just click the plus icon on the right side to install (not shown in the screenshot above).</p>
<p>This should install pretty quickly:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">***GOT REQUEST TO INSTALL***
</span></span><span class="line"><span class="cl">Currently running OPNsense 22.7.9 <span class="o">(</span>amd64/OpenSSL<span class="o">)</span> at Sun Dec  <span class="m">4</span> 12:48:38 EST <span class="m">2022</span>
</span></span><span class="line"><span class="cl">Updating OPNsense repository catalogue...
</span></span><span class="line"><span class="cl">OPNsense repository is up to date.
</span></span><span class="line"><span class="cl">Updating mimugmail repository catalogue...
</span></span><span class="line"><span class="cl">mimugmail repository is up to date.
</span></span><span class="line"><span class="cl">All repositories are up to date.
</span></span><span class="line"><span class="cl">The following <span class="m">1</span> package<span class="o">(</span>s<span class="o">)</span> will be affected <span class="o">(</span>of <span class="m">0</span> checked<span class="o">)</span>:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">New packages to be INSTALLED:
</span></span><span class="line"><span class="cl"> os-adguardhome-maxit: 1.8 <span class="o">[</span>mimugmail<span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Number of packages to be installed: <span class="m">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">The process will require <span class="m">35</span> MiB more space.
</span></span><span class="line"><span class="cl"><span class="m">7</span> MiB to be downloaded.
</span></span><span class="line"><span class="cl"><span class="o">[</span>1/1<span class="o">]</span> Fetching os-adguardhome-maxit-1.8.pkg: .......... <span class="k">done</span>
</span></span><span class="line"><span class="cl">Checking integrity... <span class="k">done</span> <span class="o">(</span><span class="m">0</span> conflicting<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">[</span>1/1<span class="o">]</span> Installing os-adguardhome-maxit-1.8...
</span></span><span class="line"><span class="cl"><span class="o">[</span>1/1<span class="o">]</span> Extracting os-adguardhome-maxit-1.8: .......... <span class="k">done</span>
</span></span><span class="line"><span class="cl">Stopping configd...done
</span></span><span class="line"><span class="cl">Starting configd.
</span></span><span class="line"><span class="cl">Migrated OPNsense<span class="se">\A</span>dguardhome<span class="se">\G</span>eneral from 0.0.0 to 0.0.1
</span></span><span class="line"><span class="cl">Reloading plugin configuration
</span></span><span class="line"><span class="cl">Configuring system logging...done.
</span></span><span class="line"><span class="cl">Reloading template OPNsense/Adguardhome: OK
</span></span><span class="line"><span class="cl">Checking integrity... <span class="k">done</span> <span class="o">(</span><span class="m">0</span> conflicting<span class="o">)</span>
</span></span><span class="line"><span class="cl">Nothing to <span class="k">do</span>.
</span></span><span class="line"><span class="cl">***DONE***
</span></span></code></pre></div><p>Now all we have to do is enable the plugin.</p>
<p>So we&rsquo;ll navigate down to <strong>Services &gt; Adguardhome &gt; General</strong>. Our only option here will be an <strong>Enable</strong> checkbox, so we&rsquo;ll select that &amp; <strong>Save</strong>.</p>
<p><img alt="enable-adguard" loading="lazy" src="/content/images/2022/12/enable-adguard.png#center"></p>
<p>The rest of the setup &amp; initial configuration will be done directly from the AdGuard-specific web interface.</p>
<h2 id="initial-setup">Initial Setup</h2>
<p>By default, the AdGuard Home web interface will run on port 3000 &amp; is not HTTPS-enabled. So if your OPNsense firewall is at <code>https://192.168.1.1</code>, you&rsquo;ll need to connect to <code>http://192.168.1.1:3000</code>.</p>
<p>As long as that works - we&rsquo;ll see the initial setup prompt below:</p>
<p><img alt="adguard-setup-01" loading="lazy" src="/content/images/2022/12/adguard-setup-01.png#center"></p>
<p>We&rsquo;ll click on <strong>Get Started</strong>.</p>
<p>Now we&rsquo;ll be asked to configure the Admin Web interface (the interface we&rsquo;re connected to now) and the DNS server interface (which clients will use to resolve domain names).</p>
<p>By default, AdGuard home will try to set both of these to listen on <strong>All interfaces</strong> - and set the web on port 80 &amp; DNS on port 53.</p>
<p>I would recommend setting the <strong>Listen Interface</strong> on both of these to only your LAN-side networks. There is no reason to enable them on your WAN, and it can be a security risk to do so.</p>
<p>You may also get warnings that port 80 &amp; 53 may already be in use. For the web interface, we could change 80 to 3000 &amp; just keep what we&rsquo;re using now.</p>
<p>However, if we change the default DNS port, that will cause some additional problems since client machines will query port 53. Likely if port 53 is already in use, it&rsquo;s because another service on OPNsense (like Unbound DNS) is already enabled. In my case, I disabled this in favor of using AdGuard. However, if you want to use both - you can change the default DNS port in AdGuard to something like 65353, then have Unbound forward requests to AdGuard (More on this down below).</p>
<p>So here&rsquo;s what my set up looks like so far, with <code>192.168.1.1</code> being my LAN side interface:</p>
<p><img alt="adguard-setup-02" loading="lazy" src="/content/images/2022/12/adguard-setup-02.png#center"></p>
<p>On the next page, we&rsquo;ll be prompted to set up an administrative user &amp; password for logging into AdGuard.</p>
<p><img alt="adguard-setup-03" loading="lazy" src="/content/images/2022/12/adguard-setup-03.png#center"></p>
<p>Next we&rsquo;ll be given instructions on how to set up client devices. In my lab network, the OPNsense firewall is providing DNS server configuration via DHCP - so we&rsquo;ll get to that configuration shortly.</p>
<p>For now, we&rsquo;ll just click <strong>Next</strong>.</p>
<p><img alt="adguard-setup-04" loading="lazy" src="/content/images/2022/12/adguard-setup-04.png#center"></p>
<p>On the last screen, we&rsquo;ll just get a message saying that setup is complete &amp; a link to open the dashboard:</p>
<p><img alt="adguard-setup-05" loading="lazy" src="/content/images/2022/12/adguard-setup-05.png#center"></p>
<p>And now we can log in:</p>
<p><img alt="adguard-setup-06" loading="lazy" src="/content/images/2022/12/adguard-setup-06.png#center"></p>
<h2 id="adguard-home-configuration">AdGuard Home Configuration</h2>
<p>After logging in, the first thing we&rsquo;ll see is a pretty empty dashboard. We don&rsquo;t have any clients configured to use this yet, so there isn&rsquo;t anything to report on.</p>
<p><img alt="adguard-dashboard-initial" loading="lazy" src="/content/images/2022/12/adguard-dashboard-initial.png#center"></p>
<h3 id="blocking-domains">Blocking Domains</h3>
<p>First thing we&rsquo;ll look at is our DNS blocklists. We&rsquo;ll navigate to <strong>Filters &gt; DNS blocklists</strong>.</p>
<p>Here is where we can ask AdGuard to query lists of what domains to block. By default, AdGuard does include two - but we can add more if we want:</p>
<p><img alt="adguard-dns-blocklists" loading="lazy" src="/content/images/2022/12/adguard-dns-blocklists.png#center"></p>
<p>If we want to add to the configured blocklists, we can do so by clicking the <strong>Add Blocklist</strong> button. This will prompt us whether we want to choose from a pre-populated list, or supply our own custom list:</p>
<p><img alt="add-blocklist" loading="lazy" src="/content/images/2022/12/add-blocklist.png#center"></p>
<p>The easy option will be selecting from the provided lists:</p>
<p><img alt="choose-blocklist" loading="lazy" src="/content/images/2022/12/choose-blocklist.png#center"></p>
<p>There are a ton of different curated block lists available depending on what you&rsquo;re trying to block. If we wanted to use a custom list, a lot can be found on GitHub just by searching for <a href="https://github.com/topics/pihole-blocklists">PiHole</a> or <a href="https://github.com/topics/adguard-blocklist">Adguard</a> blocklists.</p>
<p>How to pick a blocklist will be up to you. There are blocklists that focus on advertisements, tracking &amp; analytics, parental controls, etc. So it just depends on what areas you want to focus on.</p>
<h3 id="allowing-domains--custom-filtering">Allowing Domains &amp; Custom Filtering</h3>
<p>If we have a list of known services that we want to ensure are never blocked, we can pull those lists via <strong>Filters &gt; DNS allowlists</strong>. However, it&rsquo;s more likely you&rsquo;ll find a handful of domains you want to unblock, rather than a whole list.</p>
<p>For that - we can go to <strong>Filters &gt; Custom filtering rules</strong>. At the bottom of this page there is a tool to check filtering, where we can enter a domain name &amp; instantly see what the result is.</p>
<p>For example, with the default ruleset I&rsquo;ll check to see if 0x2142.com is filtered:</p>
<p><img alt="filter-test-default" loading="lazy" src="/content/images/2022/12/filter-test-default.png#center"></p>
<p>So by default that domain isn&rsquo;t found anywhere, so it will be permitted. The tool also gives us a convenient button to quickly block a domain.</p>
<p>We can click that button, or add the syntax <code>||0x2142.com^</code> to the custom filtering rules at the top of the page (and saving via the <strong>Apply</strong> button). Now if we check the results again - the filter check will show the domain is blocked:</p>
<p><img alt="filter-test-block" loading="lazy" src="/content/images/2022/12/filter-test-block.png#center"></p>
<p>And of course, we don&rsquo;t want to block 0x2142.com!! So let&rsquo;s add this to our allowlist instead, so that it can never be blocked 🙃. We can do that by adding <code>@@||0x2142.com^</code> to the custom filtering.</p>
<p>And now we&rsquo;ll see a green box that shows that the domain is permitted via an allowlist:</p>
<p><img alt="filter-test-allow" loading="lazy" src="/content/images/2022/12/filter-test-allow.png#center"></p>
<h3 id="blocking-known-services">Blocking Known Services</h3>
<p>The other option worth mentioning is the ability to block certain known services, like WhatsApp, Twitter, Reddit, etc. This can be great if there are certain services you want to block, or for use as parental controls.</p>
<p>This can be found on the <strong>Filters &gt; Blocked Services</strong> page.</p>
<p><img alt="blocked-services" loading="lazy" src="/content/images/2022/12/blocked-services.png#center"></p>
<p>This way we can select a service to block, rather than having to know all of the individual domains that service uses. For example, I&rsquo;ll go ahead and select <strong>YouTube</strong> to block - and we&rsquo;ll check that later on after we configure our clients.</p>
<h2 id="configure-opnsense-dhcp-to-use-adguard">Configure OPNsense DHCP to use AdGuard</h2>
<p>Now that we&rsquo;ve taken a quick look at the AdGuard Home settings &amp; have a few things configured - let&rsquo;s look at setting up our clients to use our new DNS server.</p>
<p>In the lab environment I&rsquo;m using, the OPNsense appliance is providing client IP address configuration via Dynamic Host Configuration Protocol (DHCP).</p>
<p>By default, if a specific DNS server is not configured for your client DHCP settings, then OPNsense will provide the clients with the same DNS server it uses. This could have been a DNS server that was configured when you set up OPNsense, or it also can use DNS servers that are provided by your internet service provider.</p>
<p>So to update our LAN DHCP configuration, we&rsquo;ll head back to our OPNsense web interface. From there, we&rsquo;ll navigate to <strong>Services &gt; DHCPv4 &gt; [LAN]</strong>.</p>
<p>In the configuration, there is an open option for <strong>DNS Servers</strong>. We&rsquo;ll set this to our OPNsense LAN IP address. In my case, that is <code>192.168.1.1</code>. Then scroll to the bottom of the page &amp; click <strong>Save</strong>.</p>
<p><img alt="opn-dhcp" loading="lazy" src="/content/images/2022/12/opn-dhcp.png#center"></p>
<h2 id="client-testing">Client Testing</h2>
<p>Now we should be all set up! However, it&rsquo;s important to note that because of the way DHCP works, clients may not pick up the new configuration immediately. When DHCP assigns an IP address, it also tells the client how long it can use that address for. So if a client stays powered-on &amp; connected, it won&rsquo;t ask for new configuration until that timer expires.</p>
<p>We can speed that up by resetting the network interface on our clients. This can be done in a number of ways including rebooting the client or simply disconnecting from wifi/ethernet &amp; reconnecting.</p>
<p>I&rsquo;m using a Linux computer as my test system, so first I&rsquo;ll check via the <code>nslookup</code> command - which will query our configured DNS server &amp; return the resolved IP addresses.</p>
<p>If you remember, I blocked all of YouTube&rsquo;s services earlier:</p>
<p><img alt="client-test-before" loading="lazy" src="/content/images/2022/12/client-test-before.png#center"></p>
<p>As we can see, we did get the correct IP addresses - which means our filtering isn&rsquo;t working yet.</p>
<p>I&rsquo;ll reset the network adapter on the test PC, which will refresh the DHCP configuration - then try again:</p>
<p><img alt="client-test-after" loading="lazy" src="/content/images/2022/12/client-test-after.png#center"></p>
<p>Now that&rsquo;s the result we want! By returning the <code>0.0.0.0</code> result, our client can no longer resolve that domain. So if this was an advertisement or tracking domain, it&rsquo;s now blocked from loading.</p>
<p>And sure enough, if we now try to browse to that site via a web browser - we don&rsquo;t be able to access it:</p>
<p><img alt="client-test-browser" loading="lazy" src="/content/images/2022/12/client-test-browser.png#center"></p>
<h2 id="troubleshooting-blocked-domains">Troubleshooting Blocked Domains</h2>
<p>Okay, so now we know our blocking works&hellip;. But now someone in our home is trying to access YouTube &amp; it&rsquo;s not working. How can we tell if that&rsquo;s our AdGuard service?</p>
<p>Our first stop might be the AdGuard query log. Opening this log, we can filter by domain name or client - or show only blocked queries if we like.</p>
<p>Pretty quickly we can see the issue - we blocked YouTube&rsquo;s services:</p>
<p><img alt="adguard-query-log" loading="lazy" src="/content/images/2022/12/adguard-query-log.png#center"></p>
<p>Now we know how to fix the issue, which would be to unblock that service. However, if it was just a specific domain that was blocked, we would likely want to add it to our custom filtering as we showed earlier.</p>
<h2 id="reporting">Reporting</h2>
<p>Last but not least, we can also check our AdGuard Home dashboard again, which should be much more interesting than before:</p>
<p><img alt="adguard-dashboard-after" loading="lazy" src="/content/images/2022/12/adguard-dashboard-after.png#center"></p>
<p>Here we can quickly see how many queries have been made &amp; how many were blocked for various reasons. We&rsquo;ll also see what clients are using our DNS server, and which are making the most queries.</p>
<p>Most interesting (at least to me), is being able to see the top domains that were queried or blocked. Here&rsquo;s where you might find some interesting information. For example, on my test machine - it&rsquo;s a fresh installation of Ubuntu &amp; we used FireFox to test. But we can see that even during the brief time it&rsquo;s been set up, almost all of the highest queried domains belong to Mozilla&rsquo;s analytics services. So it may be tempting to add those to our custom blocklists.</p>
<h2 id="additional-info">Additional Info</h2>
<h3 id="what-if-i-have-adguard-running-on-a-different-server-or-want-to-keep-using-unbound-dns">What if I have AdGuard running on a different server? Or want to keep using Unbound DNS?</h3>
<p>Sure - we can make both of those work.</p>
<p>For the first scenario, maybe we have AdGuard Home installed &amp; set up on a Raspberry Pi on our network. For that, all we need to do is set that Raspberry Pi as the DNS server in our DHCP configuration on OPNsense. See above where we did that for our on-box AdGuard setup.</p>
<p>For the other situation, perhaps you want to use Unbound on OPNsense, but also AdGuard. There might be reasons for this - like even though Unbound does support DNS blocklists, AdGuard has better reporting tools. But on the other hand, Unbound has more features &amp; configuration options for DNS than Unbound.</p>
<p>In this case, we would want to run AdGuard on a different DNS port (like 65353), then have Unbound forward those to AdGuard. See below if you need to change the port AdGuard uses for DNS.</p>
<p>Within OPNsense, we could go to <strong>Services &gt; Unbound DNS &gt; Query Forwarding</strong>. Then add a new custom forwarding entry. Here we can forward requests for specific domains if we want - or if we want to forward <strong>all</strong> DNS requests, we can leave the domain field empty. Then fill in the AdGuard information - so in my example this would be 192.168.1.1 and port 65353.</p>
<p><img alt="unbound-custom-1" loading="lazy" src="/content/images/2022/12/unbound-custom-1.png#center"></p>
<p>Then click <strong>Save</strong> and <strong>Apply!</strong></p>
<h3 id="how-do-i-change-the-interface--port-for-the-web-ui-or-dns">How do I change the interface / port for the Web UI or DNS?</h3>
<p>So perhaps we mis-typed something when configuring AdGuard. Or just wanted to change the interface IP address AdGuard listens on. No problem!</p>
<p>Unfortunately, since this is a community plugin - there is no configuration for the plugin within the OPNsense interface.</p>
<p>We&rsquo;ll need to reconnect to the OPNsense command line to make some additional configuration changes. This can be done via SSH or the device console.</p>
<p>Once there, we can use the command <code>edit /usr/local/AdGuardHome/AdGuardHome.yaml</code>.</p>
<p>That config file looks like this:</p>
<p><img alt="adguard-config-file" loading="lazy" src="/content/images/2022/12/adguard-config-file.png#center"></p>
<p>At the top, <code>bind_host</code> &amp; <code>bind_port</code> pertains to the admin web interface. A little below there, under the <code>dns</code> section - you&rsquo;ll see another <code>bind_hosts</code> and <code>port</code> config. Those ones are specific to the DNS server side of things.</p>
<p>Once done, save the config file by pressing <code>Esc</code> then selecting to quit the editor &amp; save the file.</p>
<p>Lastly - Go back into the OPNsense web UI &amp; restart the AdGuard Home service for the changes to take effect.</p>
]]></content:encoded>
    </item>
    <item>
      <title>[How to] Set up Wireguard VPN on OPNsense</title>
      <link>https://0x2142.com/how-to-set-up-wireguard-on-opnsense/</link>
      <pubDate>Tue, 02 Aug 2022 14:50:51 +0000</pubDate>
      <guid>https://0x2142.com/how-to-set-up-wireguard-on-opnsense/</guid>
      <description>In this post, we&amp;rsquo;ll walk through a simple WireGuard remote-access VPN configuration on OPNsense - including client setup examples with Windows &amp;amp; Android.</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/b58PpuIsQ3A?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>So in my <a href="/opnsense-qotom-q750gs/">last post</a>, I picked up a Qotom Mini-PC to run OPNsense on. After a few months, the device has been running well &amp; I&rsquo;m very happy with it.</p>
<p>One of the new things I got to try out with OPNsense was Wireguard VPN. I had previously been using something else for VPN connectivity back to my home network - but I heard good things about Wireguard &amp; wanted to give it a try.</p>
<p>So far my experience has been good! I&rsquo;ve been pleasantly suprised with how easy it is to configure &amp; get running. In addition, the performance &amp; overall experience has been very positive. The VPN connects quicker than anything I&rsquo;ve used in the past, and just simply works without issue.</p>
<p>All that being said - I wanted to put together a quick guide on how to configure Wireguard on OPNsense. Specifically, this configuraion will be for remote-access VPN - where clients will connect to a VPN headend. We&rsquo;ll walk through the OPNsense configuration &amp; a few clients as well. So let&rsquo;s dig in!</p>
<hr>
<h2 id="topology">Topology</h2>
<p>For the purpose of this blog post, we&rsquo;ll be using the lab topology below:</p>
<p><img alt="topology" loading="lazy" src="/content/images/2022/07/topology.png#center"></p>
<p>I will be using the reserved IP range 203.0.113.0/24 for the WAN-side addressing. I&rsquo;ll have one Windows &amp; one Android client that we&rsquo;ll walk through &amp; connect to the VPN.</p>
<h2 id="installing-the-wireguard-plugin">Installing the Wireguard Plugin</h2>
<p>To get started, first thing we will want to do is install the Wireguard plugin for OPNsense. By default, OPNsense will have standard IPSec &amp; OpenVPN already available - but other VPN options can be enabled easily.</p>
<p>So in OPNsense, we&rsquo;ll navigate down to <strong>System &gt; Firmware &gt; Plugins</strong>, then search for <strong>wireguard</strong> and click the plus icon.</p>
<p><img alt="addplugin" loading="lazy" src="/content/images/2022/07/addplugin.png#center"></p>
<p>This should pull down the package &amp; install pretty quickly. No reboot required here!</p>
<p><img alt="plugindownload" loading="lazy" src="/content/images/2022/07/plugindownload.png#center"></p>
<p>Once installed, you may have to refresh the page or navigate to a new page so that the menu bar has a chance to reload. Then we&rsquo;ll have a new option under <strong>VPN</strong>:</p>
<p><img alt="vpnmenu" loading="lazy" src="/content/images/2022/07/vpnmenu.png#center"></p>
<h2 id="wireguard-tunnel-configuration">Wireguard Tunnel Configuration</h2>
<p>Next we&rsquo;ll begin configuring Wireguard on the OPNsense side.</p>
<p>There is a little bit of a chicken &amp; egg scenario here since everything is based on cryptographic keys. We&rsquo;ll need to generate keys on the firewall, which we need to enter on the client - but we also need the client keys to enter on the firewall. A bit of bouncing between the two - but for now we&rsquo;ll try to complete as much as we can on the firewall side.</p>
<p>We&rsquo;ll enable Wireguard by dropping down to <strong>VPN &gt; WireGuard</strong> then clicking <strong>Enable</strong> and <strong>Apply</strong></p>
<p><img alt="enablewg" loading="lazy" src="/content/images/2022/07/enablewg.png#center"></p>
<p>Next we&rsquo;ll set up the Wireguard tunnel interface on OPNsense. This will be a virtual tunnel interface that will be created as interface <code>wg&lt;instance number&gt;</code>.</p>
<p>To do this, we&rsquo;ll navigate to the <strong>Local</strong> tab, and click the plus icon to add a new tunnel.</p>
<p><img alt="localconfig-pt1-1" loading="lazy" src="/content/images/2022/07/localconfig-pt1-1.png#center"></p>
<p>In the above screenshot, I&rsquo;ve filled in just a few details.</p>
<p>For <strong>Name</strong>, I&rsquo;ve entered our virtual interface name <code>wg1</code>. Since OPNsense shows the <strong>Instance</strong> as <code>1</code> - it will create a <code>wg</code> interface with that instance number.</p>
<p>We&rsquo;ll leave <strong>Public Key</strong> &amp; <strong>Private Key</strong> blank for now. OPNsense will auto-generate these keys once we save this config.</p>
<p>For <strong>Listen Port</strong>, I&rsquo;ve set this to 51820 which is the default for Wireguard. It&rsquo;s not stated here, but this is a UDP tunnel.</p>
<p>For <strong>Tunnel Address</strong> - this is where we add the IP address of the virtual tunnel interface. This will be the gateway for our remote clients. In my lab I&rsquo;ll be using 10.50.50.1/24 here.</p>
<p>We have no peers configured yet - so we can&rsquo;t select any here. We&rsquo;ll leave this blank for now, but come back later.</p>
<p>We will leave <strong>Disable Routes</strong> unchecked. By default, OPNsense will add static/connected routes for any client via the tunnel interface. You might not want this behavior if you wanted to do custom routing - for example, in a site-to-site VPN connection - but we&rsquo;ll leave this enabled.</p>
<p>Once we&rsquo;re done, we&rsquo;ll click <strong>Save</strong>.</p>
<p>Like I mentioned before, OPNsense will now auto-generate our crypto keys for the tunnels. So if we edit our tunnel, we&rsquo;ll now see those fields populated:</p>
<p><img alt="localconfig-pt2-1" loading="lazy" src="/content/images/2022/07/localconfig-pt2-1.png#center"></p>
<p>We&rsquo;ll want to copy the <strong>Public Key</strong> &amp; save it for later. This will need to be imported onto our clients, so that they can communicate securely with our firewall.</p>
<h2 id="wireguard-interface-assignment">Wireguard Interface Assignment</h2>
<p>Now that we have our headend tunnel interface defined, we can map our <code>wg1</code> interface to an OPNsense interface. The OPNsense documentation suggests this is optional, but I would recommend it since it will allow us to create firewall rules to permit/deny access to clients.</p>
<p>We&rsquo;ll navigate to <strong>Interfaces &gt; Assignments</strong>, and we should see a <strong>New interface</strong> available: our <code>wg1</code> tunnel.</p>
<p>We can assign this a name, then click the plus icon &amp; <strong>Save</strong>.</p>
<p><img alt="newinterface" loading="lazy" src="/content/images/2022/07/newinterface.png#center"></p>
<p>Next we&rsquo;ll enable the interface by navigating to <strong>Interfaces &gt; WG1</strong>. Here we&rsquo;ll only need to click <strong>Enable</strong> &amp; save the change - nothing else is necessary.</p>
<p><img alt="enableinterface" loading="lazy" src="/content/images/2022/07/enableinterface.png#center"></p>
<p>Of course, we&rsquo;ll be prompted to apply the changes - which we will do:</p>
<p><img alt="applychangeinterface" loading="lazy" src="/content/images/2022/07/applychangeinterface.png#center"></p>
<p>By default, all traffic through our <code>WG1</code> firewall interface will be blocked - so please make sure to configure a firewall rule to permit traffic from the Wireguard clients.</p>
<h2 id="firewall-rules-allow-inbound-wireguard-traffic">Firewall Rules: Allow Inbound Wireguard Traffic</h2>
<p>Next we need to permit the Wireguard traffic into our firewall. By default the WAN interface will block all traffic that isn&rsquo;t explicitly allowed - including our Wireguard traffic.</p>
<p>For this, we&rsquo;ll navigate to <strong>Firewall &gt; Rules &gt; WAN</strong>. Then click the plus icon to add a new rule.</p>
<p><img alt="waninboundfwrule" loading="lazy" src="/content/images/2022/07/waninboundfwrule.png#center"></p>
<p>The screenshot above shows what our firewall rule will look like.</p>
<p>Here&rsquo;s the summary:</p>
<ul>
<li>Action: Pass</li>
<li>Interface: WAN</li>
<li>Direction: In</li>
<li>TCP/IP Version: IPv4
<ul>
<li>You can enable IPv6 as well, if you have IPv6 connectivity (this is a lab box, which does not)</li>
</ul>
</li>
<li>Protocol: UDP</li>
<li>Source: Any
<ul>
<li>This will allow anyone on the internet to reach our VPN. We could restrict source IP addresses, if our clients had permanent, static IPs.</li>
</ul>
</li>
<li>Destination: WAN Address
<ul>
<li>The firewall itself is the destination for this traffic</li>
</ul>
</li>
<li>Destination Port Range: (other) / 51820</li>
</ul>
<p>I also enabled logging &amp; added a quick description. After we have all this configured, we can click <strong>Save</strong> - then <strong>Apply Changes</strong>.</p>
<h2 id="client-setup---windows">Client Setup - Windows</h2>
<p>So first we&rsquo;ll start with an easy configuration on a Windows client. Wireguard client software can be found on the Wireguard site <a href="https://www.wireguard.com/install/">here</a>.</p>
<p>For the sake of the walkthrough, we will manually configure each client. However, this can be a difficult task if there is a large number of clients. Wireguard does support importing configurations, and there are a number of free tools available to help automate generating config files for clients - including some which will generate QR codes for easy import on mobile clients.</p>
<p>So on my lab Windows machine, we&rsquo;ll open up the Wireguard client &amp; click <strong>Add Empty Tunnel:</strong></p>
<p><img alt="windows-addnew" loading="lazy" src="/content/images/2022/07/windows-addnew.png#center"></p>
<p>Then we&rsquo;ll be given a blank config file, with only the devices public &amp; private key pair generated for us.</p>
<p>We&rsquo;re going to fill in details similar to the below screenshot:</p>
<p><img alt="windows-tunnelconfig" loading="lazy" src="/content/images/2022/07/windows-tunnelconfig.png#center"></p>
<p>The configuration under [Interface] is the local, client-side configuration. I&rsquo;ve added the client&rsquo;s tunnel address - which will be 10.50.50.15/32. I&rsquo;ve also configured DNS servers which the client can reach via the VPN.</p>
<p>Then we&rsquo;ll add the [Peer] section, which contains info about our VPN headend. Here&rsquo;s where we&rsquo;ll need the public key from our OPNsense firewall. We&rsquo;ll also specify the <strong>Endpoint</strong> address, which is the IP or hostname of our VPN headend &amp; the port (which by default is 51820).</p>
<p>We&rsquo;ve also configured <strong>AllowedIPs</strong> as <code>0.0.0.0/0</code>. This will force <strong>all</strong> client traffic over the VPN tunnel - including general internet traffic. However, we could limit this to specific subnets. For example, let&rsquo;s say your network only used 172.16.90.0/24 &amp; 10.1.1.0/16 subnets &amp; we only wanted the user to be able to access those. We would configure the following: <code>AllowedIPs = 172.16.90.0/24, 10.1.1.0/16</code>. In this case, only traffic for those subnets would be routed over the VPN - any other traffic would use the devices default internet connection.</p>
<p>Now, we&rsquo;ll save this - and again need to copy the device&rsquo;s <strong>Public Key</strong>, which we&rsquo;ll need to enter on the OPNsense firewall.</p>
<h2 id="client-setup---adding-clients-to-opnsense">Client Setup - Adding Clients to OPNsense</h2>
<p>In order for the Windows machine to connect to OPNsense, we&rsquo;ll also need to configure a client profile on the firewall.</p>
<p>In OPNsense, we&rsquo;ll navigate back to <strong>VPN &gt; WireGuard</strong>, then click on the <strong>Endpoints</strong> tab.</p>
<p><img alt="wg-client-win" loading="lazy" src="/content/images/2022/07/wg-client-win.png#center"></p>
<p>Here we&rsquo;ll configure a name for our client &amp; paste in the client&rsquo;s <strong>Public Key</strong>.</p>
<p>We&rsquo;ll also set <strong>AllowedIPs</strong> to the client&rsquo;s IP address, which we have configured as <code>10.50.50.15/32</code>. This controls what IP addresses are reachable via this endpoint.</p>
<p>We do have some additional fields available, which we will leave blank. For example - <strong>Endpoint Address</strong> &amp; <strong>Endpoint Port</strong> would be used to define a public IP that we expect our client to connect from. Since a remote-access client could connect from any IP, we leave those fields blank to allow this.</p>
<p>Once we&rsquo;re done, we&rsquo;ll click <strong>Save</strong> then <strong>Apply</strong>.</p>
<p>Next we&rsquo;ll jump back to the <strong>Local</strong> tab, and edit our headend tunnel configuration.</p>
<p>We should now see our windows client in the <strong>Peers</strong> dropdown. We&rsquo;ll select that client, so that Wireguard will permit that client to connect via this tunnel interface.</p>
<p><img alt="localconfig-pt3" loading="lazy" src="/content/images/2022/07/localconfig-pt3.png#center"></p>
<p>Then, as always, click <strong>Save</strong> &amp; <strong>Apply</strong></p>
<p>Last but not least - we should restart our Wireguard server on OPNsense. This can be done by either disabling &amp; re-enabling Wireguard - or by navigating back to the OPNsense dashboard &amp; clicking the restart icon next to the <strong>wireguard-go</strong> service.</p>
<h2 id="testing-the-connection">Testing The Connection</h2>
<p>Okay - now that we have all that completed, it&rsquo;s finally time to test connectivity from our client.</p>
<p>On my Windows client, I&rsquo;ll just click the <strong>Activate</strong> button for the tunnel:</p>
<p><img alt="windows-tunnelconnected" loading="lazy" src="/content/images/2022/07/windows-tunnelconnected.png#center"></p>
<p>And we&rsquo;ll see that the <strong>Status</strong> shows <strong>Active</strong>, and we&rsquo;ll start to see updates to the <strong>Last Handshake</strong> &amp; <strong>Transfer</strong> fields - indicating we are connected &amp; sending data.</p>
<p>To further validate, we can check the <strong>Log</strong> tab:</p>
<p><img alt="windows-log" loading="lazy" src="/content/images/2022/07/windows-log.png#center"></p>
<p>The key things to look for here, are the following messages:</p>
<ul>
<li><strong>Receiving handshake response</strong> which indicates our firewall responded to our request to connect</li>
<li><strong>Keypair 1 created</strong> which indicates that our connection is healthy to our peer</li>
<li><strong>Receiving keepalive packet from peer</strong> - we should see these periodically to maintain our connection. If keepalives stop flowing, then we may have a break in connectivity between client &amp; peer.</li>
</ul>
<p>We should also be able to reach out <code>wg1</code> tunnel address from the Windows client:</p>
<p><img alt="windows-ping" loading="lazy" src="/content/images/2022/07/windows-ping.png#center"></p>
<p>On the OPNsense side of things, we can check what client is connected via the <strong>List Configuration</strong> tab, under <strong>VPN &gt; Wireguard</strong>:</p>
<p><img alt="wireguard-listconfig" loading="lazy" src="/content/images/2022/07/wireguard-listconfig.png#center"></p>
<p>On this screen, we can see we have 1 peer connected - which matches the IP &amp; public key of our Windows client. We&rsquo;ll see similar output like the Windows client, where we can see the latest handshake &amp; data transfer.</p>
<p>Additionally, for easier access we can add the Wireguard widget to the OPNsense dashboard.</p>
<p>If we navigate to our dashboard, then click <strong>Add widget</strong> - we can add the <strong>Wireguard</strong> widget.</p>
<p>Here&rsquo;s what that looks like:</p>
<p><img alt="wg-widget" loading="lazy" src="/content/images/2022/07/wg-widget.png#center"></p>
<h2 id="additional-client-setup---android">Additional Client Setup - Android</h2>
<p>Let&rsquo;s also take a quick look at a mobile client. I&rsquo;ll get through this pretty quickly, since the configuration will be very similar to our other client - just a different UI.</p>
<p>On my Android device - if I open up the Wireguard app, I have a few options for creating or importing a tunnel:</p>
<p><img alt="android-create-1" loading="lazy" src="/content/images/2022/07/android-create-1.png#center"></p>
<p>In this case, we&rsquo;ll again walk through creating a tunnel manually. Again, it&rsquo;s worth mentioning that there are 3rd party apps available to auto-generate config imports or QR codes to make this easier.</p>
<p>First we&rsquo;ll have a handful of fields to fill in about the Android-side configuration. This includes a name for the tunnel, an address, and DNS servers.</p>
<p>We can click on the refresh icon in the <strong>Private Key</strong> field to auto-generate our key pairs:</p>
<p><img alt="android-interface-1" loading="lazy" src="/content/images/2022/07/android-interface-1.png#center"></p>
<p>One of the interesting parts of the mobile app is the ability to permit/exclude individual apps from traversing the VPN tunnel.</p>
<p>Here&rsquo;s a quick screenshot, where we can pick either to allow only certain apps to use the VPN - or permit all except a few we choose to exclude:</p>
<p><img alt="android-app-list-1" loading="lazy" src="/content/images/2022/07/android-app-list-1.png#center"></p>
<p>In my case, I&rsquo;ll keep this set to allow all applications.</p>
<p>Next we&rsquo;ll work on the peer config:</p>
<p><img alt="android-peer-1" loading="lazy" src="/content/images/2022/07/android-peer-1.png#center"></p>
<p>After that, all we need to do is save our VPN configuration - then we can toggle the tunnel on or off:</p>
<p><img alt="android-enable-1" loading="lazy" src="/content/images/2022/07/android-enable-1.png#center"></p>
<p>And similar to the Windows client, we can click on the tunnel itself to see current status / data transfer:</p>
<p><img alt="android-stats-1" loading="lazy" src="/content/images/2022/07/android-stats-1.png#center"></p>
<p>So it looks like we should be connected &amp; can try accessing VPN resources!</p>
<p>We can also use the same methods as earlier to check connectivity from the OPNsense side.</p>
<hr>
<p>Okay - that&rsquo;s all I wanted to share today. I&rsquo;ve been quite pleased with how easy to use WireGuard has been  - and how well it performs! I hope this blog post was helpful if you&rsquo;re interested in trying it out.</p>
<p>Thanks!!</p>
]]></content:encoded>
    </item>
    <item>
      <title>OPNsense on Qotom Q750G5 - Hardware Overview &amp; Perf Testing</title>
      <link>https://0x2142.com/opnsense-qotom-q750gs/</link>
      <pubDate>Sat, 18 Jun 2022 18:21:18 +0000</pubDate>
      <guid>https://0x2142.com/opnsense-qotom-q750gs/</guid>
      <description>In this post, we will take a look at the Qotom Q750G5 hardware (with 2.5GbE), install OPNsense, and walk through a few performance tests.</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/ppS6IhKSkfY?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p><sup><em>Note: I may receive commissions for purchases made through links in this post. This is to help support my blog and does not have any impact on my recommendations.</em></sup></p>
<p>One day I would love to have symmetric internet speeds, but for the meantime I have to work with what I have - which is dismal upload speeds that don&rsquo;t come anywhere close to the download speed.</p>
<p>So I&rsquo;m currently at 200Mb/s down &amp; 10Mb/s up - and I would prefer to have higher upload speeds. However, even just 20Mb/s upload requires me to purchase a 500Mb/s download plan. 🙄</p>
<p>I&rsquo;ve been hesitant to upgrade, since my current Meraki MX64 tops out at ~250Mb/s throughput. I would have to upgrade my firewall or half of my new download speed would be unusable.</p>
<p>While Meraki does have faster firewalls, they&rsquo;re a bit expensive &amp; at the moment somewhat difficult to obtain. So instead I searched around for alternatives, and came across the <a href="https://amzn.to/3apFx5R">Qotom Q750G5</a> - which is a barebones mini-PC that I could load pfSense or OPNsense onto.</p>
<p>So in this blog post - I wanted to talk about the device &amp; some of the performance testing I did.</p>
<hr>
<h2 id="qotom-q750g5---hardware">Qotom Q750G5 - Hardware</h2>
<p>First let&rsquo;s take a quick look at the hardware. What got my attention quickly was the five 2.5GbE ports, but this small device offers quite a lot for how inexpensive it was.</p>
<p>A quick look at the specs:</p>
<ul>
<li>Intel Celeron J4125 Quad Core 2.0Ghz (Burst 2.7Ghz)</li>
<li>Five Intel I225-V 2.5Gb Ethernet ports</li>
<li>Optional WiFi slot</li>
<li>Optional 3G Cellular &amp; SIM card slots</li>
<li>1 RAM slot</li>
<li>1 mSATA slot</li>
<li>1 2.5in SATA HDD slot</li>
<li>2x USB 2.0 &amp; 3x USB 3.0 ports</li>
</ul>
<p>By default it seems this is a barebones kit, however I did opt to buy a model that included 16GB RAM &amp; a 256GB mSATA SSD. It arrived with a single 16GB TeamGroup DDR4 3200Mhz module &amp; 256GB Hoodisk mSATA SSD.</p>
<p>Are the specs a bit overkill for an embedded firewall? Yeah definitely. But the whole kit was only around $230 USD - which seemed crazy to me.</p>
<p>The big thing that pulled me toward this model (besides price) was the 2.5GbE ports. Since a lot more places have gigabit residential internet these days, and some lucky places are starting to see 2Gb/s - I was hoping that this little box would offer me a bit of future-proofing.</p>
<p>Of course, I was a little curious about what performance this device could realistically achieve - but more on that later!</p>
<p>I wanted to provide a few photos of the unit as well. The casing itself is pretty minimal, but the box is definitely heavier than you would expect!</p>
<p><strong>Front Photo:</strong></p>
<p><img alt="qotom750g5-front" loading="lazy" src="/content/images/2022/05/qotom750g5-front.jpg#center"></p>
<p>On the front there isn&rsquo;t a whole lot to see. Power button, reset button, status LEDs, and USB ports. Oh - and there is an HDMI port as well, which comes in handy when installing an operating system (or if you&rsquo;re using this as an actual PC).</p>
<p><strong>Back Photo:</strong></p>
<p><img alt="qotom750g5-back" loading="lazy" src="/content/images/2022/05/qotom750g5-back.jpg#center"></p>
<p>The back shows off the five 2.5Gb Ethernet ports, as well as the power plug. While I didn&rsquo;t get a WiFi-enabled unit, the back faceplate still has cutouts for wireless antenna. I could opt to add wireless to this later, but I do wish the faceplate came with plugs or something to cover the holes in the meantine.</p>
<p><strong>Inside Photo:</strong></p>
<p><img alt="qotom750g5-internal-1" loading="lazy" src="/content/images/2022/05/qotom750g5-internal-1.jpg#center"></p>
<p>Now here&rsquo;s where things get interesting! This box surprisingly packs a lot in it&rsquo;s tiny size.</p>
<p>In the upper right, there is a PCI slot for WiFi. There&rsquo;s also a WiFi/3G PCI slot in the lower left.</p>
<p>Just above the 3G slot is the SSD mSATA slot. When a drive is installed, it does cover the SIM card slot - meaning that the SSD would need to be removed to change SIM cards.</p>
<p>Also on the left, mostly out of the photo, is a connector for a 2.5in HDD. While I didn&rsquo;t snap a photo of the bottom of the unit, the drive would screw into the bottom plate.</p>
<p>Interestingly enough, the CPU is on the other side of the motherboard. While you might think that the overall unit kinda looks like a heatsink - I was surprised to see that&rsquo;s exactly what it is. The CPU is located right under the four screws with black washers and has thermal paste pre-applied. It rests up against the top of the case &amp; uses the top as a heatsink.</p>
<p>As a last note about the CPU - it does get <em>quite toasty</em> at times. During one of my performance tests, the CPU reached ~90°C - and the top of the unit was very hot to the touch. It may not act as the world&rsquo;s best heatsink, so I would avoid placing anything on top of the unit - or resting your hand there for too long 🙂.</p>
<h2 id="performance-testing">Performance Testing</h2>
<p>As a quick note before we get to the good stuff: All of my tests were performed using <a href="https://iperf.fr/iperf-download.php">iPerf3</a>. This may not show us the best real-world throughput tests, but I had quite a difficult time getting dpdk drivers to compile correctly for the Intel 2.5GbE ports (so I could use something like <a href="https://trex-tgn.cisco.com/">TRex</a>). I may attempt to go back to this later, but the iPerf data is what I&rsquo;ll provide for now.</p>
<h3 id="the-testbed">The Testbed</h3>
<p>For the performance testing, I used the two <a href="/home-lab-upgrade-intel-nuc11/">Intel NUC11</a> PCs that I purchased recently for my VMware lab. These already come with a 2.5GbE port, which I am currently using for vMotion between the two. I disconnected the vMotion port temporarily, and instead enabled PCI-passthrough to connect the ports directly to a VM.</p>
<p>I built a VM on each NUC with the following specs:</p>
<ul>
<li>Debian 11</li>
<li>8x vCPU</li>
<li>16GB RAM</li>
<li>PCI-passthrough to 2.5GbE adapter</li>
</ul>
<p>iPerf 3.9 was used for all tests. The iPerf server was enabled with the <code>iperf3 -s</code> command, and the client tests were run with <code>iperf3 -c &lt;client ip&gt; -P 8 -t 600</code>. Each test was run for 10 minutes.</p>
<p>The devices were connected &amp; configured with the following topology:</p>
<p><img alt="network-diagram" loading="lazy" src="/content/images/2022/05/network-diagram.png#center"></p>
<blockquote>
<p>Note: In the below paragraphs, I will talk about the configuration I used for each test. If you&rsquo;re interested in more detail, please check out the video at the top of this blog post. In the video, I walk through the configuration &amp; setup for most of the tests below.</p></blockquote>
<h3 id="test-1-no-firewall">Test 1: No Firewall</h3>
<blockquote>
<p>Avg: 2.35Gb/s</p></blockquote>
<p>Okay, so expecting that I likely wouldn&rsquo;t get the full 2.5Gb speeds once I added the firewall - I wanted to perform a baseline test with the VM&rsquo;s directly connected via the 2.5GbE passthrough port.</p>
<p>In each of these tests, I was able to reach an average speed of: 2.35Gb/s</p>
<h3 id="test-2-routing-nat-simple-firewall-rules">Test 2: Routing, NAT, Simple Firewall rules</h3>
<blockquote>
<p>Avg: 2.35Gb/s</p></blockquote>
<p>In this test case, OPNsense was configured to match the diagram above. The iPerf server was located on the LAN segment, with an IP of 10.2.2.1 &amp; a default route toward the LAN interface of the OPNsense box (10.2.2.2). The client is connected via the WAN interface, at 203.0.113.50.</p>
<p>I created a proxy-ARP virtual address for the 203.0.113.25 IP address, then created a NAT rule to forward traffic sent to that address to 10.2.2.1.</p>
<p>Next, there was a single firewall rule created to permit TCP port 5201 inbound from the WAN. This is the default port that iPerf will use.</p>
<p>During these tests, I averaged about 2.35Gb/s and relatively low CPU usage around 10-20%.</p>
<p><em>As an interesting side note to this: Originally I didn&rsquo;t use the default LAN &amp; WAN ports (ports 1 &amp; 2), but instead used ports 3 &amp; 4. During testing between those ports, I could only reach ~1.7Gb/s. Once I switched to ports 1 &amp; 2, I could easily hit 2.35Gb/s. I&rsquo;m curious to dig in later &amp; see if this is a hardware issue, or possibly OPNsense is prioritizing the LAN/WAN traffic differently</em></p>
<h3 id="test-3-large-firewall-ruleset">Test 3: Large Firewall Ruleset</h3>
<blockquote>
<p>Avg: 2.35Gb/s</p></blockquote>
<p>While my home network will likely have a somewhat minimal firewall ruleset, I was curious to see how well the device would perform with a large ruleset.</p>
<p>So I wrote a script to auto-generate ~1,200 firewall rules with random IP addresses, ports, and a mix of permit/block actions. I applied the ruleset inbound on both the LAN &amp; WAN ports.</p>
<p>Under this test, I was still able to reach the 2.35Gb/s speeds - but now the CPU was creeping up to 30-40%.</p>
<p>So what next? Well I decided to see if I could stress the box a little - and increased the auto-generated ruleset to just over ~15,000 rules.</p>
<p>The increased ruleset took about 5-10 minutes to load into the system, and CPU was pegged at 100% the whole time. In fact, the CPU never really came back down. Even after the rules had loaded, the CPU was flat at 100% - and it took anywhere from 2-4 minutes to navigate between pages in the web GUI. (This is the part where my CPU temps went from &lt;50°C to over 90°C 🙃)</p>
<p>I ended up having to re-image the box.</p>
<h3 id="test-4-suricata-ips">Test 4: Suricata IPS</h3>
<blockquote>
<p>Avg: 2.35Gb/s (But sometimes much, much less)</p></blockquote>
<p>Next I loaded up the built-in IDS/IPS, which uses suricata. I downloaded all available free rulesets, and enabled all of them. Ideally, you wouldn&rsquo;t necessarily enable everything - but I wanted to start off with a full load test.</p>
<p>My experience with these tests was highly variable. <em>Most</em> times, I was surprised to see that I could still push 2.35Gb/s through without any issue. During these tests, the CPU usually bounced between 50-80% usage.</p>
<p>Strangely, every so often I would test and get significantly less than that. Most times when this happened, I would instead only see somewhere between 400-700Mb/s - but on one test the box slowed to just over 200Mb/s. Each time this happened, the performance tests would remain degraded until I restarted the suricata service - then I would be able to reach the 2.35Gb/s again.</p>
<p>My best guess is that something is getting stuck. I know some older IPS systems I&rsquo;ve worked with in the past had issues with CPU-pinning, and you might get garbage performance if your traffic hit the wrong CPU core. I didn&rsquo;t spend a lot of time digging into this, but it feels a bit similar.</p>
<h3 id="test-5-wireguard-vpn">Test 5: Wireguard VPN</h3>
<blockquote>
<p>Avg: 800Mb/s, 650-700Mb/s with IPS also enabled</p></blockquote>
<p>I also wanted to try VPN performance. There are a lot of options for VPN services within OPNsense, including standard IPSec and OpenVPN. However, I opted to try out wireguard - since it&rsquo;s really easy to set up &amp; get running.</p>
<p>In this case, I definitely hit a limitation with CPU-pinning. With my initial tests, I could only reach about ~450-500Mb/s - but the Qotom CPU was only spiking up to 70%.</p>
<p>Seems like the wireguard client (at least for same source/destination/port traffic) does pin everything to a single CPU. So my client CPU, between encrypting the traffic &amp; generating it, was actually maxing out long before the Qotom was.</p>
<p>I ended up spinning up a second VM on the client side (which required disabling PCI passthough &amp; adding both VMs to a shared vSwitch). With both of these running, I was able to max out the Qotom CPU at 100% - and hit a fairly consistent 800Mb/s VPN throughput.</p>
<p>As a final test, I enabled the suricata IPS on top of the VPN as well. Now the traffic would need to be decrypted &amp; inspected before reaching the server. With a single client, I averaged ~400-450Mb/s - and with both clients it was around ~650-700Mb/s</p>
<hr>
<p>Overall I&rsquo;m really pleased with how well this thing performs, especially for how relatively inexpensive it was. I also expected OPNsense to have a steep learning curve, but it was surprisingly easy to get up and running very quickly.</p>
<p>Next I&rsquo;ll be working on getting this firewall up &amp; running at home. I may be tempted to write up some more on OPNsense - so if there are any questions or specific configurations you might like to see, please leave a comment!</p>
]]></content:encoded>
    </item>
    <item>
      <title>[How To] Cisco SD-WAN - Onboarding a Catalyst 8000v</title>
      <link>https://0x2142.com/how-to-cisco-sd-wan-onboarding-a-catalyst-8000v/</link>
      <pubDate>Fri, 14 May 2021 16:10:38 +0000</pubDate>
      <guid>https://0x2142.com/how-to-cisco-sd-wan-onboarding-a-catalyst-8000v/</guid>
      <description>Let&amp;rsquo;s look at how to join a Cisco Catalyst 8000v to an SDWAN network</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/HyPYLKrPPsk?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>I&rsquo;ve been getting a handful of questions lately on the process of bringing a Cisco Catalyst 8000v or CSR 1000v into an SD-WAN environment. So I figured maybe I should put something together to share.</p>
<p>On a related note - I&rsquo;ve been debating for a while doing a blog and/or video on building out a Cisco Viptela SD-WAN lab in EVE-NG. This would (tentatively) include everything from building controllers, bringing up remote sites, and template/policy configs.  If this is something you might get value from, please let me know!! I&rsquo;m looking for some motivation :)</p>
<p>Okay - all that being said, let&rsquo;s go ahead and get started.</p>
<blockquote>
<p>Note: This guide should work with CSR 1000v devices as well. But it will NOT be 100% accurate for physical ISR/IOS-XE routers, as there are some additional steps with certificates &amp; the Plug and Play portal to get those running.</p></blockquote>
<hr>
<h2 id="topology">Topology</h2>
<p>So to start with, figured I would share the topology that I&rsquo;m working from. If you read my <a href="/cisco-sdwan-and-umbrella-sig-integration/">last post</a> you might recognize this, but with an added location. This new location (site id 400) contains our Catalyst 8000v VM, running IOS-XE version 17.04.01a.</p>
<p><img alt="001&mdash;Topology" loading="lazy" src="/content/images/2021/05/001---Topology.PNG#center"></p>
<h2 id="controller-or-autonomous-mode">Controller or Autonomous Mode?</h2>
<p>Back in the earlier days of IOS-XE SD-WAN, there used to be two separate software images to load on your network appliance - one for traditional IOS-XE, and one for SD-WAN code.</p>
<p>With the newer releases of IOS-XE, we&rsquo;re now getting a unified image that contains both software sets. So our options now are two modes: autonomous (traditional IOS-XE) or controller (SD-WAN).</p>
<p>One way we can check this, is by running a <em>show version</em> and looking for <strong>Router operating mode</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Router# show version
</span></span><span class="line"><span class="cl">&lt;-- Output omitted --&gt;
</span></span><span class="line"><span class="cl">cisco C8000V (VXE) processor (revision VXE) with 2035355K/3075K bytes of memory.
</span></span><span class="line"><span class="cl">Processor board ID XXXXXXXXXXX
</span></span><span class="line"><span class="cl">Router operating mode: Autonomous
</span></span><span class="line"><span class="cl">4 Gigabit Ethernet interfaces
</span></span><span class="line"><span class="cl">32768K bytes of non-volatile configuration memory.
</span></span><span class="line"><span class="cl">3965744K bytes of physical memory.
</span></span><span class="line"><span class="cl">5234688K bytes of virtual hard disk at bootflash:.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Configuration register is 0x2102
</span></span></code></pre></div><p>Okay, and looks like the Catalyst 8000v image I&rsquo;m using booted up in autonomous mode. No big deal, we can change modes pretty easily!</p>
<p>So in normal exec-mode, we&rsquo;ll use the command <em>controller-mode enable</em>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Router# controller-mode enable
</span></span><span class="line"><span class="cl">Enabling controller mode will erase the nvram filesystem, remove all configuration files, and reload the box!
</span></span><span class="line"><span class="cl">Ensure the BOOT variable points to a valid image
</span></span><span class="line"><span class="cl">Continue? [confirm]
</span></span></code></pre></div><p>As noted in the snippet above - this command will erase the config! So you will want to take a backup snapshot of your existing configuration, if this is already being used.  In my case, it&rsquo;s a brand new VM - so we&rsquo;ll continue on.</p>
<p>Once the device is back online, we&rsquo;ll log in with the default login of <strong>admin/admin</strong>. Note that you will be forced to change this upon first login.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">User Access Verification
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Username: admin
</span></span><span class="line"><span class="cl">Password:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Default admin password needs to be changed.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Enter new password:
</span></span><span class="line"><span class="cl">Confirm password:
</span></span><span class="line"><span class="cl">Router#
</span></span></code></pre></div><p>And just for fun, we&rsquo;ll run a <em>show version</em> again to ensure we&rsquo;re in controller mode:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Router# show version 
</span></span><span class="line"><span class="cl">&lt;-- Output omitted --&gt;
</span></span><span class="line"><span class="cl">cisco C8000V (VXE) processor (revision VXE) with 2035355K/3075K bytes of memory.
</span></span><span class="line"><span class="cl">Processor board ID XXXXXXXXXXX
</span></span><span class="line"><span class="cl">Router operating mode: Controller-Managed
</span></span><span class="line"><span class="cl">4 Gigabit Ethernet interfaces
</span></span><span class="line"><span class="cl">32768K bytes of non-volatile configuration memory.
</span></span><span class="line"><span class="cl">3965756K bytes of physical memory.
</span></span><span class="line"><span class="cl">5234688K bytes of virtual hard disk at bootflash:.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Configuration register is 0x2102
</span></span></code></pre></div><h2 id="catalyst-8000v-initial-config">Catalyst 8000v Initial Config</h2>
<p>So since this is a lab environment, and I&rsquo;m not trying to provide any Day0 provisioning files - I&rsquo;ll have to complete some manual configuration to get started.</p>
<p>First, we&rsquo;ll start with some SD-WAN specific config (site id, org name, etc). I&rsquo;ll be using the values that apply to my lab, so be sure to change these in yours!</p>
<blockquote>
<p>Note: If you haven&rsquo;t used IOS-XE SD-WAN previously, be aware that &ldquo;conf t&rdquo; doesn&rsquo;t work! In SD-WAN/controller mode, you&rsquo;ll use &ldquo;config-transaction&rdquo;. In this mode, all changes will need to be committed before they&rsquo;re applied to the device.</p></blockquote>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Router# config-transaction
</span></span><span class="line"><span class="cl"> ! Set hostname
</span></span><span class="line"><span class="cl">Router(config)# hostname Cat8k-Site400
</span></span><span class="line"><span class="cl"> ! Required SD-WAN system configs
</span></span><span class="line"><span class="cl">Router(config)# system
</span></span><span class="line"><span class="cl">Router(config-system)# organization-name &#34;SDWAN-LAB&#34;
</span></span><span class="line"><span class="cl">Router(config-system)# site-id 400
</span></span><span class="line"><span class="cl">Router(config-system)# vbond 192.168.99.241
</span></span><span class="line"><span class="cl">Router(config-system)# system-ip 10.10.10.237
</span></span><span class="line"><span class="cl">Router(config-system)# commit
</span></span><span class="line"><span class="cl">Commit complete.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Cat8k-Site400# 
</span></span></code></pre></div><p>Once we have those basics configured, at a minimum we&rsquo;ll also need to configure our internet-facing tunnel interface. This allows our Catalyst 8000v to communicate with our control plane for bring-up.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cat8k-Site400#config-transaction
</span></span><span class="line"><span class="cl"> ! Config physical interface (This is a lab, so I&#39;m using a static IP)
</span></span><span class="line"><span class="cl">Cat8k-Site400(config)# interface GigabitEthernet1
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# ip address 192.168.99.237 255.255.255.0
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# no shut
</span></span><span class="line"><span class="cl"> ! Config tunnel interface
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# interface Tunnel1
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# no shut
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# ip unnumbered GigabitEthernet1
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# tunnel source GigabitEthernet1
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# tunnel mode sdwan
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# exit
</span></span><span class="line"><span class="cl"> ! SD-WAN tunnel config
</span></span><span class="line"><span class="cl">Cat8k-Site400(config)# sdwan
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-sdwan)# interface GigabitEthernet1
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-interface-GigabitEthernet1)# tunnel-interface
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-tunnel-interface)# encapsulation ipsec
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-tunnel-interface)# color biz-internet
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-tunnel-interface)# exit
</span></span><span class="line"><span class="cl"> ! Default route to our internet gateway
</span></span><span class="line"><span class="cl">Cat8k-Site400(config)# ip route 0.0.0.0 0.0.0.0 192.168.99.1
</span></span><span class="line"><span class="cl">Cat8k-Site400(config)# commit
</span></span><span class="line"><span class="cl">Commit complete.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Cat8k-Site400#
</span></span></code></pre></div><h2 id="a-note-on-certificates">A Note on Certificates</h2>
<p>Since this is a lab environment, I&rsquo;m using self-signed local certificate authority to provision all of my certificate infrastructure. Because of this, I&rsquo;ll need to install my local CA certificate on the Catalyst 8000v. If you&rsquo;re using the default Cisco-provisioned certificate setup, you won&rsquo;t need to do this.</p>
<p>Since my SD-WAN lab doesn&rsquo;t have direct access to my local TFTP server - I do have an out-of-band management interface connected to my Cat 8000v. We&rsquo;ll start by configuring that interface:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cat8k-Site400# config-transaction
</span></span><span class="line"><span class="cl">Cat8k-Site400(config)# vrf definition 512
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-vrf)# address-family ipv4
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-vrf)# exit
</span></span><span class="line"><span class="cl">Cat8k-Site400(config)# interface GigabitEthernet 3
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# vrf forwarding 512
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# ip address dhcp
</span></span><span class="line"><span class="cl">Cat8k-Site400(config-if)# exit
</span></span><span class="line"><span class="cl">Cat8k-Site400(config)# ip tftp source-interface GigabitEthernet 3
</span></span><span class="line"><span class="cl">Cat8k-Site400(config)# commit
</span></span></code></pre></div><p>The standard management VRF/VPN for SD-WAN is 512, so I kept that config to match when I configured this management interface. This will all be over-written anyways once we get connected to vManage &amp; configure/push our template configs.</p>
<p>Once that&rsquo;s done, we can go ahead and copy our CA certificate to bootflash.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cat8k-Site400# copy tftp://10.0.0.2/cacert.pem bootflash:
</span></span><span class="line"><span class="cl">Destination filename [cacert.pem]?
</span></span><span class="line"><span class="cl">Accessing tftp://10.0.0.2/cacert.pem...
</span></span><span class="line"><span class="cl">Loading cacert.pem from 10.0.0.2 (via GigabitEthernet3): !
</span></span><span class="line"><span class="cl">[OK - 1406 bytes]
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">1406 bytes copied in 0.112 secs (12554 bytes/sec)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Cat8k-Site400# dir bootflash: | inc cacert.pem
</span></span><span class="line"><span class="cl">16      -rw-             1406  May 14 2021 14:41:27 +00:00  cacert.pem
</span></span><span class="line"><span class="cl">```text
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Then we&#39;ll use the command below to install the CA certificate:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">```text
</span></span><span class="line"><span class="cl">Cat8k-Site400# request platform software sdwan root-cert-chain install bootflash:cacert.pem
</span></span><span class="line"><span class="cl">Uploading root-ca-cert-chain via VPN 0
</span></span><span class="line"><span class="cl">Copying ... /bootflash/cacert.pem via VPN 0
</span></span><span class="line"><span class="cl">Updating the root certificate chain..
</span></span><span class="line"><span class="cl">Successfully installed the root certificate chain
</span></span></code></pre></div><p>And we can validate by using the <em>show sdwan certificate root-ca-cert</em> command:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cat8k-Site400 show sdwan certificate root-ca-cert
</span></span><span class="line"><span class="cl">Certificate:
</span></span><span class="line"><span class="cl">    Data:
</span></span><span class="line"><span class="cl">        Version: 3 (0x2)
</span></span><span class="line"><span class="cl">        Serial Number:
</span></span><span class="line"><span class="cl">            11:3b:0a:12:17:b0:e0:b5:4b:fa:c2:e9:2c:9c:12:84
</span></span><span class="line"><span class="cl">        Signature Algorithm: sha1WithRSAEncryption
</span></span><span class="line"><span class="cl">        Issuer: DC = local, DC = 0x2142, O = SDWAN-LAB, CN = 0x2142-0XWIN1-CA-2
</span></span><span class="line"><span class="cl">        Validity
</span></span><span class="line"><span class="cl">            Not Before: Nov 29 20:00:11 2018 GMT
</span></span><span class="line"><span class="cl">            Not After : Nov 29 20:10:11 2043 GMT
</span></span><span class="line"><span class="cl">        Subject: DC = local, DC = 0x2142, O = SDWAN-LAB, CN = 0x2142-0XWIN1-CA-2
</span></span><span class="line"><span class="cl">        Subject Public Key Info:
</span></span><span class="line"><span class="cl">            Public Key Algorithm: rsaEncryption
</span></span><span class="line"><span class="cl">                RSA Public-Key: (2048 bit)
</span></span><span class="line"><span class="cl">                Modulus:
</span></span><span class="line"><span class="cl">        &lt;-- Output omitted --&gt;
</span></span></code></pre></div><h2 id="activating-the-catalyst-8000v">Activating the Catalyst 8000v</h2>
<p>Almost there! Now that we&rsquo;ve finished our pre-config &amp; added our root CA certificate - we&rsquo;re ready to join the Catalyst 8000v to the SD-WAN fabric.</p>
<p>We&rsquo;ll start over in vManage - by going to <strong>Configuration &gt; Devices</strong>.</p>
<p>Then we&rsquo;ll find our target, unused Catalyst 8000v device. Click the ellipsis on the right side, then select <strong>Generate Bootstrap Configuration</strong></p>
<p><img alt="002&mdash;Generate-bootstap-config" loading="lazy" src="/content/images/2021/05/002---Generate-bootstap-config.png#center"></p>
<p>This will give us a prompt to select which configuration style to generate. We&rsquo;ll leave this on &ldquo;Cloud-init&rdquo;:</p>
<p><img alt="003&mdash;bootstrap" loading="lazy" src="/content/images/2021/05/003---bootstrap.PNG#center"></p>
<p>Once we hit okay - we&rsquo;ll be presented with the info we need. We won&rsquo;t necessarily need all of this information, but we&rsquo;ll want to take note of our <strong>uuid</strong> and <strong>otp</strong>:</p>
<p><img alt="004&mdash;otp" loading="lazy" src="/content/images/2021/05/004---otp.png#center"></p>
<p>We&rsquo;ll drag this info back over to our Catalyst 8000v, and we can now use it to activate the device &amp; join to our SD-WAN fabric.</p>
<p>For the command below, <strong>chassis-number</strong> will be our <strong>uuid</strong> value - and <strong>token</strong> will be our <strong>otp</strong>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cat8k-Site400# request platform software sdwan vedge_cloud activate chassis-number C8K-178BXXXX-XXXX-XXXX-XXXX-XXXXXXXXBC24 token 421ecxxxxxxxxxxxxxxxxxxxxxbd53b5
</span></span></code></pre></div><h2 id="validation">Validation</h2>
<p>After a few moments, we&rsquo;ll see some log messages start to appear showing our control connections coming up. You might see these on the terminal if you&rsquo;re using the console port, or you can use <em>show log</em>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">*May 14 15:39:06.910: %Cisco-SDWAN-Cat8k-Site400-OMPD-3-ERRO-400002: R0/0: OMPD: vSmart peer 10.10.10.242 state changed to Init
</span></span><span class="line"><span class="cl">*May 14 15:39:07.980: %DMI-5-AUTH_PASSED: R0/0: dmiauthd: User &#39;vmanage-admin&#39; authenticated successfully from 10.10.10.240:48140 and was authorized for netconf over ssh. External groups:
</span></span><span class="line"><span class="cl">*May 14 15:39:08.798: %Cisco-SDWAN-Cat8k-Site400-OMPD-6-INFO-400002: R0/0: OMPD: vSmart peer 10.10.10.242 state changed to Handshake
</span></span><span class="line"><span class="cl">*May 14 15:39:08.804: %Cisco-SDWAN-Cat8k-Site400-OMPD-5-NTCE-400002: R0/0: OMPD: vSmart peer 10.10.10.242 state changed to Up
</span></span><span class="line"><span class="cl">*May 14 15:39:08.808: %Cisco-SDWAN-Cat8k-Site400-OMPD-6-INFO-400005: R0/0: OMPD: Number of vSmarts connected : 1
</span></span><span class="line"><span class="cl">*May 14 15:39:09.827: %Cisco-SDWAN-Cat8k-Site400-OMPD-3-ERRO-400002: R0/0: OMPD: vSmart peer 10.10.10.243 state changed to Init
</span></span><span class="line"><span class="cl">*May 14 15:39:10.584: %CRYPTO-6-ISAKMP_ON_OFF: ISAKMP is ON
</span></span><span class="line"><span class="cl">*May 14 15:39:11.756: %Cisco-SDWAN-Cat8k-Site400-OMPD-6-INFO-400002: R0/0: OMPD: vSmart peer 10.10.10.243 state changed to Handshake
</span></span><span class="line"><span class="cl">*May 14 15:39:11.762: %Cisco-SDWAN-Cat8k-Site400-OMPD-5-NTCE-400002: R0/0: OMPD: vSmart peer 10.10.10.243 state changed to Up
</span></span><span class="line"><span class="cl">*May 14 15:39:11.762: %Cisco-SDWAN-Cat8k-Site400-OMPD-6-INFO-400005: R0/0: OMPD: Number of vSmarts connected : 2
</span></span><span class="line"><span class="cl">*May 14 15:39:12.738: %Cisco-SDWAN-Cat8k-Site400-OMPD-6-INFO-400007: R0/0: OMPD: Using policy from peer 10.10.10.242
</span></span><span class="line"><span class="cl">*May 14 15:39:13.570: %Cisco-SDWAN-Cat8k-Site400-FTMD-6-INFO-1000020: R0/0: FTMD: SLA class added : class &#39;Default&#39; at index &#39;1&#39; loss = 25%, latency = 300ms, jitter = 100ms, app-probe-class = None
</span></span><span class="line"><span class="cl">*May 14 15:39:14.738: %Cisco-SDWAN-Cat8k-Site400-OMPD-6-INFO-400007: R0/0: OMPD: Using policy from peer 10.10.10.242
</span></span></code></pre></div><p>We can also see our control connections using the command <em>show sdwan control connections</em>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cat8k-Site400# show sdwan control connections
</span></span><span class="line"><span class="cl">                                                                                       PEER                                          PEER                                          CONTROLLER
</span></span><span class="line"><span class="cl">PEER    PEER PEER            SITE       DOMAIN PEER                                    PRIV  PEER                                    PUB                                           GROUP
</span></span><span class="line"><span class="cl">TYPE    PROT SYSTEM IP       ID         ID     PRIVATE IP                              PORT  PUBLIC IP                               PORT  ORGANIZATION            LOCAL COLOR     PROXY STATE UPTIME      ID
</span></span><span class="line"><span class="cl">----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
</span></span><span class="line"><span class="cl">vsmart  dtls 10.10.10.242    100        1      192.168.99.242                          12446 192.168.99.242                          12446 SDWAN-LAB  biz-internet    No    up     0:00:00:51  0
</span></span><span class="line"><span class="cl">vsmart  dtls 10.10.10.243    100        1      192.168.99.243                          12446 192.168.99.243                          12446 SDWAN-LAB  biz-internet    No    up     0:00:00:49  0
</span></span><span class="line"><span class="cl">vmanage dtls 10.10.10.240    100        0      192.168.99.240                          12646 192.168.99.240                          12646 SDWAN-LAB  biz-internet    No    up     0:00:00:52  0
</span></span></code></pre></div><p>Of course, we can also check to see our device status in the vManage dashboard as well.</p>
<p>Over on the <strong>Monitor &gt; Network</strong> page, we can see that our new Catalyst 8000v is now online:</p>
<p><img alt="005&mdash;monitor-network" loading="lazy" src="/content/images/2021/05/005---monitor-network.PNG#center"></p>
<hr>
<h2 id="extra-how-do-i-check-the-routing-table-on-an-ios-xe-sd-wan-device">Extra: How do I check the routing table on an IOS-XE SD-WAN device?</h2>
<p>So - if you&rsquo;ve only used the vEdge software devices, you may be used to using the <strong>show ip route</strong> or <strong>show ip route vpn 10</strong> commands.</p>
<p>In the IOS-XE world, <em>most</em> SD-WAN commands are prefixed with the <strong>sdwan</strong> keyword. For example: <strong>show sdwan bfd sessions</strong> (where on vEdges, it would just be <strong>show bfd sessions</strong>)</p>
<p>This might lead you to believe that you can use <strong>show sdwan ip route</strong> or <strong>show sdwan ip route vrf 10</strong> - but these won&rsquo;t work! In fact, you&rsquo;ll get the following message:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cat8k-Site400# show sdwan ip route
</span></span><span class="line"><span class="cl">% Error: This command is not supported
</span></span></code></pre></div><p>For the IOS-XE based devices, they actually just use the standard IOS-XE routing table and VRF constructs.</p>
<p>So on a vEdge, you would have VPN 0 as your transport VPN. On IOS-XE, this is just the default global routing table, shown with <strong>show ip route</strong>.</p>
<p>But what about our LAN-side service VPNs? In this case, our routes are being dumped into a VRF on the IOS-XE device.</p>
<p>So for example, I have VPN 10 in my lab which is used for LAN-side clients. We can use the <strong>show vrf</strong> command to see that this exists, and then <strong>show ip route vrf 10</strong> to see the routes from our other SD-WAN locations:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Cat8k-Site400# show vrf
</span></span><span class="line"><span class="cl">  Name                             Default RD            Protocols   Interfaces
</span></span><span class="line"><span class="cl">  10                               &lt;not set&gt;             ipv4        Gi2
</span></span><span class="line"><span class="cl">  512                              &lt;not set&gt;             ipv4        Gi3
</span></span><span class="line"><span class="cl">  65528                            &lt;not set&gt;             ipv4        Lo65528
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Cat8k-Site400# show ip route vrf 10
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Routing Table: 10
</span></span><span class="line"><span class="cl">Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
</span></span><span class="line"><span class="cl">       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
</span></span><span class="line"><span class="cl">       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
</span></span><span class="line"><span class="cl">       E1 - OSPF external type 1, E2 - OSPF external type 2, m - OMP
</span></span><span class="line"><span class="cl">       n - NAT, Ni - NAT inside, No - NAT outside, Nd - NAT DIA
</span></span><span class="line"><span class="cl">       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
</span></span><span class="line"><span class="cl">       ia - IS-IS inter area, * - candidate default, U - per-user static route
</span></span><span class="line"><span class="cl">       H - NHRP, G - NHRP registered, g - NHRP registration summary
</span></span><span class="line"><span class="cl">       o - ODR, P - periodic downloaded static route, l - LISP
</span></span><span class="line"><span class="cl">       a - application route
</span></span><span class="line"><span class="cl">       + - replicated route, % - next hop override, p - overrides from PfR
</span></span><span class="line"><span class="cl">       &amp; - replicated local route overrides by connected
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Gateway of last resort is not set
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      10.0.0.0/24 is subnetted, 2 subnets
</span></span><span class="line"><span class="cl">m        10.2.2.0 [251/0] via 10.10.10.235, 00:09:02, Sdwan-system-intf
</span></span><span class="line"><span class="cl">m        10.3.3.0 [251/0] via 10.10.10.236, 00:09:02, Sdwan-system-intf
</span></span></code></pre></div><hr>
<p>Okay, that&rsquo;s it! Pretty quick process overall - and now we can get into applying our device/feature templates.</p>
<p>Hope this was helpful!!</p>
]]></content:encoded>
    </item>
    <item>
      <title>[How To] Connect Cisco SD-WAN to Umbrella SIG/SWG</title>
      <link>https://0x2142.com/cisco-sdwan-and-umbrella-sig-integration/</link>
      <pubDate>Thu, 22 Apr 2021 15:17:50 +0000</pubDate>
      <guid>https://0x2142.com/cisco-sdwan-and-umbrella-sig-integration/</guid>
      <description>A tutorial for configuring Viptela SDWAN with Cisco Umbrella Secure Internet Gateway &amp;amp; Secure Web Gateway</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/kJwtIVp0-R4?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>In this post, we&rsquo;ll walk through configuring a Cisco Viptela SD-WAN network to integrate with Cisco Umbrella&rsquo;s Secure Internet Gateway (SIG) &amp; Secure Web Gateway (SWG).</p>
<p>If you&rsquo;re interested in reading more about what SIG &amp; SWG are, please check out my <a href="/meraki-mx-and-umbrella-sig-integration/">last post</a> where I walked through this integration with a Meraki MX firewall.</p>
<p>For additional reading, there&rsquo;s also a good Umbrella blog post on all the components of Cisco&rsquo;s SASE architecture, which you can find <a href="https://umbrella.cisco.com/blog/what-goes-into-the-secure-access-service-edge-sase-solution">here</a>.</p>
<p>Okay, with that being said - let&rsquo;s get started!</p>
<hr>
<h2 id="step-1-umbrella-api-keys">Step 1: Umbrella API Keys</h2>
<p>Okay, so we&rsquo;ll start on the Umbrella side. We&rsquo;ll need to generate a set of API keys, which we&rsquo;ll push out to our WAN edge devices. These API keys will allow our remote devices to reach out to Umbrella &amp; auto-configure their SIG tunnels.</p>
<p>We&rsquo;ll log into our Umbrella dashboard at <a href="https://login.umbrella.com/">https://login.umbrella.com/</a></p>
<p>Once we log in, we&rsquo;ll hop over to <strong>Admin &gt; API Keys</strong>. Then up in the upper-right corner, click <strong>Create</strong>.</p>
<p><img alt="001&mdash;umbrella-api-keys-1" loading="lazy" src="/content/images/2021/04/001---umbrella-api-keys-1.png#center"></p>
<p>For this integration, we&rsquo;ll need to select <strong>Umbrella Management</strong> to make sure our API keys have the access they need. Then click <strong>Create.</strong> Easy enough, right?</p>
<p>Once we do that, the Umbrella dashboard will display our API keys - which we&rsquo;ll need to copy over to our Viptela SD-WAN environment.</p>
<p><img alt="002&mdash;umbrella-keys" loading="lazy" src="/content/images/2021/04/002---umbrella-keys.png#center"></p>
<p>We&rsquo;ll also need to collect our Umbrella Organization ID. This is actually just embedded within the Umbrella Dashboard URL, and should be a seven-digit number. For example, if we look at our current URL on the API keys page:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">https://dashboard.umbrella.com/o/&lt;ORG ID&gt;/#/admin/apikeys
</span></span></code></pre></div><p>And that&rsquo;s all we need for now from the Umbrella side. So let&rsquo;s hop over to Viptela.</p>
<h2 id="step-2-viptela-templates--config">Step 2: Viptela Templates &amp; Config</h2>
<p>For this post, I&rsquo;ll be using my SD-WAN lab in EVE-NG. Currently I just upgraded the lab to run Viptela version 20.4.1, though the SIG integration has been supported since 20.1.</p>
<p>Just for reference, here is the lap topology that I&rsquo;m working with:</p>
<p><img alt="003&mdash;eve-topology-1" loading="lazy" src="/content/images/2021/04/003---eve-topology-1.png#center"></p>
<p>This lab includes a bridged connection to allow direct internet access from the lab network.</p>
<p>To configure our SIG automatic tunnels, we&rsquo;ll need to create / update a few templates:</p>
<ul>
<li>Create a <strong>SIG Credentials</strong> feature template</li>
<li>Create a <strong>SIG</strong> feature template</li>
<li>Assign SIG templates to device templates</li>
<li>Edit Service-side VPN Template to inject a service route</li>
</ul>
<h3 id="2a-creating-a-sig-credentials-template">2a: Creating a SIG Credentials Template</h3>
<p>First we&rsquo;ll create a template which will store our Umbrella API credentials.</p>
<p>In the vManage dashboard, we&rsquo;ll go to <strong>Configuration &gt; Templates</strong>, then drop into the <strong>Feature</strong> tab, and click on <strong>Add Template</strong>.</p>
<p><img alt="004&mdash;add-template" loading="lazy" src="/content/images/2021/04/004---add-template.png#center"></p>
<p>Once we get to the next screen, we&rsquo;ll select our device type. In my case, I&rsquo;m using a <strong>vEdge Cloud</strong>.</p>
<p>A list of templates will pop up - we&rsquo;ll drop down to <strong>SIG Credentials</strong>, which will be near the bottom under the <strong>Other Templates</strong> header.</p>
<p><img alt="005&mdash;SIGCREDTEMPLATE" loading="lazy" src="/content/images/2021/04/005---SIGCREDTEMPLATE.png#center"></p>
<p>We&rsquo;ll then be taken to the page where we create our template.</p>
<p>We&rsquo;ll fill in our template name &amp; description, then paste in our Umbrella details (Org ID, API Key, API Secret).</p>
<p><img alt="006&mdash;SIG-Cred-template-page" loading="lazy" src="/content/images/2021/04/006---SIG-Cred-template-page.png#center"></p>
<p>Once we&rsquo;re done - We&rsquo;ll hit <strong>Save</strong>.</p>
<blockquote>
<p>Note: At time of writing, the &ldquo;Get Keys&rdquo; button only functions if you&rsquo;ve purchased your SD-WAN subscription with DNA Premier licensing. This license level includes Umbrella SIG, and allows this 1-click integration that pulls your Umbrella API keys automatically.</p></blockquote>
<h3 id="2b-creating-a-sig-tunnel-template">2b: Creating a SIG Tunnel Template</h3>
<p>Okay, next we&rsquo;ll need to create another feature template to specify our IPSec tunnel configuration.</p>
<p>Just like before, we&rsquo;ll head back over to <strong>Configuration &gt; Templates &gt; Feature &gt; Add Template</strong>.</p>
<p>This time, after selecting our device type, we&rsquo;ll choose <strong>Secure Internet Gateway (SIG) / WAN</strong> - which is located under the <strong>VPN</strong> header.</p>
<p><img alt="007&mdash;SIGWANTEMPLATE" loading="lazy" src="/content/images/2021/04/007---SIGWANTEMPLATE.png#center"></p>
<p>In the template configuration, we&rsquo;ll give the template a name &amp; description as always. Then we&rsquo;ll jump down to the tunnel config.</p>
<p>We&rsquo;ll select <strong>Umbrella</strong> for SIG Provider, then click <strong>Add Tunnel</strong>.</p>
<p><img alt="008&mdash;sig-tunnel-02" loading="lazy" src="/content/images/2021/04/008---sig-tunnel-02.png#center"></p>
<p>Within the tunnel config, we&rsquo;ll specify an interface name - I&rsquo;ll name mine <em>ipsec1</em> (and I&rsquo;ll create an <em>ipsec2</em> shortly). We&rsquo;ll also specify a <em>Tunnel Source</em>, which in my lab is <strong>ge0/0</strong> for the biz-internet VPN 0 interface.</p>
<p><img alt="008&mdash;sig-tunnel-03" loading="lazy" src="/content/images/2021/04/008---sig-tunnel-03.png#center"></p>
<p>We&rsquo;ll keep <strong>Data-Center</strong> as <strong>Primary</strong>, then click <strong>Add</strong>. Then - we&rsquo;ll add a second tunnel configuration, but using <strong>Data-Center</strong> as <strong>Secondary</strong> and the interface name as <em>ipsec2</em>.</p>
<p>When all that is done, we should have the following:</p>
<p><img alt="008&mdash;sig-tunnel-04" loading="lazy" src="/content/images/2021/04/008---sig-tunnel-04.png#center"></p>
<p>If we scroll down to the bottom of the template config, we&rsquo;ll have some settings for <strong>High Availability</strong>. Here, we&rsquo;ll specify what our active &amp; backup IPSec tunnels are, and their weights. I&rsquo;ll specify <em>ipsec1</em> as active &amp; <em>ipsec2</em> as backup. Then click <strong>Save</strong> to finish our template.</p>
<blockquote>
<p>Note: Weight settings are only available starting with 20.4.1 &amp; allow for ECMP routing to SIG. Not shown above, you can create up to four HA tunnel pairs. Depending on weighting, you can equal-cost or unequal-cost load balance between those pairs.</p>
<p>Why would you want to load balance across multiple tunnels? At time of writing, each IPSec tunnel is limited to a maximum 250Mb/s throughput. By creating multiple tunnels &amp; load balancing, we can overcome this limitation if we need higher bandwidth.</p></blockquote>
<h3 id="2c-attaching-sig-to-device-templates">2c: Attaching SIG to Device Templates</h3>
<p>After we&rsquo;ve built out our two SIG templates, we can now attach them to our device templates.</p>
<p>For me, I currently only have a single device template which is applied to all of my remote WAN edge devices.</p>
<p>So we&rsquo;ll go back to <strong>Configuration &gt; Templates</strong> and find whichever device template we want to use - then click the ellipsis on the far right, end select <strong>Edit</strong>.</p>
<p><img alt="009&mdash;edit-device-template" loading="lazy" src="/content/images/2021/04/009---edit-device-template.png#center"></p>
<p>In the device template, we&rsquo;ll scroll down and look for our <strong>VPN 0</strong> configuration under <strong>Transport &amp; Management VPN</strong>. We&rsquo;ll attach our SIG tunnel template to VPN 0, since that&rsquo;s where those IPSec tunnels are being sourced from.</p>
<p>On the right side, under <strong>Additional VPN 0 Templates</strong>, we&rsquo;ll click <strong>Secure Internet Gateway</strong> to add our template. Then from the drop-down, we can select the feature template we just created:</p>
<p><img alt="010&mdash;device-template-vpn0" loading="lazy" src="/content/images/2021/04/010---device-template-vpn0.png#center"></p>
<p>We&rsquo;ll also include our SIG credentials template, which we can find at the bottom of the page, under <strong>Additional Templates</strong>:</p>
<p><img alt="011&mdash;sig-cred-template-attach-1" loading="lazy" src="/content/images/2021/04/011---sig-cred-template-attach-1.png#center"></p>
<p>Once we&rsquo;re done, we can click <strong>Save</strong> at the bottom. This will take us through the process of pushing out these changes to our remote WAN edge devices. When this configuration is deployed, each vEdge will now reach out to Umbrella &amp; auto-configure an IPSec tunnel.</p>
<blockquote>
<p>Note: While the IPSec tunnels will be established when this configuration is pushed - no traffic will flow over them yet. We&rsquo;ll need to add a service route for that, which we&rsquo;ll do next!</p></blockquote>
<h3 id="2d-injecting-a-service-route">2d: Injecting a Service Route</h3>
<p>Now we have our IPSec tunnels deployed - all we need to do is start routing traffic out to Umbrella. We&rsquo;ll accomplish this using a service route on our LAN-side VPN.</p>
<p>So we&rsquo;ll go over to <strong>Configuration &gt; Templates &gt; Feature</strong> - and we&rsquo;ll scroll down &amp; find whichever template we&rsquo;re currently using on our LAN side. For me, I want VPN 10 to route over the tunnels, so I&rsquo;ll be editing my VPN 10 template.</p>
<p>Within the template, we&rsquo;ll scroll down to the <strong>Service Route</strong> section, click <strong>New Service Route</strong>, and we&rsquo;ll enter our desired prefix. This will be what traffic will be routed over the IPSec tunnel to Umbrella. Since this is intended to be an internet gateway, I&rsquo;ll enter 0.0.0.0/0 to inject a default route to Umbrella.</p>
<p>Service should be pre-selected as <strong>SIG</strong>, so we&rsquo;ll click <strong>Add</strong>, then <strong>Update</strong> &amp; deploy our changes to the remote edge devices.</p>
<p><img alt="012&mdash;service-route" loading="lazy" src="/content/images/2021/04/012---service-route.png#center"></p>
<h2 id="step-3-validation--troubleshooting">Step 3: Validation &amp; Troubleshooting</h2>
<p>Awesome! Now we should have everything configured &amp; working. So let&rsquo;s jump through some initial testing and validation we can do.</p>
<p>Within vManage, we can check the status of our IPSec tunnels. We&rsquo;ll go over to <strong>Monitor &gt; Network</strong> then select one of our WAN edge devices.</p>
<p>We&rsquo;ll click on the <strong>Interfaces</strong> tab on the left side - and we should be able to see a list of all interfaces on our device. This should include an ipsec1 &amp; ipsec2 interface.</p>
<p>I&rsquo;ve also selected the <strong>Real Time</strong> monitor on mine, and filtered to just show traffic on the ipsec1 interface:</p>
<p><img alt="013&mdash;monitor" loading="lazy" src="/content/images/2021/04/013---monitor.png#center"></p>
<p>You might recall from my topology above, that I have a linux VM running behind each of the two vEdge Cloud appliances. Using these, I can also test web access &amp; see what my external IP is:</p>
<p><img alt="014&mdash;linuxVM" loading="lazy" src="/content/images/2021/04/014---linuxVM.png#center"></p>
<p>And sure enough, I am getting a 146.112.x.x address - which belongs to the Umbrella datacenter.</p>
<p>If we log into one of our vEdge devices, we can check the routing table with <strong>show ip route vpn 10</strong> (or whichever VPN you&rsquo;re using for the LAN-side). We should see our default 0.0.0.0/0 route via ipsec1, with a next-hop-VPN of VPN0:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">vEdge-01# show ip route vpn 10
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">     ADDRESS               PATH             PROTOCOL          NEXTHOP  NEXTHOP                         NEXTHOP
</span></span><span class="line"><span class="cl">VPN  FAMILY   PREFIX       ID    PROTOCOL   SUB TYPE  METRIC  IFNAME   ADDR     TLOC IP  COLOR  ENCAP  VPN      STATUS
</span></span><span class="line"><span class="cl">------------------------------------------------------------------------------------------------------------------------
</span></span><span class="line"><span class="cl">10   ipv4     0.0.0.0/0    0     std-ipsec  -         0       ipsec1   -        -        -      -      0        F,S
</span></span><span class="line"><span class="cl">10   ipv4     10.2.2.0/24  0     connected  -         0       ge0/2    -        -        -      -      -        F,S
</span></span></code></pre></div><p>We can also check specifically our SIG tunnel status using the command <strong>show secure-internet-gateway tunnels</strong>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">vEdge-01# show secure-internet-gateway tunnels
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">TUNNEL                                                        API   LAST
</span></span><span class="line"><span class="cl">IF                                                            HTTP  SUCCESSFUL     TUNNEL
</span></span><span class="line"><span class="cl">NAME    TUNNEL ID  TUNNEL NAME                     FSM STATE  CODE  REQ            STATE
</span></span><span class="line"><span class="cl">-------------------------------------------------------------------------------------------
</span></span><span class="line"><span class="cl">ipsec1  530233543  SITE200SYS10x10x10x235IFipsec1  st-tun-up  200   create-tunnel  -
</span></span><span class="line"><span class="cl">ipsec2  530233542  SITE200SYS10x10x10x235IFipsec2  st-tun-up  200   create-tunnel  -
</span></span></code></pre></div><p>In that output above, we&rsquo;ll see that we have both ipsec1 &amp; ipsec2 tunnels shown. The last API queries to Umbrella have a HTTP 200, which is good. We&rsquo;ll also see our tunnel names, which we can use to find our device tunnel configuration in the Umbrella dashboard.</p>
<p>The tunnel name might look like a mess at first, but it&rsquo;s a unique identifier to represent each tunnel that was created. So if we break it down for this vEdge:</p>
<ul>
<li>This vEdge is at Site ID 200
<ul>
<li>Shown as &ldquo;SITE200&rdquo;</li>
</ul>
</li>
<li>This vEdge has a system IP of 10.10.10.235
<ul>
<li>Shown as &ldquo;SYS10x10x10x235&rdquo;</li>
</ul>
</li>
<li>This vEdge has two IPSec interfaces, ipsec1 &amp; ipsec2
<ul>
<li>Shown as &ldquo;IFipec1&rdquo; and &ldquo;IFipsec2&rdquo;</li>
</ul>
</li>
</ul>
<p>If we jump over to the Umbrella dashboard, we&rsquo;ll see the same. Within the Umbrella dashboard, we can jump to <strong>Deployments &gt; Network Tunnels</strong>.</p>
<p>On this page, we should see a total of four tunnels listed (two from each vEdge appliance):</p>
<p><img alt="015&mdash;Umbrella-tunnel-status" loading="lazy" src="/content/images/2021/04/015---Umbrella-tunnel-status.png#center"></p>
<p>And with everything configured &amp; validated - now we can move onto configuring firewall and web filtering policies within Umbrella!</p>
<p>If you&rsquo;re interested in seeing how to configure Umbrella&rsquo;s cloud firewall &amp; web filtering policies - please check out my <a href="https://www.youtube.com/watch?v=kJwtIVp0-R4">YouTube Video</a> above!</p>
]]></content:encoded>
    </item>
    <item>
      <title>[How To] Connect Meraki MX to Umbrella SIG/SWG</title>
      <link>https://0x2142.com/meraki-mx-and-umbrella-sig-integration/</link>
      <pubDate>Tue, 23 Mar 2021 16:00:00 +0000</pubDate>
      <guid>https://0x2142.com/meraki-mx-and-umbrella-sig-integration/</guid>
      <description>A tutorial for configuring a Meraki MX with Cisco Umbrella Secure Internet Gateway &amp;amp; Secure Web Gateway</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/GfVEQzxT10g?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>In today&rsquo;s blog post - we&rsquo;ll be checking out how to integrate a Meraki MX firewall to Cisco&rsquo;s Umbrella Secure Internet Gateway (SIG) &amp; Secure Web Gateway (SWG) services.</p>
<p>Interested in seeing how to do this with Cisco Viptela SD-WAN? Check out <a href="/cisco-sdwan-and-umbrella-sig-integration/">this post</a></p>
<blockquote>
<p>Note: This integration is still rather new - so I anticipate some of the screenshots &amp; steps below may differ as this post ages.</p></blockquote>
<hr>
<h2 id="what-are-sig--swg">What are SIG &amp; SWG?</h2>
<p>Good question! A lot of us are probably familiar with Cisco Umbrella (formerly OpenDNS) for the DNS-layer security products. Using Cisco Umbrella, we can configure our end PCs or DNS forwarders to use the Cisco DNS servers. Then, we apply security policies to allow/deny DNS queries based on our policy.</p>
<p>Now applying security policy at the DNS level is great! Typical web filtering only inspects HTTP/HTTPS traffic, but inspecting DNS traffic allows us to stop threats that might not use those typical ports. While there may be some applications or malware that use hard-coded IP addresses, a good majority use a domain name that requires a DNS lookup.</p>
<p>But what if we wanted to still do web filtering too? Or maybe we want a centralized, cloud-hosted firewall service? That&rsquo;s where Umbrella SIG &amp; SWG come in.</p>
<p>Secure Web Gateway (SWG) is pretty much exactly what it sounds like. It&rsquo;s a cloud-hosted web filter or web proxy, where we can set URL-based policys to permit or deny access. It supports the usual allow-lists, deny-lists, HTTPS inspection, file inspection, and policies based on user/group identities.</p>
<p>Secure Internet Gateway (SIG) is a large, cloud-hosted firewall service. What we can do with SIG is tunnel all of our traffic to one centrallized location to apply firewall policies (permit/deny/etc).</p>
<p>Why would we want either of these functions to be cloud-hosted? Well we might not have the resources at every remote site to perform firewalling &amp; web filtering - or we don&rsquo;t want to invest in beefy hardware in our corporate datacenter, and backhaul all of our remote traffic back for inspection. The cloud-hosted piece also means a central management point, so only one place to make change for all of our remote sites - rather than having to touch dozens or hundreds of remote devices&hellip;..Did someone say SASE? 🙃</p>
<p>With all that said - Let&rsquo;s get into making this work!</p>
<blockquote>
<p>Note: There are many ways to use Umbrella SIG/SWG (IPSec tunnel, PAC file, Anyconnect, etc). This particular post will only cover IPSec via Meraki MX.</p></blockquote>
<h2 id="step-1-getting-our-keys">Step 1: Getting our Keys</h2>
<p>First thing we&rsquo;ll need to do is on the Umbrella side. We&rsquo;ll need to generate tunnel keys for our Meraki MX to use for IPSec negotiation.</p>
<p>We&rsquo;ll log into our Umbrella dashboard at <a href="https://login.umbrella.com/">https://login.umbrella.com/</a></p>
<p>Once we&rsquo;re in, we&rsquo;ll navigate to <strong>Deployments</strong> &gt; <strong>Core Identities</strong> &gt; <strong>Network Tunnels</strong>. Shown below, we currently have no tunnels configured:</p>
<p><img alt="001&mdash;umbrella-keys-1" loading="lazy" src="/content/images/2021/03/001---umbrella-keys-1.PNG#center"></p>
<p>In the upper right corner, let&rsquo;s click the <strong>Add Tunnel</strong> button.</p>
<p>We&rsquo;ll now see the following screen to begin creating our IPSec tunnel:</p>
<p><img alt="002&mdash;Umbrella-tunnel-create-1" loading="lazy" src="/content/images/2021/03/002---Umbrella-tunnel-create-1.png#center"></p>
<p>Here, we&rsquo;ll need to specify a name for our tunnel &amp; which device type. The name can be anything we choose that helps us identify what locations are using this tunnel. I&rsquo;ve specified <em>MX64</em> as my tunnel name, since I only have one MX that I&rsquo;ll be testing this with. We also have <strong>Meraki MX</strong> as an option in the <em>Device Type</em> drop down - so we&rsquo;ll select that as well. Then, we&rsquo;ll click <strong>Next</strong>.</p>
<p>Then we&rsquo;ll need to configure our <strong>Tunnel ID</strong> and <strong>Passphrase</strong>:</p>
<p><img alt="003&mdash;Umbrella-tunnel-create-2" loading="lazy" src="/content/images/2021/03/003---Umbrella-tunnel-create-2.png#center"></p>
<p>The <strong>Tunnel ID</strong> we&rsquo;ll be sending later, as part of our IPSec local ID. The passphrase will be used as our pre-shared key for the tunnel config. Once we&rsquo;re done with that, click <strong>Save</strong>.</p>
<p>As long as our ID &amp; passphrase are all good, we&rsquo;ll be presented with a box to easily copy these parameters into the Meraki config:</p>
<p><img alt="004&mdash;Umbrella-tunnel-create-3" loading="lazy" src="/content/images/2021/03/004---Umbrella-tunnel-create-3.png#center"></p>
<p>Finally, we&rsquo;ll be dropped back to our <em>Network Tunnels</em> page - where we can see that our tunnel is configured, but not yet established. Let&rsquo;s fix that &amp; hop over to the Meraki dashboard!</p>
<p><img alt="005&mdash;Umbrella-tunnel-create-4" loading="lazy" src="/content/images/2021/03/005---Umbrella-tunnel-create-4.png#center"></p>
<h2 id="step-2-meraki-mx-ipsec-configuration">Step 2: Meraki MX IPSec Configuration</h2>
<p>Okay, now onto the fun stuff.</p>
<p>We&rsquo;ll log into our Meraki Dashboard at <a href="https://account.meraki.com/secure/login/dashboard_login">https://account.meraki.com/secure/login/dashboard_login</a></p>
<p>Once we&rsquo;re in, you&rsquo;ll need to select the network with the MX you want to connect. For me, I currently only have a single network, which contains my MX firewall.</p>
<p>Then we&rsquo;ll navigate to <strong>Security &amp; SD-WAN</strong> &gt; <strong>Configure</strong> &gt; <strong>Site-to-site VPN</strong>.</p>
<p><img alt="006&mdash;Meraki-MX-VPN-1" loading="lazy" src="/content/images/2021/03/006---Meraki-MX-VPN-1.png#center"></p>
<p>Assuming we have no other VPNs configured, you&rsquo;ll have to change the VPN <strong>Type</strong> to <strong>Hub (Mesh)</strong> or <strong>Spoke</strong>. In my case, Umbrella SIG will be the only VPN I&rsquo;ll have configured - so I&rsquo;ll go ahead and use <strong>Hub (Mesh)</strong>. Don&rsquo;t mind the error regarding exit hubs, as we&rsquo;ll be configuring a non-Meraki peer below.</p>
<p><img alt="007&mdash;Meraki-MX-VPN-2" loading="lazy" src="/content/images/2021/03/007---Meraki-MX-VPN-2.PNG#center"></p>
<p>Okay, scrolling down the page just a bit - we&rsquo;ll need to specify which VLANs/internal subnets will be routed across the VPN &amp; pushed through Umbrella for SIG/SWG:</p>
<p><img alt="008&mdash;Meraki-MX-VPN-3-1" loading="lazy" src="/content/images/2021/03/008---Meraki-MX-VPN-3-1.PNG#center"></p>
<p>For testing purposes, I have a VM in a subnet labeled <em>DMZ</em> that I&rsquo;ll be using - So that will be the only VLAN that I&rsquo;ll set to <strong>VPN On</strong>.</p>
<p>Next we&rsquo;ll take a look at configuring <strong>Non-Meraki VPN Peers</strong>.</p>
<p>As shown in the screenshot below, we&rsquo;ll need to configure the following settings:</p>
<ul>
<li>Name - This is locally significant, I set mine to <em>Umbrella_SIG</em></li>
<li>IKE Version - Set this to IKEv2</li>
<li>IPSec Policies - Custom - See below</li>
<li>Public IP - This is the peer Umbrella Datacenter
<ul>
<li>Choose the DC closest to you <a href="https://docs.umbrella.com/umbrella-user-guide/docs/cisco-umbrella-data-centers">here</a></li>
<li>For this post, I&rsquo;m using the New York DC</li>
</ul>
</li>
<li>Local ID - Set this to the Tunnel ID we got from Umbrella</li>
<li>Remote ID - Leave blank</li>
<li>Private Subnets - This is what destination IPs will be routed over the tunnel
<ul>
<li>Since this is intended as an <em>Internet</em> gateway, we&rsquo;ll use 0.0.0.0/0</li>
</ul>
</li>
<li>Preshared Secret - Set this to the passphrase we configured in Umbrella</li>
<li>Availability - Set this to which networks this tunnel should apply
<ul>
<li>Since I only have 1 network &amp; 1 MX, I set this to <em>All Networks</em></li>
</ul>
</li>
</ul>
<p><img alt="009&mdash;Meraki-MX-VPN-4" loading="lazy" src="/content/images/2021/03/009---Meraki-MX-VPN-4.png#center"></p>
<p>Okay - I mentioned above we&rsquo;ll need to set some custom IPSec parameters. Here&rsquo;s what we&rsquo;ll configure as a custom policy:</p>
<p><img alt="010&mdash;Meraki-MX-VPN-5" loading="lazy" src="/content/images/2021/03/010---Meraki-MX-VPN-5.PNG#center"></p>
<blockquote>
<p>Note: Turns out in the drop down menu, there is also an option for &ldquo;Umbrella&rdquo;, so you don&rsquo;t have to create a custom policy. That being said, the Umbrella preset uses DH group 5, but Umbrella&rsquo;s docs ask for DH group 14.</p></blockquote>
<p>Lastly, we&rsquo;ll be able to configure whether or not we want firewall logging (I enabled this) and also whether we want to add access-lists to permit/deny any traffic over the VPN. For now I&rsquo;ll be leaving this as permit any.</p>
<p><img alt="011&mdash;Meraki-MX-6" loading="lazy" src="/content/images/2021/03/011---Meraki-MX-6.PNG#center"></p>
<p>Finally - we can click <strong>Save</strong> to push our configuration to the MX appliance!</p>
<h2 id="step-3-validation--testing">Step 3: Validation &amp; Testing</h2>
<p>Hopefully once we get all that configuration done, we&rsquo;ll be able to see our tunnel come up.</p>
<p>We can validate from both sides, but let&rsquo;s start with Meraki. In the Dashboard menu, we&rsquo;ll navigate to <strong>Security &amp; SD-WAN</strong> &gt; <strong>Monitor</strong> &gt; <strong>VPN Status</strong>.</p>
<p><img alt="012&mdash;Meraki-MX-VPN-7" loading="lazy" src="/content/images/2021/03/012---Meraki-MX-VPN-7.png#center"></p>
<p>Then we&rsquo;ll need to click the tab for <strong>Non-Meraki peer</strong>:</p>
<p>With any luck, we should see the little green circle showing that our tunnel is online.</p>
<p><img alt="016&mdash;MX-VPN-Status" loading="lazy" src="/content/images/2021/03/016---MX-VPN-Status.PNG#center"></p>
<blockquote>
<p>If your tunnel doesn&rsquo;t come up immediately, you may have to generate some traffic from your VPN subnet to the internet. This will force the MX to try and connect to Umbrella.</p>
<p>It&rsquo;s also worth noting - sometimes it may take the Meraki dashboard to show a successful connection. A better indicator is by checking the Umbrella dashboard, or checking manually with a device you are expecting to route over the VPN.</p></blockquote>
<p>If for any reason we have trouble, we can also check our VPN negotiation logs by going to <strong>Network-Wide</strong> &gt; <strong>Monitor</strong> &gt; <strong>Event Log</strong>.</p>
<p><img alt="014&mdash;Meraki-MX-VPN-9" loading="lazy" src="/content/images/2021/03/014---Meraki-MX-VPN-9.png#center"></p>
<p>On this screen, make sure you&rsquo;ve selected <strong>for security appliances</strong> at the top. If needed, we can also filter events by <strong>All Non-Meraki VPN / Client VPN</strong>.</p>
<p><img alt="015&mdash;Meraki-MX-VPN-10" loading="lazy" src="/content/images/2021/03/015---Meraki-MX-VPN-10.png#center"></p>
<p>Since my tunnel came up with no issues, the output above shows a successful tunnel negotiation.</p>
<p>Let&rsquo;s jump over to the Umbrella side, and see what the Umbrella dashboard shows.</p>
<p>Back on the <strong>Network Tunnels</strong> page - we should see that our tunnel now shows as <strong>Active</strong>.</p>
<p><img alt="013&mdash;Meraki-MX-VPN-8" loading="lazy" src="/content/images/2021/03/013---Meraki-MX-VPN-8.png#center"></p>
<p>This screen will also so the public IP that our MX is using to connect, as well as which Umbrella datacenter we&rsquo;ve connected to.</p>
<hr>
<p>Okay! That&rsquo;s it for now. To try and keep this blog post from getting too long, I&rsquo;ve decided to split this into two parts.</p>
<p>If you&rsquo;re interested in seeing how to configure Umbrella&rsquo;s cloud firewall &amp; web filtering policies - please check out my <a href="https://www.youtube.com/watch?v=GfVEQzxT10g">YouTube Video</a> above!</p>
]]></content:encoded>
    </item>
    <item>
      <title>[How To] Upgrade a Cisco SD-WAN Network</title>
      <link>https://0x2142.com/how-to-upgrade-a-cisco-sd-wan-network/</link>
      <pubDate>Fri, 27 Nov 2020 20:55:48 +0000</pubDate>
      <guid>https://0x2142.com/how-to-upgrade-a-cisco-sd-wan-network/</guid>
      <description>A short tutorial on how to upgrade a Cisco/Viptela SDWAN network, including controllers &amp;amp; edge devices</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/BuRQ0P1tq4Y?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>I have a local Cisco SD-WAN lab environment running at home, which was built in EVE-NG. It&rsquo;s what I use whenever I need to test something for a customer, or just play around with the templates or APIs.</p>
<p>I&rsquo;m planning on spending some hands-on time with new features soon, along with working on some automation projects - so it&rsquo;s well past time to upgrade my lab.</p>
<p>Currently I&rsquo;m running on version 18.4.302, but my intent is to upgrade to 20.3.2 - which is the latest version available today.</p>
<p>In this blog post, we&rsquo;ll walk through how to upgrade a Cisco SD-WAN / Viptela network, including:</p>
<ul>
<li>Control Plane:
<ul>
<li>vManage</li>
<li>vBond</li>
<li>vSmart(s)</li>
</ul>
</li>
<li>Data Plane:
<ul>
<li>vEdge / vEdge Cloud</li>
</ul>
</li>
</ul>
<p>While my lab is using the on-prem controllers, these steps will work just the same if you&rsquo;re using Cisco&rsquo;s cloud-hosted controllers.</p>
<hr>
<h2 id="downloading-the-software-images">Downloading the Software Images</h2>
<p>First thing&rsquo;s first - in order to upgrade our environment, we need the correct software images!</p>
<p>Head over to Cisco Software Downloads, and search for SD-WAN (or <a href="https://software.cisco.com/download/home/286320995/type">click here!</a>).</p>
<p><img alt="03&mdash;software-download-pt2&mdash;cropped" loading="lazy" src="/content/images/2020/11/03---software-download-pt2---cropped.png#center"></p>
<p>Once on this page, I just want to call out that we will need to click on the <strong>SD-WAN Software Update</strong> link. This may seem simple enough, but the other links for <strong>vManage Software</strong> or <strong>vSmart Software</strong> only contain images for a <em>new</em> install.</p>
<p>After that - just select the image version that you would like to upgrade to, and download both images.</p>
<p>In my case, since I&rsquo;m downloading version 20.3.2, I&rsquo;ll be using the following images:</p>
<ul>
<li>vSmart, vEdge Cloud, vEdge 5000, ISR1100 series and vBond upgrade image
<ul>
<li>File name: viptela-20.3.2-x86_64.tar.gz</li>
</ul>
</li>
<li>vManage upgrade image
<ul>
<li>File name: vmanage-20.3.2-x86_64.tar.gz</li>
</ul>
</li>
</ul>
<h2 id="adding-images-to-the-software-repository">Adding Images to the Software Repository</h2>
<p>The process for upgrading a Cisco SD-WAN environment is pretty straightforward.</p>
<p>The control plane can be upgraded independently of the edge devices, so long as everything stays within the bounds of the <a href="https://www.cisco.com/c/en/us/td/docs/routers/sdwan/release/notes/vedge-20-3/sd-wan-rel-notes-20-3.html#concept_iv2_pyz_blb">compatability matrix</a>. In my case, I&rsquo;ll be upgrading to 20.3.2 - and the controllers could still support edge devices as far back as 17.2. So no issues here!</p>
<p>Alright - let&rsquo;s get started!</p>
<p>First, we&rsquo;ll need to upload our images into our local vManage software repository. This is the file storage for all upgrade images, and it&rsquo;s where the controllers &amp; edge devices will go to pull their images from.</p>
<p>In the vManage dashboard, we&rsquo;ll go to the <strong>Maintenance</strong> tab and select <strong>Software Repository</strong>.</p>
<p>Then, click on <strong>Add New Software</strong>.</p>
<p><img alt="06&mdash;vmanage-software-repo&mdash;cropped" loading="lazy" src="/content/images/2020/11/06---vmanage-software-repo---cropped.png#center"></p>
<p>In here we&rsquo;ll see a few options: <strong>vManage</strong> and <strong>Remote Server / Remote Server - vManage</strong>.</p>
<p>We&rsquo;ll use vManage if we want to upload &amp; distribute images from the local vManage server we&rsquo;re logged into currently.</p>
<p>Alternatively, we could use a remote file storage server by using the <strong>Remote Server</strong> option. If you choose to go this route, don&rsquo;t forget to ensure that ALL controllers &amp; WAN edge devices have access to this storage location.</p>
<p>After you select an option, it&rsquo;s an easy drag &amp; drop to upload the software images.</p>
<h2 id="planning-the-upgrade">Planning the Upgrade</h2>
<p>So before we get into actually applying our image upgrades - let&rsquo;s address the questions of &ldquo;What order do I upgrade things in?&rdquo; and &ldquo;What&rsquo;s the impact?&rdquo;.</p>
<p>Since this is a lab environment for me, I&rsquo;ll be upgrading everything all at once - since uptime / outages aren&rsquo;t a factor here</p>
<p>If you&rsquo;re doing this in a production environment, I highly recommend performing these upgrades in an outage / maintenance window - or at least an off-peak time.</p>
<p>Yes, you can upgrade the controllers at any time without causing any issue. Yes, you can upgrade a redundant pair of vEdge devices and keep a branch online. However, I would advise you to try these out off-hours first - and get your own understanding of how this works &amp; what to expect before doing it in production.</p>
<p>As for the upgrade order, we&rsquo;re going to start at the top of the food chain and work our way down:</p>
<ul>
<li>Upgrade vManage first</li>
<li>Then vBond</li>
<li>Upgrade ONE vSmart controller &amp; wait for it to come online / re-establish control connections</li>
<li>Then upgrade the second / redundant vSmart controller</li>
<li>After the control plane is upgraded &amp; stable - move onto the edge devices</li>
</ul>
<p>These steps can also be found under the <strong>Best Practices</strong> section of the <strong><a href="https://www.cisco.com/c/en/us/td/docs/routers/sdwan/configuration/sdwan-xe-gs-book/hardware-and-software-installation.html#c_Software_Installation_and_Upgrade_for_vEdge_Routers_1369.xml">Cisco SD-WAN Getting Started Guide</a></strong>. Cisco&rsquo;s official recommendation is to wait 24 hours in between a few of those steps, to ensure platform stability - but for my lab that won&rsquo;t be necessary</p>
<h2 id="upgrading-vmanage">Upgrading vManage</h2>
<p>Once we have uploaded our images &amp; we have our upgrade plan - we can move forward with actually performing the image upgrades.</p>
<p>Starting with vManage - we&rsquo;ll go to <strong>Maintenance</strong> &gt; <strong>Software Upgrades</strong> &gt; <strong>vManage</strong>.</p>
<p>Then we&rsquo;ll click on <strong>Upgrade</strong> and select our version - in my case <strong>20.3.2</strong>. After that, just click <strong>Upgrade</strong></p>
<p><img alt="vmange-upgrade-dialog" loading="lazy" src="/content/images/2020/11/vmange-upgrade-dialog.png#center"></p>
<p>Now, what this does in the background is just <em>pre-stage</em> the vManage image for an upgrade. The actual software upgrade is not occurring just yet.</p>
<p>Think of this step like you might prepare an IOS/IOS-XE router: Copying the image to the device flash. The image is there and ready - but we haven&rsquo;t booted to it yet.</p>
<p>Once that&rsquo;s all done, we&rsquo;ll go back to the vManage upgrade page and click <strong>Activate</strong>, select our image again, then click <strong>Activate</strong>.</p>
<p>Now <em>this</em> step is where vManage will reboot, apply the upgrade, and come back online with the new image.</p>
<p>Again, back to the IOS/IOS-XE analogy: this is the equivalent of setting out <strong>boot system flash:&lt;image name&gt;</strong> to the new image, then rebooting our router.</p>
<p>vManage may take a short while to complete &amp; reinitialize. In my lab, about 10-15 minutes.</p>
<h2 id="upgrading-vbond--vsmart">Upgrading vBond &amp; vSmart</h2>
<p>After vManage is done, it&rsquo;s time to work on the real heart of our control plane: vBond &amp; vSmart.</p>
<p>Similar to vManage, we&rsquo;ll start by going to <strong>Maintenance</strong> &gt; <strong>Software Upgrades</strong> &gt; <strong>Controller</strong>.</p>
<p>Here we will need to select the devices we want to upgrade. As I mentioned earlier, you may want to do these one at a time &amp; in a phased approach. However, in my lab I&rsquo;ll select all of them to upgrade at once.</p>
<p>Now in this case, vManage will still follow the proper order (vBond, then vSmart), and even perform a rolling upgrade one device at a time. This may be suitable for you in production, but again I would urge you to test it for yourself first!</p>
<p><img alt="controller-upgrade-dialog" loading="lazy" src="/content/images/2020/11/controller-upgrade-dialog.png#center"></p>
<p>The other big difference here, as you can see in the screenshot above, is the presence of the <strong>Activate &amp; Reboot</strong> checkbox.</p>
<p>This does exactly as you would anticipate. Instead of doing the two-step process with vManage where we staged the image, then performed the activation/reboot - this checkbox will do all of that in one step.</p>
<p>In my lab environment, I did check this box &amp; allowed everything to reboot automatically.</p>
<p>Why is there a separation between uploading the image &amp; rebooting / activating it? To allow better granularity over the process.</p>
<p>For example, maybe you have a poor internet connection at a branch site &amp; the image upload may take a long time. This separation of tasks allows you to stage all of the images independently of applying them. If you have a short outage window, this could help you save time by pre-staging the images ahead of time.</p>
<p>Back to the upgrade - just like vManage we&rsquo;ll select the version we&rsquo;re applying then click <strong>Upgrade</strong></p>
<p>Again - Depending on the resources available to your controllers, the image upload / activation process may take a short while&hellip;</p>
<h2 id="upgrading-the-wan-edge-appliances">Upgrading the WAN Edge Appliances</h2>
<p>In my lab, I&rsquo;m currently using a handful of vEdge Cloud VMs as branch office routers. The upgrade process here should apply to other edge devices as well.</p>
<p>After we&rsquo;re confident our controller upgrades have been successful &amp; all control connections have been re-established - we can move to upgrading our edge devices.</p>
<p>It&rsquo;s also worth mentioning that my lab currently has <em>no</em> redundant deployments of WAN edge appliances. All of my test &lsquo;branch offices&rsquo; are single-homed to one vEdge Cloud - so an outage will be required to apply the images.</p>
<p>If you&rsquo;re using a redundant configuration at a remote site, ideally you would upgrade ONE edge device first. Then only upgrade the second after control connections &amp; routing adjacencies had been re-established on the first device. This should allow for an upgrade with minimal downtime.</p>
<p>The process for upgrading the edge devices mirrors what we saw for vBond / vSmart.</p>
<p>We&rsquo;ll go to <strong>Maintenance</strong> &gt; <strong>Software Upgrade</strong> &gt; <strong>WAN Edge</strong>, then select the edge devices we want to upgrade.</p>
<p>Click <strong>Upgrade</strong>, select the target version from the drop-down, then click <strong>Upgrade</strong>. Again, in my case, I also selected the <strong>Activate &amp; Reboot</strong> checkbox</p>
<p><img alt="vedge-upgrade-dialog" loading="lazy" src="/content/images/2020/11/vedge-upgrade-dialog.png#center"></p>
<p><strong>NOTE:</strong> It&rsquo;s worth mentioning that for the WAN Edge upgrade, vManage will push the upgrade to <em>all devices simultaneously</em>. <del>If you would like to perform a rolling upgrade here, you&rsquo;ll have to manage it yourself.</del> In the case of a site where a redundant vEdge is deployed &amp; they share the same site ID, vManage automatically will handle upgrading only one at a time to maintain uptime (Thanks <a href="https://twitter.com/juangolbez">Tim McConnaughy</a> for clarifying this!).</p>
<p>Once again, we&rsquo;ll give the edge devices a few minutes to download &amp; apply their software upgrades. Then we&rsquo;ll check to ensure all of the control connections re-established &amp; traffic is flowing.</p>
<h2 id="wrap-up">Wrap up</h2>
<p>Once your edge devices are back online, it&rsquo;s all done! The network has been upgraded to the new version.</p>
<p>There are a handful of ways to check this, but one easy way is via the device monitor page: <strong>Monitor</strong> &gt; <strong>Network</strong></p>
<p>This page will list a summary of everything in the network, including the current software version &amp; number of established control connections. For me, it&rsquo;s an easy way to get a one-page summary of the network.</p>
<p><img alt="monitor-networkpng" loading="lazy" src="/content/images/2020/11/monitor-networkpng.png#center"></p>
<p>From the screenshot above - we can see that all of my lab devices are back online &amp; running software version 20.3.2.</p>
<hr>
<p>That&rsquo;s it! Hope this post was helpful to you.</p>
<p>Thanks for reading!</p>
]]></content:encoded>
    </item>
    <item>
      <title>Meraki MG - Setting up Meraki&#39;s New Cellular Gateway</title>
      <link>https://0x2142.com/meraki-mg-setting-up-merakis-new-lte-gateway/</link>
      <pubDate>Thu, 20 Aug 2020 21:17:23 +0000</pubDate>
      <guid>https://0x2142.com/meraki-mg-setting-up-merakis-new-lte-gateway/</guid>
      <description>I recently got a Meraki MG21 LTE gateway. Let&amp;rsquo;s set it up!</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/Zb5KE8_OFxQ?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>So if you&rsquo;ve read some of my recent posts - you may have seen that I purchased a <a href="/how-to-setting-up-google-fi-on-a-netgear-lte-modem/">NetGear LB 1121 LTE Cellular modem</a> to use for home internet backup.</p>
<p>Well - I decided to upgrade!</p>
<p>After using the NetGear modem for a while, I started having some issues where it would disconnect from the cellular connection intermittently. Since it&rsquo;s not necessarily intended for the purpose I&rsquo;m using it for, there wasn&rsquo;t any good way to set up monitoring for it either.</p>
<p>So I opted to upgrade to a Meraki MG21. This is one of the latest additions to the Meraki family of network devices &amp; is available with internal (MG21) and external (MG21E) antenna.</p>
<p>I was pretty excited to get one, since Meraki tends to have decent analytics &amp; configuration - and they make everything so easy!</p>
<p>We&rsquo;ll walk through the setup of the MG below - but if you&rsquo;re interested in seeing what the device looks like as well, definitely check out the video above!</p>
<hr>
<h2 id="mg-setup---changing-the-apn">MG Setup - Changing the APN</h2>
<p>Okay - so after I got the SIM card inserted into the MG, the first configuration step is making sure we have the correct APN configured. As a reminder, I&rsquo;m using Google Fi as my cellular provider.</p>
<p>This change will need to be done <strong>on the local web management interface</strong> - not from Meraki Dashboard.</p>
<p>When the MG powers on, by default it will hand out DHCP addresses to any device connected to port 1. At the time of writing, these addresses were in the 192.168.5.x range.</p>
<p>Connecting a PC directly to the MG port, we should be able to reach the local management web page - either by typing in the IP address into our web browser, or using mg.meraki.com:</p>
<p><img alt="blog-01" loading="lazy" src="/content/images/2020/08/blog-01.PNG#center"></p>
<p>In my case, I could see that the MG had auto-detected my Carrier as Google Fi. However, it still had the incorrect APN.</p>
<p>Using the <strong>Configure</strong> tab, we can change that setting. You&rsquo;ll be prompted for a username &amp; password. By default, the username will be the serial number of the device (including dashes) with a blank password.</p>
<p><img alt="blog-02" loading="lazy" src="/content/images/2020/08/blog-02.PNG#center"></p>
<p>As shown in the screenshot above, we have a handful of options - though we&rsquo;ll only care about APN.</p>
<p>First - change the <strong>Cellular Override</strong> option to <strong>Override SIM Settings</strong>.
Then type in your APN. In my case, it&rsquo;s <strong>h2g2</strong> for Google Fi.
Lastly, hit save at the bottom (just outside the view in the screenshot above).</p>
<p>With any luck, the modem will connect and you&rsquo;ll see something like this:</p>
<p><img alt="blog-03" loading="lazy" src="/content/images/2020/08/blog-03.png#center"></p>
<p>The modem connects, gets an IP from the provider, and is able to validate connectivity to both the internet &amp; Meraki Cloud.</p>
<p>When I originally set up my MG, I did run into some issues with this. My MG connected to the internet successfully, but said it couldn&rsquo;t reach the Meraki Cloud. Not sure what caused it, but it shortly resolved itself within a few minutes. Just gotta be patient sometimes, I suppose!</p>
<h2 id="configuring-the-mg-in-meraki-dashboard">Configuring the MG in Meraki Dashboard</h2>
<p><em>Note: I won&rsquo;t get into how to claim your device in dashboard or how to attach it to a network. If you need help, please check out the video above where I did show how to accomplish these steps</em></p>
<p>Okay! Now that our MG is configured for the correct cell network, we can log into the Meraki Dashboard and begin configuring it.</p>
<p>After we&rsquo;ve added the MG to our network, we&rsquo;ll see a new <strong>Cellular Gateway</strong> menu:</p>
<p><img alt="blog-04" loading="lazy" src="/content/images/2020/08/blog-04.png#center"></p>
<p>We&rsquo;ll start first by going over to <strong>Configure &gt; Settings</strong></p>
<p>First section we&rsquo;ll see is for <strong>Addressing &amp; NAT</strong>:</p>
<p><img alt="blog-05" loading="lazy" src="/content/images/2020/08/blog-05.png#center"></p>
<p>As of today, the MG doesn&rsquo;t support any form of direct internet pass-through. Instead, our only option is <strong>routed</strong> mode - where the MG will hold the IP provided by our Carrier &amp; NAT any requests from the devices behind it.</p>
<p>We can change the DHCP subnet configuration here, which will affect what IP addresses are handed to clients behind the MG. In my case, I&rsquo;m connecting this directly to a firewall as a secondary internet uplink - so the addressing &amp; subnet doesn&rsquo;t matter as much. By default, the MG will always consume the first available address as it&rsquo;s own.</p>
<p>Next, we have a section for <strong>DHCP &amp; subnets</strong>:</p>
<p><img alt="blog-06" loading="lazy" src="/content/images/2020/08/blog-06.png#center"></p>
<p>Here we can change our DHCP lease time, and what DNS servers are provided to our clients. The DNS setting does have pre-defined options for Umbrella DNS, Google DNS, or using whatever the upstream carrier provides. You&rsquo;re also welcome to manually specify which DNS servers to use.</p>
<p>We can also configure reserved &amp; fixed IP addresses here.</p>
<p>Reserved IP ranges are IP addresses that we don&rsquo;t want the MG to provide via DHCP. So if we had any statically configured IP addresses, we could reserve them here.</p>
<p>Fixed IP addresses are for any client that needs a DHCP address, but we want that IP assignment to be permanent. We&rsquo;ll enter the client name &amp; MAC Address here, as well as the IP we want assigned to that device. In my case, I went ahead and inserted my firewall MAC address - and I&rsquo;ll just allow the firewall to get its IP via DHCP from the MG.</p>
<p>By default, the MG will block <strong>all</strong> inbound traffic from the cellular network. If we need to allow any traffic inbound, we can change the <strong>Port Forwarding</strong> settings:</p>
<p><img alt="blog-07" loading="lazy" src="/content/images/2020/08/blog-07.png#center"></p>
<p>This allows for a light configuration of an inbound NAT. Right now, I probably won&rsquo;t be using this. However, I may permit VPN access into my network via the MG at a later date.</p>
<p>If I needed to add anything here, the MG allows us to translate an external / public IP &amp; port to any internal IP / port combination. It appears we can even add a IP filter to permit only trusted source addresses.</p>
<p>Lastly - We can configure settings for <strong>Traffic Shaping</strong>:</p>
<p><img alt="blog-08" loading="lazy" src="/content/images/2020/08/blog-08.PNG#center"></p>
<p>In this section, we can throttle our cellular throughput &amp; configure uplink monitoring.</p>
<p>By default, the cell bandwidth is set to unlimited - but we can drop this down if needed. In my case, I am not using an unlimited cell data plan - so I will throttle cellular speeds to preserve data &amp; reduce charges.</p>
<p>In addition, we can configure one or more IP addresses to check uplink connectivity. These addresses will be used to collect loss &amp; latency data via the cellular connection. The MG monitoring dashboard will collect &amp; graph this data for easy insight into the performance metrics.</p>
<p><strong>Note: As a word of warning, these uplink monitors are constantly sending ICMP/ping requests. If you have a limited amount of cellular data, this may consume more data than you would like. In my testing, using only one IP for uplink monitoring consumed about 70-100M per day. More on this below&hellip;</strong></p>
<h2 id="monitoring-the-mg">Monitoring the MG</h2>
<p>Now we get to the good stuff! The primary reason I opted to buy an MG was for monitoring &amp; analytics.</p>
<p>Back on the dashboard, if we use the lefthand menu - we&rsquo;ll go over to <strong>Cellular Gateway &gt; Monitor &gt; Cellular Gatways</strong>. Then select our MG out of the list.</p>
<p>The primary summary page isn&rsquo;t too exciting:</p>
<p><img alt="blog-09" loading="lazy" src="/content/images/2020/08/blog-09.png#center"></p>
<p>The MG does have two gigabit ethernet ports - and we&rsquo;ll see the status here.</p>
<p>We&rsquo;ll also see the connectivity history to the Meraki cloud - which in my case is nearly 100%. Seems like one <em>very</em> minor blip just after 4am.</p>
<p>We can also see the current network utilization on the MG. This is great to have - though my current utilization is pretty low&hellip; (I am using this as a backup modem, after all).</p>
<p>On the left side of the page, we&rsquo;ll see some of the usual info we expect from a Meraki device. Current IP, location, Serial number, and IMEI. Just below the view of the screenshot, there is also an indicator for firmware version.</p>
<p>Onto the <strong>Uplink</strong> tab! Let&rsquo;s see what we have:</p>
<p><img alt="blog-10" loading="lazy" src="/content/images/2020/08/blog-10.png#center"></p>
<p>First we&rsquo;ll see the <strong>Configuration</strong> section. This just gives us a quick view into what settings the MG currently has.</p>
<p>We&rsquo;ll see the current IP info provided by our carrier, and also some statistics on our cellular connection.</p>
<p>Just below that info, we&rsquo;ll see our cellular graphs:</p>
<p><img alt="blog-11" loading="lazy" src="/content/images/2020/08/blog-11.png"></p>
<p>This is what I wanted! It&rsquo;s great to see a quick view into what our active uplink traffic is - as well as look back historically at what our LTE signal quality has been.</p>
<p>Not pictured here - but there is also a section of graphs on this page for our uplink monitor. This is where we can see our current &amp; historical loss &amp; latency stats for the cellular connection. After a few days of use - I disabled the uplink monitor due to the amount of data the feature consumes.</p>
<p>Finally, we also have the <strong>DHCP</strong> tab:</p>
<p><img alt="blog-12" loading="lazy" src="/content/images/2020/08/blog-12.PNG#center"></p>
<p>This will show our current DHCP subnet &amp; any clients that have been provided an address. In my case, there isn&rsquo;t any current leases here - because my firewall has a fixed IP.</p>
<h2 id="performance--considerations">Performance &amp;&amp; Considerations</h2>
<p>I&rsquo;ve had the MG running for about a week now, and wanted to provide some things to think about.</p>
<p>First - How does the modem perform? Well, the first day I had it set up - I was able to get ~150M download speeds using the MG&rsquo;s built-in speed test utility:</p>
<p><img alt="blog-13" loading="lazy" src="/content/images/2020/08/blog-13.PNG#center"></p>
<p>That being said - I&rsquo;m lucky if I get 30-50M on an average day. I might have just gotten lucky that day with some light cellular utilization in my area. Overall though, I&rsquo;m pleased with the speeds I get - they&rsquo;ll certainly fit my needs.</p>
<p>For the few days that I had the uplink monitoring running, I saw good results. Usually 0% packet loss, with a rare spike of 5-10%. Latency was a little less reliable, but usually bounced between 50-150ms. This was also much less than the NetGear modem I had been using, which averaged 200-250ms.</p>
<p>Speaking of uplink tests! Let&rsquo;s talk about data usage&hellip;.</p>
<p>By default, the MG communicates intermittently with the Meraki cloud - which consumes some data. By my measurement, this is usually less than 10Mb/day. No problem here.</p>
<p>The uplink tests, on the other hand, <strong>do</strong> consume a bit of data. I&rsquo;m not sure what frequency these run on, but it&rsquo;s fairly often. Even with one uplink monitor to 8.8.8.8 configured, I was seeing data usage of 70-100Mb a day.</p>
<p>While seeing those metrics is valuable to me, it&rsquo;s also not worth the data charges. If I was using a SIM card with an unlimited data plan - no doubt I would keep this feature enabled. However, since I am paying for the cell data used - I opted to disable this feature.</p>
<p>The MG does still perform it&rsquo;s check-ins to the Meraki Cloud - so you&rsquo;ll have availability statistics &amp; monitoring&hellip; But disabling the uplink monitor means you&rsquo;ll lose the granular data on loss &amp; latency.</p>
<p>Lastly, and another word of warning, when you&rsquo;re actively viewing the MG monitoring page - this <strong>also consumes additional data</strong>. To demonstrate - I&rsquo;ll post a snippet of the screenshot from earlier:</p>
<p><img alt="blog-14" loading="lazy" src="/content/images/2020/08/blog-14.png#center"></p>
<p>If you notice, all the way on the far left there was barely any activity. However, once I loaded the MG monitoring page - you begin to see minor spikes in data usage as the Meraki Cloud starts actively polling the MG for data.</p>
<p>In my experience so far, this isn&rsquo;t a ton of data. I&rsquo;ve checked in to see how the MG has been performing a few times this week, and each time has totaled around 10-15Mb of data usage.</p>
<p>To sum up - I&rsquo;m cheap and want to avoid excess data usage. Just wanted to provide some of that info as something to be aware of.</p>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>I&rsquo;m only a week in, but pretty pleased with the MG&rsquo;s performance. It&rsquo;s maintained a very solid &amp; stable connection compared to the NetGear modem it replaced. The device is intended to provide LTE connectivity or backup service for business networks, so I would certainly hope it would meet my home needs :)</p>
<p>Outside of that, I do wish there was a little better documentation &amp; clarity from the Meraki team on data usage. Right now their documentation only mentions the 6-8Mb of usage due to backend data to/from the Meraki Cloud:</p>
<p><img alt="blog-15" loading="lazy" src="/content/images/2020/08/blog-15.PNG#center"></p>
<p>I would be happy to see additional settings on the uplink monitor to allow me to choose the polling frequency. I feel like throttling down the amount of requests could reduce data to a point where I would be comfortable re-enabling that feature.</p>
<p><del>Oh - and currently there are no native email alerts for the MG. So if the MG goes offline, etc&hellip; there is no alerting from the Meraki Dashboard. This kinda sucks. I&rsquo;m sure this is coming soon, but for the time being I&rsquo;m inclined to write my own monitor using the Dashboard APIs.</del> (see note below!)</p>
<p>Overall, I&rsquo;m happy with the device. Definitely looking forward to future feature &amp; firmware updates to see where the Meraki team takes this platform!</p>
<hr>
<p><em>Update 08/28/2020 - Looks like in the week since I posted this, Meraki added alerting for the MG! Now you can be notified if the cell gateway goes offline:</em></p>
<p><img alt="blog-16" loading="lazy" src="/content/images/2020/08/blog-16.PNG#center"></p>
]]></content:encoded>
    </item>
    <item>
      <title>How To: Convert Catalyst 9100 AP to Embedded WLC</title>
      <link>https://0x2142.com/how-to-convert-catalyst-9100-ap-to-embedded-wlc/</link>
      <pubDate>Tue, 05 May 2020 16:19:35 +0000</pubDate>
      <guid>https://0x2142.com/how-to-convert-catalyst-9100-ap-to-embedded-wlc/</guid>
      <description>A tutorial for converting a Cisco 9100 series wireless access point to host an embedded controller</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/NBt370eiQ3I?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p>Hey there! First thing&rsquo;s first - Hope all is well with everyone. The past few months have seen all sorts of craziness going on in the world. I&rsquo;ve been lucky in the sense that my current job role was already well set up to make an easy transition to working from home all the time. That being said, I know it hasn&rsquo;t been easy for everyone - and I know quite a few people who have lost their jobs, etc.</p>
<p>Second thing! As I&rsquo;m sure you may have already seen above - I opted to spend some of my new-found free time trying out a new format. I&rsquo;ve had a couple of ideas in the past for making short videos, but never forced myself to sit down and give it a shot. So here we are - after about a month of on-and-off work - I finally have something to share. Please give it a look if you&rsquo;re interested, and I would appreciate any comments &amp; feedback. I still have a few other ideas - so if this one goes well I may pursue producing a few more of these.</p>
<p>Okay - Now onto the real content!</p>
<hr>
<p>A few months ago I had the chance to pick up a pair of Cisco Catalyst 9100 series access points from work. My home network has been running on Ubiquiti APs for years - but they&rsquo;re getting old and I desperately needed to replace them. So along comes the Catalyst 9100 APs, which are capable of supporting 802.11ax clients - and why not take the time to upgrade &amp; future proof? I needed some practice anyways, as I have a few customers at work that I think will be interested in these in the near future. I ended up with two 9120AXI APs.</p>
<p>So in the process of trying to dive on the opportunity to play with something new - I completely missed the fact that the 9100 APs have two different product SKUs. One which ships the AP pre-configured with the standard lightweight AP code that you might use if you had an external wireless LAN controller (WLC). And a second SKU that ships the AP with the Catalyst 9800 Embedded WLC (eWLC) software loaded. Of course, I grabbed the lightweight APs without checking.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Product SKUs (Example, using 9120AXI):
</span></span><span class="line"><span class="cl"> - Standard Lightweight AP: C9120AXI
</span></span><span class="line"><span class="cl"> - Pre-load with Embedded WLC: C9120AXI-EWC
</span></span></code></pre></div><p>I wrote in a previous blog about getting <a href="/how-to-catalyst-9800-mac-filtering/">MAC address filtering</a> set up on the Catalyst 9800 WLC. When I wrote that blog I was actually using the C9800-CL, which is a virtual machine version of the Catalyst 9800 controller software. I was originally excited to run the controller as a VM and not need a hardware appliance - but then got to thinking that maybe I should try and save VM resources as well. Which led me to looking at the 9800 eWLC.</p>
<hr>
<h2 id="finding-the-software-image">Finding the Software Image</h2>
<p>In order to convert an existing lightweight access point to one running the embedded WLC software - we first need to grab a copy of the software images from Cisco.com. Search for the model of your 9100 access point (in my case, the 9120AXI).</p>
<p>You&rsquo;ll see two options for Software Type - and it may not immediately be obvious - but we&rsquo;ll need to look under IOS XE Software to find the eWLC images:</p>
<p><img alt="image" loading="lazy" src="/content/images/2020/05/image.png#center"></p>
<p>Then we&rsquo;ll grab the EWC AP image bundle. In my case, I was waiting on a specific feature set that wasn&rsquo;t available until 17.x - so I downloaded the 17.2.1 software:</p>
<p><img alt="image" loading="lazy" src="/content/images/2020/05/image-1.png#center"></p>
<p>Okay - after we&rsquo;ve done that - let&rsquo;s drop everything onto a server/laptop/etc which has console connectivity to our AP and a running TFTP server.</p>
<p>Once you un-zip the contents of that AP image bundle, you&rsquo;ll notice there are quite a number of files. We&rsquo;ll only need two of them - one image to load onto the AP itself, and one that will get loaded for the WLC software container. Within the image bundle, there will be a <strong>readme.txt</strong> file that will tell you which image to use with your AP:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">ap1g5 : AP1815, AP154x
</span></span><span class="line"><span class="cl">ap1g4 : AP180x, AP183x, AP185x
</span></span><span class="line"><span class="cl">ap1g7 : C9115, C9120
</span></span><span class="line"><span class="cl">ap1g6 : C9117
</span></span><span class="line"><span class="cl">ap1g6a : C9130
</span></span><span class="line"><span class="cl">ap3g3 : AP380x, AP280x, AP156x
</span></span></code></pre></div><p>So in my case, I would use the file named <strong>ap1g7</strong> since I had the 9120 APs. In addition, you should also see a file named <strong>C9800-AP-iosxe-wlc.bin</strong>which we&rsquo;ll need to load the controller.</p>
<p>What&rsquo;s with that second image? Well - the Catalyst 9100 APs include a feature called Application Hosting (also found on some of the Catalyst 9000 series switches). This is equivalent to running a Linux container or Docker container directly on the AP hardware. At time of writing, this is only available for the embedded WLC software. However,  there will be a future software update that will allow you to provision other software containers as well (according to the data sheet).</p>
<h2 id="converting-the-access-point">Converting the Access Point</h2>
<p>Now we can get started on the actual conversion process. If it&rsquo;s a new AP, we can just go ahead and boot it up with a console cable connected. If it&rsquo;s already running something, you&rsquo;ll likely want to factory reset the AP first. You can find detailed instructions <a href="https://www.cisco.com/c/en/us/support/docs/wireless/embedded-wireless-controller-on-catalyst-access-points/215303-embedded-wireless-controller-conversion.html#anc7">here</a>, but a quick summary - power off the AP, hold the <strong>mode</strong> button while plugging the AP back in, and keep the <strong>mode</strong> button held for at least 20-30 seconds. If you&rsquo;re logged into the console during this time - you&rsquo;ll actually see the AP counting how long you&rsquo;ve held the button for. Once that counter shows at least 20 seconds, release the <strong>mode</strong>button and allow the AP to reboot.</p>
<p>Once the AP is booted. The default login is <strong>Cisco</strong> / <strong>Cisco</strong>. The enable password is also <strong>Cisco</strong>. You may also want to quickly issue a <strong>show version</strong>, and take note of the current software version running on the AP (hint: we&rsquo;ll need that later).</p>
<p>Next - it&rsquo;s important to note that <em>after</em> we convert the AP - our default CLI will actually be the WLC, <strong>not</strong> the AP (even when connected via console). So we should configure a hostname and IP address for the AP now:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0xAP# capwap ap hostname &lt;hostname&gt;
</span></span><span class="line"><span class="cl">0xAP# capwap ap ip &lt;ip-addr&gt; &lt;netmask&gt; &lt;gateway&gt;
</span></span></code></pre></div><p>Then we can load the new AP image and  WLC image. Depending on which software version you&rsquo;re running today, there is a different command to load the image:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0xAP# ! If you&#39;re running software 8.9 or lower, use the following:
</span></span><span class="line"><span class="cl">0xAP# ap-type mobility-express &lt;TFTP path to AP image&gt; &lt;TFTP path to WLC image&gt;
</span></span><span class="line"><span class="cl">0xAP# ! If you&#39;re running anything above 8.9, use the following:
</span></span><span class="line"><span class="cl">0xAP# ap-type ewc-ap &lt;TFTP path to AP image&gt; &lt;TFTP path to WLC image&gt;
</span></span></code></pre></div><p>Once those commands are submitted, the AP will begin copying the software from the TFTP server. The AP will automatically reboot after the image load is completed.</p>
<p>Quick note: For one of my APs, the WLC software didn&rsquo;t load correctly - and when my AP rebooted I was left with an error that said &ldquo;EWC-AP in Recovery Mode&rdquo;. Re-copying the WLC image fixed it without much trouble. If this happens, the AP will print out the command to re-image the WLC software, but I&rsquo;ll also put it here for reference:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0xAP# ! If you end up in &#34;EWC-AP Recovery Mode&#34;, run the following:
</span></span><span class="line"><span class="cl">0xAP# archive download-sw ewc-ap &lt;TFTP path to WLC image&gt;
</span></span></code></pre></div><p>Okay - Once our AP has come back from loading up all the new software, we can get on with a bit of minimal config required to access the WLC web UI.</p>
<p>First, we&rsquo;ll configure the WLC hostname &amp; our local user account. This can be switched over later to your choice of directory service:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0xC9800eWLC# config t
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# hostname &lt;hostname&gt;
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# user-name &lt;admin username&gt;
</span></span><span class="line"><span class="cl">0xC9800eWLC(config-user-name)# password &lt;admin password&gt;
</span></span><span class="line"><span class="cl">0xC9800eWLC(config-user-name)# privilege 15
</span></span></code></pre></div><p>Next we&rsquo;ll also provide the WLC with the administrative credentials used to manage the connected APs:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0xC9800eWLC(config)# ap profile &lt;profile-name&gt;
</span></span><span class="line"><span class="cl">0xC9800eWLC(config-ap-profile)# mgmtuser username &lt;AP admin user&gt; password 0 &lt;AP admin password&gt; secret 0 &lt;AP admin secret&gt;
</span></span></code></pre></div><p>After that, we&rsquo;ll go ahead and configure our basic network settings. This will be the IP address &amp; gateway info that will be used to connect to the WLC web UI and SSH:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0xC9800eWLC(config)# interface gigabit 0 
</span></span><span class="line"><span class="cl">0xC9800eWLC(config-if)# ip address &lt;managemnt IP&gt; &lt;Network mask&gt;
</span></span><span class="line"><span class="cl">0xC9800eWLC(config-if)# no shut
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# ip default-gateway &lt;Gateway IP address&gt;
</span></span></code></pre></div><p>Lastly - we&rsquo;ll need to actually enable the web server. In my case, I opted to not enable the standard HTTP server. I only enabled the encrypted SSL-enabled web server:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0xC9800eWLC(config)# ! I only enabled the HTTPS server:
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# ip http secure-server
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# ! If you wanted to enable the plain-text / unencrypted web server:
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# ip http server
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# 
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# ! Finally - Save the config
</span></span><span class="line"><span class="cl">0xC9800eWLC(config)# exit
</span></span><span class="line"><span class="cl">0xC9800eWLC# wr mem
</span></span></code></pre></div><p>When we save our config for this first time, the AP will verify that the initial configuration pieces have been completed. There is a bit of background cleanup that is performed - which removes any factory config that assisted with provisioning. Once that&rsquo;s all done - we&rsquo;re free to log into the web UI!</p>
<h2 id="embedded-wlc-web-interface">Embedded WLC Web Interface</h2>
<p>I won&rsquo;t spend a lot of time here, as there are far too many things to cover with the new 9800 series controllers. However, I did want to point out a few things that stand out regarding the Embedded WLC.</p>
<p>When we log into our WLC web UI - we&rsquo;ll be able to use the username &amp; password combo that we configured previously. Then we&rsquo;ll be dropped into our WLC dashboard.</p>
<p><img alt="image" loading="lazy" src="/content/images/2020/05/image-2.png#center"></p>
<blockquote>
<p>*Note: Screenshot taken a bit after I did my initial config. This has been running a bit now&hellip;</p></blockquote>
<p>If we click on the number under the <strong>Access Points</strong> heading, we&rsquo;ll be taken to a quick monitoring view of the current connected APs:</p>
<p><img alt="image" loading="lazy" src="/content/images/2020/05/image-3.png#center"></p>
<p>Here we can see the APs we have configured, along with their IP address &amp; status info. We will also see what our <strong>Current Active</strong> WLC controller is, and what our <strong>Current Standby</strong> / <strong>Preferred Active</strong> if we have either configured.</p>
<p>By default, if we boot up a second AP running the embedded WLC software, it will automatically join the WLC cluster as the secondary node. Any WLC config/settings will be copied, then it&rsquo;s ready in case the primary controller fails. In the event of a failure, the secondary WLC will take over - and be accessible using the same IP &amp; login info that we used on the primary.</p>
<p>In my case, I&rsquo;ve also configured one of my APs as a preferred primary controller. For me, this AP is connected to a switch that has a short battery backup - so it&rsquo;s less likely to experience failure. This option can be configured on the individual AP itself. In the left-hand menu, drop into the <strong>Configuration</strong> section, then click on <strong>Access Points</strong> under the <strong>Wireless</strong> header. We&rsquo;ll see a very similar screen to the AP monitoring screen from above. Click on the AP that we want to make our preferred primary, then jump over to the <strong>Advanced</strong> tab. There will be a checkbox for <strong>Preferred Controller</strong>:</p>
<p><img alt="image" loading="lazy" src="/content/images/2020/05/image-4.png#center"></p>
<h2 id="wlc-image-repository">WLC Image Repository</h2>
<p>Last thing - and this one is important. Normally the WLC will have dedicated storage to keep AP software images, which it distributes to new APs when they come online. Unfortunately, while we gain the flexibility and limited footprint of the embedded WLC - we also lose that dedicated storage space. As you might imagine, storage on the AP is limited.</p>
<p>So we&rsquo;ll need to make sure that the WLC has an external image repository that it can use. This configuration can be done via teh web UI and CLI. I&rsquo;ll cover both very quickly here.</p>
<p>From the web UI -  We&rsquo;ll go to <strong>Administration</strong> &gt; <strong>Software Management</strong>:</p>
<p><img alt="image" loading="lazy" src="/content/images/2020/05/image-5.png#center"></p>
<p>Here we&rsquo;ll see our options for where to get images, as well as an inventory of current APs &amp; their images. In the <strong>Mode</strong> drop-down, we&rsquo;ll have the option of tftp, sftp, CCO, and Desktop. TFTP / SFTP are what we&rsquo;re used to. With <strong>Desktop</strong>, we would just upload images directly from our laptop / PC. Interestingly though, <strong>CCO</strong> allows us to provide our Cisco.com credentials - and the controller can pull images directly from Cisco. We&rsquo;ll even have the option to enable automatic software downloads - and specify whether we want to auto-download the latest software release, or only the latest <em>recommended</em> release.</p>
<p>On the CLI side of things - we can accomplish the same using the following commands on our WLC CLI:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">0xC9800eWLC(config)# wireless profile image-download &lt;profile name&gt;
</span></span><span class="line"><span class="cl">0xC9800eWLC(config-wireless-image-download-profile)# image-download mode tftp
</span></span><span class="line"><span class="cl">0xC9800eWLC(config-wireless-image-download-profile-tftp)# tftp-image-server &lt;IP address&gt;
</span></span><span class="line"><span class="cl">0xC9800eWLC(config-wireless-image-download-profile-tftp)# tftp-image-path &lt;path to image files&gt;
</span></span></code></pre></div><p>With that, any new APs that join our WLC should be able to auto-load the software necessary.</p>
<hr>
<p>Thanks for reading!</p>
]]></content:encoded>
    </item>
    <item>
      <title>How to: Catalyst 9800 MAC Filtering</title>
      <link>https://0x2142.com/how-to-catalyst-9800-mac-filtering/</link>
      <pubDate>Tue, 12 Nov 2019 15:35:07 +0000</pubDate>
      <guid>https://0x2142.com/how-to-catalyst-9800-mac-filtering/</guid>
      <description>A tutorial on configuring MAC address filtering on a Cisco 9800 WLC</description>
      <content:encoded><![CDATA[<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/rWupjgsF0HM?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<p><strong>Update 2020 / 05 / 19</strong> - I&rsquo;ve added a video above that walks through the steps detailed in this blog post.</p>
<blockquote>
<p>If you&rsquo;re using the &lsquo;Basic&rsquo; Wireless setup, you may see an error when trying to apply the policy: &ldquo;switch 1 dbm wireless Use of default ACL preauth v4 is not permitted&rdquo;</p>
<p>If you come across this error, it&rsquo;s a known bug (<a href="https://quickview.cloudapps.cisco.com/quickview/bug/CSCvt18875">CSCvt18875</a>) specific to only the &lsquo;Basic&rsquo; setup wizard (which is what I used in this post below). If so, check out the video above which walks through the &lsquo;Advanced&rsquo; setup and bypasses this error.</p></blockquote>
<hr>
<p>I&rsquo;ve been spending a bit of time over the past few weeks building up a wireless lab. Trying to get a good understanding of how the new Catalyst 9800 wireless controller works, and how it differs from some of the previous iterations.</p>
<p>In order to play around with the new controller, I decided to try to build a new configuration that mimics my current home wireless. Today I am using Ubiquiti APs, which come with their own free controller software. Most of my current config is fairly straightforward - a few SSIDs, two APs, and a guest network with captive portal. One of my SSIDs is dedicated to any IoT devices and is more restrictive than the other networks. This network uses both a pre-shared key for authentication as well as MAC-based filtering.</p>
<p>In this post - we&rsquo;ll walk through how to set up a new SSID with client MAC filtering.</p>
<p><em>Note: This was written using Catalyst 9800-CL version 16.12.1s. APs are configured in flexconnect with local authentication (no AAA, ISE, etc)</em></p>
<hr>
<p>While this post is not focused on in-depth WLAN config, we will start by quickly setting up a new network.</p>
<p>Once you get logged into the controller - we&rsquo;ll click on the <strong>Wireless Setup</strong> icon in the upper right-hand side. Then drop down to the <strong>Basic</strong> option:</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-01.jpg#center"></p>
<p>This takes us through a pretty quick and easy wizard to set up our new location &amp; wireless networks. At first, we will have no locations configured - so we will click <strong>Add:</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-02-.jpg#center"></p>
<p>We&rsquo;ll start off building our location by giving it a name and description. These are used for some naming of policy objects within the WLC, so make sure to use a name that makes sense.</p>
<p>In my case, I&rsquo;m also going with a flexconnect deployment - so we&rsquo;ll select that option and also provide the AP native VLAN.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-03.png#center"></p>
<p>Next, we&rsquo;ll click over to the <strong>Wireless Networks</strong> tab. This is where we will create our WLAN and apply the initial configuration. We don&rsquo;t have any networks yet, so click <strong>Add</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-04.jpg#center"></p>
<p>The two primary things we need to address are highlighted in red below. We need to create a WLAN and assign it to a VLAN. Let&rsquo;s start with the WLAN by clicking <strong>Define new.</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-05.png#center"></p>
<p>On the <strong>General</strong> tab, we&rsquo;ll give this WLAN a profile name and a SSID.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-06.jpg#center"></p>
<p>Next, we&rsquo;ll hop on over to the <strong>Security</strong> tab, and focus on the <strong>Layer 2</strong> sub-tab. The first thing I want to point out - is that at this point, we will not be enabling the <strong>MAC Filtering</strong> checkbox. We&rsquo;ll need some additional config first, then come back to this later.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-07.jpg#center"></p>
<p>Scroll down to the bottom of the window and there will be some settings for your authentication. By default, <strong>802.1x</strong> will be enabled. This post won&rsquo;t cover how to setup/configure that. Instead, we&rsquo;ll be deselecting <strong>802.1x</strong> and checking the box for <strong>PSK.</strong> Then a text field will appear for us to enter the <strong>Pre-Shared Key</strong>.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-08.jpg#center"></p>
<p>Once we click <strong>Apply to Device</strong>, we&rsquo;ll finish up by assigning our <strong>VLAN or VLAN Group</strong>. In this case, I have already created a VLAN named <strong>IoT</strong>. If you haven&rsquo;t created a VLAN yet, you can do so by going to <strong>Configuration</strong> &gt; <strong>Layer 2</strong> &gt; <strong>VLAN.</strong> Then add a new VLAN under the <strong>VLAN</strong>tab.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-09.png#center"></p>
<p>Click <strong>Add</strong>, then we&rsquo;ll be back to the wizard and see the new WLAN we just created.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-10.jpg#center"></p>
<p>In order to finish up with the wizard, we just need to assign our Access Points. Click on the <strong>AP Provisioning</strong> tab. If you have already configured APs to join to this controller, you will see them on the left side under <strong>Available APs</strong>. Check which ones to apply this WLAN to, then click the arrow to move them to <strong>APs on this location.</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-11.jpg#center"></p>
<p>Click <strong>Apply</strong>, and that will finalize all of the configuration we just did - then drop us back to the <strong>Wireless Setup</strong> page.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/New-wireless-net-12.jpg#center"></p>
<p>Okay - Now that we have that completed, we can move onto creating our MAC filtering policies.</p>
<p>Back in the menu - Let&rsquo;s go to <strong>Configuration</strong> &gt; <strong>Security</strong> &gt; <strong>AAA</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-01.jpg#center"></p>
<p>In this section - we first need to create an Authorization policy. Select the <strong>AAA Method List</strong> tab, then <strong>Authorization</strong>, then <strong>Add</strong> to create the new policy.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-02.jpg#center"></p>
<p>In here we&rsquo;ll specify a name, then select <strong>Type: network</strong>, and <strong>Group Type: local</strong>. Then go ahead and <strong>Apply to Device</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-03.jpg#center"></p>
<p>Once we have that, let&rsquo;s go over to the <strong>AAA Advanced</strong> tab, and click <strong>Add</strong> in the <strong>Attribute List Name</strong> section.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-04.jpg#center"></p>
<p>Here we need to provide the SSID we want our MAC policy to apply to. Under <strong>Attribute Type</strong>, select <strong>SSID.</strong> Then under <strong>Attribute Value</strong>, select the target SSID that our policy will be tied to.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-05.jpg#center"></p>
<p>Don&rsquo;t forget to click <strong>Save</strong> on the attribute before clicking <strong>Apply to Device</strong>!</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-06.jpg#center"></p>
<p>Time to input our list of device MAC addresses! Drop into the <strong>Device Authentication</strong> section, and click <strong>Add</strong> - or upload a CSV file if you have one.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-07.jpg#center"></p>
<p>Input the device <strong>MAC Addrees</strong> and select the <strong>Attribute List Name</strong> that we configured just a minute ago. Then <strong>Apply to Device</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-08-1.jpg#center"></p>
<p>After that - we should have our completed list of MAC addresses which will be permitted to join our wireless network. All we need to do is go back to our WLAN and enable MAC filtering.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/mac-auth-09.jpg#center"></p>
<p>Let&rsquo;s go to <strong>Configuration</strong> &gt; <strong>Tags &amp; Profiles</strong> &gt; <strong>WLANs</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/config-wlans-01.jpg#center"></p>
<p>This should give us the list of any configured WLANS - including the one we created earlier. Go ahead and click on it to edit.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/config-wlans-02.jpg#center"></p>
<p>Next, we&rsquo;ll jump straight to the <strong>Layer 2</strong> section under the <strong>Security</strong> tab. Check the box for <strong>MAC Filtering</strong> and select the <strong>Authorization List</strong> we created from the drop down.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/11/config-wlans-03.jpg#center"></p>
<p>And we&rsquo;re done! Clients that want to join our newly created SSID will need the pre-shared key we configured, but they will also need to be manually added to our MAC address filter as well.  While this isn&rsquo;t a perfect security measure since MAC addresses can be easily spoofed - it does add an extra layer of protection to keep unauthorized devices from inadvertently being able to join this specific WLAN.</p>
<hr>
<p>In the event that a client is NOT on the authorized list, you may see the following logs in a client debug:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">2019/10/25 22:26:12.327 {wncd_x_R0-0}{1}: &amp;#91;client-orch-sm] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Association received. BSSID aaaa.aaaa.b34d, old BSSID 0000.0000.0000, WLAN SuperSecret, Slot 1 AP aaaa.aaaa.b340, AP_3802-1F01
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.327 {wncd_x_R0-0}{1}: &amp;#91;client-orch-state] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Client state transition: S_CO_INIT -&gt; S_CO_ASSOCIATING
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.328 {wncd_x_R0-0}{1}: &amp;#91;client-orch-state] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Client state transition: S_CO_ASSOCIATING -&gt; S_CO_MACAUTH_IN_PROGRESS
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.328 {wncd_x_R0-0}{1}: &amp;#91;client-auth] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  MAB Authentication initiated. Policy VLAN 0, AAA override = 0, NAC = 0
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.329 {wncd_x_R0-0}{1}: &amp;#91;ewlc-infra-evq] &amp;#91;22573]: (note): Authentication Success. Resolved Policy bitmap:11 for client aaaa.aaaa.aaaa 
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.329 {wncd_x_R0-0}{1}: &amp;#91;ewlc-infra-evq] &amp;#91;22573]: (ERR): SANET_AUTHC_FAILURE - AAA Server Down username ac37434a673a, audit session id 000000000000006B3E9D2A55, 
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.331 {wncd_x_R0-0}{1}: &amp;#91;client-orch-state] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Client state transition: S_CO_MACAUTH_IN_PROGRESS -&gt; S_CO_ASSOCIATING
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.331 {wncd_x_R0-0}{1}: &amp;#91;dot11] &amp;#91;22573]: (ERR): MAC: aaaa.aaaa.aaaa  Failed to assoc failure tr state entry. Incorrect validation status value :1
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.331 {wncd_x_R0-0}{1}: &amp;#91;dot11] &amp;#91;22573]: (ERR): MAC: aaaa.aaaa.aaaa  Dot11 update co assoc fail. Sent assoc failure to CO. delete reason: 9, CO_CLIENT_DELETE_REASON_MAB_FAILED
</span></span><span class="line"><span class="cl">2019/10/25 22:26:12.331 {wncd_x_R0-0}{1}: &amp;#91;client-orch-sm] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Client delete initiated. Reason: CO_CLIENT_DELETE_REASON_MAB_FAILED, fsm-state transition
</span></span></code></pre></div><p>On the opposite side, when a client is successfully able to pass MAC authentication - the logs will show the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">2019/10/25 21:25:53.148 {wncd_x_R0-0}{1}: &amp;#91;client-auth] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  MAB Authentication initiated. Policy VLAN 0, AAA override = 0, NAC = 0
</span></span><span class="line"><span class="cl">2019/10/25 21:25:53.150 {wncd_x_R0-0}{1}: &amp;#91;ewlc-infra-evq] &amp;#91;22573]: (note): Authentication Success. Resolved Policy bitmap:11 for client aaaa.aaaa.aaaa 
</span></span><span class="line"><span class="cl">2019/10/25 21:25:53.151 {wncd_x_R0-0}{1}: &amp;#91;client-auth] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  MAB Authentication success.
</span></span><span class="line"><span class="cl">2019/10/25 21:25:53.151 {wncd_x_R0-0}{1}: &amp;#91;client-orch-state] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Client state transition: S_CO_MACAUTH_IN_PROGRESS -&gt; S_CO_ASSOCIATING
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.626 {wncd_x_R0-0}{1}: &amp;#91;client-orch-sm] &amp;#91;22573]: (debug): MAC: aaaa.aaaa.aaaa  Received Dot11 association request. Processing started,SSID: SuperSecret2, Policy profile: Home_WLANID_3, AP Name: AP_3802-3F01, Ap Mac Address: aaaa.aaaa.c9a0 BSSID MAC aaaa.aaaa.b34d wlan ID: 3RSSI: 0, SNR: 32
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.626 {wncd_x_R0-0}{1}: &amp;#91;client-orch-state] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Client state transition: S_CO_L2_AUTH_IN_PROGRESS -&gt; S_CO_L2_AUTH_IN_PROGRESS
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.626 {wncd_x_R0-0}{1}: &amp;#91;dot11] &amp;#91;22573]: (info): MAC: aaaa.aaaa.aaaa  DOT11 state transition: S_DOT11_ASSOCIATED -&gt; S_DOT11_MAB_PENDING
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.626 {wncd_x_R0-0}{1}: &amp;#91;client-orch-state] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Client state transition: S_CO_L2_AUTH_IN_PROGRESS -&gt; S_CO_MACAUTH_IN_PROGRESS
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.626 {wncd_x_R0-0}{1}: &amp;#91;client-auth] &amp;#91;22573]: (info): MAC: aaaa.aaaa.aaaa  Client auth-interface state transition: S_AUTHIF_ADD_MOBILE_ACK_WAIT_KM -&gt; S_AUTHIF_MAB_AUTH_DONE
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.626 {wncd_x_R0-0}{1}: &amp;#91;client-orch-sm] &amp;#91;22573]: (debug): MAC: aaaa.aaaa.aaaa  Processing MAB authentication result status: 0, CO_AUTH_STATUS_SUCCESS
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.626 {wncd_x_R0-0}{1}: &amp;#91;client-orch-state] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Client state transition: S_CO_MACAUTH_IN_PROGRESS -&gt; S_CO_ASSOCIATING
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.626 {wncd_x_R0-0}{1}: &amp;#91;dot11] &amp;#91;22573]: (debug): MAC: aaaa.aaaa.aaaa  dot11 send association response. Sending association response with resp_status_code: 0 
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.627 {wncd_x_R0-0}{1}: &amp;#91;dot11] &amp;#91;22573]: (info): MAC: aaaa.aaaa.aaaa  dot11 send association response. Sending assoc response of length: 137 with resp_status_code: 0, DOT11_STATUS: DOT11_STATUS_SUCCESS
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.627 {wncd_x_R0-0}{1}: &amp;#91;dot11] &amp;#91;22573]: (note): MAC: aaaa.aaaa.aaaa  Association success. AID 1, Roaming = True, WGB = False, 11r = False, 11w = False
</span></span><span class="line"><span class="cl">2019/10/25 21:30:08.627 {wncd_x_R0-0}{1}: &amp;#91;dot11] &amp;#91;22573]: (info): MAC: aaaa.aaaa.aaaa  DOT11 state transition: S_DOT11_MAB_PENDING -&gt; S_DOT11_ASSOCIATED
</span></span></code></pre></div>]]></content:encoded>
    </item>
    <item>
      <title>Getting Started with Cisco NFVIS</title>
      <link>https://0x2142.com/getting-started-with-cisco-nfvis/</link>
      <pubDate>Sat, 13 Apr 2019 12:59:00 +0000</pubDate>
      <guid>https://0x2142.com/getting-started-with-cisco-nfvis/</guid>
      <description>A quick look at how to spin up NFVIS on a Cisco ENCS</description>
      <content:encoded><![CDATA[<p>A few weeks ago I got my hands on a Cisco UCS C220 M4 server - which I&rsquo;ve set up in a lab to install and test Cisco&rsquo;s Network Function Virtualization Infrastructure Software (NFVIS). I really wanted to get this running on an Enterprise Network Compute System (ENCS) box, but you can&rsquo;t always get everything what you want :). The UCS machine is also on the list of supported platforms, so we&rsquo;ll use that - but everything here should apply similarly to the ENCS platform.</p>
<h2 id="what-is-nfvis">What is NFVIS?</h2>
<p>NFVIS is an operating system developed by Cisco which is intended to be deployed at branch office locations - and allow for quick deployment of network services in lightweight VMs. For example, we might want to reduce cost and hardware footprint by deploying a single ENCS machine, then deploy our typical branch services on top of that (DNS, Firewalls, SDWAN, etc). Under the hood, NFVIS is built on top of CentOS and KVM.</p>
<p>In the image below, we have an ENCS unit that is running ISRv, FTDv, and a vEdge Cloud. NFVIS has the ability to build out traffic flows for service chaining. In this particular setup, we could have all branch traffic receive a default route up to our ISRv. The ISRv forwards traffic to a Firepower VM (FTDv) which performs some traffic inspection before passing everything up to the vEdge Cloud.</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/image.png#center"></p>
<p>We&rsquo;ll be coming back to this diagram later to see how we can build out this flow of services. For now, let&rsquo;s dive into how we can get NFVIS up and running.</p>
<h2 id="installing-nfvis">Installing NFVIS</h2>
<p>Lucky for us - the installation of NFVIS is fairly straightforward!</p>
<ol>
<li>Create a bootable USB - or mount the installation ISO via CIMC</li>
<li>Upon boot, select &ldquo;Install Cisco NFV Infrastructure Software&rdquo;:</li>
</ol>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/000-install.png#center"></p>
<ol start="3">
<li>Wait. A while. Install time can vary depending on your hardware.</li>
<li>Once completed, log into the CLI: Default login = admin/Admin123#</li>
<li>You&rsquo;ll be prompted to change the default admin password immediately:</li>
</ol>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/image-1.png#center"></p>
<p>Install completed! Now let&rsquo;s look at some of our base configuration..</p>
<h2 id="initial-configuration">Initial Configuration</h2>
<p>By default the NFVIS install will have a LAN and WAN bridge (lan-br and wan-br, respectively). The LAN config will be set up with a static IP of 192.168.1.1/24, and the WAN will be set for DHCP. We can check the current network settings by running the <em>show system settings</em>command:</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/image-2.png#center"></p>
<p>In this case, my WAN interface is able to get an IP via DHCP. We&rsquo;re likely going to want to change this to a static IP address - which we can do from the CLI or web interface. Let&rsquo;s start by trying this from the CLI:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">config t
</span></span><span class="line"><span class="cl">system settings wan ip address &lt;ip addr&gt; &lt;netmask&gt;
</span></span><span class="line"><span class="cl">system settings default-gw &lt;gateway addr&gt;
</span></span><span class="line"><span class="cl">system settings hostname &lt;hostname&gt;
</span></span></code></pre></div><p>Changes can then be applied using the <strong>commit</strong> command</p>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/image-3.png#center"></p>
<p>We can verify these settings by repeating the <code>show system settings</code> command we used earlier.</p>
<p>Let&rsquo;s go ahead and log into the web interface to see what the network configuration looks like there:</p>
<ol>
<li>If we know our WAN or LAN IP from earlier, we can just pop that in our web browser.</li>
<li>Go ahead and log in using the new admin credentials we just created:</li>
</ol>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/image-4.png#center"></p>
<ol start="3">
<li>We&rsquo;ll be taken to the primary NFVIS dashboard, which will currently show no active VMs deployed:</li>
</ol>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/image-5.png#center"></p>
<ol start="4">
<li>In the left-hand menu, expand <strong>Host</strong>then click on <strong>Settings:</strong></li>
</ol>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/image-6.png#center"></p>
<p>Here we can see that we already configured our IP Addressing/hostname - but we could use the <strong>Edit</strong> button at the bottom to change any of these values. For example - I&rsquo;m going to go ahead and select <strong>Static</strong> for both the Management (LAN) and WAN IP addresses.</p>
<p>Another quick tip - if we need to modify which physical network adapters are tied to an internal network bridge, we can find that under <strong>VM Life Cycle &gt; Networking:</strong></p>
<p><img alt="image" loading="lazy" src="/content/images/2019/03/image-7.png#center"></p>
<hr>
<p>That&rsquo;s all for this time. In the next post, we&rsquo;ll take a look at how to package VM images and deploy our service chain.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
