Update README.html.
authorMatt Birkholz <matt@birchwood-abbey.net>
Sun, 1 Jun 2025 04:28:10 +0000 (22:28 -0600)
committerMatt Birkholz <matt@birchwood-abbey.net>
Sun, 1 Jun 2025 04:28:10 +0000 (22:28 -0600)
README.html

index b92892eda2383e909b38e8860361c23cdd25c4d0..6d8b64865c355e00c5676b37f59a9d524ae1865c 100644 (file)
@@ -3,7 +3,7 @@
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
 <head>
-<!-- 2024-10-29 Tue 21:35 -->
+<!-- 2025-05-31 Sat 22:27 -->
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 <meta name="viewport" content="width=device-width, initial-scale=1" />
 <title>A Small Institute</title>
@@ -24,8 +24,8 @@ an expendable public face (easily wiped clean) while maintaining a
 secure and private campus that can function with or without the
 Internet.
 </p>
-<div id="outline-container-org56d00a8" class="outline-2">
-<h2 id="org56d00a8"><span class="section-number-2">1.</span> Overview</h2>
+<div id="outline-container-org12986b7" class="outline-2">
+<h2 id="org12986b7"><span class="section-number-2">1.</span> Overview</h2>
 <div class="outline-text-2" id="text-1">
 <p>
 This small institute has a public server on the Internet, Front, that
@@ -48,7 +48,7 @@ connects to Front making the institute email, cloud, etc. available to
 members off campus.
 </p>
 
-<pre class="example" id="org42c266c">
+<pre class="example" id="org9ebcfa4">
                 =                                                   
               _|||_                                                 
         =-The-Institute-=                                           
@@ -95,8 +95,8 @@ uses OpenPGP encryption to secure message content.
 </p>
 </div>
 </div>
-<div id="outline-container-org4c498be" class="outline-2">
-<h2 id="org4c498be"><span class="section-number-2">2.</span> Caveats</h2>
+<div id="outline-container-org68fcf87" class="outline-2">
+<h2 id="org68fcf87"><span class="section-number-2">2.</span> Caveats</h2>
 <div class="outline-text-2" id="text-2">
 <p>
 This small institute prizes its privacy, so there is little or no
@@ -144,8 +144,8 @@ month) because of this assumption.
 </p>
 </div>
 </div>
-<div id="outline-container-orgd99d86a" class="outline-2">
-<h2 id="orgd99d86a"><span class="section-number-2">3.</span> The Services</h2>
+<div id="outline-container-org1120238" class="outline-2">
+<h2 id="org1120238"><span class="section-number-2">3.</span> The Services</h2>
 <div class="outline-text-2" id="text-3">
 <p>
 The small institute's network is designed to provide a number of
@@ -157,8 +157,8 @@ policies.  On first reading, those subsections should be skipped; they
 reference particulars first introduced in the following chapter.
 </p>
 </div>
-<div id="outline-container-org12ea1d0" class="outline-3">
-<h3 id="org12ea1d0"><span class="section-number-3">3.1.</span> The Name Service</h3>
+<div id="outline-container-org189ccc3" class="outline-3">
+<h3 id="org189ccc3"><span class="section-number-3">3.1.</span> The Name Service</h3>
 <div class="outline-text-3" id="text-3-1">
 <p>
 The institute has a public domain, e.g. <code>small.example.org</code>, and a
@@ -172,8 +172,8 @@ names like <code>core</code>.
 </p>
 </div>
 </div>
-<div id="outline-container-org22a6220" class="outline-3">
-<h3 id="org22a6220"><span class="section-number-3">3.2.</span> The Email Service</h3>
+<div id="outline-container-org73635f2" class="outline-3">
+<h3 id="org73635f2"><span class="section-number-3">3.2.</span> The Email Service</h3>
 <div class="outline-text-3" id="text-3-2">
 <p>
 Front provides the public SMTP (Simple Mail Transfer Protocol) service
@@ -231,8 +231,8 @@ sign outgoing emails per DKIM (Domain Keys Identified Mail) yet.
 </p>
 
 <div class="org-src-container">
-Example Small Institute SPF Record<pre class="src src-conf"><span class="org-variable-name">TXT    v</span>=spf1 ip4:159.65.75.60 -all
-</pre>
+Example Small Institute SPF Record<pre class="src src-conf"><code><span class="org-variable-name">TXT    v</span>=spf1 ip4:159.65.75.60 -all
+</code></pre>
 </div>
 
 <p>
@@ -247,8 +247,8 @@ setting for the maximum message size is given in a code block labeled
 configurations wherever <code>&lt;&lt;postfix-message-size&gt;&gt;</code> appears.
 </p>
 </div>
-<div id="outline-container-orge0db702" class="outline-4">
-<h4 id="orge0db702"><span class="section-number-4">3.2.1.</span> The Postfix Configurations</h4>
+<div id="outline-container-org630ebd0" class="outline-4">
+<h4 id="org630ebd0"><span class="section-number-4">3.2.1.</span> The Postfix Configurations</h4>
 <div class="outline-text-4" id="text-3-2-1">
 <p>
 The institute aims to accommodate encrypted email containing short
@@ -263,8 +263,8 @@ handle maxi-messages.
 </p>
 
 <div class="org-src-container">
-<code>postfix-message-size</code><pre class="src src-conf" id="orgb73b70b">- { p: message_size_limit, v: 104857600 }
-</pre>
+<code>postfix-message-size</code><pre class="src src-conf" id="org76e6614"><code>- { p: message_size_limit, v: 104857600 }
+</code></pre>
 </div>
 
 <p>
@@ -278,10 +278,10 @@ re-sending the bounce (or just grabbing the go-bag!).
 </p>
 
 <div class="org-src-container">
-<code>postfix-queue-times</code><pre class="src src-conf" id="org3ddc4d4">- { p: delay_warning_time, v: 1h }
+<code>postfix-queue-times</code><pre class="src src-conf" id="orge1f6b9f"><code>- { p: delay_warning_time, v: 1h }
 - { p: maximal_queue_lifetime, v: 4h }
 - { p: bounce_queue_lifetime, v: 4h }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -292,9 +292,9 @@ disables relaying (other than for the local networks).
 </p>
 
 <div class="org-src-container">
-<code>postfix-relaying</code><pre class="src src-conf" id="org211f1c0">- p: smtpd_relay_restrictions
+<code>postfix-relaying</code><pre class="src src-conf" id="orgfc41c7f"><code>- p: smtpd_relay_restrictions
   v: permit_mynetworks reject_unauth_destination
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -304,8 +304,8 @@ effect.
 </p>
 
 <div class="org-src-container">
-<code>postfix-maildir</code><pre class="src src-conf" id="orga0931ea">- { p: home_mailbox, v: Maildir/ }
-</pre>
+<code>postfix-maildir</code><pre class="src src-conf" id="org38b410e"><code>- { p: home_mailbox, v: Maildir/ }
+</code></pre>
 </div>
 
 <p>
@@ -315,8 +315,8 @@ in the respective roles below.
 </p>
 </div>
 </div>
-<div id="outline-container-org768dc52" class="outline-4">
-<h4 id="org768dc52"><span class="section-number-4">3.2.2.</span> The Dovecot Configurations</h4>
+<div id="outline-container-org4c351b3" class="outline-4">
+<h4 id="org4c351b3"><span class="section-number-4">3.2.2.</span> The Dovecot Configurations</h4>
 <div class="outline-text-4" id="text-3-2-2">
 <p>
 The Dovecot settings on both Front and Core disable POP and require
@@ -330,9 +330,9 @@ The official documentation for Dovecot once was a Wiki but now is
 </p>
 
 <div class="org-src-container">
-<code>dovecot-tls</code><pre class="src src-conf" id="org574da80"><span class="org-variable-name">protocols</span> = imap
+<code>dovecot-tls</code><pre class="src src-conf" id="org9aa23d4"><code><span class="org-variable-name">protocols</span> = imap
 <span class="org-variable-name">ssl</span> = required
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -342,12 +342,12 @@ configuration keeps them from even listening at the IMAP port
 </p>
 
 <div class="org-src-container">
-<code>dovecot-ports</code><pre class="src src-conf" id="orga82cd71"><span class="org-type">service imap-login</span> {
+<code>dovecot-ports</code><pre class="src src-conf" id="orgf5fbf4b"><code><span class="org-type">service imap-login</span> {
   <span class="org-type">inet_listener imap</span> {
     <span class="org-variable-name">port</span> = 0
   }
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -356,8 +356,8 @@ directories.
 </p>
 
 <div class="org-src-container">
-<code>dovecot-maildir</code><pre class="src src-conf" id="orgf0e66f0"><span class="org-variable-name">mail_location</span> = maildir:~/Maildir
-</pre>
+<code>dovecot-maildir</code><pre class="src src-conf" id="org4ab71c8"><code><span class="org-variable-name">mail_location</span> = maildir:~/Maildir
+</code></pre>
 </div>
 
 <p>
@@ -368,15 +368,15 @@ common settings with host specific settings for <code>ssl_cert</code> and
 </div>
 </div>
 </div>
-<div id="outline-container-org43cbe17" class="outline-3">
-<h3 id="org43cbe17"><span class="section-number-3">3.3.</span> The Web Services</h3>
+<div id="outline-container-orgf659a90" class="outline-3">
+<h3 id="orgf659a90"><span class="section-number-3">3.3.</span> The Web Services</h3>
 <div class="outline-text-3" id="text-3-3">
 <p>
 Front provides the public HTTP service that serves institute web pages
 at e.g. <code>https://small.example.org/</code>.  The small institute initially
 runs with a self-signed, "snake oil" server certificate, causing
 browsers to warn of possible fraud, but this certificate is easily
-replaced by one signed by a recognized authority, as discussed in <a href="#org9240129">The
+replaced by one signed by a recognized authority, as discussed in <a href="#org1024107">The
 Front Role</a>.
 </p>
 
@@ -420,7 +420,7 @@ tree.  Changes here are merged into the live tree, <q>/WWW/live/</q>,
 once they are complete and tested.</dd>
 <dt><code>http://core/</code></dt><dd>is the Debian default site.  The institute does
 not munge this site, to avoid conflicts with Debian-packaged web
-services (e.g. Nextcloud, Zoneminder, MythTV's MythWeb).</dd>
+services (e.g. Nextcloud, AgentDVR, MythTV's MythWeb).</dd>
 </dl>
 
 <p>
@@ -431,15 +431,15 @@ will automatically wipe it within 15 minutes.
 </p>
 </div>
 </div>
-<div id="outline-container-org71fc0ac" class="outline-3">
-<h3 id="org71fc0ac"><span class="section-number-3">3.4.</span> The Cloud Service</h3>
+<div id="outline-container-orgd0834d2" class="outline-3">
+<h3 id="orgd0834d2"><span class="section-number-3">3.4.</span> The Cloud Service</h3>
 <div class="outline-text-3" id="text-3-4">
 <p>
 Core runs Nextcloud to provide a private institute cloud at
-<code>http://core.small.private/nextcloud/</code>.  It is managed manually per
+<code>https://core.small.private/nextcloud/</code>.  It is managed manually per
 <a href="https://docs.nextcloud.com/server/latest/admin_manual/">The Nextcloud Server Administration Guide</a>.  The code <i>and</i> data,
 including especially database dumps, are stored in <q>/Nextcloud/</q> which
-is included in Core's backup procedure as described in <a href="#org431068a">Backups</a>.  The
+is included in Core's backup procedure as described in <a href="#org2a7965d">Backups</a>.  The
 default Apache2 configuration expects to find the web scripts in
 <q>/var/www/nextcloud/</q>, so the institute symbolically links this to
 <q>/Nextcloud/nextcloud/</q>.
@@ -453,22 +453,22 @@ private network.
 </p>
 </div>
 </div>
-<div id="outline-container-orgc2baf19" class="outline-3">
-<h3 id="orgc2baf19"><span class="section-number-3">3.5.</span> The VPN Services</h3>
+<div id="outline-container-org1ea6412" class="outline-3">
+<h3 id="org1ea6412"><span class="section-number-3">3.5.</span> The VPN Services</h3>
 <div class="outline-text-3" id="text-3-5">
 <p>
 The institute's public and campus VPNs have many common configuration
 options that are discussed here.  These are included, with example
 certificates and network addresses, in the complete server
-configurations of <a href="#org9240129">The Front Role</a> and <a href="#org72d6fde">The Gate Role</a>, as well as the
-matching client configurations in <a href="#orge7ebc83">The Core Role</a> and the <q>.ovpn</q> files
-generated by <a href="#org0ad53cf">The Client Command</a>.  The configurations are based on the
+configurations of <a href="#org1024107">The Front Role</a> and <a href="#org936487d">The Gate Role</a>, as well as the
+matching client configurations in <a href="#orge6d718e">The Core Role</a> and the <q>.ovpn</q> files
+generated by <a href="#orgdc36b90">The Client Command</a>.  The configurations are based on the
 documentation for OpenVPN v2.4: the <code>openvpn(8)</code> manual page and <a href="https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/">this
 web page</a>.
 </p>
 </div>
-<div id="outline-container-org5b24b6e" class="outline-4">
-<h4 id="org5b24b6e"><span class="section-number-4">3.5.1.</span> The VPN Configuration Options</h4>
+<div id="outline-container-orgf621905" class="outline-4">
+<h4 id="orgf621905"><span class="section-number-4">3.5.1.</span> The VPN Configuration Options</h4>
 <div class="outline-text-4" id="text-3-5-1">
 <p>
 The institute VPNs use UDP on a subnet topology (rather than
@@ -480,11 +480,11 @@ the VPN subnets using any (experimental) protocol.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-dev-mode</code><pre class="src src-conf" id="orgea7339c">dev-type tun
+<code>openvpn-dev-mode</code><pre class="src src-conf" id="org2722342"><code>dev-type tun
 dev ovpn
 topology subnet
 client-to-client
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -495,20 +495,20 @@ interruptions.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-keepalive</code><pre class="src src-conf" id="orgb8aba90">keepalive 10 120
-</pre>
+<code>openvpn-keepalive</code><pre class="src src-conf" id="orgfe45128"><code>keepalive 10 120
+</code></pre>
 </div>
 
 <p>
-As mentioned in <a href="#org12ea1d0">The Name Service</a>, the institute uses a campus name
+As mentioned in <a href="#org189ccc3">The Name Service</a>, the institute uses a campus name
 server.  OpenVPN is instructed to push its address and the campus
 search domain.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-dns</code><pre class="src src-conf" id="org3448fff">push <span class="org-string">"dhcp-option DOMAIN {{ domain_priv }}"</span>
+<code>openvpn-dns</code><pre class="src src-conf" id="org035983f"><code>push <span class="org-string">"dhcp-option DOMAIN {{ domain_priv }}"</span>
 push <span class="org-string">"dhcp-option DNS {{ core_addr }}"</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -519,11 +519,11 @@ device nor the key files.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-drop-priv</code><pre class="src src-conf" id="org5cd7a6f">user nobody
+<code>openvpn-drop-priv</code><pre class="src src-conf" id="orge4d440d"><code>user nobody
 group nogroup
 persist-key
 persist-tun
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -535,9 +535,9 @@ the default for OpenVPN v2.4, and <code>auth</code> is upped to <code>SHA256</co
 </p>
 
 <div class="org-src-container">
-<code>openvpn-crypt</code><pre class="src src-conf" id="orgbf610a1">cipher AES-256-GCM
+<code>openvpn-crypt</code><pre class="src src-conf" id="orgb13e625"><code>cipher AES-256-GCM
 auth SHA256
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -546,8 +546,8 @@ accommodating a few members with a handful of devices each.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-max</code><pre class="src src-conf" id="org7c68569">max-clients 20
-</pre>
+<code>openvpn-max</code><pre class="src src-conf" id="orgd79815a"><code>max-clients 20
+</code></pre>
 </div>
 
 <p>
@@ -560,23 +560,23 @@ raised from the default level 1 to level 3 (just short of a deluge).
 </p>
 
 <div class="org-src-container">
-<code>openvpn-debug</code><pre class="src src-conf" id="orgddb99ce">ifconfig-pool-persist ipp.txt
+<code>openvpn-debug</code><pre class="src src-conf" id="org59b4726"><code>ifconfig-pool-persist ipp.txt
 status openvpn-status.log
 verb 3
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-org54da6ed" class="outline-3">
-<h3 id="org54da6ed"><span class="section-number-3">3.6.</span> Accounts</h3>
+<div id="outline-container-orga38c5ed" class="outline-3">
+<h3 id="orga38c5ed"><span class="section-number-3">3.6.</span> Accounts</h3>
 <div class="outline-text-3" id="text-3-6">
 <p>
 A small institute has just a handful of members.  For simplicity (and
 thus security) static configuration files are preferred over complex
 account management systems, LDAP, Active Directory, and the like.  The
 Ansible scripts configure the same set of user accounts on Core and
-Front.  <a href="#org1c6f4a8">The Institute Commands</a> (e.g. <code>./inst new dick</code>) capture the
+Front.  <a href="#org5db480b">The Institute Commands</a> (e.g. <code>./inst new dick</code>) capture the
 processes of enrolling, modifying and retiring members of the
 institute.  They update the administrator's membership roll, and run
 Ansible to create (and disable) accounts on Core, Front, Nextcloud,
@@ -591,8 +591,8 @@ accomplished via the campus cloud and the resulting desktop files can
 all be private (readable and writable only by the owner) by default.
 </p>
 </div>
-<div id="outline-container-org00e3480" class="outline-4">
-<h4 id="org00e3480"><span class="section-number-4">3.6.1.</span> The Administration Accounts</h4>
+<div id="outline-container-org4a8c2dc" class="outline-4">
+<h4 id="org4a8c2dc"><span class="section-number-4">3.6.1.</span> The Administration Accounts</h4>
 <div class="outline-text-4" id="text-3-6-1">
 <p>
 The institute avoids the use of the <code>root</code> account (<code>uid 0</code>) because
@@ -601,21 +601,21 @@ command is used to consciously (conscientiously!) run specific scripts
 and programs as <code>root</code>.  When installation of a Debian OS leaves the
 host with no user accounts, just the <code>root</code> account, the next step is
 to create a system administrator's account named <code>sysadm</code> and to give
-it permission to use the <code>sudo</code> command (e.g. as described in <a href="#org7661483">The
+it permission to use the <code>sudo</code> command (e.g. as described in <a href="#org9282df0">The
 Front Machine</a>).  When installation prompts for the name of an
 initial, privileged user account the same name is given (e.g. as
-described in <a href="#org8d60b7b">The Core Machine</a>).  Installation may <i>not</i> prompt and
+described in <a href="#orgae4ce75">The Core Machine</a>).  Installation may <i>not</i> prompt and
 still create an initial user account with a distribution specific name
 (e.g. <code>pi</code>).  Any name can be used as long as it is provided as the
 value of <code>ansible_user</code> in <a href="hosts"><q>hosts</q></a>.  Its password is specified by a
 vault-encrypted variable in the <a href="Secret/become.yml"><q>Secret/become.yml</q></a> file.  (The
-<a href="hosts"><q>hosts</q></a> and <a href="Secret/become.yml"><q>Secret/become.yml</q></a> files are described in <a href="#orgff33e02">The Ansible
+<a href="hosts"><q>hosts</q></a> and <a href="Secret/become.yml"><q>Secret/become.yml</q></a> files are described in <a href="#orgda31017">The Ansible
 Configuration</a>.)
 </p>
 </div>
 </div>
-<div id="outline-container-org726a9e8" class="outline-4">
-<h4 id="org726a9e8"><span class="section-number-4">3.6.2.</span> The Monkey Accounts</h4>
+<div id="outline-container-org9470e9b" class="outline-4">
+<h4 id="org9470e9b"><span class="section-number-4">3.6.2.</span> The Monkey Accounts</h4>
 <div class="outline-text-4" id="text-3-6-2">
 <p>
 The institute's Core uses a special account named <code>monkey</code> to run
@@ -626,8 +626,8 @@ account is created on Front as well.
 </div>
 </div>
 </div>
-<div id="outline-container-org6519b0c" class="outline-3">
-<h3 id="org6519b0c"><span class="section-number-3">3.7.</span> Keys</h3>
+<div id="outline-container-org1c1be46" class="outline-3">
+<h3 id="org1c1be46"><span class="section-number-3">3.7.</span> Keys</h3>
 <div class="outline-text-3" id="text-3-7">
 <p>
 The institute keeps its "master secrets" in an encrypted
@@ -714,7 +714,6 @@ rsync -a Secret/ Secret2/
 rsync -a Secret/ Secret3/
 </pre>
 
-
 <p>
 This is out of consideration for the fragility of USB drives, and the
 importance of a certain SSH private key, without which the
@@ -723,8 +722,8 @@ the administrator's password keep, to install a new SSH key.
 </p>
 </div>
 </div>
-<div id="outline-container-org431068a" class="outline-3">
-<h3 id="org431068a"><span class="section-number-3">3.8.</span> Backups</h3>
+<div id="outline-container-org2a7965d" class="outline-3">
+<h3 id="org2a7965d"><span class="section-number-3">3.8.</span> Backups</h3>
 <div class="outline-text-3" id="text-3-8">
 <p>
 The small institute backs up its data, but not so much so that nothing
@@ -755,12 +754,12 @@ version 2.
 Given the <code>-n</code> flag, the script does a "pre-sync" which does not pause
 Nextcloud nor dump its DB.  A pre-sync gets the big file (video)
 copies done while Nextcloud continues to run.  A follow-up <code>sudo
-backup</code> (<i>without</i> <code>-n</code>) produces the complete copy (with all the
+backup</code>, <i>without</i> <code>-n</code>, produces the complete copy (with all the
 files mentioned in the Nextcloud database dump).
 </p>
 
 <div class="org-src-container">
-<a href="private/backup"><q>private/backup</q></a><pre class="src src-sh" id="org9d5954c"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
+<a href="private/backup"><q>private/backup</q></a><pre class="src src-sh" id="org8d148e8"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
 <span class="org-comment-delimiter">#</span>
 <span class="org-comment-delimiter"># </span><span class="org-comment">DO NOT EDIT.  Maintained (will be replaced) by Ansible.</span>
 <span class="org-comment-delimiter">#</span>
@@ -798,10 +797,8 @@ files mentioned in the Nextcloud database dump).
         <span class="org-builtin">echo</span> <span class="org-string">"Mounting /backup/."</span>
         cryptsetup luksOpen /dev/disk/by-partlabel/Backup backup
         mount /dev/mapper/backup /backup
-        <span class="org-variable-name">mounted</span>=indeed
     <span class="org-keyword">else</span>
         <span class="org-builtin">echo</span> <span class="org-string">"Found /backup/ already mounted."</span>
-        <span class="org-variable-name">mounted</span>=
     <span class="org-keyword">fi</span>
 
     <span class="org-keyword">if</span> [ <span class="org-negation-char">!</span> -d /backup/home ]
@@ -813,17 +810,20 @@ files mentioned in the Nextcloud database dump).
 
     <span class="org-keyword">if</span> [ <span class="org-negation-char">!</span> $<span class="org-variable-name">presync</span> ]
     <span class="org-keyword">then</span>
-        <span class="org-builtin">echo</span> <span class="org-string">"Putting nextcloud into maintenance mode."</span>
+        <span class="org-builtin">echo</span> <span class="org-string">"Putting Nextcloud into maintenance mode."</span>
         ( <span class="org-builtin">cd</span> /Nextcloud/nextcloud/
           sudo -u www-data php occ maintenance:mode --on &amp;&gt;/dev/null )
 
-        <span class="org-builtin">echo</span> <span class="org-string">"Dumping nextcloud database."</span>
+        <span class="org-builtin">echo</span> <span class="org-string">"Dumping Nextcloud database."</span>
         ( <span class="org-builtin">cd</span> /Nextcloud/
           <span class="org-builtin">umask</span> 07
-          <span class="org-variable-name">BAK</span>=<span class="org-sh-quoted-exec">`date +"%Y%m%d"`</span>-dbbackup.bak.gz
+          <span class="org-variable-name">BAK</span>=<span class="org-sh-quoted-exec">`date +"%Y%m%d%H%M"`</span>-dbbackup.bak.gz
           <span class="org-variable-name">CNF</span>=/Nextcloud/dbbackup.cnf
           mysqldump --defaults-file=$<span class="org-variable-name">CNF</span> nextcloud | gzip &gt; $<span class="org-variable-name">BAK</span>
-          chmod 440 $<span class="org-variable-name">BAK</span> )
+          chmod 440 $<span class="org-variable-name">BAK</span>
+          ls -t1 *-dbbackup.bak.gz | tail -n +4 <span class="org-sh-escaped-newline">\</span>
+          | <span class="org-keyword">while </span><span class="org-builtin">read</span>; <span class="org-keyword">do</span> rm <span class="org-string">"$REPLY"</span>; <span class="org-keyword">done</span>
+        )
     <span class="org-keyword">fi</span>
 
 }
@@ -832,21 +832,19 @@ files mentioned in the Nextcloud database dump).
 
     <span class="org-keyword">if</span> [ <span class="org-negation-char">!</span> $<span class="org-variable-name">presync</span> ]
     <span class="org-keyword">then</span>
-        <span class="org-builtin">echo</span> <span class="org-string">"Putting nextcloud back into service."</span>
+        <span class="org-builtin">echo</span> <span class="org-string">"Putting Nextcloud back into service."</span>
         ( <span class="org-builtin">cd</span> /Nextcloud/nextcloud/
           sudo -u www-data php occ maintenance:mode --off &amp;&gt;/dev/null )
     <span class="org-keyword">fi</span>
 
-    <span class="org-keyword">if</span> [ $<span class="org-variable-name">mounted</span> ]
+    <span class="org-keyword">if</span> mountpoint -q /backup/
     <span class="org-keyword">then</span>
         <span class="org-builtin">echo</span> <span class="org-string">"Unmounting /backup/."</span>
         umount /backup
         cryptsetup luksClose backup
-        <span class="org-variable-name">mounted</span>=
+        <span class="org-builtin">echo</span> <span class="org-string">"Done."</span>
+        <span class="org-builtin">echo</span> <span class="org-string">"The backup device can be safely disconnected."</span>
     <span class="org-keyword">fi</span>
-    <span class="org-builtin">echo</span> <span class="org-string">"Done."</span>
-    <span class="org-builtin">echo</span> <span class="org-string">"The backup device can be safely disconnected."</span>
-
 }
 
 start
@@ -858,13 +856,13 @@ start
 <span class="org-keyword">done</span>
 
 finish
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-orgfa75f05" class="outline-2">
-<h2 id="orgfa75f05"><span class="section-number-2">4.</span> The Particulars</h2>
+<div id="outline-container-orgb4f5586" class="outline-2">
+<h2 id="orgb4f5586"><span class="section-number-2">4.</span> The Particulars</h2>
 <div class="outline-text-2" id="text-4">
 <p>
 This chapter introduces Ansible variables intended to simplify
@@ -876,13 +874,13 @@ stored in separate files: <a href="public/vars.yml"><q>public/vars.yml</q></a> a
 
 <p>
 The example settings in this document configure VirtualBox VMs as
-described in the <a href="#org74b454f">Testing</a> chapter.  For more information about how a
+described in the <a href="#org7832c43">Testing</a> chapter.  For more information about how a
 small institute turns the example Ansible code into a working Ansible
-configuration, see chapter <a href="#orgff33e02">The Ansible Configuration</a>.
+configuration, see chapter <a href="#orgda31017">The Ansible Configuration</a>.
 </p>
 </div>
-<div id="outline-container-org54548e2" class="outline-3">
-<h3 id="org54548e2"><span class="section-number-3">4.1.</span> Generic Particulars</h3>
+<div id="outline-container-org0ba16f9" class="outline-3">
+<h3 id="org0ba16f9"><span class="section-number-3">4.1.</span> Generic Particulars</h3>
 <div class="outline-text-3" id="text-4-1">
 <p>
 The small institute's domain name is used quite frequently in the
@@ -892,9 +890,9 @@ replace <code>{{ domain_name }}</code> in the code with <code>small.example.org<
 </p>
 
 <div class="org-src-container">
-<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf">---
+<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf"><code>---
 domain_name: small.example.org
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -915,14 +913,14 @@ like DNS-over-HTTPS will pass us by.
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">---
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>---
 domain_priv: small.private
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgda60362" class="outline-3">
-<h3 id="orgda60362"><span class="section-number-3">4.2.</span> Subnets</h3>
+<div id="outline-container-org29f9840" class="outline-3">
+<h3 id="org29f9840"><span class="section-number-3">4.2.</span> Subnets</h3>
 <div class="outline-text-3" id="text-4-2">
 <p>
 The small institute uses a private Ethernet, two VPNs, and an
@@ -1013,16 +1011,16 @@ example result follows the code.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-emacs-lisp">(<span class="org-keyword">let</span> ((bytes
+<pre class="src src-emacs-lisp"><code>(<span class="org-keyword">let</span> ((bytes
          (<span class="org-keyword">let</span> ((i (random (+ 256 16))))
            (<span class="org-keyword">if</span> (&lt; i 256)
                (list 10        i         (1+ (random 254)))
              (list  172 (+ 16 (- i 256)) (1+ (random 254)))))))
   (format <span class="org-string">"%d.%d.%d.0/24"</span> (car bytes) (cadr bytes) (caddr bytes)))
-</pre>
+</code></pre>
 </div>
 
-<div class="TEXT" id="org0dd8c3a">
+<div class="TEXT" id="org078b489">
 <p>
 =&gt; 10.62.17.0/24
 </p>
@@ -1035,16 +1033,16 @@ code block below.  The small institute treats these addresses as
 sensitive information so again the code block below "tangles" into
 <a href="private/vars.yml"><q>private/vars.yml</q></a> rather than <a href="public/vars.yml"><q>public/vars.yml</q></a>.  Two of the
 addresses are in <code>192.168</code> subnets because they are part of a test
-configuration using mostly-default VirtualBoxes (described <a href="#org74b454f">here</a>).
+configuration using mostly-default VirtualBoxes (described <a href="#org7832c43">here</a>).
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>
 private_net_cidr:           192.168.56.0/24
+wild_net_cidr:              192.168.57.0/24
 public_vpn_net_cidr:        10.177.86.0/24
 campus_vpn_net_cidr:        10.84.138.0/24
-gate_wifi_net_cidr:         192.168.57.0/24
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -1056,12 +1054,11 @@ e.g. <code>_net_and_mask</code> rather than <code>_net_cidr</code>.
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">private_net:
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>private_net:
            <span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('network') }}"</span>
 private_net_mask:
            <span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('netmask') }}"</span>
-private_net_and_mask:
-                           <span class="org-string">"{{ private_net }} {{ private_net_mask }}"</span>
+private_net_and_mask:      <span class="org-string">"{{ private_net }} {{ private_net_mask }}"</span>
 public_vpn_net:
         <span class="org-string">"{{ public_vpn_net_cidr | ansible.utils.ipaddr('network') }}"</span>
 public_vpn_net_mask:
