<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feeds.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://chameth.com/">
    <title>Chameth.com - posts like dns-over-tls-on-edgerouter-lite, utility-user-stories but not why-you-should-be-using-https</title>
    <subtitle>Personal homepage of Chris Smith</subtitle>
    <link href="https://chameth.com/feeds/posts/like/dns-over-tls-on-edgerouter-lite,utility-user-stories/unlike/why-you-should-be-using-https/" rel="self"/>
    <link href="https://chameth.com/"/>
    <icon>https://chameth.com/favicon.png</icon>
    <updated>2021-10-16T00:00:00Z</updated>
    <id>https://chameth.com/</id>
    <author>
        <name>Chris Smith</name>
    </author>
    <entry>
        <title>On the utility of user stories</title>
        <link href="https://chameth.com/utility-user-stories/"/>
        <updated>2021-10-16T00:00:00Z</updated>
        <id>https://chameth.com/utility-user-stories/</id>
        <content xml:lang="en" type="html">&lt;p&gt;User stories are a staple of most agile methodologies. You’d be hard-pressed to find
an experienced software developer that’s not come across them at some point in their
career. In case you haven’t, they look something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a frequent customer, &lt;br/&gt;
I want to be able to browse my previous orders, &lt;br/&gt;
So that I can quickly re-order products.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They provide a persona (in this case “a frequent customer”), a goal (“browse my previous
orders”) and a reason (“so that I can quickly re-order products”). This fictitious user
story would probably rank among one of the better ones I’ve seen. More typically you end
up with something like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a user, &lt;br/&gt;
I want to be able to login,&lt;br/&gt;
So that I can browse while logged in.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This doesn’t really provide a persona or any proper reasoning. It’s just a straight-forward
task pretending to be a user story. If this is written in an issue then it provides no
extra information over one that simply says “Allow users to login”. In fact, because it’s
expressed so awkwardly I’d argue that it’s worse.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;This kind of task-disguised-as-a-user-story problem becomes more obvious when people try
to write technical tasks in the same way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a developer,&lt;br/&gt;
I want to refactor the JobFactory,&lt;br/&gt;
So that I can work with it more efficiently in the future.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This just says “Refactor the JobFactory”. If you wrote that in a ticket you’d probably
feel bad for not describing it very well, but somehow when it’s dressed up as a user
story it feels more valuable.&lt;/p&gt;
&lt;h3 id=&#34;does-the-user-really-want-that&#34;&gt;Does the user really want that?&lt;/h3&gt;
&lt;p&gt;One thing that really irks me about user stories is that it lets you twist your
business objectives into sounding like they’re the user’s idea: the story becomes
a post-hoc justification for a task you decided was required.&lt;/p&gt;
&lt;p&gt;Say you’re making a mobile app for an online book store, and your team for whatever
reason has a target of increasing the number of users who view the daily book-of-the-day
offer. Maybe you do some interviews and users tell you they forget to check in each
day to see what the offer is. How can you funnel more users there?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As a mobile app user, &lt;br/&gt;
I want to receive a push notification whenever a new book-of-the-day is available, &lt;br/&gt;
So that I have the chance to buy the book.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some users probably do want such a thing, but I’d argue the vast majority of them
do not. Imagine if every app on your phone alerted you whenever there was a new
deal, or popped up a dialog whenever you went near a physical shop they had
vouchers for…&lt;/p&gt;
&lt;p&gt;Obviously in the cold reality of capitalism businesses make money by doing things
not strictly in the interests of users&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. When written up like this it becomes so
painfully disingenuous, though. Despite writing a user story that starts with
the words “As a user”, you’re not really putting yourself in the user’s shoes.&lt;/p&gt;
&lt;h3 id=&#34;who-even-is-the-user&#34;&gt;Who even is the user?&lt;/h3&gt;
&lt;p&gt;One of the big benefits of user stories comes from using &lt;em&gt;personas&lt;/em&gt;
to describe users. It’s also one of the things that’s rarely actually done, at
least in my experience. Looking at Google Trends you can see the rise of searches
for “user story” as agile slowly takes over the world, but the movement in
searches about personas is very slight:&lt;/p&gt;
&lt;figure class=&#34;image center&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/utility-user-stories/google-trends-story-persona.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/utility-user-stories/google-trends-story-persona.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/utility-user-stories/google-trends-story-persona.png&#34; alt=&#34;Graph showing relative search frequency for user stories against user personas&#34; loading=&#34;lazy&#34; width=&#34;1000&#34; height=&#34;550&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Graph showing relative search frequency for user stories against user personas&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A lot of the time stories are just written with “As a user”, or have some
adjectives tacked on to the start (“as a mobile user”, “as a logged-in user”).
The best I’ve ever seen in the wild was specifying the class of user like
in the example at the start: “as a frequent customer”, or “as a visually impaired user”.&lt;/p&gt;
&lt;p&gt;The problem with using these classes is it requires you to come up with them
when you’re writing the story. Maybe one day you think about visually impaired
users, but the next you don’t. Maybe Bob thinks about certain classes of users,
but Alice concentrates on different ones.&lt;/p&gt;
&lt;p&gt;The ideal way to solve this is to come up with personas that all the team
understand. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kiera is addicted to books. She reads across genres, and often buys books
to gift to her friends and family. She has piles and piles of books to
read, but that doesn’t stop her ordering more if she sees a good deal.
She likes receiving new books almost as much as reading them, and opts
for the fastest delivery available.&lt;/li&gt;
&lt;li&gt;Sharon is a slow, methodical reader. She buys one book at a time when she’s
close to finishing her current one, and gifts or resells her old books.
She almost exclusively reads Science Fiction, and will generally read
complete series from start to finish. She’s short-sighted and often
struggles when using mobile phones or computers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You’d probably want 2-4 personas that collectively represent most facets of your
userbase. They can be a lot more fleshed out than these - if you search for
example user personas you’ll find many beautifully presented examples that
have complete backgrounds including hobbies, education levels, and so on.
Even with this minimal level of detail, though, I’d argue they’re more useful
than just writing things in a standard user story form.&lt;/p&gt;
&lt;p&gt;Thinking back to the story about push notifications, writing it to use one
of these two personas forces you to think about the trade-offs involved. Kiera
probably &lt;em&gt;would&lt;/em&gt; like a notification, but it would annoy and possibly confuse
Sharon. This then leads you down the path of considering how to accommodate
both types of user — maybe adding it as an option, or doing some fancy machine
learning, etc. The conversation is now focused around the users, rather than
steamrolling over them to reach a business objective.&lt;/p&gt;
&lt;h3 id=&#34;youre-holding-it-wrong&#34;&gt;You’re holding it wrong&lt;/h3&gt;
&lt;p&gt;The problems I’ve described are not a problem with user stories &lt;em&gt;per se&lt;/em&gt;, but
rather common issues with how they’re used. But there’s only so many times you
can tell people they’re holding a tool wrong before you have to accept that maybe
the tool was badly designed.&lt;/p&gt;
&lt;p&gt;Considering features from the perspective of multiple personas is the single
best thing you can possibly do to ensure you’re providing value to your users.
You don’t even need to write things in the typical user story style to benefit
from this.&lt;/p&gt;
&lt;p&gt;Tacking “As a user,” to the start of all your JIRA tickets isn’t being agile,
and isn’t good for users, even if it lets you tick a box somewhere. In some
cases this lip-service to users is actively detrimental to them. We should
be valuing users and personas over stilted templates and check-box exercises
(&lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;remind you of anything?&lt;/a&gt;).&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;As a user, I want to pay more money for the things that I buy,
so that the company’s CEO can afford to go to space. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
    <entry>
        <title>DNS-over-TLS on the EdgeRouter Lite</title>
        <link href="https://chameth.com/dns-over-tls-on-edgerouter-lite/"/>
        <updated>2017-12-17T00:00:00Z</updated>
        <id>https://chameth.com/dns-over-tls-on-edgerouter-lite/</id>
        <content xml:lang="en" type="html">&lt;figure class=&#34;image left&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/dns-over-tls-on-edgerouter-lite/edgerouter.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/dns-over-tls-on-edgerouter-lite/edgerouter.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/dns-over-tls-on-edgerouter-lite/edgerouter.jpg&#34; alt=&#34;An EdgeRouter Lite&#34; loading=&#34;lazy&#34; width=&#34;500&#34; height=&#34;375&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;An EdgeRouter Lite&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;DNS-over-TLS is a fairly recent specification described in
