<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="www.adogslaboratory.net/feed.xml" rel="self" type="application/atom+xml" /><link href="www.adogslaboratory.net/" rel="alternate" type="text/html" /><updated>2026-10-18T19:28:17-07:00</updated><id>www.adogslaboratory.net/feed.xml</id><title type="html">a dog’s laboratory</title><subtitle>
The dog-in-charge has many active projects. I am tasked with organizing his research.</subtitle><entry><title type="html">changing the auto-save directory in emacs</title><link href="www.adogslaboratory.net/2026/09/13/changing-the-autosave-directory-in-emacs.html" rel="alternate" type="text/html" title="changing the auto-save directory in emacs" /><published>2026-09-13T00:00:00-07:00</published><updated>2026-09-13T00:00:00-07:00</updated><id>www.adogslaboratory.net/2026/09/13/changing-the-autosave-directory-in-emacs</id><content type="html" xml:base="www.adogslaboratory.net/2026/09/13/changing-the-autosave-directory-in-emacs.html"><![CDATA[<p>I’m using git and emacs at the same time and I’ve run into an issue
regarding the emacs auto-save options.</p>

<p>When I switch from one git branch to another emacs autosaves the files
I’ve been working on using <code class="language-plaintext highlighter-rouge">#&lt;file-name&gt;#</code> and the lock-file
using <code class="language-plaintext highlighter-rouge">.#&lt;file-name&gt;</code>. These files show up as un-tracked files when 
I run <code class="language-plaintext highlighter-rouge">git status</code>. They can be added to <code class="language-plaintext highlighter-rouge">.gitignore</code> but they will
still clutter up the directory tree.</p>

<p>The solution I landed on is to configure emacs to auto-save these files
in a different directory. I use <code class="language-plaintext highlighter-rouge">~/.emacs.d/auto-save/</code>.</p>

<p>This is the command in <code class="language-plaintext highlighter-rouge">init.el</code>:</p>

<figure class="highlight"><pre><code class="language-elisp" data-lang="elisp"><span class="c1">;; Save auto-save files to ~/.emacs.d/auto-save/</span>
<span class="p">(</span><span class="k">setq</span> <span class="nv">auto-save-file-name-transforms</span>
      <span class="o">`</span><span class="p">((</span><span class="s">".*"</span> <span class="o">,</span><span class="nv">concat</span> <span class="nv">user-emacs-directory</span> <span class="s">"auto-save/"</span><span class="p">)</span> <span class="no">t</span><span class="p">))</span></code></pre></figure>]]></content><author><name></name></author><category term="git" /><category term="emacs" /><category term="elisp" /><summary type="html"><![CDATA[I’m using git and emacs at the same time and I’ve run into an issue regarding the emacs auto-save options.]]></summary></entry><entry><title type="html">the process of creating TLS credentials</title><link href="www.adogslaboratory.net/2026/09/12/the-process-of-creating-TLS-credentials.html" rel="alternate" type="text/html" title="the process of creating TLS credentials" /><published>2026-09-12T00:00:00-07:00</published><updated>2026-09-12T00:00:00-07:00</updated><id>www.adogslaboratory.net/2026/09/12/the-process-of-creating-TLS-credentials</id><content type="html" xml:base="www.adogslaboratory.net/2026/09/12/the-process-of-creating-TLS-credentials.html"><![CDATA[<p>I’ve been setting up a vpn network using OpenVPN. The dog-in-charge demands
that I implement Transport Layer Security (TLS). TLS requires creating a series of
certifications and keys which can then be referenced from a VPN configuration
file.</p>

<p>This post is about the <em>process</em> of implementing TLS. It is not about the <em>tools</em>,
i.e. the command-line instructions, that are available for implementing TLS. The
<em>tools</em> will be discussed in another post.</p>

<h3 id="the-certificate-authority">The Certificate Authority</h3>

<p>Transport Layer Security begins with a Certificate Authority (CA). The CA has two
parts: a private key, stored in the file <code class="language-plaintext highlighter-rouge">ca.key</code>, and a public certificate,
stored in the file <code class="language-plaintext highlighter-rouge">ca.crt</code>. Those file names are arbitrary–you can call them anything
you want–but those are the names commonly used on the interwebs for talking about them.</p>

<p><code class="language-plaintext highlighter-rouge">ca.key</code> is super-secret. <code class="language-plaintext highlighter-rouge">ca.key</code> has the “root” signing authority. The only way to
gain access to the network is with a certificate that has been signed by <code class="language-plaintext highlighter-rouge">ca.key</code>.
It’s secrecy is important enough that it is often kept off the network and
stored off-site or on a thumb-drive. I keep mine in my prison wallet.</p>

<p><code class="language-plaintext highlighter-rouge">ca.crt</code> is public. It can (and must) be shared with vpn clients. Its contents include
an encrypted code for verifying that a peer-machine’s certificate was signed by <code class="language-plaintext highlighter-rouge">ca.key</code>.
<code class="language-plaintext highlighter-rouge">ca.crt</code> establishes a link to <code class="language-plaintext highlighter-rouge">ca.key</code> without disclosing <code class="language-plaintext highlighter-rouge">ca.key</code>’s contents or
location. <code class="language-plaintext highlighter-rouge">ca.crt</code> has no signing authority. It cannot sign new certificates for new
clients; it can only verify that a client’s certificate was signed by a legitimate signing
authority.</p>

<p>On a small vpn network like mine, the CA is “self-signing”. Large networks and secure
internet addresses use certificates signed by a commercial signing authority. For example, when
I purchased the domain <code class="language-plaintext highlighter-rouge">adogslaboratory.net</code> from Porkbun, it came with a certificate
signed by Let’s Encrypt that I can use to publish my website over the <code class="language-plaintext highlighter-rouge">https</code> protocol.
Websites without an official CA can’t use <code class="language-plaintext highlighter-rouge">https</code>.</p>

<p>But for my private purposes a self-signing certificate is sufficient. I create <code class="language-plaintext highlighter-rouge">ca.key</code>
and I am responsible for keeping it super-secret. No one can join my vpn unless they have
a certificate that was signed by <em>my</em> <code class="language-plaintext highlighter-rouge">ca.key</code>.</p>

<p>So, if our server, <code class="language-plaintext highlighter-rouge">home-cooking</code>, is going to use TLS	to secure its vpn network, the first step
is to generate <code class="language-plaintext highlighter-rouge">ca.key</code> and <code class="language-plaintext highlighter-rouge">ca.crt</code>. We will skip over the CLI commands for now and come
back to them in a later post.</p>

<h3 id="the-private-key-the-certificate-signing-request-and-the-public-certificate">The private key, the Certificate Signing Request, and the public certificate</h3>

<p>Once <code class="language-plaintext highlighter-rouge">home-cooking</code> has <code class="language-plaintext highlighter-rouge">ca.key</code> and <code class="language-plaintext highlighter-rouge">ca.crt</code> in hand it can proceed to the next step:
creating a private key (which we will call <code class="language-plaintext highlighter-rouge">home-cooking.key</code>) and a Certificate Signing
Request (<code class="language-plaintext highlighter-rouge">home-cooking.csr</code>).</p>

<p>Like <code class="language-plaintext highlighter-rouge">ca.key</code>, <code class="language-plaintext highlighter-rouge">home-cooking.key</code> is secret. It may not be super-secret, but it is secret.
<code class="language-plaintext highlighter-rouge">home-cooking</code> will keep its private key protected with <code class="language-plaintext highlighter-rouge">600</code> security permissions.</p>

<p>The <code class="language-plaintext highlighter-rouge">.csr</code> file  is only temporary. It will be presented to <code class="language-plaintext highlighter-rouge">ca.key</code> for signing. <code class="language-plaintext highlighter-rouge">ca.key</code> will
respond to the CSR and sign a new public certificate, <code class="language-plaintext highlighter-rouge">home-cooking.crt</code>. Once 
the public certificate has been signed,<code class="language-plaintext highlighter-rouge">home-cooking.csr</code> is no longer needed and it can be deleted.</p>

<p>Our server now has its own private key (<code class="language-plaintext highlighter-rouge">home-cooking.key</code>) and public certificate 
(<code class="language-plaintext highlighter-rouge">home-cooking.crt</code>). It also has possession of <code class="language-plaintext highlighter-rouge">ca.key</code> and <code class="language-plaintext highlighter-rouge">ca.crt</code>.</p>

<h3 id="what-about-the-client">What about the client?</h3>

<p>It’s time to introduce <code class="language-plaintext highlighter-rouge">distant-cousin</code>. <code class="language-plaintext highlighter-rouge">distant-cousin</code> wants to be a client on
<code class="language-plaintext highlighter-rouge">home-cooking</code>’s vpn but it lacks the credentials. So, it asks <code class="language-plaintext highlighter-rouge">home-cooking</code> to hook
a cousin up. <code class="language-plaintext highlighter-rouge">home-cooking</code> goes through the same steps as before: create <code class="language-plaintext highlighter-rouge">distant-cousin.key</code>
and <code class="language-plaintext highlighter-rouge">distant-cousin.csr</code>; present the <code class="language-plaintext highlighter-rouge">.csr</code> file to <code class="language-plaintext highlighter-rouge">ca.key</code>; receive the signed<code class="language-plaintext highlighter-rouge">
distant-cousin.crt</code> back from <code class="language-plaintext highlighter-rouge">ca.key</code>; and delete <code class="language-plaintext highlighter-rouge">distant-cousin.csr</code>.</p>

<p>At this point we have signed certificates for both machines. We are done using 
<code class="language-plaintext highlighter-rouge">ca.key</code> for now. It can be safely keistered (keystered?).</p>

<p>Now, if you are keeping track, <code class="language-plaintext highlighter-rouge">home-cooking</code> has five files in its possession: <code class="language-plaintext highlighter-rouge">ca.crt</code>,
<code class="language-plaintext highlighter-rouge">home-cooking.key</code>, <code class="language-plaintext highlighter-rouge">home-cooking.crt</code>, <code class="language-plaintext highlighter-rouge">distant-cousin.key</code>, and <code class="language-plaintext highlighter-rouge">distant-cousin.crt</code>.
<code class="language-plaintext highlighter-rouge">home-cooking</code> sends <code class="language-plaintext highlighter-rouge">distant-cousin.key</code>, <code class="language-plaintext highlighter-rouge">distant-cousin.crt</code> and a copy of <code class="language-plaintext highlighter-rouge">ca.crt</code>
to <code class="language-plaintext highlighter-rouge">distant-cousin</code>.</p>

<p>Each computer now has in its possession its own private key (the <code class="language-plaintext highlighter-rouge">&lt;hostname&gt;.key</code> file),
a public certificate (<code class="language-plaintext highlighter-rouge">&lt;hostname&gt;.crt</code>) and a copy of the CA’s public certificate, <code class="language-plaintext highlighter-rouge">ca.crt</code>.
These three files, locally stored on each machine connected to the vpn, combine to produce
a TLS-secured network.</p>

<h3 id="teamwork-makes-the-dream-work">Teamwork makes the dream work</h3>

<p>So, how do these pieces all fit together?</p>

<p>When <code class="language-plaintext highlighter-rouge">distant-cousin</code> wants to connect to the vpn it contacts the server, <code class="language-plaintext highlighter-rouge">home-cooking</code>.
<code class="language-plaintext highlighter-rouge">home-cooking</code> uses <code class="language-plaintext highlighter-rouge">home-cooking.key</code> to generate a personal signature. It presents
its public certificate, <code class="language-plaintext highlighter-rouge">home-cooking.crt</code>, to <code class="language-plaintext highlighter-rouge">distant-cousin</code> along with the signature.
<code class="language-plaintext highlighter-rouge">distant-cousin</code> compares the signature against the contents of the certificate and uses
<code class="language-plaintext highlighter-rouge">ca.crt</code> to verify that the certificate was issued by <code class="language-plaintext highlighter-rouge">ca.key</code>.</p>

<p><code class="language-plaintext highlighter-rouge">distant-cousin</code> does the whole thing in reverse, sending its signature and certificate
to <code class="language-plaintext highlighter-rouge">home-cooking</code> so that <code class="language-plaintext highlighter-rouge">home-cooking</code> can authenticate its credentials using the
same process.</p>

<p>Each of the documents performs an essential function. The private key is secret and never
leaves its host. Only the private key can produce the signature used by that
particular machine. The public certificate is the credential signed by the “root” 
signing authority, <code class="language-plaintext highlighter-rouge">ca.key</code>. And <code class="language-plaintext highlighter-rouge">ca.crt</code> is the CA’s public certificate,
providing an authoritative link to <code class="language-plaintext highlighter-rouge">ca.key</code>.</p>

<h3 id="wrapping-things-up">Wrapping things up</h3>

<p>So that is how it all works toge….wait….I feel like I’ve forgotten something…oh crap.</p>

<p>I forgot <code class="language-plaintext highlighter-rouge">ta.key</code>. Screw it, I’m done for the night.</p>]]></content><author><name></name></author><category term="vpn" /><category term="tls" /><summary type="html"><![CDATA[I’ve been setting up a vpn network using OpenVPN. The dog-in-charge demands that I implement Transport Layer Security (TLS). TLS requires creating a series of certifications and keys which can then be referenced from a VPN configuration file.]]></summary></entry><entry><title type="html">using dolist to add multiple entries to an alist</title><link href="www.adogslaboratory.net/2026/09/12/using-dolist-to-add-entries-to-an-alist.html" rel="alternate" type="text/html" title="using dolist to add multiple entries to an alist" /><published>2026-09-12T00:00:00-07:00</published><updated>2026-09-12T00:00:00-07:00</updated><id>www.adogslaboratory.net/2026/09/12/using-dolist-to-add-entries-to-an-alist</id><content type="html" xml:base="www.adogslaboratory.net/2026/09/12/using-dolist-to-add-entries-to-an-alist.html"><![CDATA[<p>I previously posted about increasing the default font-size for a frame in emacs.
The code looked like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(add-to-list 'default-frame-alist '(font . "Monospace-18"))
</code></pre></div></div>

<p>I decided that I <em>also</em> wanted to open a new emacs frame in fullscreen mode. The code
for <em>that</em> looks like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(add-to-list 'default-frame-alist '(fullscreen . fullscreen))
</code></pre></div></div>

<p>Rather than perform the <code class="language-plaintext highlighter-rouge">add-to-list</code> operation twice, I investigated how to add
multiple entries to <code class="language-plaintext highlighter-rouge">default-frame-alist</code> at one time. That led me to the <code class="language-plaintext highlighter-rouge">dolist</code>
macro:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(dolist (entry '((font . "Monospace-18")
	            (fullscreen . fullscreen)))
  (add-to-list 'default-frame-alist entry))
</code></pre></div></div>]]></content><author><name></name></author><category term="emacs" /><category term="elisp" /><summary type="html"><![CDATA[I previously posted about increasing the default font-size for a frame in emacs. The code looked like this:]]></summary></entry><entry><title type="html">setting the emacs default font size</title><link href="www.adogslaboratory.net/2026/09/10/setting-the-emacs-default-font-size.html" rel="alternate" type="text/html" title="setting the emacs default font size" /><published>2026-09-10T00:00:00-07:00</published><updated>2026-09-10T00:00:00-07:00</updated><id>www.adogslaboratory.net/2026/09/10/setting-the-emacs-default-font-size</id><content type="html" xml:base="www.adogslaboratory.net/2026/09/10/setting-the-emacs-default-font-size.html"><![CDATA[<p>My eyes are losing their resolve.</p>

<p>I have embraced large(r) fonts as an accommodation.</p>

<p>In emacs, I include the following line in <code class="language-plaintext highlighter-rouge">init.el</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(add-to-list 'default-frame-alist '(font . "Monospace-18"))
</code></pre></div></div>]]></content><author><name></name></author><category term="emacs" /><category term="init.el" /><summary type="html"><![CDATA[My eyes are losing their resolve.]]></summary></entry><entry><title type="html">mounting linux NFS exports from macOS</title><link href="www.adogslaboratory.net/2026/09/09/mounting-linux-nfs-shares-from-macos.html" rel="alternate" type="text/html" title="mounting linux NFS exports from macOS" /><published>2026-09-09T00:00:00-07:00</published><updated>2026-09-09T00:00:00-07:00</updated><id>www.adogslaboratory.net/2026/09/09/mounting-linux-nfs-shares-from-macos</id><content type="html" xml:base="www.adogslaboratory.net/2026/09/09/mounting-linux-nfs-shares-from-macos.html"><![CDATA[<p>I have a slackware machine (hostname: <code class="language-plaintext highlighter-rouge">cyberdyne</code>) that has a directory I want to export via NFS
so it can be mounted by my macOS machine (hostname: <code class="language-plaintext highlighter-rouge">lightfoot</code>).</p>

<p>The directory I want to export is <code class="language-plaintext highlighter-rouge">/home/me/shared</code>. I want to mount this directory
on my macOS machine at <code class="language-plaintext highlighter-rouge">/Users/me/cyberdyne</code>.</p>

<p>This is <code class="language-plaintext highlighter-rouge">/etc/exports</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Export the directory as the root directory of the virtual file tree:
/home/aaron/shared lightfoot(ro,fsid=root)
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">lightfoot</code> mounts the export with this command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mount_nfs -o vers=4,resvport cyberdyne:/ ~/cyberdyne
</code></pre></div></div>

<p>A stroll through the export flags:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">ro</code> sets read-only permissions. Note that when macOS mounts an NFS share exported
by a linux server it will always have read-only privileges regardless of the flags I
set in <code class="language-plaintext highlighter-rouge">/etc/exports</code>, but in the future I may mount this export with a linux client, in
which case I will have to change this flag if I want read-write privileges for that
machine. Setting the <code class="language-plaintext highlighter-rouge">ro</code> flag now ensures that I will have to make that decision
consciously.</li>
  <li><code class="language-plaintext highlighter-rouge">fsid=root</code> sets the exported directory as the root of the virtual filesystem. The purpose
of this flag is better explained when examining the <code class="language-plaintext highlighter-rouge">mount_nfs</code> command below.</li>
</ul>

<p>A romp through the <code class="language-plaintext highlighter-rouge">mount_nfs</code> command:</p>
<ul>
  <li><code class="language-plaintext highlighter-rouge">vers=4</code> enforces the use of NFSv4. The <code class="language-plaintext highlighter-rouge">fsid=root</code> flag is only available on NFSv4. And,
NFSv4 simplifies ipv6 addressing. Using ipv6 with NFSv3 requires special <code class="language-plaintext highlighter-rouge">rpc</code> settings that
took me down an ai rabbit-hole for several days before I realized I could bypass all of that
by using <code class="language-plaintext highlighter-rouge">vers=4</code>, with the added benefit of enabling <code class="language-plaintext highlighter-rouge">fsid=root</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">resvport</code> is necessary when a macOS machine mounts a linux export. It has to do with
arcane rules governing which ports are available. I learned that the same result can
be accomplished by adding <code class="language-plaintext highlighter-rouge">insecure</code> to the flags in <code class="language-plaintext highlighter-rouge">/etc/exports</code> but that creates
a server-wide exception to the default linux behavior, whilst using <code class="language-plaintext highlighter-rouge">resvport</code> as a
mount option alters the default behavior only for clients who need it.</li>
  <li><code class="language-plaintext highlighter-rouge">cyberdyne:/</code> defines the <code class="language-plaintext highlighter-rouge">hostname:/directory</code> being mounted. This is where
the benefits of <code class="language-plaintext highlighter-rouge">fsid=root</code> really shine. Without <code class="language-plaintext highlighter-rouge">fsid=root</code> the <code class="language-plaintext highlighter-rouge">hostname:/directory</code>
would require an absolute path, e.g. <code class="language-plaintext highlighter-rouge">cyberdyne:/home/aaron/shared</code>; and that would
require that the client-user know the parent directory structure of the export. <code class="language-plaintext highlighter-rouge">fsid=root</code>
allows the client-user to mount the export without knowing its locaion on the server.</li>
  <li><code class="language-plaintext highlighter-rouge">~/cyberdyne</code> is the mountpoint on the client. Using the <code class="language-plaintext highlighter-rouge">~/</code> makes the command portable.
I have another macOS machine that will mount the same shared directory at the same
mountpoint location. I can use the same command without change.</li>
</ul>]]></content><author><name></name></author><category term="macOS" /><category term="linux" /><category term="nfs" /><summary type="html"><![CDATA[I have a slackware machine (hostname: cyberdyne) that has a directory I want to export via NFS so it can be mounted by my macOS machine (hostname: lightfoot).]]></summary></entry><entry><title type="html">up and running</title><link href="www.adogslaboratory.net/2026/09/05/up-and-running.html" rel="alternate" type="text/html" title="up and running" /><published>2026-09-05T00:00:00-07:00</published><updated>2026-09-05T00:00:00-07:00</updated><id>www.adogslaboratory.net/2026/09/05/up-and-running</id><content type="html" xml:base="www.adogslaboratory.net/2026/09/05/up-and-running.html"><![CDATA[<p>45 days ago the dog-in-charge bought a used Dell PowerEdge T330 server for $100,
a decent machine with 16GB RAM, a RAID controller, eight hard-drive bays, and no
hard-drives. So the same day he bought a 2TB hard-drive from a guy on Facebook Marketplace. He sent
me to pick it up.</p>

<p>We met at night in the parking lot of the local shopping mall underneath the Regal Cinemas sign.
He rode in on a black motorcycle–not the noisy kind–dressed in black, with a black helmet that
had a camera mounted on the chin. Do you mind if I record this? he asked. No, I
didn’t mind. He gave me the drive and said to message him if I had any problems.</p>

<p>I left before he did and ended up at a red light just outside of the
parking lot. I sat waiting for the light to change. I turned my head just in time
to see him drive off, going about 50 in a 35, with all the lights on his
motorcycle turned off.</p>]]></content><author><name></name></author><category term="dog-in-charge" /><category term="machines" /><summary type="html"><![CDATA[45 days ago the dog-in-charge bought a used Dell PowerEdge T330 server for $100, a decent machine with 16GB RAM, a RAID controller, eight hard-drive bays, and no hard-drives. So the same day he bought a 2TB hard-drive from a guy on Facebook Marketplace. He sent me to pick it up.]]></summary></entry></feed>