@@ -1074,15 +1071,13 @@ campus_vpn_net_mask:
         <span class="org-string">"{{ campus_vpn_net_cidr | ansible.utils.ipaddr('netmask') }}"</span>
 campus_vpn_net_and_mask:
                      <span class="org-string">"{{ campus_vpn_net }} {{ campus_vpn_net_mask }}"</span>
-gate_wifi_net:
-         <span class="org-string">"{{ gate_wifi_net_cidr | ansible.utils.ipaddr('network') }}"</span>
-gate_wifi_net_mask:
-         <span class="org-string">"{{ gate_wifi_net_cidr | ansible.utils.ipaddr('netmask') }}"</span>
-gate_wifi_net_and_mask:
-                       <span class="org-string">"{{ gate_wifi_net }} {{ gate_wifi_net_mask }}"</span>
-gate_wifi_broadcast:
-       <span class="org-string">"{{ gate_wifi_net_cidr | ansible.utils.ipaddr('broadcast') }}"</span>
-</pre>
+wild_net:     <span class="org-string">"{{ wild_net_cidr | ansible.utils.ipaddr('network') }}"</span>
+wild_net_mask:
+              <span class="org-string">"{{ wild_net_cidr | ansible.utils.ipaddr('netmask') }}"</span>
+wild_net_and_mask:               <span class="org-string">"{{ wild_net }} {{ wild_net_mask }}"</span>
+wild_net_broadcast:
+            <span class="org-string">"{{ wild_net_cidr | ansible.utils.ipaddr('broadcast') }}"</span>
+</code></pre>
 </div>
 
 <p>
@@ -1093,8 +1088,8 @@ the institute's Internet domain name.
 </p>
 
 <div class="org-src-container">
-<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf">front_addr: 192.168.15.5
-</pre>
+<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf"><code>front_addr: 192.168.15.5
+</code></pre>
 </div>
 
 <p>
@@ -1109,49 +1104,48 @@ virtual machines and networks, and the VirtualBox user manual uses
 Finally, five host addresses are needed frequently in the Ansible
 code.  The first two are Core's and Gate's addresses on the private
 Ethernet.  The next two are Gate's and the campus Wi-Fi's addresses on
-the Gate-WiFi subnet, the tiny Ethernet (<code>gate_wifi_net</code>) between Gate
-and the (untrusted) campus Wi-Fi access point.  The last is Front's
-address on the public VPN, perversely called <code>front_private_addr</code>.
-The following code block picks the obvious IP addresses for Core
-(host 1) and Gate (host 2).
+the "wild" subnet, the untrusted Ethernet (<code>wild_net</code>) between Gate
+and the campus Wi-Fi access point(s) and IoT appliances.  The last is
+Front's address on the public VPN, perversely called
+<code>front_private_addr</code>.  The following code block picks the obvious IP
+addresses for Core (host 1) and Gate (host 2).
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">core_addr_cidr:  <span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('1') }}"</span>
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>core_addr_cidr:  <span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('1') }}"</span>
 gate_addr_cidr:  <span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('2') }}"</span>
-gate_wifi_addr_cidr:
-               <span class="org-string">"{{ gate_wifi_net_cidr | ansible.utils.ipaddr('1') }}"</span>
-wifi_wan_addr_cidr:
-               <span class="org-string">"{{ gate_wifi_net_cidr | ansible.utils.ipaddr('2') }}"</span>
+gate_wild_addr_cidr:
+                    <span class="org-string">"{{ wild_net_cidr | ansible.utils.ipaddr('1') }}"</span>
+wifi_wan_addr_cidr: <span class="org-string">"{{ wild_net_cidr | ansible.utils.ipaddr('2') }}"</span>
 front_private_addr_cidr:
               <span class="org-string">"{{ public_vpn_net_cidr | ansible.utils.ipaddr('1') }}"</span>
 
 core_addr:   <span class="org-string">"{{ core_addr_cidr | ansible.utils.ipaddr('address') }}"</span>
 gate_addr:   <span class="org-string">"{{ gate_addr_cidr | ansible.utils.ipaddr('address') }}"</span>
-gate_wifi_addr:
-        <span class="org-string">"{{ gate_wifi_addr_cidr | ansible.utils.ipaddr('address') }}"</span>
+gate_wild_addr:
+        <span class="org-string">"{{ gate_wild_addr_cidr | ansible.utils.ipaddr('address') }}"</span>
 wifi_wan_addr:
          <span class="org-string">"{{ wifi_wan_addr_cidr | ansible.utils.ipaddr('address') }}"</span>
 front_private_addr:
     <span class="org-string">"{{ front_private_addr_cidr | ansible.utils.ipaddr('address') }}"</span>
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-org754e9f1" class="outline-2">
-<h2 id="org754e9f1"><span class="section-number-2">5.</span> The Hardware</h2>
+<div id="outline-container-orgbf29081" class="outline-2">
+<h2 id="orgbf29081"><span class="section-number-2">5.</span> The Hardware</h2>
 <div class="outline-text-2" id="text-5">
 <p>
 The small institute's network was built by its system administrator
 using Ansible on a trusted notebook.  The Ansible configuration and
 scripts were generated by "tangling" the Ansible code included here.
-(<a href="#orgff33e02">The Ansible Configuration</a> describes how to do this.)  The following
+(<a href="#orgda31017">The Ansible Configuration</a> describes how to do this.)  The following
 sections describe how Front, Gate and Core were prepared for Ansible.
 </p>
 </div>
-<div id="outline-container-org7661483" class="outline-3">
-<h3 id="org7661483"><span class="section-number-3">5.1.</span> The Front Machine</h3>
+<div id="outline-container-org9282df0" class="outline-3">
+<h3 id="org9282df0"><span class="section-number-3">5.1.</span> The Front Machine</h3>
 <div class="outline-text-3" id="text-5-1">
 <p>
 Front is the small institute's public facing server, a virtual machine
@@ -1164,8 +1158,8 @@ possible to quickly re-provision a new Front machine from a frontier
 Internet café using just the administrator's notebook.
 </p>
 </div>
-<div id="outline-container-orgb446788" class="outline-4">
-<h4 id="orgb446788"><span class="section-number-4">5.1.1.</span> A Digital Ocean Droplet</h4>
+<div id="outline-container-org7dbbd56" class="outline-4">
+<h4 id="org7dbbd56"><span class="section-number-4">5.1.1.</span> A Digital Ocean Droplet</h4>
 <div class="outline-text-4" id="text-5-1-1">
 <p>
 The following example prepared a new front on a Digital Ocean droplet.
@@ -1186,11 +1180,10 @@ notebook$ ssh root@159.65.75.60
 root@ubuntu# 
 </pre>
 
-
 <p>
 The freshly created Digital Ocean droplet came with just one account,
 <code>root</code>, but the small institute avoids remote access to the "super
-user" account (per the policy in <a href="#org00e3480">The Administration Accounts</a>), so the
+user" account (per the policy in <a href="#org4a8c2dc">The Administration Accounts</a>), so the
 administrator created a <code>sysadm</code> account with the ability to request
 escalated privileges via the <code>sudo</code> command.
 </p>
@@ -1209,12 +1202,11 @@ root@ubuntu# logout
 notebook$
 </pre>
 
-
 <p>
 The password was generated by <code>gpw</code>, saved in the administrator's
 password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as shown below.
 (Producing a working Ansible configuration with <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
-file is described in <a href="#orgff33e02">The Ansible Configuration</a>.)
+file is described in <a href="#orgda31017">The Ansible Configuration</a>.)
 </p>
 
 <pre class="example">
@@ -1225,11 +1217,10 @@ notebook$ ansible-vault encrypt_string givitysticangout \
 notebook_     &gt;&gt;Secret/become.yml
 </pre>
 
-
 <p>
 After creating the <code>sysadm</code> account on the droplet, the administrator
 concatenated a personal public ssh key and the key found in
-<a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org671a111">The CA Command</a>) into an <q>admin_keys</q>
+<a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org3fe9e37">The CA Command</a>) into an <q>admin_keys</q>
 file, copied it to the droplet, and installed it as the
 <q>authorized_keys</q> for <code>sysadm</code>.
 </p>
@@ -1253,7 +1244,6 @@ notebook$ rm admin_keys
 notebook$
 </pre>
 
-
 <p>
 The Ansible configuration expects certain host keys on the new front.
 The administrator should install them now, and deal with the machine's
@@ -1272,7 +1262,6 @@ sysadm@ubuntu$ logout
 notebook$ ssh-keygen -f ~/.ssh/known_hosts -R 159.65.75.60
 </pre>
 
-
 <p>
 The last command removes the old host key from the administrator's
 <q>known_hosts</q> file.  The next SSH connection should ask to confirm the
@@ -1291,7 +1280,6 @@ sysadm@ubuntu$ sudo head -1 /etc/shadow
 root:*:18355:0:99999:7:::
 </pre>
 
-
 <p>
 <i>After</i> passing the above test, the administrator disabled root logins
 on the droplet.  The last command below tested that root logins were
@@ -1306,7 +1294,6 @@ root@159.65.75.60: Permission denied (publickey).
 notebook$ 
 </pre>
 
-
 <p>
 At this point the droplet was ready for configuration by Ansible.
 Later, provisioned with all of Front's services <i>and</i> tested, the
@@ -1316,8 +1303,8 @@ address.
 </div>
 </div>
 </div>
-<div id="outline-container-org8d60b7b" class="outline-3">
-<h3 id="org8d60b7b"><span class="section-number-3">5.2.</span> The Core Machine</h3>
+<div id="outline-container-orgae4ce75" class="outline-3">
+<h3 id="orgae4ce75"><span class="section-number-3">5.2.</span> The Core Machine</h3>
 <div class="outline-text-3" id="text-5-2">
 <p>
 Core is the small institute's private file, email, cloud and whatnot
@@ -1341,7 +1328,7 @@ The following example prepared a new core on a PC with Debian 11
 freshly installed.  During installation, the machine was named <code>core</code>,
 no desktop or server software was installed, no root password was set,
 and a privileged account named <code>sysadm</code> was created (per the policy in
-<a href="#org00e3480">The Administration Accounts</a>).
+<a href="#org4a8c2dc">The Administration Accounts</a>).
 </p>
 
 <pre class="example">
@@ -1353,12 +1340,11 @@ Retype new password: oingstramextedil
 Is the information correct? [Y/n] 
 </pre>
 
-
 <p>
 The password was generated by <code>gpw</code>, saved in the administrator's
 password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as shown below.
 (Producing a working Ansible configuration with <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
-file is described in <a href="#orgff33e02">The Ansible Configuration</a>.)
+file is described in <a href="#orgda31017">The Ansible Configuration</a>.)
 </p>
 
 <pre class="example">
@@ -1369,7 +1355,6 @@ notebook$ ansible-vault encrypt_string oingstramextedil \
 notebook_     &gt;&gt;Secret/become.yml
 </pre>
 
-
 <p>
 With Debian freshly installed, Core needed several additional software
 packages.  The administrator temporarily plugged Core into a cable
@@ -1383,7 +1368,6 @@ _                  postfix dovecot-imapd fetchmail expect rsync \
 _                  gnupg openssh-server
 </pre>
 
-
 <p>
 The Nextcloud configuration requires Apache2, MariaDB and a number of
 PHP modules.  Installing them while Core was on a cable modem sped up
@@ -1396,7 +1380,6 @@ _                  php-{json,mysql,mbstring,intl,imagick,xml,zip} \
 _                  libapache2-mod-php
 </pre>
 
-
 <p>
 Similarly, the NAGIOS configuration requires a handful of packages
 that were pre-loaded via cable modem (to test a frontier deployment).
@@ -1407,10 +1390,9 @@ $ sudo apt install nagios4 monitoring-plugins-basic lm-sensors \
 _                  nagios-nrpe-plugin
 </pre>
 
-
 <p>
 Next, the administrator concatenated a personal public ssh key and the
-key found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org671a111">The CA Command</a>) into an
+key found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org3fe9e37">The CA Command</a>) into an
 <q>admin_keys</q> file, copied it to Core, and installed it as the
 <q>authorized_keys</q> for <code>sysadm</code>.
 </p>
@@ -1434,7 +1416,6 @@ notebook$ rm admin_keys
 notebook$
 </pre>
 
-
 <p>
 Note that the name <code>core.lan</code> should be known to the cable modem's DNS
 service.  An IP address might be used instead, discovered with an <code>ip
@@ -1451,7 +1432,7 @@ a new, private IP address and a default route.
 <p>
 In the example command lines below, the address <code>10.227.248.1</code> was
 generated by the random subnet address picking procedure described in
-<a href="#orgda60362">Subnets</a>, and is named <code>core_addr</code> in the Ansible code.  The second
+<a href="#org29f9840">Subnets</a>, and is named <code>core_addr</code> in the Ansible code.  The second
 address, <code>10.227.248.2</code>, is the corresponding address for Gate's
 Ethernet interface, and is named <code>gate_addr</code> in the Ansible
 code.
@@ -1462,14 +1443,13 @@ sysadm@core$ sudo ip address add 10.227.248.1 dev enp82s0
 sysadm@core$ sudo ip route add default via 10.227.248.2 dev enp82s0
 </pre>
 
-
 <p>
 At this point Core was ready for provisioning with Ansible.
 </p>
 </div>
 </div>
-<div id="outline-container-org24e627c" class="outline-3">
-<h3 id="org24e627c"><span class="section-number-3">5.3.</span> The Gate Machine</h3>
+<div id="outline-container-org40481f7" class="outline-3">
+<h3 id="org40481f7"><span class="section-number-3">5.3.</span> The Gate Machine</h3>
 <div class="outline-text-3" id="text-5-3">
 <p>
 Gate is the small institute's route to the Internet, and the campus
@@ -1480,9 +1460,9 @@ interfaces.
 <ol class="org-ol">
 <li><code>lan</code> is its main Ethernet interface, connected to the campus's
 private Ethernet switch.</li>
-<li><code>wifi</code> is its second Ethernet interface, connected to the campus
-Wi-Fi access point's WAN Ethernet interface (with a cross-over
-cable).</li>
+<li><code>wild</code> is its second Ethernet interface, connected to the
+untrusted network of campus IoT appliances and Wi-Fi access
+point(s).</li>
 <li><code>isp</code> is its third network interface, connected to the campus
 ISP.  This could be an Ethernet device connected to a cable
 modem.  It could be a USB port tethered to a phone, a
@@ -1490,7 +1470,7 @@ USB-Ethernet adapter, or a wireless adapter connected to a
 campground Wi-Fi access point, etc.</li>
 </ol>
 
-<pre class="example" id="org04f5b91">
+<pre class="example" id="orgf49687b">
 =============== | ==================================================
                 |                                           Premises
           (Campus ISP)                                              
@@ -1503,8 +1483,8 @@ campground Wi-Fi access point, etc.</li>
                 +----Ethernet switch                                
 </pre>
 </div>
-<div id="outline-container-org60db67e" class="outline-4">
-<h4 id="org60db67e"><span class="section-number-4">5.3.1.</span> Alternate Gate Topology</h4>
+<div id="outline-container-org6edd1eb" class="outline-4">
+<h4 id="org6edd1eb"><span class="section-number-4">5.3.1.</span> Alternate Gate Topology</h4>
 <div class="outline-text-4" id="text-5-3-1">
 <p>
 While Gate and Core really need to be separate machines for security
@@ -1513,7 +1493,7 @@ This avoids the need for a second Wi-Fi access point and leads to the
 following topology.
 </p>
 
-<pre class="example" id="org56d9e40">
+<pre class="example" id="org0d82eb6">
 =============== | ==================================================
                 |                                           Premises
            (House ISP)                                              
@@ -1525,7 +1505,8 @@ following topology.
                 +----Ethernet switch                                
 </pre>
 <p>
-In this case Gate has two interfaces and there is no Gate-WiFi subnet.
+In this case Gate has two interfaces and there is no wild subnet
+other than the Internets themselves.
 </p>
 
 <p>
@@ -1536,12 +1517,12 @@ its Ethernet and Wi-Fi clients are allowed to communicate).
 </p>
 </div>
 </div>
-<div id="outline-container-org78bf309" class="outline-4">
-<h4 id="org78bf309"><span class="section-number-4">5.3.2.</span> Original Gate Topology</h4>
+<div id="outline-container-orgaa27474" class="outline-4">
+<h4 id="orgaa27474"><span class="section-number-4">5.3.2.</span> Original Gate Topology</h4>
 <div class="outline-text-4" id="text-5-3-2">
 <p>
 The Ansible code in this document is somewhat dependent on the
-physical network shown in the <a href="#org56d00a8">Overview</a> wherein Gate has three network
+physical network shown in the <a href="#org12986b7">Overview</a> wherein Gate has three network
 interfaces.
 </p>
 
@@ -1550,7 +1531,7 @@ The following example prepared a new gate on a PC with Debian 11
 freshly installed.  During installation, the machine was named <code>gate</code>,
 no desktop or server software was installed, no root password was set,
 and a privileged account named <code>sysadm</code> was created (per the policy in
-<a href="#org00e3480">The Administration Accounts</a>).
+<a href="#org4a8c2dc">The Administration Accounts</a>).
 </p>
 
 <pre class="example">
@@ -1562,12 +1543,11 @@ Retype new password: icismassssadestm
 Is the information correct? [Y/n] 
 </pre>
 
-
 <p>
 The password was generated by <code>gpw</code>, saved in the administrator's
 password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as shown below.
 (Producing a working Ansible configuration with <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
-file is described in <a href="#orgff33e02">The Ansible Configuration</a>.)
+file is described in <a href="#orgda31017">The Ansible Configuration</a>.)
 </p>
 
 <pre class="example">
@@ -1578,7 +1558,6 @@ notebook$ ansible-vault encrypt_string icismassssadestm \
 notebook_     &gt;&gt;Secret/become.yml
 </pre>
 
-
 <p>
 With Debian freshly installed, Gate needed a couple additional
 software packages.  The administrator temporarily plugged Gate into a
@@ -1591,10 +1570,9 @@ _                  ufw isc-dhcp-server postfix openvpn \
 _                  openssh-server
 </pre>
 
-
 <p>
 Next, the administrator concatenated a personal public ssh key and the
-key found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org671a111">The CA Command</a>) into an
+key found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org3fe9e37">The CA Command</a>) into an
 <q>admin_keys</q> file, copied it to Gate, and installed it as the
 <q>authorized_keys</q> for <code>sysadm</code>.
 </p>
@@ -1618,7 +1596,6 @@ notebook$ rm admin_keys
 notebook$
 </pre>
 
-
 <p>
 Note that the name <code>gate.lan</code> should be known to the cable modem's DNS
 service.  An IP address might be used instead, discovered with an <code>ip
@@ -1635,20 +1612,19 @@ a new, private IP address.
 <p>
 In the example command lines below, the address <code>10.227.248.2</code> was
 generated by the random subnet address picking procedure described in
-<a href="#orgda60362">Subnets</a>, and is named <code>gate_addr</code> in the Ansible code.
+<a href="#org29f9840">Subnets</a>, and is named <code>gate_addr</code> in the Ansible code.
 </p>
 
 <pre class="example">
 $ sudo ip address add 10.227.248.2 dev eth0
 </pre>
 
-
 <p>
 Gate was also connected to the USB Ethernet dongles cabled to the
 campus Wi-Fi access point and the campus ISP.  The three network
 adapters are known by their MAC addresses, the values of the variables