&lt;a href=&#34;https://tools.ietf.org/html/rfc7858&#34;&gt;RFC7858&lt;/a&gt;, which enables DNS clients to
communicate with servers over a TLS (encrypted) connection instead of requests
and responses being sent in plain text. I won’t ramble on about why it’s a good
thing that your ISP, government, or neighbour can’t see your DNS requests…&lt;/p&gt;
&lt;p&gt;I use an &lt;a href=&#34;https://www.ubnt.com/edgemax/edgerouter-lite/&#34;&gt;EdgeRouter Lite&lt;/a&gt; from
Ubiquiti Networks at home, and recently configured it to use DNS-over-TLS for
all DNS queries. Here’s how I did it.&lt;/p&gt;
&lt;h3 id=&#34;installing-unbound&#34;&gt;Installing unbound&lt;/h3&gt;
&lt;p&gt;Out of the box, the ERL uses &lt;code&gt;dnsmasq&lt;/code&gt; to service DNS requests from local
clients. To get DNS-over-TLS support I switched to using
&lt;a href=&#34;https://unbound.net/&#34;&gt;Unbound&lt;/a&gt;, an open source DNS resolver with support
for many modern features such as DNSSEC and DNS-over-TLS.&lt;/p&gt;
&lt;!--more--&gt;
&lt;aside class=&#34;update raised-box&#34;&gt;
  &lt;h5 class=&#34;plain-header&#34;&gt;Update 2017-05-31:&lt;/h5&gt;
  &lt;p&gt;Before installing unbound, if you haven’t done so before, you will need to enable the apt