-<code>gate_lan_mac</code>, <code>gate_wifi_mac</code>, and <code>gate_isp_mac</code>.  (For more
-information, see the Gate role's <a href="#org176e1b0">Configure Netplan</a> task.)
+<code>gate_lan_mac</code>, <code>gate_wild_mac</code>, and <code>gate_isp_mac</code>.  (For more
+information, see the Gate role's <a href="#orgfd4af3f">Configure Netplan</a> task.)
 </p>
 
 <p>
@@ -1658,37 +1634,37 @@ At this point Gate was ready for provisioning with Ansible.
 </div>
 </div>
 </div>
-<div id="outline-container-orgd60dcd1" class="outline-2">
-<h2 id="orgd60dcd1"><span class="section-number-2">6.</span> The All Role</h2>
+<div id="outline-container-org72438bf" class="outline-2">
+<h2 id="org72438bf"><span class="section-number-2">6.</span> The All Role</h2>
 <div class="outline-text-2" id="text-6">
 <p>
 The <code>all</code> role contains tasks that are executed on all of the
 institute's servers.  At the moment there is just the one.
 </p>
 </div>
-<div id="outline-container-orgbc53e05" class="outline-3">
-<h3 id="orgbc53e05"><span class="section-number-3">6.1.</span> Include Particulars</h3>
+<div id="outline-container-org204ceac" class="outline-3">
+<h3 id="org204ceac"><span class="section-number-3">6.1.</span> Include Particulars</h3>
 <div class="outline-text-3" id="text-6-1">
 <p>
 The <code>all</code> role's task contains a reference to a common institute
 particular, the institute's <code>domain_name</code>, a variable found in the
 <q>public/vars.yml</q> file.  Thus the first task of the <code>all</code> role is to
-include the variables defined in this file (described in <a href="#orgfa75f05">The
+include the variables defined in this file (described in <a href="#orgb4f5586">The
 Particulars</a>).  The code block below is the first to tangle into
 <a href="roles/front/tasks/main.yml"><q>roles/all/tasks/main.yml</q></a>.
 </p>
 
 <div class="org-src-container">
-<a href="roles/front/tasks/main.yml"><q>roles/all/tasks/main.yml</q></a><pre class="src src-conf">---
+<a href="roles/front/tasks/main.yml"><q>roles/all/tasks/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Include public variables.
   include_vars: ../public/vars.yml
   tags: accounts
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgf85cc27" class="outline-3">
-<h3 id="orgf85cc27"><span class="section-number-3">6.2.</span> Enable Systemd Resolved</h3>
+<div id="outline-container-orgbfaf303" class="outline-3">
+<h3 id="orgbfaf303"><span class="section-number-3">6.2.</span> Enable Systemd Resolved</h3>
 <div class="outline-text-3" id="text-6-2">
 <p>
 The <code>systemd-networkd</code> and <code>systemd-resolved</code> service units are not
@@ -1709,7 +1685,7 @@ follows these recommendations (and <i>not</i> the suggestion to enable
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/all/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/all/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install systemd-resolved.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=systemd-resolved
@@ -1741,22 +1717,22 @@ follows these recommendations (and <i>not</i> the suggestion to enable
   when:
   <span class="org-variable-name">- ansible_distribution</span> == <span class="org-string">'Debian'</span>
   - 12 &gt; ansible_distribution_major_version|int
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgd3cb8ca" class="outline-3">
-<h3 id="orgd3cb8ca"><span class="section-number-3">6.3.</span> Trust Institute Certificate Authority</h3>
+<div id="outline-container-org2756611" class="outline-3">
+<h3 id="org2756611"><span class="section-number-3">6.3.</span> Trust Institute Certificate Authority</h3>
 <div class="outline-text-3" id="text-6-3">
 <p>
 All servers should recognize the institute's Certificate Authority as
 trustworthy, so its certificate is added to the set of trusted CAs on
 each host.  More information about how the small institute manages its
-X.509 certificates is available in <a href="#org6519b0c">Keys</a>.
+X.509 certificates is available in <a href="#org1c1be46">Keys</a>.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/all/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/all/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Trust the institute CA.
   become: yes
   copy:
@@ -1766,28 +1742,28 @@ X.509 certificates is available in <a href="#org6519b0c">Keys</a>.
     owner: root
     group: root
   notify: Update CAs.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/all/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/all/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Update CAs.
   become: yes
   command: update-ca-certificates
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-org9240129" class="outline-2">
-<h2 id="org9240129"><span class="section-number-2">7.</span> The Front Role</h2>
+<div id="outline-container-org1024107" class="outline-2">
+<h2 id="org1024107"><span class="section-number-2">7.</span> The Front Role</h2>
 <div class="outline-text-2" id="text-7">
 <p>
 The <code>front</code> role installs and configures the services expected on the
 institute's publicly accessible "front door": email, web, VPN.  The
 virtual machine is prepared with an Ubuntu Server install and remote
 access to a privileged, administrator's account.  (For details, see
-<a href="#org7661483">The Front Machine</a>.)
+<a href="#org9282df0">The Front Machine</a>.)
 </p>
 
 <p>
@@ -1808,17 +1784,17 @@ uses the institute's CA and server certificates, and expects client
 certificates signed by the institute CA.
 </p>
 </div>
-<div id="outline-container-org12c1e48" class="outline-3">
-<h3 id="org12c1e48"><span class="section-number-3">7.1.</span> Include Particulars</h3>
+<div id="outline-container-org92fa9ca" class="outline-3">
+<h3 id="org92fa9ca"><span class="section-number-3">7.1.</span> Include Particulars</h3>
 <div class="outline-text-3" id="text-7-1">
 <p>
-The first task, as in <a href="#orgd60dcd1">The All Role</a>, is to include the institute
+The first task, as in <a href="#org72438bf">The All Role</a>, is to include the institute
 particulars.  The <code>front</code> role refers to private variables and the
 membership roll, so these are included was well.
 </p>
 
 <div class="org-src-container">
-<a href="roles/front/tasks/main.yml"><q>roles/front/tasks/main.yml</q></a><pre class="src src-conf">---
+<a href="roles/front/tasks/main.yml"><q>roles/front/tasks/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Include public variables.
   include_vars: ../public/vars.yml
   tags: accounts
@@ -1830,12 +1806,12 @@ membership roll, so these are included was well.
 - name: Include members.
   include_vars: <span class="org-string">"{{ lookup('first_found', membership_rolls) }}"</span>
   tags: accounts
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org4c87c3a" class="outline-3">
-<h3 id="org4c87c3a"><span class="section-number-3">7.2.</span> Configure Hostname</h3>
+<div id="outline-container-orgd1223b4" class="outline-3">
+<h3 id="orgd1223b4"><span class="section-number-3">7.2.</span> Configure Hostname</h3>
 <div class="outline-text-3" id="text-7-2">
 <p>
 This task ensures that Front's <q>/etc/hostname</q> and <q>/etc/mailname</q> are
@@ -1844,7 +1820,7 @@ delivery.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">- name: Configure hostname.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure hostname.
   become: yes
   copy:
     content: <span class="org-string">"{{ domain_name }}\n"</span>
@@ -1853,20 +1829,20 @@ delivery.
   - /etc/hostname
   - /etc/mailname
   notify: Update hostname.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">---
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Update hostname.
   become: yes
   command: hostname -F /etc/hostname
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org053261f" class="outline-3">
-<h3 id="org053261f"><span class="section-number-3">7.3.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-orgc60729b" class="outline-3">
+<h3 id="orgc60729b"><span class="section-number-3">7.3.</span> Add Administrator to System Groups</h3>
 <div class="outline-text-3" id="text-7-3">
 <p>
 The administrator often needs to read (directories of) log files owned
@@ -1875,19 +1851,19 @@ these groups speeds up debugging.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Add {{ ansible_user }} to system groups.
   become: yes
   user:
     name: <span class="org-string">"{{ ansible_user }}"</span>
     append: yes
     groups: root,adm
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org633cf3e" class="outline-3">
-<h3 id="org633cf3e"><span class="section-number-3">7.4.</span> Configure SSH</h3>
+<div id="outline-container-org581d004" class="outline-3">
+<h3 id="org581d004"><span class="section-number-3">7.4.</span> Configure SSH</h3>
 <div class="outline-text-3" id="text-7-4">
 <p>
 The SSH service on Front needs to be known to Monkey.  The following
@@ -1896,7 +1872,7 @@ those stored in <a href="Secret/ssh_front/etc/ssh/"><q>Secret/ssh_front/etc/ssh/
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install SSH host keys.
   become: yes
   copy:
@@ -1911,22 +1887,22 @@ those stored in <a href="Secret/ssh_front/etc/ssh/"><q>Secret/ssh_front/etc/ssh/
   - { name: ssh_host_rsa_key,         mode: <span class="org-string">"u=rw,g=,o="</span> }
   - { name: ssh_host_rsa_key.pub,     mode: <span class="org-string">"u=rw,g=r,o=r"</span> }
   notify: Reload SSH server.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Reload SSH server.
   become: yes
   systemd:
     service: ssh
     state: reloaded
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orga03d6a3" class="outline-3">
-<h3 id="orga03d6a3"><span class="section-number-3">7.5.</span> Configure Monkey</h3>
+<div id="outline-container-org345d680" class="outline-3">
+<h3 id="org345d680"><span class="section-number-3">7.5.</span> Configure Monkey</h3>
 <div class="outline-text-3" id="text-7-5">
 <p>
 The small institute runs cron jobs and web scripts that generate
@@ -1934,13 +1910,13 @@ reports and perform checks.  The un-privileged jobs are run by a
 system account named <code>monkey</code>.  One of Monkey's more important jobs on
 Core is to run <code>rsync</code> to update the public web site on Front.  Monkey
 on Core will login as <code>monkey</code> on Front to synchronize the files (as
-described in <a href="#orgf59dafb">*Configure Apache2</a>).  To do that without needing a
+described in <a href="#orgbcda1ce">*Configure Apache2</a>).  To do that without needing a
 password, the <code>monkey</code> account on Front should authorize Monkey's SSH
 key on Core.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Create monkey.
   become: yes
   user:
@@ -1962,54 +1938,54 @@ key on Core.
     name: <span class="org-string">"{{ ansible_user }}"</span>
     append: yes
     groups: monkey
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgd1c69a2" class="outline-3">
-<h3 id="orgd1c69a2"><span class="section-number-3">7.6.</span> Install Rsync</h3>
+<div id="outline-container-orgce756fc" class="outline-3">
+<h3 id="orgce756fc"><span class="section-number-3">7.6.</span> Install Rsync</h3>
 <div class="outline-text-3" id="text-7-6">
 <p>
 Monkey uses Rsync to keep the institute's public web site up-to-date.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install rsync.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=rsync
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org80f3494" class="outline-3">
-<h3 id="org80f3494"><span class="section-number-3">7.7.</span> Install Unattended Upgrades</h3>
+<div id="outline-container-org0ec2b68" class="outline-3">
+<h3 id="org0ec2b68"><span class="section-number-3">7.7.</span> Install Unattended Upgrades</h3>
 <div class="outline-text-3" id="text-7-7">
 <p>
 The institute prefers to install security updates as soon as possible.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install basic software.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=unattended-upgrades
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org07c2e32" class="outline-3">
-<h3 id="org07c2e32"><span class="section-number-3">7.8.</span> Configure User Accounts</h3>
+<div id="outline-container-orgdd1398a" class="outline-3">
+<h3 id="orgdd1398a"><span class="section-number-3">7.8.</span> Configure User Accounts</h3>
 <div class="outline-text-3" id="text-7-8">
 <p>
 User accounts are created immediately so that Postfix and Dovecot can
 start delivering email immediately, <i>without</i> returning "no such
-recipient" replies.  The <a href="#orge7fe793">Account Management</a> chapter describes the
+recipient" replies.  The <a href="#org6138e49">Account Management</a> chapter describes the
 <code>members</code> and <code>usernames</code> variables used below.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Create user accounts.
   become: yes
   user:
@@ -2038,12 +2014,12 @@ recipient" replies.  The <a href="#orge7fe793">Account Management</a> chapter de
   loop: <span class="org-string">"{{ usernames }}"</span>
   <span class="org-variable-name">when: members[item].status !</span>= <span class="org-string">'current'</span>
   tags: accounts
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org42ffdc5" class="outline-3">
-<h3 id="org42ffdc5"><span class="section-number-3">7.9.</span> Install Server Certificate</h3>
+<div id="outline-container-org7ce2595" class="outline-3">
+<h3 id="org7ce2595"><span class="section-number-3">7.9.</span> Install Server Certificate</h3>
 <div class="outline-text-3" id="text-7-9">
 <p>
 The servers on Front use the same certificate (and key) to
@@ -2053,7 +2029,7 @@ readable by <code>root</code>.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install server certificate/key.
   become: yes
   copy:
@@ -2069,12 +2045,12 @@ readable by <code>root</code>.
   notify:
   - Restart Postfix.
   - Restart Dovecot.
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgba341a6" class="outline-3">
-<h3 id="orgba341a6"><span class="section-number-3">7.10.</span> Configure Postfix on Front</h3>
+<div id="outline-container-orga330953" class="outline-3">
+<h3 id="orga330953"><span class="section-number-3">7.10.</span> Configure Postfix on Front</h3>
 <div class="outline-text-3" id="text-7-10">
 <p>
 Front uses Postfix to provide the institute's public SMTP service, and
@@ -2091,7 +2067,7 @@ The appropriate answers are listed here but will be checked
 </ul>
 
 <p>
-As discussed in <a href="#org22a6220">The Email Service</a> above, Front's Postfix configuration
+As discussed in <a href="#org73635f2">The Email Service</a> above, Front's Postfix configuration
 includes site-wide support for larger message sizes, shorter queue
 times, the relaying configuration, and the common path to incoming
 emails.  These and a few Front-specific Postfix configurations
@@ -2104,13 +2080,13 @@ relays messages from the campus.
 </p>
 
 <div class="org-src-container">
-<code>postfix-front-networks</code><pre class="src src-conf" id="org4009fa9">- p: mynetworks
+<code>postfix-front-networks</code><pre class="src src-conf" id="orgba644bd"><code>- p: mynetworks
   v: &gt;-
      {{ public_vpn_net_cidr }}
      127.0.0.0/8
      [<span class="org-type">::ffff:127.0.0.0</span>]/104
      [<span class="org-type">::1</span>]/128
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2120,13 +2096,13 @@ difficult for internal hosts, who do <i>not</i> have (public) domain names.
 </p>
 
 <div class="org-src-container">
-<code>postfix-front-restrictions</code><pre class="src src-conf" id="org8c163ac">- p: smtpd_recipient_restrictions
+<code>postfix-front-restrictions</code><pre class="src src-conf" id="orga288f25"><code>- p: smtpd_recipient_restrictions
   v: &gt;-
      permit_mynetworks
      reject_unauth_pipelining
      reject_unauth_destination
      reject_unknown_sender_domain
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2141,15 +2117,15 @@ messages; incoming messages are delivered locally, without
 </p>
 
 <div class="org-src-container">
-<code>postfix-header-checks</code><pre class="src src-conf" id="org041fc35">- p: smtp_header_checks
+<code>postfix-header-checks</code><pre class="src src-conf" id="orga20329d"><code>- p: smtp_header_checks
   v: regexp:/etc/postfix/header_checks.cf
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<code>postfix-header-checks-content</code><pre class="src src-conf" id="org19e49f9">/^Received:/    IGNORE
+<code>postfix-header-checks-content</code><pre class="src src-conf" id="org0057dfe"><code>/^Received:/    IGNORE
 /^User-Agent:/  IGNORE
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2159,7 +2135,7 @@ Debian default for <code>inet_interfaces</code>.
 </p>
 
 <div class="org-src-container">
-<code>postfix-front</code><pre class="src src-conf" id="org86d7293">- { p: smtpd_tls_cert_file, v: /etc/server.crt }
+<code>postfix-front</code><pre class="src src-conf" id="org5ee702d"><code>- { p: smtpd_tls_cert_file, v: /etc/server.crt }
 - { p: smtpd_tls_key_file, v: /etc/server.key }
 &lt;&lt;postfix-front-networks&gt;&gt;
 &lt;&lt;postfix-front-restrictions&gt;&gt;
@@ -2168,7 +2144,7 @@ Debian default for <code>inet_interfaces</code>.
 &lt;&lt;postfix-queue-times&gt;&gt;
 &lt;&lt;postfix-maildir&gt;&gt;
 &lt;&lt;postfix-header-checks&gt;&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2178,7 +2154,7 @@ start and enable the service.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Postfix.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=postfix
@@ -2207,11 +2183,11 @@ start and enable the service.
     service: postfix
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart Postfix.
   become: yes
   systemd:
@@ -2224,12 +2200,12 @@ start and enable the service.
     chdir: /etc/postfix/
     cmd: postmap header_checks.cf
   notify: Restart Postfix.
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orge52533b" class="outline-3">
-<h3 id="orge52533b"><span class="section-number-3">7.11.</span> Configure Public Email Aliases</h3>
+<div id="outline-container-org75a0395" class="outline-3">
+<h3 id="org75a0395"><span class="section-number-3">7.11.</span> Configure Public Email Aliases</h3>
 <div class="outline-text-3" id="text-7-11">
 <p>
 The institute's Front needs to deliver email addressed to a number of
@@ -2246,7 +2222,7 @@ created by a more specialized role.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">- name: Install institute email aliases.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install institute email aliases.
   become: yes
   blockinfile:
     block: |
@@ -2258,20 +2234,20 @@ created by a more specialized role.
     path: /etc/aliases
     marker: <span class="org-string">"# {mark} INSTITUTE MANAGED BLOCK"</span>
   notify: New aliases.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: New aliases.
   become: yes
   command: newaliases
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org7960eac" class="outline-3">
-<h3 id="org7960eac"><span class="section-number-3">7.12.</span> Configure Dovecot IMAPd</h3>
+<div id="outline-container-orgdc00207" class="outline-3">
+<h3 id="orgdc00207"><span class="section-number-3">7.12.</span> Configure Dovecot IMAPd</h3>
 <div class="outline-text-3" id="text-7-12">
 <p>
 Front uses Dovecot's IMAPd to allow user Fetchmail jobs on Core to
@@ -2280,7 +2256,7 @@ default with POP and IMAP (without TLS) support disabled.  This is a
 bit "over the top" given that Core accesses Front via VPN, but helps
 to ensure privacy even when members must, in extremis, access recent
 email directly from their accounts on Front.  For more information
-about Front's role in the institute's email services, see <a href="#org22a6220">The Email
+about Front's role in the institute's email services, see <a href="#org73635f2">The Email
 Service</a>.
 </p>
 
@@ -2299,7 +2275,7 @@ and enables it to start at every reboot.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Dovecot IMAPd.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=dovecot-imapd
@@ -2322,22 +2298,22 @@ and enables it to start at every reboot.
     service: dovecot
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart Dovecot.
   become: yes
   systemd:
     service: dovecot
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgae570f4" class="outline-3">
-<h3 id="orgae570f4"><span class="section-number-3">7.13.</span> Configure Apache2 <a id="orgf59dafb"></a></h3>
+<div id="outline-container-orga7d4870" class="outline-3">
+<h3 id="orga7d4870"><span class="section-number-3">7.13.</span> Configure Apache2 <a id="orgbcda1ce"></a></h3>
 <div class="outline-text-3" id="text-7-13">
 <p>
 This is the small institute's public web site.  It is simple, static,
@@ -2373,7 +2349,7 @@ taken from <a href="https://www.ssllabs.com/projects/best-practices">https://www
 </p>
 
 <div class="org-src-container">
-<code>apache-ciphers</code><pre class="src src-conf" id="orgd788462">SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
+<code>apache-ciphers</code><pre class="src src-conf" id="orgd32683d"><code>SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
 SSLHonorCipherOrder on
 <span class="org-type">SSLCipherSuite {</span>{ [ <span class="org-string">'ECDHE-ECDSA-AES128-GCM-SHA256'</span>,
                     <span class="org-string">'ECDHE-ECDSA-AES256-GCM-SHA384'</span>,
@@ -2403,7 +2379,7 @@ SSLHonorCipherOrder on
                     <span class="org-string">'!SRP'</span>,
                     <span class="org-string">'!DSS'</span>,
                     <span class="org-string">'!RC4'</span> ] |join(<span class="org-string">":"</span>) }}
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2428,12 +2404,12 @@ used on all of the institute's web sites.
 </p>
 
 <div class="org-src-container">
-<code>apache-userdir-front</code><pre class="src src-conf" id="org02137da">UserDir /home/www-users
+<code>apache-userdir-front</code><pre class="src src-conf" id="org5949197"><code>UserDir /home/www-users
 &lt;Directory /home/www-users/&gt;
         Require all granted
         AllowOverride None
 &lt;/Directory&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2443,10 +2419,10 @@ HTTPS URLs.
 </p>
 
 <div class="org-src-container">
-<code>apache-redirect-front</code><pre class="src src-conf" id="org77c4862">&lt;VirtualHost *:80&gt;
+<code>apache-redirect-front</code><pre class="src src-conf" id="org8203d34"><code>&lt;VirtualHost *:80&gt;
         Redirect permanent / https://{{ domain_name }}/
 &lt;/VirtualHost&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2468,7 +2444,7 @@ the inside of a <code>VirtualHost</code> block.  They should apply globally.
 </p>
 
 <div class="org-src-container">
-<code>apache-front</code><pre class="src src-conf" id="org303a264">ServerName {{ domain_name }}
+<code>apache-front</code><pre class="src src-conf" id="org26265cf"><code>ServerName {{ domain_name }}
 ServerAdmin webmaster@{{ domain_name }}
 
 DocumentRoot /home/www
@@ -2493,7 +2469,7 @@ CustomLog ${APACHE_LOG_DIR}/access.log combined
 &lt;/VirtualHost&gt;
 
 &lt;&lt;apache-ciphers&gt;&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2503,7 +2479,7 @@ e.g. <q>/etc/apache2/sites-available/small.example.org.conf</q> and runs
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Apache2.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=apache2
@@ -2544,17 +2520,17 @@ e.g. <q>/etc/apache2/sites-available/small.example.org.conf</q> and runs
     service: apache2
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart Apache2.
   become: yes
   systemd:
     service: apache2
     state: restarted
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2563,7 +2539,7 @@ that it does not interfere with its replacement.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Disable default vhosts.
   become: yes
   file:
@@ -2571,7 +2547,7 @@ that it does not interfere with its replacement.
     state: absent
   loop: [ 000-default.conf, default-ssl.conf ]
   notify: Restart Apache2.
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2581,14 +2557,14 @@ same records as <q>access.log</q>.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Disable other-vhosts-access-log option.
   become: yes
   file:
     path: /etc/apache2/conf-enabled/other-vhosts-access-log.conf
     state: absent
   notify: Restart Apache2.
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2597,7 +2573,7 @@ the users' <q>~/Public/HTML/</q> directories.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Create UserDir.
   become: yes
   file:
@@ -2623,12 +2599,12 @@ the users' <q>~/Public/HTML/</q> directories.
   loop: <span class="org-string">"{{ usernames }}"</span>
   <span class="org-variable-name">when: members[item].status !</span>= <span class="org-string">'current'</span>
   tags: accounts
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org24ac22d" class="outline-3">
-<h3 id="org24ac22d"><span class="section-number-3">7.14.</span> Configure OpenVPN</h3>
+<div id="outline-container-org3bc00f9" class="outline-3">
+<h3 id="org3bc00f9"><span class="section-number-3">7.14.</span> Configure OpenVPN</h3>
 <div class="outline-text-3" id="text-7-14">
 <p>
 Front uses OpenVPN to provide the institute's public VPN service.  The
@@ -2641,9 +2617,9 @@ route packets for the campus networks to Core.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-ccd-core</code><pre class="src src-conf" id="orge20d97e">iroute {{ private_net_and_mask }}
+<code>openvpn-ccd-core</code><pre class="src src-conf" id="orgbbdd4f4"><code>iroute {{ private_net_and_mask }}
 iroute {{ campus_vpn_net_and_mask }}
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2658,21 +2634,21 @@ through some ISP, and thus needs the same routes as the clients.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-front-routes</code><pre class="src src-conf" id="org2a2ea3d">route {{ private_net_and_mask }}
+<code>openvpn-front-routes</code><pre class="src src-conf" id="org9e2d873"><code>route {{ private_net_and_mask }}
 route {{ campus_vpn_net_and_mask }}
 push <span class="org-string">"route {{ private_net_and_mask }}"</span>
 push <span class="org-string">"route {{ campus_vpn_net_and_mask }}"</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
 The complete OpenVPN configuration for Front includes a <code>server</code>
 option, the <code>client-config-dir</code> option, the routes mentioned above,
-and the common options discussed in <a href="#orgc2baf19">The VPN Service</a>.
+and the common options discussed in <a href="#org1ea6412">The VPN Service</a>.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-front</code><pre class="src src-conf" id="orgc467eda">server {{ public_vpn_net_and_mask }}
+<code>openvpn-front</code><pre class="src src-conf" id="org069808e"><code>server {{ public_vpn_net_and_mask }}
 client-config-dir /etc/openvpn/ccd
 &lt;&lt;openvpn-front-routes&gt;&gt;
 &lt;&lt;openvpn-dev-mode&gt;&gt;
@@ -2686,8 +2662,8 @@ ca /usr/local/share/ca-certificates/{{ domain_name }}.crt
 cert server.crt
 key server.key
 dh dh2048.pem
-tls-auth ta.key 0
-</pre>
+tls-crypt shared.key
+</code></pre>
 </div>
 
 <p>
@@ -2696,7 +2672,7 @@ configure the OpenVPN server on Front.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install OpenVPN.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=openvpn
@@ -2752,7 +2728,7 @@ configure the OpenVPN server on Front.
     <span class="org-variable-name">mode: u</span>=r,g=,o=
   loop:
   - { src: front-dh2048.pem, dest: dh2048.pem }
-  - { src: front-ta.key, dest: ta.key }
+  - { src: front-shared.key, dest: shared.key }
   notify: Restart OpenVPN.
 
 - name: Configure OpenVPN.
@@ -2770,22 +2746,22 @@ configure the OpenVPN server on Front.
     service: openvpn@server
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart OpenVPN.
   become: yes
   systemd:
     service: openvpn@server
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgc93df1f" class="outline-3">
-<h3 id="orgc93df1f"><span class="section-number-3">7.15.</span> Configure Kamailio</h3>
+<div id="outline-container-org4ec56d2" class="outline-3">
+<h3 id="org4ec56d2"><span class="section-number-3">7.15.</span> Configure Kamailio</h3>
 <div class="outline-text-3" id="text-7-15">
 <p>
 Front uses Kamailio to provide a SIP service on the public VPN so that
@@ -2807,8 +2783,8 @@ specifies the actual IP, known here as <code>front_private_addr</code>.
 </p>
 
 <div class="org-src-container">
-<code>kamailio</code><pre class="src src-conf" id="org3b9039b"><span class="org-variable-name">listen</span>=udp:{{ front_private_addr }}:5060
-</pre>
+<code>kamailio</code><pre class="src src-conf" id="orga8e875c"><code><span class="org-variable-name">listen</span>=udp:{{ front_private_addr }}:5060
+</code></pre>
 </div>
 
 <p>
@@ -2823,11 +2799,11 @@ The first step is to install Kamailio.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Kamailio.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=kamailio
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2838,7 +2814,7 @@ be started before the <code>tun</code> device has appeared.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Create Kamailio/Systemd configuration drop.
   become: yes
   file:
@@ -2854,16 +2830,16 @@ be started before the <code>tun</code> device has appeared.
       <span class="org-variable-name">After</span>=sys-devices-virtual-net-ovpn.device
     dest: /etc/systemd/system/kamailio.service.d/depend.conf
   notify: Reload Systemd.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Reload Systemd.
   become: yes
   systemd:
     daemon-reload: yes
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -2871,7 +2847,7 @@ Finally, Kamailio can be configured and started.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure Kamailio.
   become: yes
   copy:
@@ -2886,42 +2862,42 @@ Finally, Kamailio can be configured and started.
     service: kamailio
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart Kamailio.
   become: yes
   systemd:
     service: kamailio
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-orge7ebc83" class="outline-2">
-<h2 id="orge7ebc83"><span class="section-number-2">8.</span> The Core Role</h2>
+<div id="outline-container-orge6d718e" class="outline-2">
+<h2 id="orge6d718e"><span class="section-number-2">8.</span> The Core Role</h2>
 <div class="outline-text-2" id="text-8">
 <p>
 The <code>core</code> role configures many essential campus network services as
 well as the institute's private cloud, so the core machine has
 horsepower (CPUs and RAM) and large disks and is prepared with a
 Debian install and remote access to a privileged, administrator's
-account.  (For details, see <a href="#org8d60b7b">The Core Machine</a>.)
+account.  (For details, see <a href="#orgae4ce75">The Core Machine</a>.)
 </p>
 </div>
-<div id="outline-container-orgca8f5da" class="outline-3">
-<h3 id="orgca8f5da"><span class="section-number-3">8.1.</span> Include Particulars</h3>
+<div id="outline-container-org9f10251" class="outline-3">
+<h3 id="org9f10251"><span class="section-number-3">8.1.</span> Include Particulars</h3>
 <div class="outline-text-3" id="text-8-1">
 <p>
-The first task, as in <a href="#org9240129">The Front Role</a>, is to include the institute
+The first task, as in <a href="#org1024107">The Front Role</a>, is to include the institute
 particulars and membership roll.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">---
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Include public variables.
   include_vars: ../public/vars.yml
   tags: accounts
@@ -2931,12 +2907,12 @@ particulars and membership roll.
 - name: Include members.
   include_vars: <span class="org-string">"{{ lookup('first_found', membership_rolls) }}"</span>
   tags: accounts
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org90da685" class="outline-3">
-<h3 id="org90da685"><span class="section-number-3">8.2.</span> Configure Hostname</h3>
+<div id="outline-container-orgf5285f9" class="outline-3">
+<h3 id="orgf5285f9"><span class="section-number-3">8.2.</span> Configure Hostname</h3>
 <div class="outline-text-3" id="text-8-2">
 <p>
 This task ensures that Core's <q>/etc/hostname</q> and <q>/etc/mailname</q> are
@@ -2947,7 +2923,7 @@ proper email delivery.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure hostname.
   become: yes
   copy:
@@ -2957,20 +2933,20 @@ proper email delivery.
   - { name: <span class="org-string">"core.{{ domain_priv }}"</span>, file: /etc/mailname }
   - { name: <span class="org-string">"{{ inventory_hostname }}"</span>, file: /etc/hostname }
   notify: Update hostname.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">---
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Update hostname.
   become: yes
   command: hostname -F /etc/hostname
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org0fa3ade" class="outline-3">
-<h3 id="org0fa3ade"><span class="section-number-3">8.3.</span> Configure Systemd Resolved</h3>
+<div id="outline-container-org06a86c3" class="outline-3">
+<h3 id="org06a86c3"><span class="section-number-3">8.3.</span> Configure Systemd Resolved</h3>
 <div class="outline-text-3" id="text-8-3">
 <p>
 Core runs the campus name server, so Resolved is configured to use it
@@ -2979,7 +2955,7 @@ list, and to disable its cache and stub listener.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure resolved.
   become: yes
   lineinfile:
@@ -2995,11 +2971,11 @@ list, and to disable its cache and stub listener.
   notify:
   - Reload Systemd.
   - Restart Systemd resolved.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Reload Systemd.
   become: yes
   systemd:
@@ -3010,12 +2986,12 @@ list, and to disable its cache and stub listener.
   systemd:
     service: systemd-resolved
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org2dec986" class="outline-3">
-<h3 id="org2dec986"><span class="section-number-3">8.4.</span> Configure Netplan</h3>
+<div id="outline-container-org9272d80" class="outline-3">
+<h3 id="org9272d80"><span class="section-number-3">8.4.</span> Configure Netplan</h3>
 <div class="outline-text-3" id="text-8-4">
 <p>
 Core's network interface is statically configured using Netplan and an
@@ -3035,12 +3011,12 @@ fact was an empty hash at first boot on a simulated campus Ethernet.)
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">core_ethernet:              enp0s3
-</pre>
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>core_ethernet:              enp0s3
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install netplan.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=netplan.io
@@ -3062,20 +3038,20 @@ fact was an empty hash at first boot on a simulated campus Ethernet.)
     dest: /etc/netplan/60-core.yaml
     <span class="org-variable-name">mode: u</span>=rw,g=r,o=
   notify: Apply netplan.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Apply netplan.
   become: yes
   command: netplan apply
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org404665f" class="outline-3">
-<h3 id="org404665f"><span class="section-number-3">8.5.</span> Configure DHCP For the Private Ethernet</h3>
+<div id="outline-container-orgf1c124e" class="outline-3">
+<h3 id="orgf1c124e"><span class="section-number-3">8.5.</span> Configure DHCP For the Private Ethernet</h3>
 <div class="outline-text-3" id="text-8-5">
 <p>
 Core speaks DHCP (Dynamic Host Configuration Protocol) using the
@@ -3090,12 +3066,13 @@ The example configuration file, <a href="private/core-dhcpd.conf"><q>private/cor
 RFC3442's extension to encode a second (non-default) static route.
 The default route is through the campus ISP at Gate.  A second route
 directs campus traffic to the Front VPN through Core.  This is just an
-example file.  The administrator adds and removes actual machines from
-the actual <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a> file.
+example file, with MAC addresses chosen to (probably?) match
+VirtualBox test machines.  In actual use <q>private/core-dhcpd.conf</q>
+refers to a replacement file.
 </p>
 
 <div class="org-src-container">
-<a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a><pre class="src src-conf">option domain-name <span class="org-string">"small.private"</span>;
+<a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a><pre class="src src-conf"><code>option domain-name <span class="org-string">"small.private"</span>;
 option domain-name-servers 192.168.56.1;
 
 default-lease-time 3600;
@@ -3123,16 +3100,16 @@ log-facility daemon;
   hardware ethernet 08:00:27:e0:79:ab; fixed-address 192.168.56.2; }
 <span class="org-type">host server</span> {
   hardware ethernet 08:00:27:f3:41:66; fixed-address 192.168.56.3; }
-</pre>
+</code></pre>
 </div>
 
 <p>
-The following tasks install the ISC's DHCP server and configure it
-with the real <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a> (<i>not</i> the example above).
+The following tasks install ISC's DHCP server and configure it with
+the real <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a> (<i>not</i> the example above).
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install DHCP server.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=isc-dhcp-server
@@ -3158,26 +3135,26 @@ with the real <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></
     service: isc-dhcp-server
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart DHCP server.
   become: yes
   systemd:
     service: isc-dhcp-server
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org2134214" class="outline-3">
-<h3 id="org2134214"><span class="section-number-3">8.6.</span> Configure BIND9</h3>
+<div id="outline-container-org40752b1" class="outline-3">
+<h3 id="org40752b1"><span class="section-number-3">8.6.</span> Configure BIND9</h3>
 <div class="outline-text-3" id="text-8-6">
 <p>
 Core uses BIND9 to provide name service for the institute as described
-in <a href="#org12ea1d0">The Name Service</a>.  The configuration supports reverse name lookups,
+in <a href="#org189ccc3">The Name Service</a>.  The configuration supports reverse name lookups,
 resolving many private network addresses to private domain names.
 </p>
 
@@ -3186,7 +3163,7 @@ The following tasks install and configure BIND9 on Core.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install BIND9.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=bind9
@@ -3221,17 +3198,17 @@ The following tasks install and configure BIND9 on Core.
     service: bind9
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Reload BIND9.
   become: yes
   systemd:
     service: bind9
     state: reloaded
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -3242,11 +3219,11 @@ probably be used as forwarders rather than Google.
 </p>
 
 <div class="org-src-container">
-<code>bind-options</code><pre class="src src-conf" id="orgd750f78"><span class="org-type">acl </span><span class="org-string"><span class="org-type">"trusted"</span></span> {
+<code>bind-options</code><pre class="src src-conf" id="orgaf3e96b"><code><span class="org-type">acl </span><span class="org-string"><span class="org-type">"trusted"</span></span> {
         {{ private_net_cidr }};
+        {{ wild_net_cidr }};
         {{ public_vpn_net_cidr }};
         {{ campus_vpn_net_cidr }};
-        {{ gate_wifi_net_cidr }};
         localhost;
 };
 
@@ -3267,11 +3244,11 @@ probably be used as forwarders rather than Google.
                 localhost;
         };
 };
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<code>bind-local</code><pre class="src src-conf" id="orge2f865d">include <span class="org-string">"/etc/bind/zones.rfc1918"</span>;
+<code>bind-local</code><pre class="src src-conf" id="org5ab6230"><code>include <span class="org-string">"/etc/bind/zones.rfc1918"</span>;
 
 <span class="org-type">zone </span><span class="org-string"><span class="org-type">"{{ domain_priv }}."</span></span> {
         type master;
@@ -3295,11 +3272,11 @@ probably be used as forwarders rather than Google.
         type master;
         file <span class="org-string">"/etc/bind/db.campus_vpn"</span>;
 };
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="private/db.domain"><q>private/db.domain</q></a><pre class="src src-conf">;
+<a href="private/db.domain"><q>private/db.domain</q></a><pre class="src src-conf"><code>;
 ; BIND data file for a small institute<span class="org-string">'s PRIVATE domain names.</span>
 <span class="org-string">;</span>
 <span class="org-string">$TTL    604800</span>
@@ -3323,11 +3300,11 @@ probably be used as forwarders rather than Google.
 <span class="org-string">;</span>
 <span class="org-string">core    IN      A       192.168.56.1</span>
 <span class="org-string">gate    IN      A       192.168.56.2</span>
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="private/db.private"><q>private/db.private</q></a><pre class="src src-conf">;
+<a href="private/db.private"><q>private/db.private</q></a><pre class="src src-conf"><code>;
 ; BIND reverse data file for a small institute<span class="org-string">'s private Ethernet.</span>
 <span class="org-string">;</span>
 <span class="org-string">$TTL    604800</span>
@@ -3342,11 +3319,11 @@ probably be used as forwarders rather than Google.
 <span class="org-string">$TTL    7200</span>
 <span class="org-string">1       IN      PTR     core.small.private.</span>
 <span class="org-string">2       IN      PTR     gate.small.private.</span>
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="private/db.public_vpn"><q>private/db.public_vpn</q></a><pre class="src src-conf">;
+<a href="private/db.public_vpn"><q>private/db.public_vpn</q></a><pre class="src src-conf"><code>;
 ; BIND reverse data file for a small institute<span class="org-string">'s public VPN.</span>
 <span class="org-string">;</span>
 <span class="org-string">$TTL    604800</span>
@@ -3361,11 +3338,11 @@ probably be used as forwarders rather than Google.
 <span class="org-string">$TTL    7200</span>
 <span class="org-string">1       IN      PTR     front-p.small.private.</span>
 <span class="org-string">2       IN      PTR     core-p.small.private.</span>
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="private/db.campus_vpn"><q>private/db.campus_vpn</q></a><pre class="src src-conf">;
+<a href="private/db.campus_vpn"><q>private/db.campus_vpn</q></a><pre class="src src-conf"><code>;
 ; BIND reverse data file for a small institute<span class="org-string">'s campus VPN.</span>
 <span class="org-string">;</span>
 <span class="org-string">$TTL    604800</span>
@@ -3379,12 +3356,12 @@ probably be used as forwarders rather than Google.
 <span class="org-string">@       IN      NS      core.small.private.</span>
 <span class="org-string">$TTL    7200</span>
 <span class="org-string">1       IN      PTR     gate-c.small.private.</span>
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgb5d04d3" class="outline-3">
-<h3 id="orgb5d04d3"><span class="section-number-3">8.7.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-org7b737c7" class="outline-3">
+<h3 id="org7b737c7"><span class="section-number-3">8.7.</span> Add Administrator to System Groups</h3>
 <div class="outline-text-3" id="text-8-7">
 <p>
 The administrator often needs to read (directories of) log files owned
@@ -3393,30 +3370,30 @@ these groups speeds up debugging.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Add {{ ansible_user }} to system groups.
   become: yes
   user:
     name: <span class="org-string">"{{ ansible_user }}"</span>
     append: yes
     groups: root,adm
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org6f07952" class="outline-3">
-<h3 id="org6f07952"><span class="section-number-3">8.8.</span> Configure Monkey</h3>
+<div id="outline-container-orgd39c2c0" class="outline-3">
+<h3 id="orgd39c2c0"><span class="section-number-3">8.8.</span> Configure Monkey</h3>
 <div class="outline-text-3" id="text-8-8">
 <p>
 The small institute runs cron jobs and web scripts that generate
 reports and perform checks.  The un-privileged jobs are run by a
 system account named <code>monkey</code>.  One of Monkey's more important jobs on
 Core is to run <code>rsync</code> to update the public web site on Front (as
-described in <a href="#org1ac6235">*Configure Apache2</a>).
+described in <a href="#org682dcfc">*Configure Apache2</a>).
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Create monkey.
   become: yes
   user:
@@ -3468,54 +3445,54 @@ described in <a href="#org1ac6235">*Configure Apache2</a>).
     owner: monkey
     group: monkey
     mode: <span class="org-string">"u=rw,g=,o="</span>
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org3a924c4" class="outline-3">
-<h3 id="org3a924c4"><span class="section-number-3">8.9.</span> Install Unattended Upgrades</h3>
+<div id="outline-container-orgb3bf17a" class="outline-3">
+<h3 id="orgb3bf17a"><span class="section-number-3">8.9.</span> Install Unattended Upgrades</h3>
 <div class="outline-text-3" id="text-8-9">
 <p>
 The institute prefers to install security updates as soon as possible.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install basic software.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=unattended-upgrades
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgd919e4d" class="outline-3">
-<h3 id="orgd919e4d"><span class="section-number-3">8.10.</span> Install Expect</h3>
+<div id="outline-container-org9e31a35" class="outline-3">
+<h3 id="org9e31a35"><span class="section-number-3">8.10.</span> Install Expect</h3>
 <div class="outline-text-3" id="text-8-10">
 <p>
-The <code>expect</code> program is used by <a href="#org1c6f4a8">The Institute Commands</a> to interact
+The <code>expect</code> program is used by <a href="#org5db480b">The Institute Commands</a> to interact
 with Nextcloud on the command line.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install expect.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=expect
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org2e19b28" class="outline-3">
-<h3 id="org2e19b28"><span class="section-number-3">8.11.</span> Configure User Accounts</h3>
+<div id="outline-container-org2d28846" class="outline-3">
+<h3 id="org2d28846"><span class="section-number-3">8.11.</span> Configure User Accounts</h3>
 <div class="outline-text-3" id="text-8-11">
 <p>
 User accounts are created immediately so that backups can begin
-restoring as soon as possible.  The <a href="#orge7fe793">Account Management</a> chapter
+restoring as soon as possible.  The <a href="#org6138e49">Account Management</a> chapter
 describes the <code>members</code> and <code>usernames</code> variables.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Create user accounts.
   become: yes
   user:
@@ -3544,12 +3521,12 @@ describes the <code>members</code> and <code>usernames</code> variables.
   loop: <span class="org-string">"{{ usernames }}"</span>
   <span class="org-variable-name">when: members[item].status !</span>= <span class="org-string">'current'</span>
   tags: accounts
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org3893d2e" class="outline-3">
-<h3 id="org3893d2e"><span class="section-number-3">8.12.</span> Install Server Certificate</h3>
+<div id="outline-container-org3c35b95" class="outline-3">
+<h3 id="org3c35b95"><span class="section-number-3">8.12.</span> Install Server Certificate</h3>
 <div class="outline-text-3" id="text-8-12">
 <p>
 The servers on Core use the same certificate (and key) to authenticate
@@ -3558,7 +3535,7 @@ themselves to institute clients.  They share the <q>/etc/server.crt</q> and
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install server certificate/key.
   become: yes
   copy:
@@ -3574,12 +3551,12 @@ themselves to institute clients.  They share the <q>/etc/server.crt</q> and
   - Restart Postfix.
   - Restart Dovecot.
   - Restart OpenVPN.
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org1a74046" class="outline-3">
-<h3 id="org1a74046"><span class="section-number-3">8.13.</span> Install NTP</h3>
+<div id="outline-container-org668ece0" class="outline-3">
+<h3 id="org668ece0"><span class="section-number-3">8.13.</span> Install NTP</h3>
 <div class="outline-text-3" id="text-8-13">
 <p>
 Core uses NTP to provide a time synchronization service to the campus.
@@ -3587,16 +3564,16 @@ The default daemon's default configuration is fine.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install NTP.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=ntp
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org948efaa" class="outline-3">
-<h3 id="org948efaa"><span class="section-number-3">8.14.</span> Configure Postfix on Core</h3>
+<div id="outline-container-org296b053" class="outline-3">
+<h3 id="org296b053"><span class="section-number-3">8.14.</span> Configure Postfix on Core</h3>
 <div class="outline-text-3" id="text-8-14">
 <p>
 Core uses Postfix to provide SMTP service to the campus.  The default
@@ -3612,7 +3589,7 @@ The appropriate answers are listed here but will be checked
 </ul>
 
 <p>
-As discussed in <a href="#org22a6220">The Email Service</a> above, Core delivers email addressed
+As discussed in <a href="#org73635f2">The Email Service</a> above, Core delivers email addressed
 to any internal domain name locally, and uses its smarthost Front to
 relay the rest.  Core is reachable only on institute networks, so
 there is little benefit in enabling TLS, but it does need to handle
@@ -3625,7 +3602,7 @@ Core relays messages from any institute network.
 </p>
 
 <div class="org-src-container">
-<code>postfix-core-networks</code><pre class="src src-conf" id="orgf232831">- p: mynetworks
+<code>postfix-core-networks</code><pre class="src src-conf" id="org24ddb59"><code>- p: mynetworks
   v: &gt;-
      {{ private_net_cidr }}
      {{ public_vpn_net_cidr }}
@@ -3633,7 +3610,7 @@ Core relays messages from any institute network.
      127.0.0.0/8
      [<span class="org-type">::ffff:127.0.0.0</span>]/104
      [<span class="org-type">::1</span>]/128
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -3641,8 +3618,8 @@ Core uses Front to relay messages to the Internet.
 </p>
 
 <div class="org-src-container">
-<code>postfix-core-relayhost</code><pre class="src src-conf" id="org4eda440">- { p: relayhost, v: <span class="org-string">"[{{ front_private_addr }}]"</span> }
-</pre>
+<code>postfix-core-relayhost</code><pre class="src src-conf" id="orgabfee7f"><code>- { p: relayhost, v: <span class="org-string">"[{{ front_private_addr }}]"</span> }
+</code></pre>
 </div>
 
 <p>
@@ -3653,9 +3630,9 @@ file.
 </p>
 
 <div class="org-src-container">
-<code>postfix-transport</code><pre class="src src-conf" id="org32b43ff">.{{ domain_name }}      local:$myhostname
+<code>postfix-transport</code><pre class="src src-conf" id="org7dc82f6"><code>.{{ domain_name }}      local:$myhostname
 .{{ domain_priv }}      local:$myhostname
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -3664,7 +3641,7 @@ The complete list of Core's Postfix settings for
 </p>
 
 <div class="org-src-container">
-<code>postfix-core</code><pre class="src src-conf" id="org4ccefef">&lt;&lt;postfix-relaying&gt;&gt;
+<code>postfix-core</code><pre class="src src-conf" id="org7e631cc"><code>&lt;&lt;postfix-relaying&gt;&gt;
 - { p: smtpd_tls_security_level, v: none }
 - { p: smtp_tls_security_level, v: none }
 &lt;&lt;postfix-message-size&gt;&gt;
@@ -3673,7 +3650,7 @@ The complete list of Core's Postfix settings for
 &lt;&lt;postfix-core-networks&gt;&gt;
 &lt;&lt;postfix-core-relayhost&gt;&gt;
 - { p: inet_interfaces, v: <span class="org-string">"127.0.0.1 {{ core_addr }}"</span> }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -3684,7 +3661,7 @@ enable the service.  Whenever <q>/etc/postfix/transport</q> is changed, the
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Postfix.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=postfix
@@ -3714,11 +3691,11 @@ enable the service.  Whenever <q>/etc/postfix/transport</q> is changed, the
     service: postfix
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart Postfix.
   become: yes
   systemd:
@@ -3731,12 +3708,12 @@ enable the service.  Whenever <q>/etc/postfix/transport</q> is changed, the
     chdir: /etc/postfix/
     cmd: postmap transport
   notify: Restart Postfix.
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgaf844fe" class="outline-3">
-<h3 id="orgaf844fe"><span class="section-number-3">8.15.</span> Configure Private Email Aliases</h3>
+<div id="outline-container-org8d9476a" class="outline-3">
+<h3 id="org8d9476a"><span class="section-number-3">8.15.</span> Configure Private Email Aliases</h3>
 <div class="outline-text-3" id="text-8-15">
 <p>
 The institute's Core needs to deliver email addressed to institute
@@ -3748,7 +3725,7 @@ installed by more specialized roles.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install institute email aliases.
   become: yes
   blockinfile:
@@ -3761,20 +3738,20 @@ installed by more specialized roles.
     path: /etc/aliases
     marker: <span class="org-string">"# {mark} INSTITUTE MANAGED BLOCK"</span>
   notify: New aliases.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: New aliases.
   become: yes
   command: newaliases
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org14b48ba" class="outline-3">
-<h3 id="org14b48ba"><span class="section-number-3">8.16.</span> Configure Dovecot IMAPd</h3>
+<div id="outline-container-org77e47c0" class="outline-3">
+<h3 id="org77e47c0"><span class="section-number-3">8.16.</span> Configure Dovecot IMAPd</h3>
 <div class="outline-text-3" id="text-8-16">
 <p>
 Core uses Dovecot's IMAPd to store and serve member emails.  As on
@@ -3784,7 +3761,7 @@ top" given that Core is only accessed from private (encrypted)
 networks, but helps to ensure privacy even when members accidentally
 attempt connections from outside the private networks.  For more
 information about Core's role in the institute's email services, see
-<a href="#org22a6220">The Email Service</a>.
+<a href="#org73635f2">The Email Service</a>.
 </p>
 
 <p>
@@ -3792,7 +3769,7 @@ The institute follows the recommendation in the package
 <q>README.Debian</q> (in <q>/usr/share/dovecot-core/</q>) but replaces the
 default "snake oil" certificate with another, signed by the institute.
 (For more information about the institute's X.509 certificates, see
-<a href="#org6519b0c">Keys</a>.)
+<a href="#org1c1be46">Keys</a>.)
 </p>
 
 <p>
@@ -3802,7 +3779,7 @@ and enables it to start at every reboot.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Dovecot IMAPd.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=dovecot-imapd
@@ -3824,22 +3801,22 @@ and enables it to start at every reboot.
     service: dovecot
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart Dovecot.
   become: yes
   systemd:
     service: dovecot
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org5a3cd75" class="outline-3">
-<h3 id="org5a3cd75"><span class="section-number-3">8.17.</span> Configure Fetchmail</h3>
+<div id="outline-container-orgea0cf88" class="outline-3">
+<h3 id="orgea0cf88"><span class="section-number-3">8.17.</span> Configure Fetchmail</h3>
 <div class="outline-text-3" id="text-8-17">
 <p>
 Core runs a <code>fetchmail</code> for each member of the institute.  Individual
@@ -3856,7 +3833,7 @@ the username.  The template is only used when the record has a
 </p>
 
 <div class="org-src-container">
-<code>fetchmail-config</code><pre class="src src-conf" id="orgfa39704"><span class="org-comment-delimiter"># </span><span class="org-comment">Permissions on this file may be no greater than 0600.</span>
+<code>fetchmail-config</code><pre class="src src-conf" id="orge18ab2e"><code><span class="org-comment-delimiter"># </span><span class="org-comment">Permissions on this file may be no greater than 0600.</span>
 
 set no bouncemail
 set no spambounce
@@ -3867,7 +3844,7 @@ poll {{ front_private_addr }} protocol imap timeout 15
     username {{ item }}
     password <span class="org-string">"{{ members[item].password_fetchmail }}"</span> fetchall
     ssl sslproto tls1.2+ sslcertck sslcommonname {{ domain_name }}
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -3875,7 +3852,7 @@ The Systemd service description.
 </p>
 
 <div class="org-src-container">
-<code>fetchmail-service</code><pre class="src src-conf" id="org712bd17">[<span class="org-type">Unit</span>]
+<code>fetchmail-service</code><pre class="src src-conf" id="orga4027c9"><code>[<span class="org-type">Unit</span>]
 <span class="org-variable-name">Description</span>=Fetchmail --idle task for {{ item }}.
 <span class="org-variable-name">AssertPathExists</span>=/home/{{ item }}/.fetchmailrc
 <span class="org-variable-name">After</span>=openvpn@front.service
@@ -3890,7 +3867,7 @@ The Systemd service description.
 
 [<span class="org-type">Install</span>]
 <span class="org-variable-name">WantedBy</span>=default.target
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -3903,7 +3880,7 @@ provided the Core service.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install fetchmail.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=fetchmail
@@ -3946,7 +3923,7 @@ provided the Core service.
   <span class="org-variable-name">- members[item].status</span> == <span class="org-string">'current'</span>
   - members[item].password_fetchmail is defined
   tags: accounts
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -3955,7 +3932,7 @@ stopped and disabled from restarting at boot, deleted even.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Stop former user fetchmail services.
   become: yes
   systemd:
@@ -3967,7 +3944,7 @@ stopped and disabled from restarting at boot, deleted even.
   <span class="org-variable-name">- members[item].status !</span>= <span class="org-string">'current'</span>
   - members[item].password_fetchmail is defined
   tags: accounts
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -3977,7 +3954,7 @@ Otherwise the following task might be appropriate.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-conf">
+<pre class="src src-conf"><code>
 - name: Delete former user fetchmail services.
   become: yes
   file:
@@ -3988,16 +3965,16 @@ Otherwise the following task might be appropriate.
   <span class="org-variable-name">- members[item].status !</span>= <span class="org-string">'current'</span>
   - members[item].password_fetchmail is defined
   tags: accounts
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org14de2c2" class="outline-3">
-<h3 id="org14de2c2"><span class="section-number-3">8.18.</span> Configure Apache2 <a id="org1ac6235"></a></h3>
+<div id="outline-container-orgbdf8137" class="outline-3">
+<h3 id="orgbdf8137"><span class="section-number-3">8.18.</span> Configure Apache2 <a id="org682dcfc"></a></h3>
 <div class="outline-text-3" id="text-8-18">
 <p>
 This is the small institute's campus web server.  It hosts several web
-sites as described in <a href="#org43cbe17">The Web Services</a>.
+sites as described in <a href="#orgf659a90">The Web Services</a>.
 </p>
 
 <table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
@@ -4068,12 +4045,12 @@ naming a sub-directory in the member's home directory on Core.  The
 </p>
 
 <div class="org-src-container">