repositories as described in the &lt;a href=&#34;https://help.ubnt.com/hc/en-us/articles/205202560-EdgeRouter-Add-other-Debian-packages-to-EdgeOS&#34;&gt;Ubiquiti help center&lt;/a&gt;.
Thanks to &lt;a href=&#34;https://twitter.com/ozaed/status/960615650489233408&#34;&gt;@ozaed&lt;/a&gt; for the tip.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Installing unbound on the ERL is a simple case of SSHing in, and then:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;sudo apt-get install unbound
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And then configuring the ERL to use the new local resolver for DNS requests,
turn off dnsmasq, and tell DHCP clients to send DNS requests to it
(obviously substituting network names and subnets as appropriate):&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set system name-server 127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service dhcp-server shared-network-name lan1 subnet 192.168.1.0/24 dns-server 192.168.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service dhcp-server use-dnsmasq disable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service dns
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point DNS should still work, but Unbound will still be sending requests
out in plaintext.&lt;/p&gt;
&lt;h3 id=&#34;configuration&#34;&gt;Configuration&lt;/h3&gt;
&lt;p&gt;The unbound configuration lives in &lt;code&gt;/etc/unbound/unbound.conf&lt;/code&gt;, here’s a basic
example that I use to enable DNS-over-TLS:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-c&#34;&gt;# Unbound configuration file for Debian.&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-c&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-c&#34;&gt;# See the unbound.conf(5) man page.&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-c&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-c&#34;&gt;# See /usr/share/doc/unbound/examples/unbound.conf for a commented&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-c&#34;&gt;# reference config file.&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-nt&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;auto-trust-anchor-file&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;/var/lib/unbound/root.key&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;verbosity&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;interface&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;0.0.0.0&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;interface&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;port&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;53&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;do-ip4&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;do-ip6&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;do-udp&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;do-tcp&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;access-control&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;192.168.0.0&lt;/span&gt;&lt;span class=&#34;chroma-l&#34;&gt;/16 allow&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;access-control&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;127.0.0.0&lt;/span&gt;&lt;span class=&#34;chroma-l&#34;&gt;/8 allow&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;access-control&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;10.0.0.0&lt;/span&gt;&lt;span class=&#34;chroma-l&#34;&gt;/8 allow&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;root-hints&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;/var/lib/unbound/root.hints&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;hide-identity&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;hide-version&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;harden-glue&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;harden-dnssec-stripped&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;cache-min-ttl&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;900&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;cache-max-ttl&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;14400&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;prefetch&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;rrset-roundrobin&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;ssl-upstream&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;use-caps-for-id&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-kc&#34;&gt;yes&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;private-address&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;192.168.0.0&lt;/span&gt;&lt;span class=&#34;chroma-l&#34;&gt;/16&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;private-address&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;172.16.0.0&lt;/span&gt;&lt;span class=&#34;chroma-l&#34;&gt;/12&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;private-address&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;10.0.0.0&lt;/span&gt;&lt;span class=&#34;chroma-l&#34;&gt;/8&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;logfile&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;/var/lib/unbound/unbound.log&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;verbosity&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;val-log-level&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-nt&#34;&gt;forward-zone&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nt&#34;&gt;forward-addr&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-m&#34;&gt;9.9.9.9&lt;/span&gt;@&lt;span class=&#34;chroma-m&#34;&gt;853&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice the server directive &lt;code&gt;ssl-upstream&lt;/code&gt;, and that the forward zone specifies
the &lt;a href=&#34;https://www.quad9.net/&#34;&gt;quad9&lt;/a&gt; resolver on its TLS port (853).&lt;/p&gt;
&lt;h4 id=&#34;dnssec&#34;&gt;DNSSEC&lt;/h4&gt;
&lt;p&gt;To enable Unbound to validate DNSSEC signatures, we need to provide it with
some information about the root nameservers that we trust. First, download the
list of root nameservers to the &lt;code&gt;root-hints&lt;/code&gt; file specified in the unbound
config:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;wget ftp://FTP.INTERNIC.NET/domain/named.cache -O /var/lib/unbound/root.hints
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we need to add the root keys to the &lt;code&gt;auto-trust-anchor-file&lt;/code&gt;. The trust
anchor at the time of writing is below, but you can get the latest values from
the &lt;a href=&#34;https://data.iana.org/root-anchors/&#34;&gt;IANA&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;.       172800  IN      DNSKEY  257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQu
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;.       172800  IN      DNSKEY  257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuY
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;redirecting-unencrypted-requests&#34;&gt;Redirecting unencrypted requests&lt;/h3&gt;
&lt;p&gt;I have a slew of devices on my network that, over time, I have configured to
use 8.8.8.8 as a DNS server. They’re not going to care about the DHCP reply,
and I don’t really feel like going around checking every weird and wonderful
internet-connected device in the house, so I decided to just intercept requests
to 8.8.8.8 and send them to Unbound. A simple NAT rule does the trick:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 description &amp;#34;HonestDNS Redirect&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 destination address 8.8.8.8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 destination port 53
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 inbound-interface eth0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 inside-address address 192.168.1.1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 inside-address port 53
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 log disable
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 protocol tcp_udp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;set service nat rule 1 type destination
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You could of course redirect any traffic to port 53, but that would prevent you
from explicitly querying any other DNS server. By just intercepting traffic to
8.8.8.8 I’m taking care of the vast majority of my statically configured
devices, and can still issue manual queries to other resolvers when needed.&lt;/p&gt;
&lt;h3 id=&#34;validating&#34;&gt;Validating&lt;/h3&gt;
&lt;p&gt;To check that everything is working, you can use &lt;code&gt;tcpdump&lt;/code&gt; on the router to
inspect packets on the WAN interface directed at port 53:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;sudo tcpdump -Xi eth0 port 53
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should, hopefully, not see anything.&lt;/p&gt;
</content>
    </entry>
</feed>