-<code>apache-userdir-core</code><pre class="src src-conf" id="org74593c4">UserDir Public/HTML
+<code>apache-userdir-core</code><pre class="src src-conf" id="orge344fe6"><code>UserDir Public/HTML
 &lt;Directory /home/*/Public/HTML/&gt;
         Require all granted
         AllowOverride None
 &lt;/Directory&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4083,7 +4060,7 @@ redirect, the encryption ciphers and certificates.
 </p>
 
 <div class="org-src-container">
-<code>apache-live</code><pre class="src src-conf" id="org59c4779">&lt;VirtualHost *:80&gt;
+<code>apache-live</code><pre class="src src-conf" id="org6306943"><code>&lt;VirtualHost *:80&gt;
         ServerName live
         ServerAlias live.{{ domain_priv }}
         ServerAdmin webmaster@core.{{ domain_priv }}
@@ -4101,7 +4078,7 @@ redirect, the encryption ciphers and certificates.
 
         IncludeOptional /etc/apache2/sites-available/live-vhost.conf
 &lt;/VirtualHost&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4110,7 +4087,7 @@ familiar.
 </p>
 
 <div class="org-src-container">
-<code>apache-test</code><pre class="src src-conf" id="orgb260f70">&lt;VirtualHost *:80&gt;
+<code>apache-test</code><pre class="src src-conf" id="org455bb19"><code>&lt;VirtualHost *:80&gt;
         ServerName test
         ServerAlias test.{{ domain_priv }}
         ServerAdmin webmaster@core.{{ domain_priv }}
@@ -4128,7 +4105,7 @@ familiar.
 
         IncludeOptional /etc/apache2/sites-available/test-vhost.conf
 &lt;/VirtualHost&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4139,7 +4116,7 @@ trained staffers, monitored by a revision control system, etc.
 </p>
 
 <div class="org-src-container">
-<code>apache-campus</code><pre class="src src-conf" id="orgeec93c4">&lt;VirtualHost *:80&gt;
+<code>apache-campus</code><pre class="src src-conf" id="org474a92e"><code>&lt;VirtualHost *:80&gt;
         ServerName www
         ServerAlias www.{{ domain_priv }}
         ServerAdmin webmaster@core.{{ domain_priv }}
@@ -4159,7 +4136,7 @@ trained staffers, monitored by a revision control system, etc.
 
         IncludeOptional /etc/apache2/sites-available/www-vhost.conf
 &lt;/VirtualHost&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4167,7 +4144,7 @@ The tasks below install Apache2 and edit its default configuration.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Apache2.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=apache2
@@ -4176,9 +4153,21 @@ The tasks below install Apache2 and edit its default configuration.
   become: yes
   apache2_module:
     name: <span class="org-string">"{{ item }}"</span>
-  loop: [ userdir, cgid ]
+  loop: [ userdir, cgid, ssl ]
   notify: Restart Apache2.
-</pre>
+
+- name: Configure Apache2 SSL certificate.
+  become: yes
+  lineinfile:
+    path: /etc/apache2/sites-available/default-ssl.conf
+    regexp: <span class="org-string">"^([\t ]*){{ item.p }}"</span>
+    line: <span class="org-string">"\\1{{ item.p }}\t{{ item.v }}"</span>
+    backrefs: yes
+  loop:
+    - { p: SSLCertificateFile, v: <span class="org-string">"/etc/server.crt"</span> }
+    - { p: SSLCertificateKeyFile, v: <span class="org-string">"/etc/server.key"</span> }
+  notify: Restart Apache2.
+</code></pre>
 </div>
 
 <p>
@@ -4188,7 +4177,7 @@ The <code>a2ensite</code> command enables them.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install live web site.
   become: yes
   copy:
@@ -4221,7 +4210,7 @@ The <code>a2ensite</code> command enables them.
   command:
     cmd: a2ensite -q {{ item }}
     creates: /etc/apache2/sites-enabled/{{ item }}.conf
-  loop: [ live, test, www ]
+  loop: [ live, test, www, default-ssl ]
   notify: Restart Apache2.
 
 - name: Enable/Start Apache2.
@@ -4230,22 +4219,22 @@ The <code>a2ensite</code> command enables them.
     service: apache2
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart Apache2.
   become: yes
   systemd:
     service: apache2
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org5eefe23" class="outline-3">
-<h3 id="org5eefe23"><span class="section-number-3">8.19.</span> Configure Website Updates</h3>
+<div id="outline-container-org88cbb1f" class="outline-3">
+<h3 id="org88cbb1f"><span class="section-number-3">8.19.</span> Configure Website Updates</h3>
 <div class="outline-text-3" id="text-8-19">
 <p>
 Monkey on Core runs <q>/usr/local/sbin/webupdate</q> every 15 minutes via a
@@ -4254,7 +4243,7 @@ Monkey on Core runs <q>/usr/local/sbin/webupdate</q> every 15 minutes via a
 </p>
 
 <div class="org-src-container">
-<a href="private/webupdate"><q>private/webupdate</q></a><pre class="src src-sh" id="orgbb22232"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
+<a href="private/webupdate"><q>private/webupdate</q></a><pre class="src src-sh" id="org56430fc"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
 <span class="org-comment-delimiter">#</span>
 <span class="org-comment-delimiter"># </span><span class="org-comment">DO NOT EDIT.  This file was tangled from institute.org.</span>
 
@@ -4264,17 +4253,17 @@ rsync -avz --delete --chmod=g-w         <span class="org-sh-escaped-newline">\</
         --filter=<span class="org-string">'exclude *~'</span>           <span class="org-sh-escaped-newline">\</span>
         --filter=<span class="org-string">'exclude .git*'</span>        <span class="org-sh-escaped-newline">\</span>
         ./ {{ domain_name }}:/home/www/
-</pre>
+</code></pre>
 </div>
 
 <p>
 The following tasks install the <q>webupdate</q> script from <a href="private/"><q>private/</q></a>,
 and create Monkey's <code>cron</code> job.  An example <q>webupdate</q> script is
-provided <a href="#orgbb22232">here</a>.
+provided <a href="#org56430fc">here</a>.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: <span class="org-string">"Install Monkey's webupdate script."</span>
   become: yes
   copy:
@@ -4291,12 +4280,12 @@ provided <a href="#orgbb22232">here</a>.
     job: <span class="org-string">"[ -d /WWW/live ] &amp;&amp; /usr/local/sbin/webupdate"</span>
     name: webupdate
     user: monkey
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org0eac7f7" class="outline-3">
-<h3 id="org0eac7f7"><span class="section-number-3">8.20.</span> Configure OpenVPN Connection to Front</h3>
+<div id="outline-container-org31f8027" class="outline-3">
+<h3 id="org31f8027"><span class="section-number-3">8.20.</span> Configure OpenVPN Connection to Front</h3>
 <div class="outline-text-3" id="text-8-20">
 <p>
 Core connects to Front's public VPN to provide members abroad with a
@@ -4313,7 +4302,7 @@ called <code>openvpn@front</code>.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-core</code><pre class="src src-conf" id="orgffe384f">client
+<code>openvpn-core</code><pre class="src src-conf" id="org7db87cf"><code>client
 dev-type tun
 dev ovpn
 remote {{ front_addr }}
@@ -4326,8 +4315,8 @@ verb 3
 ca /usr/local/share/ca-certificates/{{ domain_name }}.crt
 cert client.crt
 key client.key
-tls-auth ta.key 1
-</pre>
+tls-crypt shared.key
+</code></pre>
 </div>
 
 <p>
@@ -4336,7 +4325,7 @@ for Core.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install OpenVPN.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=openvpn
@@ -4351,8 +4340,8 @@ for Core.
 - name: Install OpenVPN secret.
   become: yes
   copy:
-    src: ../Secret/front-ta.key
-    dest: /etc/openvpn/ta.key
+    src: ../Secret/front-shared.key
+    dest: /etc/openvpn/shared.key
     <span class="org-variable-name">mode: u</span>=r,g=,o=
   notify: Restart OpenVPN.
 
@@ -4382,22 +4371,22 @@ for Core.
     service: openvpn@front
     state: started
     enabled: yes
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart OpenVPN.
   become: yes
   systemd:
     service: openvpn@front
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org517dee3" class="outline-3">
-<h3 id="org517dee3"><span class="section-number-3">8.21.</span> Configure NAGIOS</h3>
+<div id="outline-container-org6cb627e" class="outline-3">
+<h3 id="org6cb627e"><span class="section-number-3">8.21.</span> Configure NAGIOS</h3>
 <div class="outline-text-3" id="text-8-21">
 <p>
 Core runs a <code>nagios4</code> server to monitor "services" on institute hosts.
@@ -4417,7 +4406,7 @@ Core and Campus (and thus Gate) machines.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install NAGIOS4.
   become: yes
   apt:
@@ -4465,21 +4454,21 @@ Core and Campus (and thus Gate) machines.
     service: nagios4
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Reload NAGIOS4.
   become: yes
   systemd:
     service: nagios4
     state: reloaded
-</pre>
+</code></pre>
 </div>
 </div>
-<div id="outline-container-orgda831f7" class="outline-4">
-<h4 id="orgda831f7"><span class="section-number-4">8.21.1.</span> Configure NAGIOS Monitors for Core</h4>
+<div id="outline-container-org74a0c8d" class="outline-4">
+<h4 id="org74a0c8d"><span class="section-number-4">8.21.1.</span> Configure NAGIOS Monitors for Core</h4>
 <div class="outline-text-4" id="text-8-21-1">
 <p>
 The first block in <q>nagios.cfg</q> specifies monitors for services on
@@ -4489,7 +4478,7 @@ used here <i>may</i> specify plugin arguments.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><span class="org-type">define host</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define host</span> {
     use                     linux-server
     host_name               core
     address                 127.0.0.1
@@ -4550,12 +4539,12 @@ used here <i>may</i> specify plugin arguments.
     service_description     HTTP
     check_command           check_http
 }
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org447bb4c" class="outline-4">
-<h4 id="org447bb4c"><span class="section-number-4">8.21.2.</span> Custom NAGIOS Monitor <code>inst_sensors</code></h4>
+<div id="outline-container-orgb9ed6e7" class="outline-4">
+<h4 id="orgb9ed6e7"><span class="section-number-4">8.21.2.</span> Custom NAGIOS Monitor <code>inst_sensors</code></h4>
 <div class="outline-text-4" id="text-8-21-2">
 <p>
 The <code>check_sensors</code> plugin is included in the package
@@ -4565,7 +4554,7 @@ small institute substitutes a slightly modified version,
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/files/inst_sensors"><q>roles_t/core/files/inst_sensors</q></a><pre class="src src-sh"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">sh</span>
+<a href="roles_t/core/files/inst_sensors"><q>roles_t/core/files/inst_sensors</q></a><pre class="src src-sh"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">sh</span>
 
 <span class="org-variable-name">PATH</span>=<span class="org-string">"/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"</span>
 <span class="org-builtin">export</span> PATH
@@ -4641,7 +4630,7 @@ small institute substitutes a slightly modified version,
                 <span class="org-keyword">exit</span> $<span class="org-variable-name">exit</span>
                 ;;
 <span class="org-keyword">esac</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4650,7 +4639,7 @@ Core.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
 <span class="org-type">define command</span> {
     command_name            inst_sensors
     command_line            /usr/local/sbin/inst_sensors
@@ -4662,12 +4651,12 @@ Core.
     service_description     Temperature Sensors
     check_command           inst_sensors
 }
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orge20967c" class="outline-4">
-<h4 id="orge20967c"><span class="section-number-4">8.21.3.</span> Configure NAGIOS Monitors for Remote Hosts</h4>
+<div id="outline-container-org4c8f989" class="outline-4">
+<h4 id="org4c8f989"><span class="section-number-4">8.21.3.</span> Configure NAGIOS Monitors for Remote Hosts</h4>
 <div class="outline-text-4" id="text-8-21-3">
 <p>
 The following sections contain code blocks specifying monitors for
@@ -4684,12 +4673,12 @@ plugin with pre-defined arguments appropriate for the institute.  The
 commands are defined in code blocks interleaved with the blocks that
 monitor them.  The command blocks are appended to <q>nrpe.cfg</q> and the
 monitoring blocks to <q>nagios.cfg</q>.  The <q>nrpe.cfg</q> file is installed
-on each campus host by the campus role's <a href="#orgbd0ce38">Configure NRPE</a> tasks.
+on each campus host by the campus role's <a href="#org356ce5d">Configure NRPE</a> tasks.
 </p>
 </div>
 </div>
-<div id="outline-container-orgfe68c96" class="outline-4">
-<h4 id="orgfe68c96"><span class="section-number-4">8.21.4.</span> Configure NAGIOS Monitors for Gate</h4>
+<div id="outline-container-org5f33bb4" class="outline-4">
+<h4 id="org5f33bb4"><span class="section-number-4">8.21.4.</span> Configure NAGIOS Monitors for Gate</h4>
 <div class="outline-text-4" id="text-8-21-4">
 <p>
 Define the monitored host, <code>gate</code>.  Monitor its response to network
@@ -4697,13 +4686,13 @@ pings.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
 <span class="org-type">define host</span> {
     use                     linux-server
     host_name               gate
     address                 {{ gate_addr }}
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4712,8 +4701,8 @@ space on the root partition.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_root</span>]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
-</pre>
+<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><code><span class="org-variable-name">command</span>[<span class="org-constant">inst_root</span>]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
+</code></pre>
 </div>
 
 <p>
@@ -4721,14 +4710,14 @@ Monitor <code>inst_root</code> on Gate.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
 <span class="org-type">define service</span> {
     use                     generic-service
     host_name               gate
     service_description     Root Partition
     check_command           check_nrpe!inst_root
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4736,14 +4725,14 @@ Monitor <code>check_load</code> on Gate.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
 <span class="org-type">define service</span> {
     use                     generic-service
     host_name               gate
     service_description     Current Load
     check_command           check_nrpe!check_load
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4751,7 +4740,7 @@ Monitor <code>check_zombie_procs</code> and <code>check_total_procs</code> on Ga
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
 <span class="org-type">define service</span> {
     use                     generic-service
     host_name               gate
@@ -4765,7 +4754,7 @@ Monitor <code>check_zombie_procs</code> and <code>check_total_procs</code> on Ga
     service_description     Total Processes
     check_command           check_nrpe!check_total_procs
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4774,8 +4763,8 @@ usage.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_swap</span>]=/usr/lib/nagios/plugins/check_swap -w 20% -c 10%
-</pre>
+<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><code><span class="org-variable-name">command</span>[<span class="org-constant">inst_swap</span>]=/usr/lib/nagios/plugins/check_swap -w 20% -c 10%
+</code></pre>
 </div>
 
 <p>
@@ -4783,14 +4772,14 @@ Monitor <code>inst_swap</code> on Gate.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
 <span class="org-type">define service</span> {
     use                     generic-service
     host_name               gate
     service_description     Swap Usage
     check_command           check_nrpe!inst_swap
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4799,8 +4788,8 @@ CPU temperatures.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_sensors</span>]=/usr/local/sbin/inst_sensors
-</pre>
+<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><code><span class="org-variable-name">command</span>[<span class="org-constant">inst_sensors</span>]=/usr/local/sbin/inst_sensors
+</code></pre>
 </div>
 
 <p>
@@ -4808,52 +4797,52 @@ Monitor <code>inst_sensors</code> on Gate.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
 <span class="org-type">define service</span> {
     use                     generic-service
     host_name               gate
     service_description     Temperature Sensors
     check_command           check_nrpe!inst_sensors
 }
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-org04cc272" class="outline-3">
-<h3 id="org04cc272"><span class="section-number-3">8.22.</span> Configure Backups</h3>
+<div id="outline-container-org2323be4" class="outline-3">
+<h3 id="org2323be4"><span class="section-number-3">8.22.</span> Configure Backups</h3>
 <div class="outline-text-3" id="text-8-22">
 <p>
 The following task installs the <q>backup</q> script from <a href="private/"><q>private/</q></a>.  An
-example script is provided in <a href="#org9d5954c">here</a>.
+example script is provided in <a href="#org8d148e8">here</a>.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install backup script.
   become: yes
   copy:
     src: ../private/backup
     dest: /usr/local/sbin/backup
     <span class="org-variable-name">mode: u</span>=rx,g=r,o=
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgd97190a" class="outline-3">
-<h3 id="orgd97190a"><span class="section-number-3">8.23.</span> Configure Nextcloud</h3>
+<div id="outline-container-org640e4f7" class="outline-3">
+<h3 id="org640e4f7"><span class="section-number-3">8.23.</span> Configure Nextcloud</h3>
 <div class="outline-text-3" id="text-8-23">
 <p>
 Core runs Nextcloud to provide a private institute cloud, as described
-in <a href="#org71fc0ac">The Cloud Service</a>.  Installing, restoring (from backup), and
+in <a href="#orgd0834d2">The Cloud Service</a>.  Installing, restoring (from backup), and
 upgrading Nextcloud are manual processes documented in <a href="https://docs.nextcloud.com/server/latest/admin_manual/maintenance/">The Nextcloud
 Admin Manual, Maintenance</a>.  However Ansible can help prepare Core
 before an install or restore, and perform basic security checks
 afterwards.
 </p>
 </div>
-<div id="outline-container-orga7bf888" class="outline-4">
-<h4 id="orga7bf888"><span class="section-number-4">8.23.1.</span> Prepare Core For Nextcloud</h4>
+<div id="outline-container-orgea15814" class="outline-4">
+<h4 id="orgea15814"><span class="section-number-4">8.23.1.</span> Prepare Core For Nextcloud</h4>
 <div class="outline-text-4" id="text-8-23-1">
 <p>
 The Ansible code contained herein prepares Core to run Nextcloud by
@@ -4862,7 +4851,7 @@ installing a cron job.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install packages required by Nextcloud.
   become: yes
   apt:
@@ -4870,7 +4859,7 @@ installing a cron job.
            php-curl, php-gd, php-gmp, php-json, php-mysql,
            php-mbstring, php-intl, php-imagick, php-xml, php-zip,
            libapache2-mod-php ]
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4878,13 +4867,13 @@ Next, a number of Apache2 modules are enabled.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Enable Apache2 modules for Nextcloud.
   become: yes
   apache2_module:
     name: <span class="org-string">"{{ item }}"</span>
   loop: [ rewrite, headers, env, dir, mime ]
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4896,7 +4885,7 @@ Administration Guide (sub-section <a href="https://docs.nextcloud.com/server/lat
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf">Alias /nextcloud <span class="org-string">"/var/www/nextcloud/"</span>
+<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf"><code>Alias /nextcloud <span class="org-string">"/var/www/nextcloud/"</span>
 
 &lt;Directory /var/www/nextcloud/&gt;
     Require all granted
@@ -4907,11 +4896,11 @@ Administration Guide (sub-section <a href="https://docs.nextcloud.com/server/lat
         Dav off
     &lt;/IfModule&gt;
 &lt;/Directory&gt;
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Nextcloud web configuration.
   become: yes
   copy:
@@ -4925,7 +4914,7 @@ Administration Guide (sub-section <a href="https://docs.nextcloud.com/server/lat
     cmd: a2ensite nextcloud
     creates: /etc/apache2/sites-enabled/nextcloud.conf
   notify: Restart Apache2.
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4936,7 +4925,7 @@ virtual host's document root.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf">
+<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf"><code>
 &lt;Directory /var/www/html/&gt;
     &lt;IfModule mod_rewrite.c&gt;
         RewriteEngine on
@@ -4951,7 +4940,7 @@ virtual host's document root.
             <span class="org-variable-name">/nextcloud/index.php/.well-known/nodeinfo [R</span>=301,L]
       &lt;/IfModule&gt;
 &lt;/Directory&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4962,12 +4951,12 @@ page.  The following portion of <q>nextcloud.conf</q> sets a
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf">
+<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf"><code>
 &lt;IfModule mod_headers.c&gt;
     Header always set \
         Strict-Transport-Security <span class="org-string">"max-age=15552000; includeSubDomains"</span>
 &lt;/IfModule&gt;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4978,14 +4967,14 @@ cloud FUBARs.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Add {{ ansible_user }} to web server group.
   become: yes
   user:
     name: <span class="org-string">"{{ ansible_user }}"</span>
     append: yes
     groups: www-data
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -4994,7 +4983,7 @@ jobs.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Create Nextcloud cron job.
   become: yes
   cron:
@@ -5004,7 +4993,7 @@ jobs.
       &amp;&amp; /usr/bin/php -f /var/www/nextcloud/cron.php
     name: Nextcloud
     user: www-data
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5015,8 +5004,8 @@ the <code>apg -n 1 -x 12 -m 12</code> command.
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">nextcloud_dbpass:           ippAgmaygyob
-</pre>
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>nextcloud_dbpass:           ippAgmaygyob
+</code></pre>
 </div>
 
 <p>
@@ -5025,7 +5014,7 @@ the following task can create Nextcloud's DB.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-conf">
+<pre class="src src-conf"><code>
 - name: Create Nextcloud DB.
   become: yes
   mysql_db:
@@ -5033,7 +5022,7 @@ the following task can create Nextcloud's DB.
     name: nextcloud
     collation: utf8mb4_general_ci
     encoding: utf8mb4
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5047,12 +5036,12 @@ created manually.
 The following task would work (<code>mysql_user</code> supports
 <code>check_implicit_admin</code>) <i>but</i> the <code>nextcloud</code> database was not created
 above.  Thus both database and user are created manually, with SQL
-given in the <a href="#orga610911">8.23.5</a> subsection below, before <code>occ
+given in the <a href="#orgb7a7660">8.23.5</a> subsection below, before <code>occ
 maintenance:install</code> can run.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-conf">
+<pre class="src src-conf"><code>
 - name: Create Nextcloud DB user.
   become: yes
   mysql_user:
@@ -5061,7 +5050,7 @@ maintenance:install</code> can run.
     password: <span class="org-string">"{{ nextcloud_dbpass }}"</span>
     update_password: always
     priv: <span class="org-string">'nextcloud.*:all'</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5072,7 +5061,7 @@ its document root.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Link /var/www/nextcloud.
   become: yes
   file:
@@ -5081,12 +5070,12 @@ its document root.
     state: link
     force: yes
     follow: no
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org06f8ed1" class="outline-4">
-<h4 id="org06f8ed1"><span class="section-number-4">8.23.2.</span> Configure PHP</h4>
+<div id="outline-container-org3f0d821" class="outline-4">
+<h4 id="org3f0d821"><span class="section-number-4">8.23.2.</span> Configure PHP</h4>
 <div class="outline-text-4" id="text-8-23-2">
 <p>
 The following tasks set a number of PHP parameters for better
@@ -5094,7 +5083,7 @@ performance, as recommended by Nextcloud.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Set PHP memory_limit for Nextcloud.
   become: yes
   lineinfile:
@@ -5125,12 +5114,12 @@ performance, as recommended by Nextcloud.
     creates: /etc/php/8.2/apache2/conf.d/20-{{ item }}.ini
   loop: [ nextcloud, apcu ]
   notify: Restart Apache2.
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org45a4a2a" class="outline-4">
-<h4 id="org45a4a2a"><span class="section-number-4">8.23.3.</span> Create <q>/Nextcloud/</q></h4>
+<div id="outline-container-orgdb3439f" class="outline-4">
+<h4 id="orgdb3439f"><span class="section-number-4">8.23.3.</span> Create <q>/Nextcloud/</q></h4>
 <div class="outline-text-4" id="text-8-23-3">
 <p>
 The Ansible tasks up to this point have completed Core's LAMP stack
@@ -5155,9 +5144,9 @@ test machines.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo mkdir /Nextcloud
+<pre class="src src-sh"><code>sudo mkdir /Nextcloud
 sudo chmod 775 /Nextcloud
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5167,10 +5156,10 @@ second partition is mounted at <q>/home/</q>.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo mkdir /home/nextcloud
+<pre class="src src-sh"><code>sudo mkdir /home/nextcloud
 sudo chmod 775 /home/nextcloud
 sudo ln -s /home/nextcloud /Nextcloud
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5179,17 +5168,17 @@ partitioning) second hard drive, <q>/dev/sdb</q>.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo mkfs -t ext4 /dev/sdb
+<pre class="src src-sh"><code>sudo mkfs -t ext4 /dev/sdb
 sudo mkdir /Nextcloud
 <span class="org-builtin">echo</span> <span class="org-string">"/dev/sdb  /Nextcloud  ext4  errors=remount-ro  0  2"</span> <span class="org-sh-escaped-newline">\</span>
 | sudo tee -a /etc/fstab &gt;/dev/null
 sudo mount /Nextcloud
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org0568172" class="outline-4">
-<h4 id="org0568172"><span class="section-number-4">8.23.4.</span> Restore Nextcloud</h4>
+<div id="outline-container-org3c8ed7b" class="outline-4">
+<h4 id="org3c8ed7b"><span class="section-number-4">8.23.4.</span> Restore Nextcloud</h4>
 <div class="outline-text-4" id="text-8-23-4">
 <p>
 Restoring Nextcloud in the newly created <q>/Nextcloud/</q> presumably
@@ -5201,8 +5190,8 @@ a successful, complete copy).
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">rsync -a /media/sysadm/Backup/Nextcloud/ /Nextcloud/
-</pre>
+<pre class="src src-sh"><code>rsync -a /media/sysadm/Backup/Nextcloud/ /Nextcloud/
+</code></pre>
 </div>
 
 <p>
@@ -5213,8 +5202,8 @@ make it so.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo chown -R www-data.www-data /Nextcloud/nextcloud/
-</pre>
+<pre class="src src-sh"><code>sudo chown -R www-data.www-data /Nextcloud/nextcloud/
+</code></pre>
 </div>
 
 <p>
@@ -5222,15 +5211,15 @@ The database is restored with the following commands, which assume the
 last dump was made February 20th 2022 and thus was saved in
 <q>/Nextcloud/20220220.bak</q>.  The database will need to be
 created first as when installing Nextcloud.  The appropriate SQL are
-given in <a href="#orga610911">Install Nextcloud</a> below.
+given in <a href="#orgb7a7660">Install Nextcloud</a> below.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-builtin">cd</span> /Nextcloud/
+<pre class="src src-sh"><code><span class="org-builtin">cd</span> /Nextcloud/
 sudo mysql --defaults-file=dbbackup.cnf nextcloud &lt; 20220220.bak
 <span class="org-builtin">cd</span> nextcloud/
 sudo -u www-data php occ maintenance:data-fingerprint
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5240,8 +5229,8 @@ Overview web page.
 </p>
 </div>
 </div>
-<div id="outline-container-orga610911" class="outline-4">
-<h4 id="orga610911"><span class="section-number-4">8.23.5.</span> Install Nextcloud</h4>
+<div id="outline-container-orgb7a7660" class="outline-4">
+<h4 id="orgb7a7660"><span class="section-number-4">8.23.5.</span> Install Nextcloud</h4>
 <div class="outline-text-4" id="text-8-23-5">
 <p>
 Installing Nextcloud in the newly created <q>/Nextcloud/</q> starts with
@@ -5252,12 +5241,12 @@ directories and files.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-builtin">cd</span> /Nextcloud/
+<pre class="src src-sh"><code><span class="org-builtin">cd</span> /Nextcloud/
 tar xzf ~/Downloads/nextcloud-23.0.0.tar.bz2
 sudo chown -R www-data.www-data nextcloud
 sudo find nextcloud -type d -exec chmod 750 {} <span class="org-string">\;</span>
 sudo find nextcloud -type f -exec chmod 640 {} <span class="org-string">\;</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5271,25 +5260,25 @@ SQL prompt of the <code>sudo mysql</code> command).  The shell command then runs
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sql"><span class="org-keyword">create</span> database nextcloud
+<pre class="src src-sql"><code><span class="org-keyword">create</span> database nextcloud
     <span class="org-type">character</span> <span class="org-keyword">set</span> utf8mb4
     <span class="org-keyword">collate</span> utf8mb4_general_ci;
 <span class="org-keyword">grant</span> <span class="org-keyword">all</span> <span class="org-keyword">on</span> nextcloud.*
     <span class="org-keyword">to</span> <span class="org-string">'nextclouduser'</span>@<span class="org-string">'localhost'</span>
     identified <span class="org-keyword">by</span> <span class="org-string">'ippAgmaygyobwyt5'</span>;
 flush <span class="org-keyword">privileges</span>;
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-builtin">cd</span> /var/www/nextcloud/
+<pre class="src src-sh"><code><span class="org-builtin">cd</span> /var/www/nextcloud/
 sudo -u www-data php occ maintenance:install <span class="org-sh-escaped-newline">\</span>
      --data-dir=/var/www/nextcloud/data <span class="org-sh-escaped-newline">\</span>
      --database=mysql --database-name=nextcloud <span class="org-sh-escaped-newline">\</span>
      --database-user=nextclouduser <span class="org-sh-escaped-newline">\</span>
      --database-pass=ippAgmaygyobwyt5 <span class="org-sh-escaped-newline">\</span>
      --admin-user=sysadm --admin-pass=PASSWORD
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5305,15 +5294,14 @@ Core is next checked (or updated) e.g. with <code>./inst config -n core</code>.
 
 <p>
 Before calling Nextcloud "configured", the administrator runs <code>./inst
-config core</code>, surfs to <code>http://core.small.private/nextcloud/</code>,
-logins in as <code>sysadm</code>, and follows any reasonable
-instructions (reasonable for a small organization) on the
+config core</code>, surfs to <code>https://core.small.private/nextcloud/</code>, logins
+in as <code>sysadm</code>, and follows any reasonable instructions on the
 Administration &gt; Overview page.
 </p>
 </div>
 </div>
-<div id="outline-container-org380598a" class="outline-4">
-<h4 id="org380598a"><span class="section-number-4">8.23.6.</span> Afterwards</h4>
+<div id="outline-container-orgdc9a64a" class="outline-4">
+<h4 id="orgdc9a64a"><span class="section-number-4">8.23.6.</span> Afterwards</h4>
 <div class="outline-text-4" id="text-8-23-6">
 <p>
 Whether Nextcloud was restored or installed, there are a few things
@@ -5326,7 +5314,7 @@ afterwards tasks causes them to skip rather than fail.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Test for /Nextcloud/nextcloud/.
   stat:
     path: /Nextcloud/nextcloud
@@ -5334,7 +5322,7 @@ afterwards tasks causes them to skip rather than fail.
 - debug:
     msg: <span class="org-string">"/Nextcloud/ does not yet exist"</span>
   when: not nextcloud.stat.exists
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5357,7 +5345,7 @@ Pretty URLs (below).
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure Nextcloud trusted domains.
   become: yes
   replace:
@@ -5379,7 +5367,7 @@ Pretty URLs (below).
     insertbefore: <span class="org-string">"^[)];"</span>
     firstmatch: yes
   when: nextcloud.stat.exists
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5389,7 +5377,7 @@ enables it.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure Nextcloud memcache.
   become: yes
   lineinfile:
@@ -5399,7 +5387,7 @@ enables it.
     insertbefore: <span class="org-string">"^[)];"</span>
     firstmatch: yes
   when: nextcloud.stat.exists
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5411,7 +5399,7 @@ and <code>htaccess.RewriteBase</code>.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure Nextcloud for Pretty URLs.
   become: yes
   lineinfile:
@@ -5428,7 +5416,7 @@ and <code>htaccess.RewriteBase</code>.
   - regexp: <span class="org-string">"^ *'htaccess.RewriteBase' *=&gt;"</span>
     line: <span class="org-string">"  'htaccess.RewriteBase' =&gt; '/nextcloud',"</span>
   when: nextcloud.stat.exists
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5437,12 +5425,12 @@ a complaint on the Settings &gt; Administration &gt; Overview web page.
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">nextcloud_region:           US
-</pre>
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>nextcloud_region:           US
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure Nextcloud phone region.
   become: yes
   lineinfile:
@@ -5452,7 +5440,7 @@ a complaint on the Settings &gt; Administration &gt; Overview web page.
     insertbefore: <span class="org-string">"^[)];"</span>
     firstmatch: yes
   when: nextcloud.stat.exists
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5465,7 +5453,7 @@ run before the next backup.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Create /Nextcloud/dbbackup.cnf.
   no_log: yes
   become: yes
@@ -5489,33 +5477,33 @@ run before the next backup.
     <span class="org-variable-name">regexp: password</span>=
     <span class="org-variable-name">line: password</span>={{ nextcloud_dbpass }}
   when: nextcloud.stat.exists
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-org72d6fde" class="outline-2">
-<h2 id="org72d6fde"><span class="section-number-2">9.</span> The Gate Role</h2>
+<div id="outline-container-org936487d" class="outline-2">
+<h2 id="org936487d"><span class="section-number-2">9.</span> The Gate Role</h2>
 <div class="outline-text-2" id="text-9">
 <p>
-The <code>gate</code> role configures the services expected at the campus gate: a
-VPN into the campus network via a campus Wi-Fi access point, and
-Internet access via NAT to the Internet.  The gate machine uses
-three network interfaces (see <a href="#org24e627c">The Gate Machine</a>) configured with
-persistent names used in its firewall rules.
+The <code>gate</code> role configures the services expected at the campus gate:
+access to the private Ethernet from the untrusted Ethernet (e.g. a
+campus Wi-Fi AP) via VPN, and access to the Internet via NAT.  The
+gate machine uses three network interfaces (see <a href="#org40481f7">The Gate Machine</a>)
+configured with persistent names used in its firewall rules.
 </p>
 
 <dl class="org-dl">
 <dt><code>lan</code></dt><dd>The campus Ethernet.</dd>
-<dt><code>wifi</code></dt><dd>The campus Wi-Fi AP.</dd>
+<dt><code>wild</code></dt><dd>The campus IoT (Wi-Fi APs).</dd>
 <dt><code>isp</code></dt><dd>The campus ISP.</dd>
 </dl>
 
 <p>
-Requiring a VPN to access the campus network from the campus Wi-Fi
-bolsters the native Wi-Fi encryption and frustrates non-RYF (<a href="https://ryf.fsf.org">Respects
-Your Freedom</a>) wireless equipment.
+Requiring a VPN to access the campus network from the untrusted
+Ethernet (a campus Wi-Fi AP) bolsters the native Wi-Fi encryption and
+frustrates non-RYF (<a href="https://ryf.fsf.org">Respects Your Freedom</a>) wireless equipment.
 </p>
 
 <p>
@@ -5524,15 +5512,15 @@ applied first, by which Gate gets a campus machine's DNS and Postfix
 configurations, etc.
 </p>
 </div>
-<div id="outline-container-org0a4dc99" class="outline-3">
-<h3 id="org0a4dc99"><span class="section-number-3">9.1.</span> Include Particulars</h3>
+<div id="outline-container-orge1f832f" class="outline-3">
+<h3 id="orge1f832f"><span class="section-number-3">9.1.</span> Include Particulars</h3>
 <div class="outline-text-3" id="text-9-1">
 <p>
 The following should be familiar boilerplate by now.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">---
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Include public variables.
   include_vars: ../public/vars.yml
   tags: accounts
@@ -5542,17 +5530,17 @@ The following should be familiar boilerplate by now.
 - name: Include members.
   include_vars: <span class="org-string">"{{ lookup('first_found', membership_rolls) }}"</span>
   tags: accounts
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org1e2857f" class="outline-3">
-<h3 id="org1e2857f"><span class="section-number-3">9.2.</span> Configure Netplan <a id="org176e1b0"></a></h3>
+<div id="outline-container-org73026e0" class="outline-3">
+<h3 id="org73026e0"><span class="section-number-3">9.2.</span> Configure Netplan <a id="orgfd4af3f"></a></h3>
 <div class="outline-text-3" id="text-9-2">
 <p>
 Gate's network interfaces are configured using Netplan and two files.
 <q>/etc/netplan/60-gate.yaml</q> describes the static interfaces, to the
-campus Ethernet and WiFi.  <q>/etc/netplan/60-isp.yaml</q> is expected to
+campus Ethernet and Wi-Fi.  <q>/etc/netplan/60-isp.yaml</q> is expected to
 be revised more frequently as the campus ISP changes.
 </p>
 
@@ -5563,10 +5551,10 @@ example code here.
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">gate_lan_mac:               08:00:27:f3:16:79
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>gate_lan_mac:               08:00:27:f3:16:79
+gate_wild_mac:              08:00:27:4a:de:d2
 gate_isp_mac:               08:00:27:3d:42:e5
-gate_wifi_mac:              08:00:27:4a:de:d2
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5575,7 +5563,7 @@ new network plan.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install netplan (gate).
   become: yes
   <span class="org-variable-name">apt: pkg</span>=netplan.io
@@ -5598,11 +5586,11 @@ new network plan.
             routes:
               - to: {{ public_vpn_net_cidr }}
                 via: {{ core_addr }}
-          wifi:
+          wild:
             match:
-              macaddress: {{ gate_wifi_mac }}
-            addresses: [ {{ gate_wifi_addr_cidr }} ]
-            set-name: wifi
+              macaddress: {{ gate_wild_mac }}
+            addresses: [ {{ gate_wild_addr_cidr }} ]
+            set-name: wild
             dhcp4: false
     dest: /etc/netplan/60-gate.yaml
     <span class="org-variable-name">mode: u</span>=rw,g=r,o=
@@ -5625,15 +5613,15 @@ new network plan.
     <span class="org-variable-name">mode: u</span>=rw,g=r,o=
     force: no
   notify: Apply netplan.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf">---
+<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Apply netplan.
   become: yes
   command: netplan apply
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -5643,8 +5631,8 @@ campus ISP without interference from Ansible.
 </p>
 </div>
 </div>
-<div id="outline-container-orga752cf7" class="outline-3">
-<h3 id="orga752cf7"><span class="section-number-3">9.3.</span> UFW Rules</h3>
+<div id="outline-container-orge89b196" class="outline-3">
+<h3 id="orge89b196"><span class="section-number-3">9.3.</span> UFW Rules</h3>
 <div class="outline-text-3" id="text-9-3">
 <p>
 Gate uses the Uncomplicated FireWall (UFW) to install its packet
@@ -5662,32 +5650,32 @@ in <q>/etc/ufw/sysctl.conf</q>.
 NAT is enabled per the <code>ufw-framework(8)</code> manual page, by introducing
 <code>nat</code> table rules in a block at the end of <q>/etc/ufw/before.rules</q>.
 They translate packets going to the ISP.  These can come from the
-private Ethernet or campus Wi-Fi.  Hosts on the other institute
-networks (the two VPNs) should not be routing their Internet traffic
-through their VPN.
+private Ethernet or the untrusted Ethernet (campus IoT, including
+Wi-Fi APs).  Hosts on the other institute networks (the two VPNs)
+should not be routing their Internet traffic through their VPN.
 </p>
 
 <div class="org-src-container">
-<code>ufw-nat</code><pre class="src src-conf" id="org059a7f2">-A POSTROUTING -s {{   private_net_cidr }} -o isp -j MASQUERADE
--A POSTROUTING -s {{ gate_wifi_net_cidr }} -o isp -j MASQUERADE
-</pre>
+<code>ufw-nat</code><pre class="src src-conf" id="org2b6b37d"><code>-A POSTROUTING -s {{ private_net_cidr }} -o isp -j MASQUERADE
+-A POSTROUTING -s {{    wild_net_cidr }} -o isp -j MASQUERADE
+</code></pre>
 </div>
 
 <p>
 Forwarding rules are also needed.  The <code>nat</code> table is a <i>post</i> routing
 rule set, so the default routing policy (<code>DENY</code>) will drop packets
 before NAT can translate them.  The following rules are added to allow
-packets to be forwarded from the campus Ethernet or Gate-WiFi subnet
+packets to be forwarded from the campus Ethernet or its wild subnet
 to an ISP on the <code>isp</code> interface, and back (if related to an outgoing
 packet).
 </p>
 
 <div class="org-src-container">
-<code>ufw-forward-nat</code><pre class="src src-conf" id="org6c6443f">-A FORWARD -i lan  -o isp  -j ACCEPT
--A FORWARD -i wifi -o isp  -j ACCEPT
+<code>ufw-forward-nat</code><pre class="src src-conf" id="org63ab446"><code>-A FORWARD -i lan  -o isp  -j ACCEPT
+-A FORWARD -i wild -o isp  -j ACCEPT
 -A FORWARD -i isp  -o lan  {{ ACCEPT_RELATED }}
--A FORWARD -i isp  -o wifi {{ ACCEPT_RELATED }}
-</pre>
+-A FORWARD -i isp  -o wild {{ ACCEPT_RELATED }}
+</code></pre>
 </div>
 
 <p>
@@ -5700,7 +5688,6 @@ the following <code>iptables(8)</code> rule specification parameters.
 -m state --state ESTABLISHED,RELATED -j ACCEPT
 </pre>
 
-
 <p>
 If "the standard <code>iptables-restore</code> syntax" as it is described in the
 <code>ufw-framework</code> manual page, allows continuation lines, please let us
@@ -5716,19 +5703,19 @@ public and campus VPNs is also allowed.
 </p>
 
 <div class="org-src-container">
-<code>ufw-forward-private</code><pre class="src src-conf" id="orgbf5f811">-A FORWARD -i lan  -o ovpn -j ACCEPT
+<code>ufw-forward-private</code><pre class="src src-conf" id="org9b9c5a4"><code>-A FORWARD -i lan  -o ovpn -j ACCEPT
 -A FORWARD -i ovpn -o lan  -j ACCEPT
-</pre>
+</code></pre>
 </div>
 
 <p>
 Note that there are no forwarding rules to allow packets to pass from
-the <code>wifi</code> device to the <code>lan</code> device, just the <code>ovpn</code> device.
+the <code>wild</code> device to the <code>lan</code> device, just the <code>ovpn</code> device.
 </p>
 </div>
 </div>
-<div id="outline-container-org092a0fa" class="outline-3">
-<h3 id="org092a0fa"><span class="section-number-3">9.4.</span> Install UFW</h3>
+<div id="outline-container-org036ac74" class="outline-3">
+<h3 id="org036ac74"><span class="section-number-3">9.4.</span> Install UFW</h3>
 <div class="outline-text-3" id="text-9-4">
 <p>
 The following tasks install the Uncomplicated Firewall (UFW), set its
@@ -5740,16 +5727,15 @@ new-gate</code>, enabling the firewall could break Ansible's current and
 future ssh sessions.  For this reason, Ansible <i>does not</i> enable the
 firewall.  The administrator must login and execute the following
 command after Gate is configured or new gate is "in position"
-(connected to old Gate's <code>wifi</code> and <code>isp</code> networks).
+(connected to old Gate's <code>wild</code> and <code>isp</code> networks).
 </p>
 
 <pre class="example">
 sudo ufw enable
 </pre>
 
-
 <div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install UFW.
   become:
   <span class="org-variable-name">apt: pkg</span>=ufw
@@ -5785,64 +5771,68 @@ sudo ufw enable
       &lt;&lt;ufw-forward-private&gt;&gt;
       COMMIT
     insertafter: EOF
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org6b47f34" class="outline-3">
-<h3 id="org6b47f34"><span class="section-number-3">9.5.</span> Configure DHCP For The Gate-WiFi Ethernet</h3>
+<div id="outline-container-org43b50b8" class="outline-3">
+<h3 id="org43b50b8"><span class="section-number-3">9.5.</span> Configure DHCP For The Wild Ethernet</h3>
 <div class="outline-text-3" id="text-9-5">
 <p>
-To accommodate commodity Wi-Fi access points without re-configuring
-them, the institute attempts to look like an up-link, an ISP, e.g. a
-cable modem.  Thus it expects the wireless AP to route non-local
-traffic out its WAN Ethernet port, and to get an IP address for the
-WAN port using DHCP.  Thus Gate runs ISC's DHCP daemon configured to
-listen on one network interface, recognize exactly one client host,
-and provide that one client with an IP address and customary network
-parameters (default route, time server, etc.).
+To accommodate commodity Wi-Fi access points, as well as wired IoT
+appliances, without re-configuring them, the institute attempts to
+look like an up-link, an ISP, e.g. a cable modem (aka "router").  It
+expects a wireless AP (or IoT appliance) to route non-local traffic
+out its WAN (or only) Ethernet port, and to get an IP address for that
+port using DHCP.  Thus Gate runs ISC's DHCP daemon configured to
+listen on one network interface, recognize a specific list of clients,
+and provide each with an IP address and customary network parameters
+(default route, time server, etc.), much as was done on Core for the
+private Ethernet.
 </p>
 
 <p>
-Two Ansible variables are needed to configure Gate's DHCP service,
-specifically the sole subnet host: <code>wifi_wan_name</code> is any word
-appropriate for identifying the Wi-Fi AP, and <code>wifi_wan_mac</code> is the
-AP's MAC address.
+The example configuration file, <a href="private/gate-dhcpd.conf"><q>private/gate-dhcpd.conf</q></a>, unlike
+<a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a>, does not need RFC3442 (Classless static
+routes).  The wild, wired or wireless IoT need know nothing about the
+private network(s).  This is just an example file, with a MAC address
+chosen to (probably?) match a VirtualBox test machine.  In actual use
+<q>private/core-dhcpd.conf</q> refers to a replacement file.
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">wifi_wan_mac:               94:83:c4:19:7d:57
-wifi_wan_name:              campus-wifi-ap
-</pre>
-</div>
+<a href="private/gate-dhcpd.conf"><q>private/gate-dhcpd.conf</q></a><pre class="src src-conf"><code>default-lease-time 3600;
+max-lease-time 7200;
 
-<p>
-If Gate is configured with <code>./abbey config gate</code> and then connected to
-actual networks (i.e. <i>not</i> rebooted), the following command is
-executed.  If a new gate was configured with <code>./abbey config new-gate</code>
-and not rebooted, the following command would also be executed.
-</p>
+ddns-update-style none;
 
-<pre class="example">
-sudo systemctl start isc-dhcp-server
-</pre>
+authoritative;
 
+log-facility daemon;
 
-<p>
-If physically moved or rebooted for some other reason, the above
-command would not be necessary.
-</p>
+<span class="org-type">subnet 192.168.57.0 netmask 255.255.255.0</span> {
+  option subnet-mask 255.255.255.0;
+  option broadcast-address 192.168.57.255;
+  option routers 192.168.57.1;
+}
+
+<span class="org-type">host campus-wifi-ap</span> {
+  hardware ethernet 94:83:c4:19:7d:57;
+  fixed-address 192.168.57.2;
+}
+</code></pre>
+</div>
 
 <p>
 Installation and configuration of the DHCP daemon follows.  Note that
-the daemon listens <i>only</i> on the Gate-WiFi network interface.  Also
-note the drop-in <code>Requires</code> dependency, without which the DHCP server
-intermittently fails, finding the <code>wifi</code> interface has no IPv4
-addresses (or perhaps finding no <code>wifi</code> interface at all?).
+the daemon listens <i>only</i> on the <code>wild</code> network interface.  Also note
+the drop-in <code>Requires</code> dependency, without which the DHCP server
+intermittently fails, finding the <code>wild</code> interface has no IPv4
+addresses (or perhaps finding no <code>wild</code> interface at all?).
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install DHCP server.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=isc-dhcp-server
@@ -5851,10 +5841,17 @@ addresses (or perhaps finding no <code>wifi</code> interface at all?).
   become: yes
   lineinfile:
     path: /etc/default/isc-dhcp-server
-    <span class="org-variable-name">line: INTERFACESv4</span>=<span class="org-string">"wifi"</span>
+    <span class="org-variable-name">line: INTERFACESv4</span>=<span class="org-string">"wild"</span>
     <span class="org-variable-name">regexp: ^INTERFACESv4</span>=
   notify: Restart DHCP server.
 
+- name: Configure DHCP subnet.
+  become: yes
+  copy:
+    src: ../private/gate-dhcpd.conf
+    dest: /etc/dhcp/dhcpd.conf
+  notify: Restart DHCP server.
+
 - name: Configure DHCP server dependence on interface.
   become: yes
   copy:
@@ -5864,39 +5861,17 @@ addresses (or perhaps finding no <code>wifi</code> interface at all?).
     dest: /etc/systemd/system/isc-dhcp-server.service.d/depend.conf
   notify: Reload Systemd.
 
-- name: Configure DHCP for WiFiAP service.
-  become: yes
-  copy:
-    content: |
-      default-lease-time 3600;
-      max-lease-time 7200;
-      ddns-update-style none;
-      authoritative;
-      log-facility daemon;
-
-      <span class="org-type">subnet {{ gate_wifi_net }} netmask {{ gate_wifi_net_mask }}</span> {
-        option subnet-mask {{ gate_wifi_net_mask }};
-        option broadcast-address {{ gate_wifi_broadcast }};
-        option routers {{ gate_wifi_addr }};
-      }
-
-      <span class="org-type">host {{ wifi_wan_name }}</span> {
-        hardware ethernet {{ wifi_wan_mac }};
-        fixed-address {{ wifi_wan_addr }};
-      }
-    dest: /etc/dhcp/dhcpd.conf
-  notify: Restart DHCP server.
-
-- name: Enable DHCP server.
+- name: Enable/Start DHCP server.
   become: yes
   systemd:
     service: isc-dhcp-server
     enabled: yes
-</pre>
+    state: started
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart DHCP server.
   become: yes
   systemd:
@@ -5907,12 +5882,28 @@ addresses (or perhaps finding no <code>wifi</code> interface at all?).
   become: yes
   systemd:
     daemon-reload: yes
-</pre>
+</code></pre>
 </div>
+
+<p>
+If Gate is configured with <code>./abbey config gate</code> and then connected to
+actual networks (i.e. <i>not</i> rebooted), the following command is
+executed.  If a new gate was configured with <code>./abbey config new-gate</code>
+and not rebooted, the following command would also be executed.
+</p>
+
+<pre class="example">
+sudo systemctl start isc-dhcp-server
+</pre>
+
+<p>
+If physically moved or rebooted for some other reason, the above
+command would not be necessary.
+</p>
 </div>
 </div>
-<div id="outline-container-orgf647926" class="outline-3">
-<h3 id="orgf647926"><span class="section-number-3">9.6.</span> Install Server Certificate</h3>
+<div id="outline-container-org435e716" class="outline-3">
+<h3 id="org435e716"><span class="section-number-3">9.6.</span> Install Server Certificate</h3>
 <div class="outline-text-3" id="text-9-6">
 <p>
 The (OpenVPN) server on Gate uses an institute certificate (and key)
@@ -5922,7 +5913,7 @@ and Front) do.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install server certificate/key.
   become: yes
   copy:
@@ -5935,12 +5926,12 @@ and Front) do.
   - { path: <span class="org-string">"private/gate.{{ domain_priv }}"</span>, typ: key,
       mode: <span class="org-string">"u=r,g=,o="</span> }
   notify: Restart OpenVPN.
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orga48817c" class="outline-3">
-<h3 id="orga48817c"><span class="section-number-3">9.7.</span> Configure OpenVPN</h3>
+<div id="outline-container-org877d1b2" class="outline-3">
+<h3 id="org877d1b2"><span class="section-number-3">9.7.</span> Configure OpenVPN</h3>
 <div class="outline-text-3" id="text-9-7">
 <p>
 Gate uses OpenVPN to provide the institute's campus VPN service.  Its
@@ -5951,19 +5942,19 @@ to Front.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-gate-routes</code><pre class="src src-conf" id="org23c801d">push <span class="org-string">"route {{ private_net_and_mask }}"</span>
+<code>openvpn-gate-routes</code><pre class="src src-conf" id="org20aef17"><code>push <span class="org-string">"route {{ private_net_and_mask }}"</span>
 push <span class="org-string">"route {{ public_vpn_net_and_mask }}"</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
 The complete OpenVPN configuration for Gate includes a <code>server</code>
 option, the pushed routes mentioned above, and the common options
-discussed in <a href="#orgc2baf19">The VPN Services</a>.
+discussed in <a href="#org1ea6412">The VPN Services</a>.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-gate</code><pre class="src src-conf" id="org95cfc89">server {{ campus_vpn_net_and_mask }}
+<code>openvpn-gate</code><pre class="src src-conf" id="orgd61aa9a"><code>server {{ campus_vpn_net_and_mask }}
 client-config-dir /etc/openvpn/ccd
 &lt;&lt;openvpn-gate-routes&gt;&gt;
 &lt;&lt;openvpn-dev-mode&gt;&gt;
@@ -5977,8 +5968,8 @@ ca /usr/local/share/ca-certificates/{{ domain_name }}.crt
 cert /etc/server.crt
 key /etc/server.key
 dh dh2048.pem
-tls-auth ta.key 0
-</pre>
+tls-crypt shared.key
+</code></pre>
 </div>
 
 <p>
@@ -5987,7 +5978,7 @@ configure the OpenVPN server on Gate.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install OpenVPN.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=openvpn
@@ -6023,7 +6014,7 @@ configure the OpenVPN server on Gate.
     <span class="org-variable-name">mode: u</span>=r,g=,o=
   loop:
   - { src: gate-dh2048.pem, dest: dh2048.pem }
-  - { src: gate-ta.key, dest: ta.key }
+  - { src: gate-shared.key, dest: shared.key }
   notify: Restart OpenVPN.
 
 - name: Configure OpenVPN.
@@ -6034,23 +6025,23 @@ configure the OpenVPN server on Gate.
     dest: /etc/openvpn/server.conf
     <span class="org-variable-name">mode: u</span>=r,g=r,o=
   notify: Restart OpenVPN.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart OpenVPN.
   become: yes
   systemd:
     service: openvpn@server
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-org2d914f2" class="outline-2">
-<h2 id="org2d914f2"><span class="section-number-2">10.</span> The Campus Role</h2>
+<div id="outline-container-orgb271096" class="outline-2">
+<h2 id="orgb271096"><span class="section-number-2">10.</span> The Campus Role</h2>
 <div class="outline-text-2" id="text-10">
 <p>
 The <code>campus</code> role configures generic campus server machines: network
@@ -6067,32 +6058,32 @@ Wireless campus devices can get a key to the campus VPN from the
 configured manually.
 </p>
 </div>
-<div id="outline-container-org84fdcbf" class="outline-3">
-<h3 id="org84fdcbf"><span class="section-number-3">10.1.</span> Include Particulars</h3>
+<div id="outline-container-orgeb3c56c" class="outline-3">
+<h3 id="orgeb3c56c"><span class="section-number-3">10.1.</span> Include Particulars</h3>
 <div class="outline-text-3" id="text-10-1">
 <p>
 The following should be familiar boilerplate by now.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">---
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Include public variables.
   include_vars: ../public/vars.yml
 - name: Include private variables.
   include_vars: ../private/vars.yml
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgce42bc5" class="outline-3">
-<h3 id="orgce42bc5"><span class="section-number-3">10.2.</span> Configure Hostname</h3>
+<div id="outline-container-org6c045dd" class="outline-3">
+<h3 id="org6c045dd"><span class="section-number-3">10.2.</span> Configure Hostname</h3>
 <div class="outline-text-3" id="text-10-2">
 <p>
 Clients should be using the expected host name.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure hostname.
   become: yes
   copy:
@@ -6108,12 +6099,12 @@ Clients should be using the expected host name.
   become: yes
   command: hostname -F /etc/hostname
   <span class="org-variable-name">when: inventory_hostname !</span>= ansible_hostname
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org87b2fe8" class="outline-3">
-<h3 id="org87b2fe8"><span class="section-number-3">10.3.</span> Configure Systemd Resolved</h3>
+<div id="outline-container-orgb5ed705" class="outline-3">
+<h3 id="orgb5ed705"><span class="section-number-3">10.3.</span> Configure Systemd Resolved</h3>
 <div class="outline-text-3" id="text-10-3">
 <p>
 Campus machines use the campus name server on Core (or <code>dns.google</code>),
@@ -6121,7 +6112,7 @@ and include the institute's private domain in their search lists.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure resolved.
   become: yes
   lineinfile:
@@ -6135,11 +6126,11 @@ and include the institute's private domain in their search lists.
   notify:
   - Reload Systemd.
   - Restart Systemd resolved.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">---
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf"><code>---
 - name: Reload Systemd.
   become: yes
   systemd:
@@ -6150,12 +6141,12 @@ and include the institute's private domain in their search lists.
   systemd:
     service: systemd-resolved
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orge768e1b" class="outline-3">
-<h3 id="orge768e1b"><span class="section-number-3">10.4.</span> Configure Systemd Timesyncd</h3>
+<div id="outline-container-orgc9318c9" class="outline-3">
+<h3 id="orgc9318c9"><span class="section-number-3">10.4.</span> Configure Systemd Timesyncd</h3>
 <div class="outline-text-3" id="text-10-4">
 <p>
 The institute uses a common time reference throughout the campus.
@@ -6164,29 +6155,29 @@ and file timestamps.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Configure timesyncd.
   become: yes
   lineinfile:
     path: /etc/systemd/timesyncd.conf
     <span class="org-variable-name">line: NTP</span>=ntp.{{ domain_priv }}
   notify: Restart systemd-timesyncd.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart systemd-timesyncd.
   become: yes
   systemd:
     service: systemd-timesyncd
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgd519148" class="outline-3">
-<h3 id="orgd519148"><span class="section-number-3">10.5.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-org17d2e8d" class="outline-3">
+<h3 id="org17d2e8d"><span class="section-number-3">10.5.</span> Add Administrator to System Groups</h3>
 <div class="outline-text-3" id="text-10-5">
 <p>
 The administrator often needs to read (directories of) log files owned
@@ -6195,35 +6186,35 @@ these groups speeds up debugging.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Add {{ ansible_user }} to system groups.
   become: yes
   user:
     name: <span class="org-string">"{{ ansible_user }}"</span>
     append: yes
     groups: root,adm
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org66ef6c6" class="outline-3">
-<h3 id="org66ef6c6"><span class="section-number-3">10.6.</span> Install Unattended Upgrades</h3>
+<div id="outline-container-org1c6f15d" class="outline-3">
+<h3 id="org1c6f15d"><span class="section-number-3">10.6.</span> Install Unattended Upgrades</h3>
 <div class="outline-text-3" id="text-10-6">
 <p>
 The institute prefers to install security updates as soon as possible.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install basic software.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=unattended-upgrades
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgb964f6c" class="outline-3">
-<h3 id="orgb964f6c"><span class="section-number-3">10.7.</span> Configure Postfix on Campus</h3>
+<div id="outline-container-org990a25f" class="outline-3">
+<h3 id="org990a25f"><span class="section-number-3">10.7.</span> Configure Postfix on Campus</h3>
 <div class="outline-text-3" id="text-10-7">
 <p>
 The Postfix settings used by the campus include message size, queue
@@ -6240,7 +6231,7 @@ tasks below.
 </ul>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install Postfix.
   become: yes
   <span class="org-variable-name">apt: pkg</span>=postfix
@@ -6270,22 +6261,22 @@ tasks below.
     service: postfix
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Restart Postfix.
   become: yes
   systemd:
     service: postfix
     state: restarted
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgcdd657f" class="outline-3">
-<h3 id="orgcdd657f"><span class="section-number-3">10.8.</span> Set Domain Name</h3>
+<div id="outline-container-org2b656fb" class="outline-3">
+<h3 id="org2b656fb"><span class="section-number-3">10.8.</span> Set Domain Name</h3>
 <div class="outline-text-3" id="text-10-8">
 <p>
 The host's fully qualified (private) domain name (FQDN) is set by an
@@ -6295,7 +6286,7 @@ manpage.)
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Set domain name.
   become: yes
   vars:
@@ -6304,22 +6295,22 @@ manpage.)
     path: /etc/hosts
     regexp: <span class="org-string">"^127.0.1.1[        ].*"</span>
     line: <span class="org-string">"127.0.1.1    {{ name }}.{{ domain_priv }} {{ name }}"</span>
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgbd0ce38" class="outline-3">
-<h3 id="orgbd0ce38"><span class="section-number-3">10.9.</span> Configure NRPE</h3>
+<div id="outline-container-org356ce5d" class="outline-3">
+<h3 id="org356ce5d"><span class="section-number-3">10.9.</span> Configure NRPE</h3>
 <div class="outline-text-3" id="text-10-9">
 <p>
 Each campus host runs an NRPE (a NAGIOS Remote Plugin Executor)
 server so that the NAGIOS4 server on Core can collect statistics.  The
-NAGIOS service is discussed in the <a href="#orgbd0ce38">Configure NRPE</a> section of <a href="#orge7ebc83">The Core
+NAGIOS service is discussed in the <a href="#org356ce5d">Configure NRPE</a> section of <a href="#orge6d718e">The Core
 Role</a>.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install NRPE.
   become: yes
   apt:
@@ -6353,23 +6344,23 @@ Role</a>.
     service: nagios-nrpe-server
     enabled: yes
     state: started
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Reload NRPE server.
   become: yes
   systemd:
     service: nagios-nrpe-server
     state: reloaded
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-orgff33e02" class="outline-2">
-<h2 id="orgff33e02"><span class="section-number-2">11.</span> The Ansible Configuration</h2>
+<div id="outline-container-orgda31017" class="outline-2">
+<h2 id="orgda31017"><span class="section-number-2">11.</span> The Ansible Configuration</h2>
 <div class="outline-text-2" id="text-11">
 <p>
 The small institute uses Ansible to maintain the configuration of its
@@ -6378,7 +6369,7 @@ runs playbook <a href="playbook/site.yml"><q>site.yml</q></a> to apply the appro
 role(s) to each host.  Examples of these files are included here, and
 are used to test the roles.  The example configuration applies the
 institutional roles to VirtualBox machines prepared according to
-chapter <a href="#org74b454f">Testing</a>.
+chapter <a href="#org7832c43">Testing</a>.
 </p>
 
 <p>
@@ -6391,13 +6382,13 @@ while changes to the institute's particulars are committed to a
 separate revision history.
 </p>
 </div>
-<div id="outline-container-orgfefb674" class="outline-3">
-<h3 id="orgfefb674"><span class="section-number-3">11.1.</span> <q>ansible.cfg</q></h3>
+<div id="outline-container-orgf6e5306" class="outline-3">
+<h3 id="orgf6e5306"><span class="section-number-3">11.1.</span> <q>ansible.cfg</q></h3>
 <div class="outline-text-3" id="text-11-1">
 <p>
 The Ansible configuration file <a href="ansible.cfg"><q>ansible.cfg</q></a> contains just a handful
 of settings, some included just to create a test jig as described in
-<a href="#org74b454f">Testing</a>.
+<a href="#org7832c43">Testing</a>.
 </p>
 
 <ul class="org-ul">
@@ -6406,7 +6397,7 @@ of settings, some included just to create a test jig as described in
 that Python 3 can be expected on all institute hosts.</li>
 <li><code>vault_password_file</code> is set to suppress prompts for the vault
 password.  The institute keeps its vault password in <a href="Secret/"><q>Secret/</q></a> (as
-described in <a href="#org6519b0c">Keys</a>) and thus sets this parameter to
+described in <a href="#org1c1be46">Keys</a>) and thus sets this parameter to
 <a href="Secret/vault-password"><q>Secret/vault-password</q></a>.</li>
 <li><code>inventory</code> is set to avoid specifying it on the command line.</li>
 <li><code>roles_path</code> is set to the recently tangled roles files in
@@ -6414,17 +6405,17 @@ described in <a href="#org6519b0c">Keys</a>) and thus sets this parameter to
 </ul>
 
 <div class="org-src-container">
-<a href="ansible.cfg"><q>ansible.cfg</q></a><pre class="src src-conf">[<span class="org-type">defaults</span>]
+<a href="ansible.cfg"><q>ansible.cfg</q></a><pre class="src src-conf"><code>[<span class="org-type">defaults</span>]
 <span class="org-variable-name">interpreter_python</span>=/usr/bin/python3
 <span class="org-variable-name">vault_password_file</span>=Secret/vault-password
 <span class="org-variable-name">inventory</span>=hosts
 <span class="org-variable-name">roles_path</span>=roles_t
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgb932c38" class="outline-3">
-<h3 id="orgb932c38"><span class="section-number-3">11.2.</span> <q>hosts</q></h3>
+<div id="outline-container-orge7d3e33" class="outline-3">
+<h3 id="orge7d3e33"><span class="section-number-3">11.2.</span> <q>hosts</q></h3>
 <div class="outline-text-3" id="text-11-2">
 <p>
 The Ansible inventory file <a href="hosts"><q>hosts</q></a> describes all of the institute's
@@ -6436,7 +6427,7 @@ describes three test servers named <code>front</code>, <code>core</code> and <co
 </p>
 
 <div class="org-src-container">
-<a href="hosts"><q>hosts</q></a><pre class="src src-conf" id="orgafeb78d">all:
+<a href="hosts"><q>hosts</q></a><pre class="src src-conf" id="org0b95976"><code>all:
   vars:
     ansible_user: sysadm
     ansible_ssh_extra_args: -i Secret/ssh_admin/id_rsa
@@ -6454,7 +6445,7 @@ describes three test servers named <code>front</code>, <code>core</code> and <co
     campus:
       hosts:
         gate:
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -6465,7 +6456,7 @@ line.
 </p>
 
 <div class="org-src-container">
-<a href="Secret/become.yml"><q>Secret/become.yml</q></a><pre class="src src-conf">become_front: !vault |
+<a href="Secret/become.yml"><q>Secret/become.yml</q></a><pre class="src src-conf"><code>become_front: !vault |
         $ANSIBLE_VAULT;1.1;AES256
         3563626131333733666466393166323135383838666338666131336335326
         3656437663032653333623461633866653462636664623938356563306264
@@ -6489,7 +6480,7 @@ become_gate: !vault |
         0636537633139366333373933396637633034383132373064393939363231
         636264323132370a393135666335303361326330623438613630333638393
         1303632663738306634
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -6501,8 +6492,8 @@ the <a href="Secret/vault-password"><q>Secret/vault-password</q></a> file.
 </p>
 </div>
 </div>
-<div id="outline-container-org074c362" class="outline-3">
-<h3 id="org074c362"><span class="section-number-3">11.3.</span> <q>playbooks/site.yml</q></h3>
+<div id="outline-container-org723c67b" class="outline-3">
+<h3 id="org723c67b"><span class="section-number-3">11.3.</span> <q>playbooks/site.yml</q></h3>
 <div class="outline-text-3" id="text-11-3">
 <p>
 The example <a href="playbooks/site.yml"><q>playbooks/site.yml</q></a> playbook (below) applies the
@@ -6511,7 +6502,7 @@ the example inventory: <a href="hosts"><q>hosts</q></a>.
 </p>
 
 <div class="org-src-container">
-<a href="playbooks/site.yml"><q>playbooks/site.yml</q></a><pre class="src src-conf">---
+<a href="playbooks/site.yml"><q>playbooks/site.yml</q></a><pre class="src src-conf"><code>---
 - name: Configure All
   hosts: all
   roles: [ all ]
@@ -6531,12 +6522,12 @@ the example inventory: <a href="hosts"><q>hosts</q></a>.
 - name: Configure Campus
   hosts: campus
   roles: [ campus ]
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orge85b5b4" class="outline-3">
-<h3 id="orge85b5b4"><span class="section-number-3">11.4.</span> <q>Secret/vault-password</q></h3>
+<div id="outline-container-org696cc09" class="outline-3">
+<h3 id="org696cc09"><span class="section-number-3">11.4.</span> <q>Secret/vault-password</q></h3>
 <div class="outline-text-3" id="text-11-4">
 <p>
 As already mentioned, the small institute keeps its Ansible vault
@@ -6548,17 +6539,17 @@ example password matches the example encryptions above.
 </p>
 
 <div class="org-src-container">
-<a href="Secret/vault-password"><q>Secret/vault-password</q></a><pre class="src src-conf" id="org3cd4611">alitysortstagess
-</pre>
+<a href="Secret/vault-password"><q>Secret/vault-password</q></a><pre class="src src-conf" id="org442ebbb"><code>alitysortstagess
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org0517849" class="outline-3">
-<h3 id="org0517849"><span class="section-number-3">11.5.</span> Creating A Working Ansible Configuration</h3>
+<div id="outline-container-org93d3d06" class="outline-3">
+<h3 id="org93d3d06"><span class="section-number-3">11.5.</span> Creating A Working Ansible Configuration</h3>
 <div class="outline-text-3" id="text-11-5">
 <p>
 A working Ansible configuration can be "tangled" from this document to
-produce the test configuration described in the <a href="#org74b454f">Testing</a> chapter.  The
+produce the test configuration described in the <a href="#org7832c43">Testing</a> chapter.  The
 tangling is done by Emacs's <code>org-babel-tangle</code> function and has
 already been performed with the resulting tangle included in the
 distribution with this document.
@@ -6574,13 +6565,13 @@ and add an <q>Institute/</q> submodule.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-builtin">cd</span>
+<pre class="src src-sh"><code><span class="org-builtin">cd</span>
 mkdir network
 <span class="org-builtin">cd</span> network
 git init
 git submodule add git://birchwood-abbey.net/~puck/Institute
 git add Institute
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -6601,7 +6592,7 @@ would be copied, with appropriate changes, into new subdirectories
 <q>public/</q> and <q>private/</q>.</li>
 <li><q>~/net/Secret</q> would be a symbolic link to the (auto-mounted?)
 location of the administrator's encrypted USB drive, as described in
-section <a href="#org6519b0c">Keys</a>.</li>
+section <a href="#org1c1be46">Keys</a>.</li>
 </ul>
 
 <p>
@@ -6621,9 +6612,9 @@ the example <q>~/net/Institute/private/</q>.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">cp -r Institute/roles_t Institute/roles
+<pre class="src src-sh"><code>cp -r Institute/roles_t Institute/roles
 ( <span class="org-builtin">cd</span> playbooks; ln -s ../Institute/playbooks/* . )
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -6632,13 +6623,13 @@ super-project's directory.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">./Institute/inst config -n
-</pre>
+<pre class="src src-sh"><code>./Institute/inst config -n
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgb70ec0e" class="outline-3">
-<h3 id="orgb70ec0e"><span class="section-number-3">11.6.</span> Maintaining A Working Ansible Configuration</h3>
+<div id="outline-container-orgb3fb614" class="outline-3">
+<h3 id="orgb3fb614"><span class="section-number-3">11.6.</span> Maintaining A Working Ansible Configuration</h3>
 <div class="outline-text-3" id="text-11-6">
 <p>
 The Ansible roles currently tangle into the <a href="roles_t/"><q>roles_t/</q></a> directory to
@@ -6657,8 +6648,8 @@ their way back to the code block in this document.
 </div>
 </div>
 </div>
-<div id="outline-container-org1c6f4a8" class="outline-2">
-<h2 id="org1c6f4a8"><span class="section-number-2">12.</span> The Institute Commands</h2>
+<div id="outline-container-org5db480b" class="outline-2">
+<h2 id="org5db480b"><span class="section-number-2">12.</span> The Institute Commands</h2>
 <div class="outline-text-2" id="text-12">
 <p>
 The institute's administrator uses a convenience script to reliably
@@ -6668,8 +6659,8 @@ Ansible configuration.  The Ansible commands it executes are expected
 to get their defaults from <q>./ansible.cfg</q>.
 </p>
 </div>
-<div id="outline-container-orgf00b9ce" class="outline-3">
-<h3 id="orgf00b9ce"><span class="section-number-3">12.1.</span> Sub-command Blocks</h3>
+<div id="outline-container-orgad96cbc" class="outline-3">
+<h3 id="orgad96cbc"><span class="section-number-3">12.1.</span> Sub-command Blocks</h3>
 <div class="outline-text-3" id="text-12-1">
 <p>
 The code blocks in this chapter tangle into the <a href="inst"><q>inst</q></a> script.  Each
@@ -6683,18 +6674,18 @@ The first code block is the header of the <code>./inst</code> script.
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><span class="org-comment-delimiter">#</span><span class="org-comment">!/usr/bin/perl -w</span>
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/usr/bin/perl -w</span>
 <span class="org-comment-delimiter">#</span>
 <span class="org-comment-delimiter"># </span><span class="org-comment">DO NOT EDIT.  This file was tangled from an institute.org file.</span>
 
 <span class="org-keyword">use</span> <span class="org-constant">strict</span>;
 <span class="org-keyword">use</span> <span class="org-constant">IO::File</span>;
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org20782dc" class="outline-3">
-<h3 id="org20782dc"><span class="section-number-3">12.2.</span> Sanity Check</h3>
+<div id="outline-container-org3b3c0fd" class="outline-3">
+<h3 id="org3b3c0fd"><span class="section-number-3">12.2.</span> Sanity Check</h3>
 <div class="outline-text-3" id="text-12-2">
 <p>
 The next code block does not implement a sub-command; it implements
@@ -6706,7 +6697,7 @@ permissions.  It probes past the <a href="Secret/"><q>Secret/</q></a> mount poin
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">sub</span> <span class="org-function-name">note_missing_file_p</span> ($);
 <span class="org-keyword">sub</span> <span class="org-function-name">note_missing_directory_p</span> ($);
 
@@ -6750,12 +6741,12 @@ permissions.  It probes past the <a href="Secret/"><q>Secret/</q></a> mount poin
     <span class="org-keyword">return</span> 0;
   }
 }
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org10ec3d5" class="outline-3">
-<h3 id="org10ec3d5"><span class="section-number-3">12.3.</span> Importing Ansible Variables</h3>
+<div id="outline-container-org1a212b5" class="outline-3">
+<h3 id="org1a212b5"><span class="section-number-3">12.3.</span> Importing Ansible Variables</h3>
 <div class="outline-text-3" id="text-12-3">
 <p>
 To ensure that Ansible and <code>./inst</code> are sympatico vis-a-vi certain
@@ -6767,7 +6758,7 @@ them.
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-conf">
+<a href="inst"><q>inst</q></a><pre class="src src-conf"><code>
 <span class="org-type">sub mysystem (@)</span> {
   <span class="org-variable-name">my $line</span> = join (<span class="org-string">" "</span>, @_);
   print <span class="org-string">"$line\n"</span>;
@@ -6777,9 +6768,9 @@ them.
 
 mysystem <span class="org-string">"ansible-playbook playbooks/check-inst-vars.yml &gt;/dev/null"</span>;
 
-our ($domain_name, $domain_priv, $front_addr, $gate_wifi_addr);
+our ($domain_name, $domain_priv, $front_addr, $gate_wild_addr);
 do <span class="org-string">"./private/vars.pl"</span>;
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -6787,7 +6778,7 @@ The playbook that updates <a href="private/vars.pl"><q>private/vars.pl</q></a>:
 </p>
 
 <div class="org-src-container">
-<a href="playbooks/check-inst-vars.yml"><q>playbooks/check-inst-vars.yml</q></a><pre class="src src-conf">- hosts: localhost
+<a href="playbooks/check-inst-vars.yml"><q>playbooks/check-inst-vars.yml</q></a><pre class="src src-conf"><code>- hosts: localhost
   gather_facts: no
   tasks:
   - include_vars: ../public/vars.yml
@@ -6797,15 +6788,15 @@ The playbook that updates <a href="private/vars.pl"><q>private/vars.pl</q></a>:
         <span class="org-variable-name">$domain_name</span> = <span class="org-string">"{{ domain_name }}"</span>;
         <span class="org-variable-name">$domain_priv</span> = <span class="org-string">"{{ domain_priv }}"</span>;
         <span class="org-variable-name">$front_addr</span> = <span class="org-string">"{{ front_addr }}"</span>;
-        <span class="org-variable-name">$gate_wifi_addr</span> = <span class="org-string">"{{ gate_wifi_addr }}"</span>;
+        <span class="org-variable-name">$gate_wild_addr</span> = <span class="org-string">"{{ gate_wild_addr }}"</span>;
       dest: ../private/vars.pl
       <span class="org-variable-name">mode: u</span>=rw,g=,o=
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org671a111" class="outline-3">
-<h3 id="org671a111"><span class="section-number-3">12.4.</span> The CA Command</h3>
+<div id="outline-container-org3fe9e37" class="outline-3">
+<h3 id="org3fe9e37"><span class="section-number-3">12.4.</span> The CA Command</h3>
 <div class="outline-text-3" id="text-12-4">
 <p>
 The next code block implements the <code>CA</code> sub-command, which creates a
@@ -6817,8 +6808,8 @@ here.
 </p>
 
 <div class="org-src-container">
-<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf">full_name: Small Institute LLC
-</pre>
+<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf"><code>full_name: Small Institute LLC
+</code></pre>
 </div>
 
 <p>
@@ -6831,7 +6822,6 @@ symbolic link to a volume's automount location.
 ln -s /media/sysadm/ADE7-F866/ Secret
 </pre>
 
-
 <p>
 The <a href="Secret/CA/"><q>Secret/CA/</q></a> directory is prepared using Easy RSA's <code>make-cadir</code>
 command.  The <a href="Secret/CA/vars"><q>Secret/CA/vars</q></a> file thus created is edited to contain
@@ -6844,7 +6834,6 @@ sudo apt install easy-rsa
 ./inst CA
 </pre>
 
-
 <p>
 Running <code>./inst CA</code> creates the new CA and keys.  The command prompts
 for the Common Name (or several levels of Organizational names) of the
@@ -6855,7 +6844,7 @@ config</code>.
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"CA"</span>) {
   <span class="org-keyword">die</span> <span class="org-string">"usage: $0 CA"</span> <span class="org-keyword">if</span> @<span class="org-perl-non-scalar-variable">ARGV</span> != 1;
   <span class="org-keyword">die</span> <span class="org-string">"Secret/CA/easyrsa: not an executable\n"</span>
@@ -6874,8 +6863,8 @@ config</code>.
   mysystem <span class="org-string">"cd Secret/CA; ./easyrsa build-server-full core.$pvt nopass"</span>;
   mysystem <span class="org-string">"cd Secret/CA; ./easyrsa build-client-full core nopass"</span>;
   umask 077;
-  mysystem <span class="org-string">"openvpn --genkey secret Secret/front-ta.key"</span>;
-  mysystem <span class="org-string">"openvpn --genkey secret Secret/gate-ta.key"</span>;
+  mysystem <span class="org-string">"openvpn --genkey secret Secret/front-shared.key"</span>;
+  mysystem <span class="org-string">"openvpn --genkey secret Secret/gate-shared.key"</span>;
   mysystem <span class="org-string">"openssl dhparam -out Secret/front-dh2048.pem 2048"</span>;
   mysystem <span class="org-string">"openssl dhparam -out Secret/gate-dh2048.pem 2048"</span>;
 
@@ -6909,17 +6898,17 @@ config</code>.
   mysystem <span class="org-string">"ssh-keygen -A -f Secret/ssh_front -C $dom"</span>;
   <span class="org-keyword">exit</span>;
 }
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org5877bb0" class="outline-3">
-<h3 id="org5877bb0"><span class="section-number-3">12.5.</span> The Config Command</h3>
+<div id="outline-container-orge93c2cb" class="outline-3">
+<h3 id="orge93c2cb"><span class="section-number-3">12.5.</span> The Config Command</h3>
 <div class="outline-text-3" id="text-12-5">
 <p>
 The next code block implements the <code>config</code> sub-command, which
 provisions network services by running the <q>site.yml</q> playbook
-described in <a href="#org074c362"><q>playbooks/site.yml</q></a>.  It recognizes an optional <code>-n</code>
+described in <a href="#org723c67b"><q>playbooks/site.yml</q></a>.  It recognizes an optional <code>-n</code>
 flag indicating that the service configurations should just be
 checked.  Given an optional host name, it provisions (or checks) just
 the named host.
@@ -6935,9 +6924,8 @@ Example command lines:
 ./inst config -n HOST
 </pre>
 
-
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"config"</span>) {
   <span class="org-keyword">die</span> <span class="org-string">"Secret/CA/easyrsa: not executable\n"</span>
     <span class="org-keyword">if</span> ! -x <span class="org-string">"Secret/CA/easyrsa"</span>;
@@ -6961,16 +6949,16 @@ Example command lines:
   mysystem $<span class="org-variable-name">cmd</span>;
   <span class="org-keyword">exit</span>;
 }
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orge7fe793" class="outline-3">
-<h3 id="orge7fe793"><span class="section-number-3">12.6.</span> Account Management</h3>
+<div id="outline-container-org6138e49" class="outline-3">
+<h3 id="org6138e49"><span class="section-number-3">12.6.</span> Account Management</h3>
 <div class="outline-text-3" id="text-12-6">
 <p>
 For general information about members and their Unix accounts, see
-<a href="#org54da6ed">Accounts</a>.  The account management sub-commands maintain a mapping
+<a href="#orga38c5ed">Accounts</a>.  The account management sub-commands maintain a mapping
 associating member "usernames" (Unix account names) with their
 records.  The mapping is stored among other things in
 <q>private/members.yml</q> as the value associated with the key <code>members</code>.
@@ -6995,7 +6983,7 @@ Front and Core.  (The example hashes are truncated versions.)
 </p>
 
 <div class="org-src-container">
-<q>private/members.yml</q><pre class="src src-conf">---
+<q>private/members.yml</q><pre class="src src-conf"><code>---
 members:
   dick:
     status: current
@@ -7018,7 +7006,7 @@ usernames:
 - dick
 revoked:
 - dick-phone
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -7030,11 +7018,11 @@ is used instead.
 </p>
 
 <div class="org-src-container">
-<a href="private/members-empty.yml"><q>private/members-empty.yml</q></a><pre class="src src-conf">---
+<a href="private/members-empty.yml"><q>private/members-empty.yml</q></a><pre class="src src-conf"><code>---
 members:
 usernames: []
 revoked: []
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -7043,10 +7031,10 @@ Both locations go on the <code>membership_rolls</code> variable used by the
 </p>
 
 <div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">membership_rolls:
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>membership_rolls:
 - <span class="org-string">"../private/members.yml"</span>
 - <span class="org-string">"../private/members-empty.yml"</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -7056,7 +7044,7 @@ read from the file.  The dump subroutine is another story (below).
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">use</span> <span class="org-constant">YAML::XS</span> qw<span class="org-string">(LoadFile DumpFile)</span>;
 
 <span class="org-keyword">sub</span> <span class="org-function-name">read_members_yaml</span> () {
@@ -7115,7 +7103,7 @@ read from the file.  The dump subroutine is another story (below).
   }
   close $<span class="org-variable-name">O</span> or <span class="org-keyword">die</span> <span class="org-string">"Could not close $pathname: $!\n"</span>;
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -7132,7 +7120,7 @@ each record.
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">sub</span> <span class="org-function-name">print_member</span> ($$) {
   <span class="org-keyword">my</span> ($<span class="org-variable-name">out</span>, $<span class="org-variable-name">member</span>) = @<span class="org-perl-non-scalar-variable">_</span>;
   print $<span class="org-variable-name">out</span> <span class="org-string">"  "</span>, $<span class="org-variable-name">member</span>-&gt;{<span class="org-string">"username"</span>}, <span class="org-string">":\n"</span>;
@@ -7165,12 +7153,12 @@ each record.
     print $<span class="org-variable-name">out</span> <span class="org-string">"    $key: "</span>, $<span class="org-variable-name">member</span>-&gt;{$<span class="org-variable-name">key</span>}, <span class="org-string">"\n"</span>;
   }
 }
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgebc3780" class="outline-3">
-<h3 id="orgebc3780"><span class="section-number-3">12.7.</span> The New Command</h3>
+<div id="outline-container-org541678b" class="outline-3">
+<h3 id="org541678b"><span class="section-number-3">12.7.</span> The New Command</h3>
 <div class="outline-text-3" id="text-12-7">
 <p>
 The next code block implements the <code>new</code> sub-command.  It adds a new
@@ -7184,7 +7172,7 @@ initial, generated password.
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">sub</span> <span class="org-function-name">valid_username</span> (@);
 <span class="org-keyword">sub</span> <span class="org-function-name">shell_escape</span> ($);
 <span class="org-keyword">sub</span> <span class="org-function-name">strip_vault</span> ($);
@@ -7243,11 +7231,11 @@ initial, generated password.
   <span class="org-keyword">my</span> @<span class="org-perl-non-scalar-variable">lines</span> = split <span class="org-string">/^ */</span>m, $<span class="org-variable-name">string</span>;
   <span class="org-keyword">return</span> (join <span class="org-string">""</span>, @<span class="org-perl-non-scalar-variable">lines</span>[1..$#<span class="org-perl-non-scalar-variable">lines</span>]);
 }
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="playbooks/nextcloud-new.yml"><q>playbooks/nextcloud-new.yml</q></a><pre class="src src-conf">- hosts: core
+<a href="playbooks/nextcloud-new.yml"><q>playbooks/nextcloud-new.yml</q></a><pre class="src src-conf"><code>- hosts: core
   no_log: yes
   tasks:
   - name: Run occ user:add.
@@ -7270,12 +7258,12 @@ initial, generated password.
     args:
       chdir: /var/www/nextcloud/
       executable: /usr/bin/expect
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org0a5d277" class="outline-3">
-<h3 id="org0a5d277"><span class="section-number-3">12.8.</span> The Pass Command</h3>
+<div id="outline-container-org5e1c62d" class="outline-3">
+<h3 id="org5e1c62d"><span class="section-number-3">12.8.</span> The Pass Command</h3>
 <div class="outline-text-3" id="text-12-8">
 <p>
 The institute's <code>passwd</code> command on Core securely emails <code>root</code> with a
@@ -7289,8 +7277,8 @@ Ansible <a href="playbooks/site.yml"><q>site.yml</q></a> playbook to update the
 message is sent to <code>member@core</code>.
 </p>
 </div>
-<div id="outline-container-org1e2a891" class="outline-4">
-<h4 id="org1e2a891"><span class="section-number-4">12.8.1.</span> Less Aggressive passwd.</h4>
+<div id="outline-container-orgdf2b1f0" class="outline-4">
+<h4 id="orgdf2b1f0"><span class="section-number-4">12.8.1.</span> Less Aggressive passwd.</h4>
 <div class="outline-text-4" id="text-12-8-1">
 <p>
 The next code block implements the less aggressive <code>passwd</code> command.
@@ -7304,7 +7292,7 @@ in <a href="Secret/"><q>Secret/</q></a>.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/templates/passwd"><q>roles_t/core/templates/passwd</q></a><pre class="src src-perl"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/perl -wT</span>
+<a href="roles_t/core/templates/passwd"><q>roles_t/core/templates/passwd</q></a><pre class="src src-perl"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/perl -wT</span>
 
 <span class="org-keyword">use</span> <span class="org-constant">strict</span>;
 
@@ -7382,12 +7370,12 @@ print <span class="org-string">"</span>
 <span class="org-string">Your request was sent to Root.  PLEASE WAIT for email confirmation</span>
 <span class="org-string">that the change was completed.\n"</span>;
 <span class="org-keyword">exit</span>;
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org9b6d5b8" class="outline-4">
-<h4 id="org9b6d5b8"><span class="section-number-4">12.8.2.</span> Less Aggressive Pass Command</h4>
+<div id="outline-container-org02d38d2" class="outline-4">
+<h4 id="org02d38d2"><span class="section-number-4">12.8.2.</span> Less Aggressive Pass Command</h4>
 <div class="outline-text-4" id="text-12-8-2">
 <p>
 The following code block implements the <code>./inst pass</code> command, used by
@@ -7396,7 +7384,7 @@ the administrator to update <q>private/members.yml</q> before running
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">use</span> <span class="org-constant">MIME::Base64</span>;
 
 <span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"pass"</span>) {
@@ -7446,7 +7434,7 @@ the administrator to update <q>private/members.yml</q> before running
   close $<span class="org-variable-name">O</span> or <span class="org-keyword">die</span> <span class="org-string">"pipe to sendmail failed: $!\n"</span>;
   <span class="org-keyword">exit</span>;
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -7455,7 +7443,7 @@ users:resetpassword</code> command using <code>expect(1)</code>.
 </p>
 
 <div class="org-src-container">
-<a href="playbooks/nextcloud-pass.yml"><q>playbooks/nextcloud-pass.yml</q></a><pre class="src src-conf">- hosts: core
+<a href="playbooks/nextcloud-pass.yml"><q>playbooks/nextcloud-pass.yml</q></a><pre class="src src-conf"><code>- hosts: core
   no_log: yes
   tasks:
   - name: Run occ user:resetpassword.
@@ -7480,12 +7468,12 @@ users:resetpassword</code> command using <code>expect(1)</code>.
     args:
       chdir: /var/www/nextcloud/
       executable: /usr/bin/expect
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org739e719" class="outline-4">
-<h4 id="org739e719"><span class="section-number-4">12.8.3.</span> Installing the Less Aggressive passwd</h4>
+<div id="outline-container-org77d62a8" class="outline-4">
+<h4 id="org77d62a8"><span class="section-number-4">12.8.3.</span> Installing the Less Aggressive passwd</h4>
 <div class="outline-text-4" id="text-12-8-3">
 <p>
 The following Ansible tasks install the less aggressive <code>passwd</code>
@@ -7498,7 +7486,7 @@ configuration so that the email to root can be encrypted.
 </p>
 
 <div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
 - name: Install institute passwd command.
   become: yes
   template:
@@ -7540,28 +7528,28 @@ configuration so that the email to root can be encrypted.
     dest: ~/.gnupg-root-pub.pem
     <span class="org-variable-name">mode: u</span>=r,g=r,o=r
   notify: Import root PGP key.
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>
 - name: Import root PGP key.
   become: no
   command: gpg --import ~/.gnupg-root-pub.pem
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-orga2f39ee" class="outline-3">
-<h3 id="orga2f39ee"><span class="section-number-3">12.9.</span> The Old Command</h3>
+<div id="outline-container-org2db4274" class="outline-3">
+<h3 id="org2db4274"><span class="section-number-3">12.9.</span> The Old Command</h3>
 <div class="outline-text-3" id="text-12-9">
 <p>
 The <code>old</code> command disables a member's accounts and clients.
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] &amp;&amp; $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"old"</span>) {
   <span class="org-keyword">my</span> $<span class="org-variable-name">user</span> = valid_username (@<span class="org-perl-non-scalar-variable">ARGV</span>);
   <span class="org-keyword">my</span> $<span class="org-variable-name">yaml</span> = read_members_yaml ();
@@ -7579,11 +7567,11 @@ The <code>old</code> command disables a member's accounts and clients.
             <span class="org-string">"-t accounts playbooks/site.yml"</span>);
   <span class="org-keyword">exit</span>;
 }
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="playbooks/nextcloud-old.yml"><q>playbooks/nextcloud-old.yml</q></a><pre class="src src-conf">- hosts: core
+<a href="playbooks/nextcloud-old.yml"><q>playbooks/nextcloud-old.yml</q></a><pre class="src src-conf"><code>- hosts: core
   tasks:
   - name: Run occ user:disable.
     shell: |
@@ -7595,12 +7583,12 @@ The <code>old</code> command disables a member's accounts and clients.
     args:
       chdir: /var/www/nextcloud/
       executable: /usr/bin/expect
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org0ad53cf" class="outline-3">
-<h3 id="org0ad53cf"><span class="section-number-3">12.10.</span> The Client Command</h3>
+<div id="outline-container-orgdc36b90" class="outline-3">
+<h3 id="orgdc36b90"><span class="section-number-3">12.10.</span> The Client Command</h3>
 <div class="outline-text-3" id="text-12-10">
 <p>
 The <code>client</code> command creates an OpenVPN configuration (<q>.ovpn</q>) file
@@ -7647,14 +7635,14 @@ connection is restarted.
 </p>
 
 <div class="org-src-container">
-<code>openvpn-up</code><pre class="src src-conf" id="orgaef0340">script-security 2
+<code>openvpn-up</code><pre class="src src-conf" id="org87ee394"><code>script-security 2
 up /etc/openvpn/update-systemd-resolved
 up-restart
-</pre>
+</code></pre>
 </div>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><span class="org-keyword">sub</span> <span class="org-function-name">write_template</span> ($$$$$$$$$);
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">sub</span> <span class="org-function-name">write_template</span> ($$$$$$$$$);
 <span class="org-keyword">sub</span> <span class="org-function-name">read_file</span> ($);
 <span class="org-keyword">sub</span> <span class="org-function-name">add_client</span> ($$$);
 
@@ -7715,13 +7703,13 @@ up-restart
 <span class="org-string">&lt;&lt;openvpn-up&gt;&gt;"</span>;
 
   <span class="org-keyword">if</span> ($<span class="org-variable-name">type</span> ne <span class="org-string">"campus"</span>) {
-    <span class="org-keyword">my</span> $<span class="org-variable-name">TA</span> = read_file <span class="org-string">"Secret/front-ta.key"</span>;
-    write_template ($<span class="org-variable-name">DEV</span>,$<span class="org-variable-name">UP</span>,$<span class="org-variable-name">CA</span>,$<span class="org-variable-name">CRT</span>,$<span class="org-variable-name">KEY</span>,$<span class="org-variable-name">TA</span>, $<span class="org-variable-name">front_addr</span>,
+    <span class="org-keyword">my</span> $<span class="org-variable-name">TC</span> = read_file <span class="org-string">"Secret/front-shared.key"</span>;
+    write_template ($<span class="org-variable-name">DEV</span>,$<span class="org-variable-name">UP</span>,$<span class="org-variable-name">CA</span>,$<span class="org-variable-name">CRT</span>,$<span class="org-variable-name">KEY</span>,$<span class="org-variable-name">TC</span>, $<span class="org-variable-name">front_addr</span>,
                     $<span class="org-variable-name">domain_name</span>, <span class="org-string">"public.ovpn"</span>);
     print <span class="org-string">"Wrote public VPN configuration to public.ovpn.\n"</span>;
   }
-  <span class="org-keyword">my</span> $<span class="org-variable-name">TA</span> = read_file <span class="org-string">"Secret/gate-ta.key"</span>;
-  write_template ($<span class="org-variable-name">DEV</span>,$<span class="org-variable-name">UP</span>,$<span class="org-variable-name">CA</span>,$<span class="org-variable-name">CRT</span>,$<span class="org-variable-name">KEY</span>,$<span class="org-variable-name">TA</span>, $<span class="org-variable-name">gate_wifi_addr</span>,
+  <span class="org-keyword">my</span> $<span class="org-variable-name">TC</span> = read_file <span class="org-string">"Secret/gate-shared.key"</span>;
+  write_template ($<span class="org-variable-name">DEV</span>,$<span class="org-variable-name">UP</span>,$<span class="org-variable-name">CA</span>,$<span class="org-variable-name">CRT</span>,$<span class="org-variable-name">KEY</span>,$<span class="org-variable-name">TC</span>, $<span class="org-variable-name">gate_wild_addr</span>,
                   <span class="org-string">"gate.$domain_priv"</span>, <span class="org-string">"campus.ovpn"</span>);
   print <span class="org-string">"Wrote campus VPN configuration to campus.ovpn.\n"</span>;
 
@@ -7729,7 +7717,7 @@ up-restart
 }
 
 <span class="org-keyword">sub</span> <span class="org-function-name">write_template</span> ($$$$$$$$$) {
-  <span class="org-keyword">my</span> ($<span class="org-variable-name">DEV</span>,$<span class="org-variable-name">UP</span>,$<span class="org-variable-name">CA</span>,$<span class="org-variable-name">CRT</span>,$<span class="org-variable-name">KEY</span>,$<span class="org-variable-name">TA</span>,$<span class="org-variable-name">ADDR</span>,$<span class="org-variable-name">NAME</span>,$<span class="org-variable-name">FILE</span>) = @<span class="org-perl-non-scalar-variable">_</span>;
+  <span class="org-keyword">my</span> ($<span class="org-variable-name">DEV</span>,$<span class="org-variable-name">UP</span>,$<span class="org-variable-name">CA</span>,$<span class="org-variable-name">CRT</span>,$<span class="org-variable-name">KEY</span>,$<span class="org-variable-name">TC</span>,$<span class="org-variable-name">ADDR</span>,$<span class="org-variable-name">NAME</span>,$<span class="org-variable-name">FILE</span>) = @<span class="org-perl-non-scalar-variable">_</span>;
   <span class="org-keyword">my</span> $<span class="org-variable-name">O</span> = new IO::File;
   open ($<span class="org-variable-name">O</span>, <span class="org-string">"&gt;$FILE.tmp"</span>) or <span class="org-keyword">die</span> <span class="org-string">"Could not open $FILE.tmp: $!\n"</span>;
   print $<span class="org-variable-name">O</span> <span class="org-string">"client</span>
@@ -7746,7 +7734,7 @@ up-restart
 <span class="org-string">&lt;ca&gt;\n$CA&lt;/ca&gt;</span>
 <span class="org-string">&lt;cert&gt;\n$CRT&lt;/cert&gt;</span>
 <span class="org-string">&lt;key&gt;\n$KEY&lt;/key&gt;</span>
-<span class="org-string">&lt;tls-auth&gt;\n$TA&lt;/tls-auth&gt;\n"</span>;
+<span class="org-string">&lt;tls-crypt&gt;\n$TC&lt;/tls-crypt&gt;\n"</span>;
   close $<span class="org-variable-name">O</span> or <span class="org-keyword">die</span> <span class="org-string">"Could not close $FILE.tmp: $!\n"</span>;
   rename (<span class="org-string">"$FILE.tmp"</span>, $<span class="org-variable-name">FILE</span>)
     or <span class="org-keyword">die</span> <span class="org-string">"Could not rename $FILE.tmp: $!\n"</span>;
@@ -7761,12 +7749,12 @@ up-restart
   close $<span class="org-variable-name">I</span> or <span class="org-keyword">die</span> <span class="org-string">"$path: could not close: $!\n"</span>;
   <span class="org-keyword">return</span> $<span class="org-variable-name">c</span>;
 }
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org875755b" class="outline-3">
-<h3 id="org875755b"><span class="section-number-3">12.11.</span> Institute Command Help</h3>
+<div id="outline-container-orgb98a15e" class="outline-3">
+<h3 id="orgb98a15e"><span class="section-number-3">12.11.</span> Institute Command Help</h3>
 <div class="outline-text-3" id="text-12-11">
 <p>
 This should be the last block tangled into the <a href="inst"><q>inst</q></a> script.  It
@@ -7775,33 +7763,34 @@ above.
 </p>
 
 <div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
 <span class="org-keyword">die</span> <span class="org-string">"usage: $0 [CA|config|new|pass|old|client] ...\n"</span>;
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
 </div>
-<div id="outline-container-org74b454f" class="outline-2">
-<h2 id="org74b454f"><span class="section-number-2">13.</span> Testing</h2>
+<div id="outline-container-org7832c43" class="outline-2">
+<h2 id="org7832c43"><span class="section-number-2">13.</span> Testing</h2>
 <div class="outline-text-2" id="text-13">
 <p>
 The example files in this document, <a href="ansible.cfg"><q>ansible.cfg</q></a> and <a href="hosts"><q>hosts</q></a> as well
 as those in <a href="public/"><q>public/</q></a> and <a href="private/"><q>private/</q></a>, along with the matching EasyRSA
 certificate authority and GnuPG key-ring in <a href="Secret/"><q>Secret/</q></a> (included in the
 distribution), can be used to configure three VirtualBox VMs
-simulating Core, Gate and Front in test networks simulating a campus
-Ethernet, Wi-Fi, ISP, and a commercial cloud.  With the test networks
-up and running, a simulated member's notebook can be created and
-alternately attached to the simulated campus Wi-Fi or the Internet (as
-though abroad).  The administrator's notebook in this simulation is
-the VirtualBox host.
+simulating Core, Gate and Front in test networks simulating a private
+Ethernet, an untrusted Ethernet, the campus ISP, and a commercial
+cloud.  With the test networks up and running, a simulated member's
+notebook can be created and alternately attached to the untrusted
+Ethernet (as though it were on the campus Wi-Fi) or the Internet (as
+though it were abroad).  The administrator's notebook in this
+simulation is the VirtualBox host.
 </p>
 
 <p>
 The next two sections list the steps taken to create the simulated
 Core, Gate and Front machines, and connect them to their networks.
-The process is similar to that described in <a href="#org754e9f1">The (Actual) Hardware</a>, but
+The process is similar to that described in <a href="#orgbf29081">The (Actual) Hardware</a>, but
 is covered in detail here where the VirtualBox hypervisor can be
 assumed and exact command lines can be given (and copied during
 re-testing).  The remaining sections describe the manual testing
@@ -7817,8 +7806,8 @@ HTML version of the latest revision can be found on the official web
 site at <a href="https://www.virtualbox.org/manual/UserManual.html">https://www.virtualbox.org/manual/UserManual.html</a>.
 </p>
 </div>
-<div id="outline-container-org6e2b33d" class="outline-3">
-<h3 id="org6e2b33d"><span class="section-number-3">13.1.</span> The Test Networks</h3>
+<div id="outline-container-orgf8057e6" class="outline-3">
+<h3 id="orgf8057e6"><span class="section-number-3">13.1.</span> The Test Networks</h3>
 <div class="outline-text-3" id="text-13-1">
 <p>
 The networks used in the test:
@@ -7835,8 +7824,8 @@ private Ethernet switch.  It has no services, no DHCP, just the host
 machine at <code>192.168.56.10</code> pretending to be the administrator's
 notebook.</dd>
 
-<dt><code>vboxnet1</code></dt><dd>Another Host-only network, simulating the tiny
-Ethernet between Gate and the campus Wi-Fi access point.  It has no
+<dt><code>vboxnet1</code></dt><dd>Another Host-only network, simulating the untrusted
+Ethernet between Gate and the campus IoT (and Wi-Fi APs).  It has no
 services, no DHCP, just the host at <code>192.168.57.2</code>, simulating the
 NATed Wi-Fi network.</dd>
 </dl>
@@ -7856,7 +7845,7 @@ following <code>VBoxManage</code> commands.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">VBoxManage natnetwork add --netname premises <span class="org-sh-escaped-newline">\</span>
+<pre class="src src-sh"><code>VBoxManage natnetwork add --netname premises <span class="org-sh-escaped-newline">\</span>
                           --network 192.168.15.0/24 <span class="org-sh-escaped-newline">\</span>
                           --enable --dhcp on --ipv6 off
 VBoxManage natnetwork start --netname premises
@@ -7865,7 +7854,7 @@ VBoxManage hostonlyif ipconfig vboxnet0 --ip=192.168.56.10
 VBoxManage dhcpserver modify --interface=vboxnet0 --disable
 VBoxManage hostonlyif create <span class="org-comment-delimiter"># </span><span class="org-comment">vboxnet1</span>
 VBoxManage hostonlyif ipconfig vboxnet1 --ip=192.168.57.2
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -7882,15 +7871,15 @@ on the private <code>192.168.15.0/24</code> network.
 </p>
 </div>
 </div>
-<div id="outline-container-org28b0352" class="outline-3">
-<h3 id="org28b0352"><span class="section-number-3">13.2.</span> The Test Machines</h3>
+<div id="outline-container-orgd7a9abd" class="outline-3">
+<h3 id="orgd7a9abd"><span class="section-number-3">13.2.</span> The Test Machines</h3>
 <div class="outline-text-3" id="text-13-2">
 <p>
 The virtual machines are created by <code>VBoxManage</code> command lines in the
 following sub-sections.  They each start with a recent Debian release
 (e.g. <q>debian-12.5.0-amd64-netinst.iso</q>) in their simulated DVD
-drives.  As in <a href="#org754e9f1">The Hardware</a> preparation process being simulated, a few
-additional software packages are installed.  Unlike in <a href="#org754e9f1">The Hardware</a>
+drives.  As in <a href="#orgbf29081">The Hardware</a> preparation process being simulated, a few
+additional software packages are installed.  Unlike in <a href="#orgbf29081">The Hardware</a>
 preparation, machines are moved to their final networks and <i>then</i>
 remote access is authorized.  (They are not accessible via <code>ssh</code> on
 the VirtualBox NAT network where they first boot.)
@@ -7902,8 +7891,8 @@ privileged accounts on the virtual machines, they are prepared for
 configuration by Ansible.
 </p>
 </div>
-<div id="outline-container-orgde4a074" class="outline-4">
-<h4 id="orgde4a074"><span class="section-number-4">13.2.1.</span> A Test Machine</h4>
+<div id="outline-container-org310a70b" class="outline-4">
+<h4 id="org310a70b"><span class="section-number-4">13.2.1.</span> A Test Machine</h4>
 <div class="outline-text-4" id="text-13-2-1">
 <p>
 The following shell function contains most of the <code>VBoxManage</code>
@@ -7916,7 +7905,7 @@ taken from the <code>ISO</code> shell variable.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-keyword">function</span> <span class="org-function-name">create_vm</span> {
+<pre class="src src-sh"><code><span class="org-keyword">function</span> <span class="org-function-name">create_vm</span> {
   VBoxManage createvm --name $<span class="org-variable-name">NAME</span> --ostype Debian_64 --register
   VBoxManage modifyvm $<span class="org-variable-name">NAME</span> --memory $<span class="org-variable-name">RAM</span>
   VBoxManage createhd --size $<span class="org-variable-name">DISK</span> <span class="org-sh-escaped-newline">\</span>
@@ -7932,7 +7921,7 @@ taken from the <code>ISO</code> shell variable.
       --port 0 --device 0 --type dvddrive --medium $<span class="org-variable-name">ISO</span>
   VBoxManage modifyvm $<span class="org-variable-name">NAME</span> --boot1 dvd --boot2 disk
 }
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -7948,12 +7937,12 @@ CDROM drive.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-variable-name">NAME</span>=front
+<pre class="src src-sh"><code><span class="org-variable-name">NAME</span>=front
 <span class="org-variable-name">RAM</span>=512
 <span class="org-variable-name">DISK</span>=4096
 <span class="org-variable-name">ISO</span>=~/Downloads/debian-12.5.0-amd64-netinst.iso
 create_vm
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8034,8 +8023,8 @@ preparation (below).
 </p>
 </div>
 </div>
-<div id="outline-container-org96e03aa" class="outline-4">
-<h4 id="org96e03aa"><span class="section-number-4">13.2.2.</span> The Test Front Machine</h4>
+<div id="outline-container-org28db7d4" class="outline-4">
+<h4 id="org28db7d4"><span class="section-number-4">13.2.2.</span> The Test Front Machine</h4>
 <div class="outline-text-4" id="text-13-2-2">
 <p>
 The <code>front</code> machine is created with 512MiB of RAM, 4GiB of disk, and
@@ -8048,13 +8037,13 @@ After Debian is installed (as detailed above) <code>front</code> is shut down an
 its primary network interface moved to the simulated Internet, the NAT
 network <code>premises</code>.  <code>front</code> also gets a second network interface, on
 the host-only network <code>vboxnet1</code>, to make it directly accessible to
-the administrator's notebook (as described in <a href="#org6e2b33d">The Test Networks</a>).
+the administrator's notebook (as described in <a href="#orgf8057e6">The Test Networks</a>).
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">VBoxManage modifyvm front --nic1 natnetwork --natnetwork1 premises
+<pre class="src src-sh"><code>VBoxManage modifyvm front --nic1 natnetwork --natnetwork1 premises
 VBoxManage modifyvm front --nic2 hostonly --hostonlyadapter2 vboxnet1
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8065,10 +8054,10 @@ address using a drop-in configuration file:
 </p>
 
 <div class="org-src-container">
-<q>eth1</q><pre class="src src-conf">auto enp0s8
+<q>eth1</q><pre class="src src-conf"><code>auto enp0s8
 iface enp0s8 inet static
     address 192.168.57.3/24
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8080,13 +8069,13 @@ Note that there is no pre-provisioning for <code>front</code>, which is never
 deployed on a frontier, always in the cloud.  Additional Debian
 packages are assumed to be readily available.  Thus Ansible installs
 them as necessary, but first the administrator authorizes remote
-access by following the instructions in the final section: <a href="#orgc910086">Ansible
+access by following the instructions in the final section: <a href="#orgab73a63">Ansible
 Test Authorization</a>.
 </p>
 </div>
 </div>
-<div id="outline-container-org038abd9" class="outline-4">
-<h4 id="org038abd9"><span class="section-number-4">13.2.3.</span> The Test Gate Machine</h4>
+<div id="outline-container-org4da3a01" class="outline-4">
+<h4 id="org4da3a01"><span class="section-number-4">13.2.3.</span> The Test Gate Machine</h4>
 <div class="outline-text-4" id="text-13-2-3">
 <p>
 The <code>gate</code> machine is created with the same amount of RAM and disk as
@@ -8095,21 +8084,21 @@ not changed, <code>gate</code> can be created with two commands.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-variable-name">NAME</span>=gate
+<pre class="src src-sh"><code><span class="org-variable-name">NAME</span>=gate
 create_vm
-</pre>
+</code></pre>
 </div>
 
 <p>
-After Debian is installed (as detailed in <a href="#orgde4a074">A Test Machine</a>) and the
+After Debian is installed (as detailed in <a href="#org310a70b">A Test Machine</a>) and the
 machine rebooted, the administrator logs in and installs several
 additional software packages.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo apt install netplan.io systemd-resolved unattended-upgrades <span class="org-sh-escaped-newline">\</span>
+<pre class="src src-sh"><code>sudo apt install netplan.io systemd-resolved unattended-upgrades <span class="org-sh-escaped-newline">\</span>
                  ufw isc-dhcp-server postfix openvpn
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8125,19 +8114,19 @@ defaults, listed below, are fine.
 <p>
 <code>gate</code> can then move to the campus.  It is shut down before the
 following <code>VBoxManage</code> commands are executed.  The commands disconnect
-the primary Ethernet interface from <code>premises</code> and connected it to
-<code>vboxnet0</code>.  They also create two new interfaces, <code>isp</code> and <code>wifi</code>,
+the primary Ethernet interface from <code>premises</code> and connect it to
+<code>vboxnet0</code>.  They also create two new interfaces, <code>isp</code> and <code>wild</code>,
 connected to the simulated ISP and campus wireless access point.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">VBoxManage modifyvm gate --mac-address1=080027f31679
+<pre class="src src-sh"><code>VBoxManage modifyvm gate --mac-address1=080027f31679
 VBoxManage modifyvm gate --nic1 hostonly --hostonlyadapter1 vboxnet0
 VBoxManage modifyvm gate --mac-address2=0800273d42e5
 VBoxManage modifyvm gate --nic2 natnetwork --natnetwork2 premises
 VBoxManage modifyvm gate --mac-address3=0800274aded2
 VBoxManage modifyvm gate --nic3 hostonly --hostonlyadapter3 vboxnet1
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8183,8 +8172,8 @@ values of the MAC address variables in this table.
 <tr>
 <td class="org-left"><code>enp0s9</code></td>
 <td class="org-left"><code>vboxnet1</code></td>
-<td class="org-left">campus wireless</td>
-<td class="org-left"><code>gate_wifi_mac</code></td>
+<td class="org-left">campus IoT</td>
+<td class="org-left"><code>gate_wild_mac</code></td>
 </tr>
 </tbody>
 </table>
@@ -8196,18 +8185,18 @@ Ethernet interface is temporarily configured with an IP address.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo ip address add 192.168.56.2/24 dev enp0s3
-</pre>
+<pre class="src src-sh"><code>sudo ip address add 192.168.56.2/24 dev enp0s3
+</code></pre>
 </div>
 
 <p>
 Finally, the administrator authorizes remote access by following the
-instructions in the final section: <a href="#orgc910086">Ansible Test Authorization</a>.
+instructions in the final section: <a href="#orgab73a63">Ansible Test Authorization</a>.
 </p>
 </div>
 </div>
-<div id="outline-container-org18f3c58" class="outline-4">
-<h4 id="org18f3c58"><span class="section-number-4">13.2.4.</span> The Test Core Machine</h4>
+<div id="outline-container-org1f40acc" class="outline-4">
+<h4 id="org1f40acc"><span class="section-number-4">13.2.4.</span> The Test Core Machine</h4>
 <div class="outline-text-4" id="text-13-2-4">
 <p>
 The <code>core</code> machine is created with 1GiB of RAM and 6GiB of disk.
@@ -8216,21 +8205,21 @@ created with following commands.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-variable-name">NAME</span>=core
+<pre class="src src-sh"><code><span class="org-variable-name">NAME</span>=core
 <span class="org-variable-name">RAM</span>=2048
 <span class="org-variable-name">DISK</span>=6144
 create_vm
-</pre>
+</code></pre>
 </div>
 
 <p>
-After Debian is installed (as detailed in <a href="#orgde4a074">A Test Machine</a>) and the
+After Debian is installed (as detailed in <a href="#org310a70b">A Test Machine</a>) and the
 machine rebooted, the administrator logs in and installs several
 additional software packages.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo apt install netplan.io systemd-resolved unattended-upgrades <span class="org-sh-escaped-newline">\</span>
+<pre class="src src-sh"><code>sudo apt install netplan.io systemd-resolved unattended-upgrades <span class="org-sh-escaped-newline">\</span>
                  ntp isc-dhcp-server bind9 apache2 openvpn <span class="org-sh-escaped-newline">\</span>
                  postfix dovecot-imapd fetchmail expect rsync <span class="org-sh-escaped-newline">\</span>
                  gnupg
@@ -8239,7 +8228,7 @@ sudo apt install mariadb-server php php-{apcu,bcmath,curl,gd,gmp}<span class="or
                  libapache2-mod-php
 sudo apt install nagios4 monitoring-plugins-basic lm-sensors <span class="org-sh-escaped-newline">\</span>
                  nagios-nrpe-plugin
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8252,6 +8241,12 @@ defaults, listed below, are fine.
 <li>System mail name: core.small.private</li>
 </ul>
 
+<p>
+And domain name resolution may be broken after installing
+<code>systemd-resolved</code>.  A reboot is often needed after the first <code>apt
+install</code> command above.
+</p>
+
 <p>
 Before shutting down, the name of the primary Ethernet interface
 should be compared to the example variable setting in
@@ -8267,8 +8262,8 @@ Ethernet.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">VBoxManage modifyvm core --nic1 hostonly --hostonlyadapter1 vboxnet0
-</pre>
+<pre class="src src-sh"><code>VBoxManage modifyvm core --nic1 hostonly --hostonlyadapter1 vboxnet0
+</code></pre>
 </div>
 
 <p>
@@ -8278,18 +8273,18 @@ Netplan soon.)
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo ip address add 192.168.56.1/24 dev enp0s3
-</pre>
+<pre class="src src-sh"><code>sudo ip address add 192.168.56.1/24 dev enp0s3
+</code></pre>
 </div>
 
 <p>
 Finally, the administrator authorizes remote access by following the
-instructions in the next section: <a href="#orgc910086">Ansible Test Authorization</a>.
+instructions in the next section: <a href="#orgab73a63">Ansible Test Authorization</a>.
 </p>
 </div>
 </div>
-<div id="outline-container-orgc910086" class="outline-4">
-<h4 id="orgc910086"><span class="section-number-4">13.2.5.</span> Ansible Test Authorization</h4>
+<div id="outline-container-orgab73a63" class="outline-4">
+<h4 id="orgab73a63"><span class="section-number-4">13.2.5.</span> Ansible Test Authorization</h4>
 <div class="outline-text-4" id="text-13-2-5">
 <p>
 To authorize Ansible's access to the three test machines, they must
@@ -8299,11 +8294,11 @@ key to each test machine.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-variable-name">SRC</span>=Secret/ssh_admin/id_rsa.pub
+<pre class="src src-sh"><code><span class="org-variable-name">SRC</span>=Secret/ssh_admin/id_rsa.pub
 scp $<span class="org-variable-name">SRC</span> sysadm@192.168.57.3:admin_key <span class="org-comment-delimiter"># </span><span class="org-comment">Front</span>
 scp $<span class="org-variable-name">SRC</span> sysadm@192.168.56.2:admin_key <span class="org-comment-delimiter"># </span><span class="org-comment">Gate</span>
 scp $<span class="org-variable-name">SRC</span> sysadm@192.168.56.1:admin_key <span class="org-comment-delimiter"># </span><span class="org-comment">Core</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8313,8 +8308,8 @@ each machine).
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">( <span class="org-builtin">cd</span>; <span class="org-builtin">umask</span> 077; mkdir .ssh; cp admin_key .ssh/authorized_keys )
-</pre>
+<pre class="src src-sh"><code>( <span class="org-builtin">cd</span>; <span class="org-builtin">umask</span> 077; mkdir .ssh; cp admin_key .ssh/authorized_keys )
+</code></pre>
 </div>
 
 <p>
@@ -8330,8 +8325,8 @@ command.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">scp Secret/ssh_front/etc/ssh/ssh_host_* sysadm@192.168.57.3:
-</pre>
+<pre class="src src-sh"><code>scp Secret/ssh_front/etc/ssh/ssh_host_* sysadm@192.168.57.3:
+</code></pre>
 </div>
 
 <p>
@@ -8339,10 +8334,10 @@ Then they are installed with these commands.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">chmod 600 ssh_host_*
+<pre class="src src-sh"><code>chmod 600 ssh_host_*
 chmod 644 ssh_host_*.pub
 sudo cp -b ssh_host_* /etc/ssh/
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8355,8 +8350,8 @@ ssh-keygen -f ~/.ssh/known_hosts -R 192.168.57.3
 </div>
 </div>
 </div>
-<div id="outline-container-org0e22649" class="outline-3">
-<h3 id="org0e22649"><span class="section-number-3">13.3.</span> Configure Test Machines</h3>
+<div id="outline-container-org870180a" class="outline-3">
+<h3 id="org870180a"><span class="section-number-3">13.3.</span> Configure Test Machines</h3>
 <div class="outline-text-3" id="text-13-3">
 <p>
 At this point the three test machines <code>core</code>, <code>gate</code>, and <code>front</code> are
@@ -8374,8 +8369,8 @@ not</i>.
 </p>
 </div>
 </div>
-<div id="outline-container-orge71084a" class="outline-3">
-<h3 id="orge71084a"><span class="section-number-3">13.4.</span> Test Basics</h3>
+<div id="outline-container-orga849e1c" class="outline-3">
+<h3 id="orga849e1c"><span class="section-number-3">13.4.</span> Test Basics</h3>
 <div class="outline-text-3" id="text-13-4">
 <p>
 At this point the test institute is just <code>core</code>, <code>gate</code> and <code>front</code>,
@@ -8385,8 +8380,8 @@ with 0 failed units.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">systemctl status
-</pre>
+<pre class="src src-sh"><code>systemctl status
+</code></pre>
 </div>
 
 <p>
@@ -8396,9 +8391,9 @@ forwarding (and NATing).  On <code>core</code> (and <code>gate</code>):
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">ping -c 1 8.8.4.4      <span class="org-comment-delimiter"># </span><span class="org-comment">dns.google</span>
+<pre class="src src-sh"><code>ping -c 1 8.8.4.4      <span class="org-comment-delimiter"># </span><span class="org-comment">dns.google</span>
 ping -c 1 192.168.15.5 <span class="org-comment-delimiter"># </span><span class="org-comment">front_addr</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8408,10 +8403,10 @@ names yet.)  On <code>core</code> (and <code>gate</code>):
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">host dns.google
+<pre class="src src-sh"><code>host dns.google
 host core.small.private
 host www
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8420,10 +8415,10 @@ administrator's account.  On <code>core</code>, <code>gate</code> and <code>fron
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">/sbin/sendmail root
+<pre class="src src-sh"><code>/sbin/sendmail root
 Testing email to root.
 <span class="org-builtin">.</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8437,12 +8432,12 @@ instant attention).
 </p>
 </div>
 </div>
-<div id="outline-container-org626187b" class="outline-3">
-<h3 id="org626187b"><span class="section-number-3">13.5.</span> The Test Nextcloud</h3>
+<div id="outline-container-org560f2c4" class="outline-3">
+<h3 id="org560f2c4"><span class="section-number-3">13.5.</span> The Test Nextcloud</h3>
 <div class="outline-text-3" id="text-13-5">
 <p>
 Further tests involve Nextcloud account management.  Nextcloud is
-installed on <code>core</code> as described in <a href="#orgd97190a">Configure Nextcloud</a>.  Once
+installed on <code>core</code> as described in <a href="#org640e4f7">Configure Nextcloud</a>.  Once
 <q>/Nextcloud/</q> is created, <code>./inst config core</code> will validate
 or update its configuration files.
 </p>
@@ -8464,8 +8459,8 @@ using the <code>./inst new</code> command and issuing client VPN keys with the
 </p>
 </div>
 </div>
-<div id="outline-container-orgf1f2447" class="outline-3">
-<h3 id="orgf1f2447"><span class="section-number-3">13.6.</span> Test New Command</h3>
+<div id="outline-container-orgd08a549" class="outline-3">
+<h3 id="orgd08a549"><span class="section-number-3">13.6.</span> Test New Command</h3>
 <div class="outline-text-3" id="text-13-6">
 <p>
 A member must be enrolled so that a member's client machine can be
@@ -8476,8 +8471,8 @@ named <code>dick</code>, as is his notebook.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">./inst new dick
-</pre>
+<pre class="src src-sh"><code>./inst new dick
+</code></pre>
 </div>
 
 <p>
@@ -8485,8 +8480,8 @@ Take note of Dick's initial password.
 </p>
 </div>
 </div>
-<div id="outline-container-orgc9c0613" class="outline-3">
-<h3 id="orgc9c0613"><span class="section-number-3">13.7.</span> The Test Member Notebook</h3>
+<div id="outline-container-orgdab6eef" class="outline-3">
+<h3 id="orgdab6eef"><span class="section-number-3">13.7.</span> The Test Member Notebook</h3>
 <div class="outline-text-3" id="text-13-7">
 <p>
 A test member's notebook is created next, much like the servers,
@@ -8497,13 +8492,13 @@ desktop VPN client and web browser test the OpenVPN configurations on
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh"><span class="org-variable-name">NAME</span>=dick
+<pre class="src src-sh"><code><span class="org-variable-name">NAME</span>=dick
 <span class="org-variable-name">RAM</span>=2048
 <span class="org-variable-name">DISK</span>=8192
 create_vm
 VBoxManage modifyvm $<span class="org-variable-name">NAME</span> --macaddress1 080027dc54b5
 VBoxManage modifyvm $<span class="org-variable-name">NAME</span> --nic1 hostonly --hostonlyadapter1 vboxnet1
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8514,7 +8509,7 @@ behind) the access point.
 </p>
 
 <p>
-Debian is installed much as detailed in <a href="#orgde4a074">A Test Machine</a> <i>except</i> that
+Debian is installed much as detailed in <a href="#org310a70b">A Test Machine</a> <i>except</i> that
 the SSH server option is <i>not</i> needed and the GNOME desktop option
 <i>is</i>.  When the machine reboots, the administrator logs into the
 desktop and installs a couple additional software packages (which
@@ -8522,15 +8517,15 @@ require several more).
 </p>
 
 <div class="org-src-container">
-<pre class="src src-nil">sudo apt install network-manager-openvpn-gnome \
+<pre class="src src-nil"><code>sudo apt install network-manager-openvpn-gnome \
                  openvpn-systemd-resolved \
                  nextcloud-desktop evolution
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgbaaca36" class="outline-3">
-<h3 id="orgbaaca36"><span class="section-number-3">13.8.</span> Test Client Command</h3>
+<div id="outline-container-orgec34fb6" class="outline-3">
+<h3 id="orgec34fb6"><span class="section-number-3">13.8.</span> Test Client Command</h3>
 <div class="outline-text-3" id="text-13-8">
 <p>
 The <code>./inst client</code> command is used to issue keys for the institute's
@@ -8541,23 +8536,23 @@ the test VPNs.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">./inst client debian dick dick
-</pre>
+<pre class="src src-sh"><code>./inst client debian dick dick
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-orgefe17f8" class="outline-3">
-<h3 id="orgefe17f8"><span class="section-number-3">13.9.</span> Test Campus VPN</h3>
+<div id="outline-container-org788a72a" class="outline-3">
+<h3 id="org788a72a"><span class="section-number-3">13.9.</span> Test Campus VPN</h3>
 <div class="outline-text-3" id="text-13-9">
 <p>
-The <q>campus.ovpn</q> OpenVPN configuration file (generated in <a href="#orgbaaca36">Test Client
+The <q>campus.ovpn</q> OpenVPN configuration file (generated in <a href="#orgec34fb6">Test Client
 Command</a>) is transferred to <code>dick</code>, which is at the Wi-Fi access
 point's <code>wifi_wan_addr</code>.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">scp *.ovpn sysadm@192.168.57.2:
-</pre>
+<pre class="src src-sh"><code>scp *.ovpn sysadm@192.168.57.2:
+</code></pre>
 </div>
 
 <p>
@@ -8575,18 +8570,18 @@ instantly) and does a few basic tests in a terminal.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">systemctl status
+<pre class="src src-sh"><code>systemctl status
 ping -c 1 8.8.4.4      <span class="org-comment-delimiter"># </span><span class="org-comment">dns.google</span>
 ping -c 1 192.168.56.1 <span class="org-comment-delimiter"># </span><span class="org-comment">core</span>
 host dns.google
 host core.small.private
 host www
-</pre>
+</code></pre>
 </div>
 </div>
 </div>
-<div id="outline-container-org861e789" class="outline-3">
-<h3 id="org861e789"><span class="section-number-3">13.10.</span> Test Web Pages</h3>
+<div id="outline-container-org6342178" class="outline-3">
+<h3 id="org6342178"><span class="section-number-3">13.10.</span> Test Web Pages</h3>
 <div class="outline-text-3" id="text-13-10">
 <p>
 Next, the administrator copies <a href="Backup/WWW/"><q>Backup/WWW/</q></a> (included in the
@@ -8595,11 +8590,11 @@ appropriately.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo chown -R sysadm.staff /WWW/campus
+<pre class="src src-sh"><code>sudo chown -R sysadm.staff /WWW/campus
 sudo chown -R monkey.staff /WWW/live /WWW/test
 sudo chmod 02775 /WWW/*
 sudo chmod 664 /WWW/*/index.html
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8625,8 +8620,8 @@ will warn but allow the luser to continue.
 </p>
 </div>
 </div>
-<div id="outline-container-orgbe2a118" class="outline-3">
-<h3 id="orgbe2a118"><span class="section-number-3">13.11.</span> Test Web Update</h3>
+<div id="outline-container-org9931f74" class="outline-3">
+<h3 id="org9931f74"><span class="section-number-3">13.11.</span> Test Web Update</h3>
 <div class="outline-text-3" id="text-13-11">
 <p>
 Modify <q>/WWW/live/index.html</q> on <code>core</code> and wait 15 minutes for it to
@@ -8640,8 +8635,8 @@ Hack <q>/home/www/index.html</q> on <code>front</code> and observe the result at
 </p>
 </div>
 </div>
-<div id="outline-container-org11876cb" class="outline-3">
-<h3 id="org11876cb"><span class="section-number-3">13.12.</span> Test Nextcloud</h3>
+<div id="outline-container-org0145aad" class="outline-3">
+<h3 id="org0145aad"><span class="section-number-3">13.12.</span> Test Nextcloud</h3>
 <div class="outline-text-3" id="text-13-12">
 <p>
 Nextcloud is typically installed and configured <i>after</i> the first
@@ -8649,9 +8644,9 @@ Ansible run, when <code>core</code> has Internet access via <code>gate</code>.
 installation directory <q>/Nextcloud/nextcloud/</q> appears, the Ansible
 code skips parts of the Nextcloud configuration.  The same
 installation (or restoration) process used on Core is used on <code>core</code>
-to create <q>/Nextcloud/</q>.  The process starts with <a href="#org45a4a2a">Create
-<q>/Nextcloud/</q></a>, involves <a href="#org0568172">Restore Nextcloud</a> or <a href="#orga610911">Install Nextcloud</a>,
-and runs <code>./inst config core</code> again <a href="#org380598a">8.23.6</a>.  When the <code>./inst
+to create <q>/Nextcloud/</q>.  The process starts with <a href="#orgdb3439f">Create
+<q>/Nextcloud/</q></a>, involves <a href="#org3c8ed7b">Restore Nextcloud</a> or <a href="#orgb7a7660">Install Nextcloud</a>,
+and runs <code>./inst config core</code> again <a href="#orgdc9a64a">8.23.6</a>.  When the <code>./inst
 config core</code> command is happy with the Nextcloud configuration on
 <code>core</code>, the administrator uses Dick's notebook to test it, performing
 the following tests on <code>dick</code>'s desktop.
@@ -8661,7 +8656,7 @@ the following tests on <code>dick</code>'s desktop.
 <li>Use a web browser to get <code>http://core/nextcloud/</code>.  It should be a
 warning about accessing Nextcloud by an untrusted name.</li>
 
-<li>Get <code>http://core.small.private/nextcloud/</code>.  It should be a
+<li>Get <code>https://core.small.private/nextcloud/</code>.  It should be a
 login web page.</li>
 
 <li>Login as <code>sysadm</code> with password <code>fubar</code>.</li>
@@ -8680,7 +8675,7 @@ above).</li>
 <li>Use the Nextcloud app to sync <q>~/nextCloud/</q> with the cloud.  In the
 Nextcloud app's Connection Wizard (the initial dialog), choose to
 "Log in to your Nextcloud" with the URL
-<code>http://core.small.private/nextcloud</code>.  The web browser should pop
+<code>https://core.small.private/nextcloud</code>.  The web browser should pop
 up with a new tab: "Connect to your account".  Press "Log in" and
 "Grant access".  The Nextcloud Connection Wizard then prompts for
 sync parameters.  The defaults are fine.  Presumably the Local
@@ -8714,7 +8709,7 @@ self-signed and unknown.  It must be accepted (permanently).
 
 <li>Create a CardDAV account in Evolution.  Choose Edit, Accounts, Add,
 Address Book, Type CardDAV, name Small Institute, and user <code>dick</code>.
-The URL starts with <code>http://core.small.private/nextcloud/</code> and
+The URL starts with <code>https://core.small.private/nextcloud/</code> and
 ends with <code>remote.php/dav/addressbooks/users/dick/contacts/</code> (yeah,
 88 characters!).  Create a contact in the new address book and see
 it in the Contacts web page.  At some point Evolution will need
@@ -8729,8 +8724,8 @@ the calendar.</li>
 </ul>
 </div>
 </div>
-<div id="outline-container-org10daf29" class="outline-3">
-<h3 id="org10daf29"><span class="section-number-3">13.13.</span> Test Email</h3>
+<div id="outline-container-org89efb80" class="outline-3">
+<h3 id="org89efb80"><span class="section-number-3">13.13.</span> Test Email</h3>
 <div class="outline-text-3" id="text-13-13">
 <p>
 With Evolution running on the member notebook <code>dick</code>, one second email
@@ -8739,12 +8734,12 @@ commands on <code>front</code>
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">/sbin/sendmail dick
+<pre class="src src-sh"><code>/sbin/sendmail dick
 Subject: Hello, Dick.
 
 How are you?
 <span class="org-builtin">.</span>
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8758,8 +8753,8 @@ Outgoing email is also tested.  A message to
 </p>
 </div>
 </div>
-<div id="outline-container-orgcb10c33" class="outline-3">
-<h3 id="orgcb10c33"><span class="section-number-3">13.14.</span> Test Public VPN</h3>
+<div id="outline-container-orgd3f059a" class="outline-3">
+<h3 id="orgd3f059a"><span class="section-number-3">13.14.</span> Test Public VPN</h3>
 <div class="outline-text-3" id="text-13-14">
 <p>
 At this point, <code>dick</code> can move abroad, from the campus Wi-Fi
@@ -8769,8 +8764,8 @@ machine does not need to be shut down.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-s">VBoxManage modifyvm dick --nic1 natnetwork --natnetwork1 premises
-</pre>
+<pre class="src src-s"><code>VBoxManage modifyvm dick --nic1 natnetwork --natnetwork1 premises
+</code></pre>
 </div>
 
 <p>
@@ -8783,12 +8778,12 @@ tested in a terminal.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">ping -c 1 8.8.4.4      <span class="org-comment-delimiter"># </span><span class="org-comment">dns.google</span>
+<pre class="src src-sh"><code>ping -c 1 8.8.4.4      <span class="org-comment-delimiter"># </span><span class="org-comment">dns.google</span>
 ping -c 1 192.168.56.1 <span class="org-comment-delimiter"># </span><span class="org-comment">core</span>
 host dns.google
 host core.small.private
 host www
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8812,8 +8807,8 @@ calendar events.
 </p>
 </div>
 </div>
-<div id="outline-container-org4ecdc5b" class="outline-3">
-<h3 id="org4ecdc5b"><span class="section-number-3">13.15.</span> Test Pass Command</h3>
+<div id="outline-container-org1fd1f8b" class="outline-3">
+<h3 id="org1fd1f8b"><span class="section-number-3">13.15.</span> Test Pass Command</h3>
 <div class="outline-text-3" id="text-13-15">
 <p>
 To test the <code>./inst pass</code> command, the administrator logs in to <code>core</code>
@@ -8832,10 +8827,10 @@ On <code>core</code>, logged in as <code>sysadm</code>:
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">( <span class="org-builtin">cd</span> ~/Maildir/new/
+<pre class="src src-sh"><code>( <span class="org-builtin">cd</span> ~/Maildir/new/
   cp <span class="org-sh-quoted-exec">`ls -1t | head -1`</span> ~/msg )
 grep Subject: ~/msg
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8845,9 +8840,9 @@ password.</code>.  Then on the administrator's notebook:
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">scp sysadm@192.168.56.1:msg ./
+<pre class="src src-sh"><code>scp sysadm@192.168.56.1:msg ./
 ./inst pass &lt; msg
-</pre>
+</code></pre>
 </div>
 
 <p>
@@ -8860,8 +8855,8 @@ Finally, the administrator verifies that <code>dick</code> can login on <code>co
 </p>
 </div>
 </div>
-<div id="outline-container-org37b7a4b" class="outline-3">
-<h3 id="org37b7a4b"><span class="section-number-3">13.16.</span> Test Old Command</h3>
+<div id="outline-container-org567770b" class="outline-3">
+<h3 id="org567770b"><span class="section-number-3">13.16.</span> Test Old Command</h3>
 <div class="outline-text-3" id="text-13-16">
 <p>
 One more institute command is left to exercise.  The administrator
@@ -8869,8 +8864,8 @@ retires <code>dick</code> and his main device <code>dick</code>.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">./inst old dick
-</pre>
+<pre class="src src-sh"><code>./inst old dick
+</code></pre>
 </div>
 
 <p>
@@ -8881,16 +8876,16 @@ should fail.
 </div>
 </div>
 </div>
-<div id="outline-container-orgd49e21c" class="outline-2">
-<h2 id="orgd49e21c"><span class="section-number-2">14.</span> Future Work</h2>
+<div id="outline-container-orgf6f9793" class="outline-2">
+<h2 id="orgf6f9793"><span class="section-number-2">14.</span> Future Work</h2>
 <div class="outline-text-2" id="text-14">
 <p>
 The small institute's network, as currently defined in this doocument,
 is lacking in a number of respects.
 </p>
 </div>
-<div id="outline-container-org25c0257" class="outline-3">
-<h3 id="org25c0257"><span class="section-number-3">14.1.</span> Deficiencies</h3>
+<div id="outline-container-org26639c5" class="outline-3">
+<h3 id="org26639c5"><span class="section-number-3">14.1.</span> Deficiencies</h3>
 <div class="outline-text-3" id="text-14-1">
 <p>
 The current network monitoring is rudimentary.  It could use some
@@ -8942,30 +8937,18 @@ include the essential <code>verify-x509-name</code>.  Use the same name on
 separate certificates for Gate and Front?  Use the same certificate
 and key on Gate and Front?
 </p>
-
-<p>
-Nextcloud should really be found at <code>https://CLOUD.small.private/</code>
-rather than <code>https://core.small.private/nextcloud/</code>, to ease
-future expansion (moving services to additional machines).
-</p>
-
-<p>
-HTTPS could be used for Nextcloud transactions even though they are
-carried on encrypted VPNs.  This would eliminate a big warning on the
-Nextcloud Administration Overview page.
-</p>
 </div>
 </div>
-<div id="outline-container-org252a7b9" class="outline-3">
-<h3 id="org252a7b9"><span class="section-number-3">14.2.</span> More Tests</h3>
+<div id="outline-container-orgfe73858" class="outline-3">
+<h3 id="orgfe73858"><span class="section-number-3">14.2.</span> More Tests</h3>
 <div class="outline-text-3" id="text-14-2">
 <p>
 The testing process described in the previous chapter is far from
 complete.  Additional tests are needed.
 </p>
 </div>
-<div id="outline-container-orgf7d014e" class="outline-4">
-<h4 id="orgf7d014e"><span class="section-number-4">14.2.1.</span> Backup</h4>
+<div id="outline-container-orgc61d0e9" class="outline-4">
+<h4 id="orgc61d0e9"><span class="section-number-4">14.2.1.</span> Backup</h4>
 <div class="outline-text-4" id="text-14-2-1">
 <p>
 The <code>backup</code> command has not been tested.  It needs an encrypted
@@ -8974,8 +8957,8 @@ partition with which to sync?  And then some way to compare that to
 </p>
 </div>
 </div>
-<div id="outline-container-org2053b4a" class="outline-4">
-<h4 id="org2053b4a"><span class="section-number-4">14.2.2.</span> Restore</h4>
+<div id="outline-container-org6d144a5" class="outline-4">
+<h4 id="org6d144a5"><span class="section-number-4">14.2.2.</span> Restore</h4>
 <div class="outline-text-4" id="text-14-2-2">
 <p>
 The restore process has not been tested.  It might just copy <a href="Backup/"><q>Backup/</q></a>
@@ -8985,8 +8968,8 @@ perhaps permissions too.  It could also use an example
 </p>
 </div>
 </div>
-<div id="outline-container-org262e2b2" class="outline-4">
-<h4 id="org262e2b2"><span class="section-number-4">14.2.3.</span> Campus Disconnect</h4>
+<div id="outline-container-org876c9cb" class="outline-4">
+<h4 id="org876c9cb"><span class="section-number-4">14.2.3.</span> Campus Disconnect</h4>
 <div class="outline-text-4" id="text-14-2-3">
 <p>
 Email access (IMAPS) on <code>front</code> is&#x2026; difficult to test unless
@@ -9010,8 +8993,8 @@ could be used.</li>
 </div>
 </div>
 </div>
-<div id="outline-container-orge6607e3" class="outline-2">
-<h2 id="orge6607e3"><span class="section-number-2">15.</span> Appendix: The Bootstrap</h2>
+<div id="outline-container-orgb988f90" class="outline-2">
+<h2 id="orgb988f90"><span class="section-number-2">15.</span> Appendix: The Bootstrap</h2>
 <div class="outline-text-2" id="text-15">
 <p>
 Creating the private network from whole cloth (machines with recent
@@ -9031,11 +9014,11 @@ etc.: quite a bit of temporary, manual localnet configuration just to
 get to the additional packages.
 </p>
 </div>
-<div id="outline-container-orgc34cb28" class="outline-3">
-<h3 id="orgc34cb28"><span class="section-number-3">15.1.</span> The Current Strategy</h3>
+<div id="outline-container-org7fe37c6" class="outline-3">
+<h3 id="org7fe37c6"><span class="section-number-3">15.1.</span> The Current Strategy</h3>
 <div class="outline-text-3" id="text-15-1">
 <p>
-The strategy pursued in <a href="#org754e9f1">The Hardware</a> is two phase: prepare the servers
+The strategy pursued in <a href="#orgbf29081">The Hardware</a> is two phase: prepare the servers
 on the Internet where additional packages are accessible, then connect
 them to the campus facilities (the private Ethernet switch, Wi-Fi AP,
 ISP), manually configure IP addresses (while the DHCP client silently
@@ -9043,8 +9026,8 @@ fails), and avoid names until BIND9 is configured.
 </p>
 </div>
 </div>
-<div id="outline-container-org11fbf4b" class="outline-3">
-<h3 id="org11fbf4b"><span class="section-number-3">15.2.</span> Starting With Gate</h3>
+<div id="outline-container-org94b8b56" class="outline-3">
+<h3 id="org94b8b56"><span class="section-number-3">15.2.</span> Starting With Gate</h3>
 <div class="outline-text-3" id="text-15-2">
 <p>
 The strategy of Starting With Gate concentrates on configuring Gate's
@@ -9088,8 +9071,8 @@ ansible-playbook -l core site.yml
 </ul>
 </div>
 </div>
-<div id="outline-container-org679fbc3" class="outline-3">
-<h3 id="org679fbc3"><span class="section-number-3">15.3.</span> Pre-provision With Ansible</h3>
+<div id="outline-container-org1c34ede" class="outline-3">
+<h3 id="org1c34ede"><span class="section-number-3">15.3.</span> Pre-provision With Ansible</h3>
 <div class="outline-text-3" id="text-15-3">
 <p>
 A refinement of the current strategy might avoid the need to maintain
@@ -9142,7 +9125,7 @@ routes on Front and Gate, making the simulation less&#x2026; similar.
 </div></div>
 <div id="postamble" class="status">
 <p class="author">Author: Matt Birkholz</p>
-<p class="date">Created: 2024-10-29 Tue 21:35</p>
+<p class="date">Created: 2025-05-31 Sat 22:27</p>
 <p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
 </div>
 </body>