Update README.html.
authorMatt Birkholz <matt@birchwood-abbey.net>
Tue, 27 Feb 2024 02:43:02 +0000 (19:43 -0700)
committerMatt Birkholz <matt@birchwood-abbey.net>
Tue, 27 Feb 2024 02:43:02 +0000 (19:43 -0700)
README.html

index 98664c69b16ed21235ff2f75553b3422889d471f..765c7fce1bbdec822632ef7beaec81a6afa25372 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-01-02 Tue 13:37 -->
+<!-- 2024-02-26 Mon 19:42 -->
 <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>
@@ -48,7 +48,7 @@ connects to Front making the institute email, cloud, etc. available to
 members off campus.
 </p>
 
-<pre class="example" id="orgb9b8e48">
+<pre class="example" id="org984133a">
                 =                                                   
               _|||_                                                 
         =-The-Institute-=                                           
@@ -1030,7 +1030,7 @@ example result follows the code.
 </pre>
 </div>
 
-<div class="TEXT" id="org296b7f8">
+<div class="TEXT" id="org65edca1">
 <p>
 =&gt; 10.62.17.0/24
 </p>
@@ -1230,7 +1230,7 @@ file, copied it to the droplet, and installed it as the
 <pre class="example">
 notebook$ cat ~/.ssh/id_rsa.pub Secret/ssh_admin/id_rsa.pub \
 notebook_     &gt; admin_keys
-notebook$ rsync admin_keys sysadm@159.65.75.60:
+notebook$ scp admin_keys sysadm@159.65.75.60:
 The authenticity of host '159.65.75.60' can't be established.
 ....
 Are you sure you want to continue connecting (...)? yes
@@ -1247,6 +1247,31 @@ 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
+change of SSH identity.  The following commands copied the host keys
+in <q>Secret/ssh_front/</q> to the droplet and restarted the SSH server.
+</p>
+
+<pre class="example">
+notebook$ scp Secret/ssh_front/etc/ssh/ssh_host_* sysadm@159.65.75.60:
+notebook$ ssh sysadm@159.65.75.60
+sysadm@ubuntu$ chmod 600 ssh_host_*
+sysadm@ubuntu$ chmod 644 ssh_host_*.pub
+sysadm@ubuntu$ sudo cp -b ssh_host_* /etc/ssh/
+sysadm@ubuntu$ sudo systemctl restart ssh
+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
+new host identity.
+</p>
+
 <p>
 The administrator then tested the password-less ssh login as well as
 the privilege escalation command.
@@ -1345,8 +1370,10 @@ modem and installed them as shown below.
 </p>
 
 <pre class="example">
-$ sudo apt install openssh-server rsync isc-dhcp-server netplan.io \
-_                  bind9 fetchmail openvpn apache2
+$ sudo apt install netplan.io systemd-resolved unattended-upgrades \
+_                  ntp isc-dhcp-server bind9 apache2 openvpn \
+_                  postfix dovecot-imapd fetchmail expect rsync \
+_                  gnupg openssh-server
 </pre>
 
 
@@ -1357,12 +1384,23 @@ final configuration "in position" (on a frontier).
 </p>
 
 <pre class="example">
-$ sudo apt install mariadb-server php php-{bcmath,curl,gd,gmp,json}\
-_                  php-{mysql,mbstring,intl,imagick,xml,zip} \
+$ sudo apt install mariadb-server php php-{apcu,bcmath,curl,gd,gmp}\
+_                  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).
+</p>
+
+<pre class="example">
+$ 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
@@ -1373,7 +1411,7 @@ key found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created b
 <pre class="example">
 notebook$ cat ~/.ssh/id_rsa.pub Secret/ssh_admin/id_rsa.pub \
 notebook_     &gt; admin_keys
-notebook$ rsync admin_keys sysadm@core.lan:
+notebook$ scp admin_keys sysadm@core.lan:
 The authenticity of host 'core.lan' can't be established.
 ....
 Are you sure you want to continue connecting (...)? yes
@@ -1445,7 +1483,7 @@ USB-Ethernet adapter, or a wireless adapter connected to a
 campground Wi-Fi access point, etc.</li>
 </ol>
 
-<pre class="example" id="org43284fb">
+<pre class="example" id="orgba151ee">
 =============== | ==================================================
                 |                                           Premises
           (Campus ISP)                                              
@@ -1468,7 +1506,7 @@ This avoids the need for a second Wi-Fi access point and leads to the
 following topology.
 </p>
 
-<pre class="example" id="org51ead45">
+<pre class="example" id="org20945a6">
 =============== | ==================================================
                 |                                           Premises
            (House ISP)                                              
@@ -1541,7 +1579,9 @@ cable modem and installed them as shown below.
 </p>
 
 <pre class="example">
-$ sudo apt install openssh-server isc-dhcp-server netplan.io
+$ sudo apt install netplan.io systemd-resolved unattended-upgrades \
+_                  ufw isc-dhcp-server postfix openvpn \
+_                  openssh-server
 </pre>
 
 
@@ -1555,7 +1595,7 @@ key found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created b
 <pre class="example">
 notebook$ cat ~/.ssh/id_rsa.pub Secret/ssh_admin/id_rsa.pub \
 notebook_     &gt; admin_keys
-notebook$ rsync admin_keys sysadm@gate.lan:
+notebook$ scp admin_keys sysadm@gate.lan:
 The authenticity of host 'gate.lan' can't be established.
 ....
 Are you sure you want to continue connecting (...)? yes
@@ -1611,10 +1651,73 @@ At this point Gate was ready for provisioning with Ansible.
 </div>
 </div>
 </div>
-<div id="outline-container-org9240129" class="outline-2">
-<h2 id="org9240129"><span class="section-number-2">6.</span> The Front Role</h2>
+<div id="outline-container-orgd60dcd1" class="outline-2">
+<h2 id="orgd60dcd1"><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-orga1f8b11" class="outline-3">
+<h3 id="orga1f8b11"><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
+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">---
+- name: Include public variables.
+  include_vars: ../public/vars.yml
+  tags: accounts
+</pre>
+</div>
+</div>
+</div>
+<div id="outline-container-orgd3cb8ca" class="outline-3">
+<h3 id="orgd3cb8ca"><span class="section-number-3">6.2.</span> Trust Institute Certificate Authority</h3>
+<div class="outline-text-3" id="text-6-2">
+<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>.
+</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">
+- name: Trust the institute CA.
+  become: yes
+  copy:
+    src: ../Secret/CA/pki/ca.crt
+    dest: /usr/local/share/ca-certificates/{{ domain_name }}.crt
+    <span class="org-variable-name">mode: u</span>=r,g=r,o=r
+    owner: root
+    group: root
+  notify: Update CAs.
+</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">
+- name: Update CAs.
+  become: yes
+  command: update-ca-certificates
+</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 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
@@ -1640,20 +1743,13 @@ uses the institute's CA and server certificates, and expects client
 certificates signed by the institute CA.
 </p>
 </div>
-<div id="outline-container-org3c15e11" class="outline-3">
-<h3 id="org3c15e11"><span class="section-number-3">6.1.</span> Include Particulars</h3>
-<div class="outline-text-3" id="text-6-1">
-<p>
-The <code>front</code> role's tasks contain references to several common
-institute particulars, variables in the public and private <q>vars.yml</q>
-files and the institute membership roll in <q>private/members.yml</q>.  The
-first <code>front</code> role tasks are to include these files (described in <a href="#orgfa75f05">The
-Particulars</a> and <a href="#orge7fe793">Account Management</a>).
-</p>
-
+<div id="outline-container-orgc8a61a6" class="outline-3">
+<h3 id="orgc8a61a6"><span class="section-number-3">7.1.</span> Include Particulars</h3>
+<div class="outline-text-3" id="text-7-1">
 <p>
-The code block below is the first to tangle into
-<a href="roles/front/tasks/main.yml"><q>roles/front/tasks/main.yml</q></a>.
+The first task, as in <a href="#orgd60dcd1">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">
@@ -1673,9 +1769,9 @@ The code block below is the first to tangle into
 </div>
 </div>
 </div>
-<div id="outline-container-org39d7e52" class="outline-3">
-<h3 id="org39d7e52"><span class="section-number-3">6.2.</span> Configure Hostname</h3>
-<div class="outline-text-3" id="text-6-2">
+<div id="outline-container-orge2015ee" class="outline-3">
+<h3 id="orge2015ee"><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
 correct.  The correct <q>/etc/mailname</q> is essential to proper email
@@ -1705,8 +1801,8 @@ delivery.
 </div>
 </div>
 <div id="outline-container-org6267a25" class="outline-3">
-<h3 id="org6267a25"><span class="section-number-3">6.3.</span> Enable Systemd Resolved <a id="org5738867"></a></h3>
-<div class="outline-text-3" id="text-6-3">
+<h3 id="org6267a25"><span class="section-number-3">7.3.</span> Enable Systemd Resolved <a id="org5738867"></a></h3>
+<div class="outline-text-3" id="text-7-3">
 <p>
 The <code>systemd-networkd</code> and <code>systemd-resolved</code> service units are not
 enabled by default in Debian, but <i>are</i> the default in Ubuntu, and
@@ -1798,9 +1894,9 @@ separate code block named <code>enable-resolved</code>.<sup><a id="fnr.2" class=
 </div>
 </div>
 </div>
-<div id="outline-container-org56dc8b5" class="outline-3">
-<h3 id="org56dc8b5"><span class="section-number-3">6.4.</span> Add Administrator to System Groups</h3>
-<div class="outline-text-3" id="text-6-4">
+<div id="outline-container-orga3ab592" class="outline-3">
+<h3 id="orga3ab592"><span class="section-number-3">7.4.</span> Add Administrator to System Groups</h3>
+<div class="outline-text-3" id="text-7-4">
 <p>
 The administrator often needs to read (directories of) log files owned
 by groups <code>root</code> and <code>adm</code>.  Adding the administrator's account to
@@ -1820,8 +1916,8 @@ these groups speeds up debugging.
 </div>
 </div>
 <div id="outline-container-org633cf3e" class="outline-3">
-<h3 id="org633cf3e"><span class="section-number-3">6.5.</span> Configure SSH</h3>
-<div class="outline-text-3" id="text-6-5">
+<h3 id="org633cf3e"><span class="section-number-3">7.5.</span> Configure SSH</h3>
+<div class="outline-text-3" id="text-7-5">
 <p>
 The SSH service on Front needs to be known to Monkey.  The following
 tasks ensure this by replacing the automatically generated keys with
@@ -1858,9 +1954,9 @@ those stored in <a href="Secret/ssh_front/etc/ssh/"><q>Secret/ssh_front/etc/ssh/
 </div>
 </div>
 </div>
-<div id="outline-container-org63b4dba" class="outline-3">
-<h3 id="org63b4dba"><span class="section-number-3">6.6.</span> Configure Monkey</h3>
-<div class="outline-text-3" id="text-6-6">
+<div id="outline-container-orgc8386a2" class="outline-3">
+<h3 id="orgc8386a2"><span class="section-number-3">7.6.</span> Configure Monkey</h3>
+<div class="outline-text-3" id="text-7-6">
 <p>
 The small institute runs cron jobs and web scripts that generate
 reports and perform checks.  The un-privileged jobs are run by a
@@ -1900,8 +1996,8 @@ key on Core.
 </div>
 </div>
 <div id="outline-container-orgd1c69a2" class="outline-3">
-<h3 id="orgd1c69a2"><span class="section-number-3">6.7.</span> Install Rsync</h3>
-<div class="outline-text-3" id="text-6-7">
+<h3 id="orgd1c69a2"><span class="section-number-3">7.7.</span> Install Rsync</h3>
+<div class="outline-text-3" id="text-7-7">
 <p>
 Monkey uses Rsync to keep the institute's public web site up-to-date.
 </p>
@@ -1915,9 +2011,9 @@ Monkey uses Rsync to keep the institute's public web site up-to-date.
 </div>
 </div>
 </div>
-<div id="outline-container-org59be0a3" class="outline-3">
-<h3 id="org59be0a3"><span class="section-number-3">6.8.</span> Install Unattended Upgrades</h3>
-<div class="outline-text-3" id="text-6-8">
+<div id="outline-container-orge530d98" class="outline-3">
+<h3 id="orge530d98"><span class="section-number-3">7.8.</span> Install Unattended Upgrades</h3>
+<div class="outline-text-3" id="text-7-8">
 <p>
 The institute prefers to install security updates as soon as possible.
 </p>
@@ -1931,9 +2027,9 @@ The institute prefers to install security updates as soon as possible.
 </div>
 </div>
 </div>
-<div id="outline-container-orgae89ce8" class="outline-3">
-<h3 id="orgae89ce8"><span class="section-number-3">6.9.</span> Configure User Accounts</h3>
-<div class="outline-text-3" id="text-6-9">
+<div id="outline-container-org0f197d7" class="outline-3">
+<h3 id="org0f197d7"><span class="section-number-3">7.9.</span> Configure User Accounts</h3>
+<div class="outline-text-3" id="text-7-9">
 <p>
 User accounts are created immediately so that Postfix and Dovecot can
 start delivering email immediately, <i>without</i> returning "no such
@@ -1975,42 +2071,9 @@ recipient" replies.  The <a href="#orge7fe793">Account Management</a> chapter de
 </div>
 </div>
 </div>
-<div id="outline-container-org986ecf6" class="outline-3">
-<h3 id="org986ecf6"><span class="section-number-3">6.10.</span> Trust Institute Certificate Authority</h3>
-<div class="outline-text-3" id="text-6-10">
-<p>
-Front should recognize the institute's Certificate Authority as
-trustworthy, so its certificate is added to Front's set of trusted
-CAs.  More information about how the small institute manages its
-X.509 certificates is available in <a href="#org6519b0c">Keys</a>.
-</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: Trust the institute CA.
-  become: yes
-  copy:
-    src: ../Secret/CA/pki/ca.crt
-    dest: /usr/local/share/ca-certificates/{{ domain_name }}.crt
-    <span class="org-variable-name">mode: u</span>=r,g=r,o=r
-    owner: root
-    group: root
-  notify: Update CAs.
-</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">
-- name: Update CAs.
-  become: yes
-  command: update-ca-certificates
-</pre>
-</div>
-</div>
-</div>
-<div id="outline-container-org5d3587e" class="outline-3">
-<h3 id="org5d3587e"><span class="section-number-3">6.11.</span> Install Server Certificate</h3>
-<div class="outline-text-3" id="text-6-11">
+<div id="outline-container-org357b596" class="outline-3">
+<h3 id="org357b596"><span class="section-number-3">7.10.</span> Install Server Certificate</h3>
+<div class="outline-text-3" id="text-7-10">
 <p>
 The servers on Front use the same certificate (and key) to
 authenticate themselves to institute clients.  They share the
@@ -2040,8 +2103,8 @@ readable by <code>root</code>.
 </div>
 </div>
 <div id="outline-container-orgba341a6" class="outline-3">
-<h3 id="orgba341a6"><span class="section-number-3">6.12.</span> Configure Postfix on Front</h3>
-<div class="outline-text-3" id="text-6-12">
+<h3 id="orgba341a6"><span class="section-number-3">7.11.</span> Configure Postfix on Front</h3>
+<div class="outline-text-3" id="text-7-11">
 <p>
 Front uses Postfix to provide the institute's public SMTP service, and
 uses the institute's domain name for its host name.  The default
@@ -2232,8 +2295,8 @@ start and enable the service.
 </div>
 </div>
 <div id="outline-container-orge52533b" class="outline-3">
-<h3 id="orge52533b"><span class="section-number-3">6.13.</span> Configure Public Email Aliases</h3>
-<div class="outline-text-3" id="text-6-13">
+<h3 id="orge52533b"><span class="section-number-3">7.12.</span> Configure Public Email Aliases</h3>
+<div class="outline-text-3" id="text-7-12">
 <p>
 The institute's Front needs to deliver email addressed to a number of
 common aliases as well as those advertised on the web site.  System
@@ -2273,9 +2336,9 @@ created by a more specialized role.
 </div>
 </div>
 </div>
-<div id="outline-container-orgef69b4b" class="outline-3">
-<h3 id="orgef69b4b"><span class="section-number-3">6.14.</span> Configure Dovecot IMAPd</h3>
-<div class="outline-text-3" id="text-6-14">
+<div id="outline-container-org62ed00b" class="outline-3">
+<h3 id="org62ed00b"><span class="section-number-3">7.13.</span> Configure Dovecot IMAPd</h3>
+<div class="outline-text-3" id="text-7-13">
 <p>
 Front uses Dovecot's IMAPd to allow user Fetchmail jobs on Core to
 pick up messages.  Front's Dovecot configuration is largely the Debian
@@ -2345,8 +2408,8 @@ and enables it to start at every reboot.
 </div>
 </div>
 <div id="outline-container-orgae570f4" class="outline-3">
-<h3 id="orgae570f4"><span class="section-number-3">6.15.</span> Configure Apache2 <a id="orgf59dafb"></a></h3>
-<div class="outline-text-3" id="text-6-15">
+<h3 id="orgae570f4"><span class="section-number-3">7.14.</span> Configure Apache2 <a id="orgf59dafb"></a></h3>
+<div class="outline-text-3" id="text-7-14">
 <p>
 This is the small institute's public web site.  It is simple, static,
 and thus (hopefully) difficult to subvert.  There are no server-side
@@ -2738,9 +2801,9 @@ the users' <q>~/Public/HTML/</q> directories.
 </div>
 </div>
 </div>
-<div id="outline-container-org0c71d3a" class="outline-3">
-<h3 id="org0c71d3a"><span class="section-number-3">6.16.</span> Configure OpenVPN</h3>
-<div class="outline-text-3" id="text-6-16">
+<div id="outline-container-org9f6de30" class="outline-3">
+<h3 id="org9f6de30"><span class="section-number-3">7.15.</span> Configure OpenVPN</h3>
+<div class="outline-text-3" id="text-7-15">
 <p>
 Front uses OpenVPN to provide the institute's public VPN service.  The
 configuration is straightforward with one complication.  OpenVPN needs
@@ -2937,8 +3000,8 @@ configure the OpenVPN server on Front.
 </div>
 </div>
 <div id="outline-container-orgc93df1f" class="outline-3">
-<h3 id="orgc93df1f"><span class="section-number-3">6.17.</span> Configure Kamailio</h3>
-<div class="outline-text-3" id="text-6-17">
+<h3 id="orgc93df1f"><span class="section-number-3">7.16.</span> Configure Kamailio</h3>
+<div class="outline-text-3" id="text-7-16">
 <p>
 Front uses Kamailio to provide a SIP service on the public VPN so that
 members abroad can chat privately.  This is a connection-less UDP
@@ -3053,8 +3116,8 @@ Finally, Kamailio can be configured and started.
 </div>
 </div>
 <div id="outline-container-orge7ebc83" class="outline-2">
-<h2 id="orge7ebc83"><span class="section-number-2">7.</span> The Core Role</h2>
-<div class="outline-text-2" id="text-7">
+<h2 id="orge7ebc83"><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
@@ -3063,9 +3126,9 @@ Debian install and remote access to a privileged, administrator's
 account.  (For details, see <a href="#org8d60b7b">The Core Machine</a>.)
 </p>
 </div>
-<div id="outline-container-orgdc88f33" class="outline-3">
-<h3 id="orgdc88f33"><span class="section-number-3">7.1.</span> Include Particulars</h3>
-<div class="outline-text-3" id="text-7-1">
+<div id="outline-container-orgabb953b" class="outline-3">
+<h3 id="orgabb953b"><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
 particulars and membership roll.
@@ -3086,9 +3149,9 @@ particulars and membership roll.
 </div>
 </div>
 </div>
-<div id="outline-container-org6836eeb" class="outline-3">
-<h3 id="org6836eeb"><span class="section-number-3">7.2.</span> Configure Hostname</h3>
-<div class="outline-text-3" id="text-7-2">
+<div id="outline-container-org7ee9fb1" class="outline-3">
+<h3 id="org7ee9fb1"><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
 correct.  Core accepts email addressed to the institute's public or
@@ -3120,9 +3183,9 @@ proper email delivery.
 </div>
 </div>
 </div>
-<div id="outline-container-org7ecb710" class="outline-3">
-<h3 id="org7ecb710"><span class="section-number-3">7.3.</span> Enable Systemd Resolved</h3>
-<div class="outline-text-3" id="text-7-3">
+<div id="outline-container-orgdcf7bec" class="outline-3">
+<h3 id="orgdcf7bec"><span class="section-number-3">8.3.</span> Enable Systemd Resolved</h3>
+<div class="outline-text-3" id="text-8-3">
 <p>
 Core starts the <code>systemd-networkd</code> and <code>systemd-resolved</code> service
 units on boot.  See <a href="#org5738867">Enable Systemd Resolved</a>.
@@ -3165,9 +3228,9 @@ units on boot.  See <a href="#org5738867">Enable Systemd Resolved</a>.
 </div>
 </div>
 </div>
-<div id="outline-container-orgd4cda12" class="outline-3">
-<h3 id="orgd4cda12"><span class="section-number-3">7.4.</span> Configure Systemd Resolved</h3>
-<div class="outline-text-3" id="text-7-4">
+<div id="outline-container-orgecf0743" class="outline-3">
+<h3 id="orgecf0743"><span class="section-number-3">8.4.</span> Configure Systemd Resolved</h3>
+<div class="outline-text-3" id="text-8-4">
 <p>
 Core runs the campus name server, so Resolved is configured to use it
 (or <code>dns.google</code>), to include the institute's domain in its search
@@ -3210,8 +3273,8 @@ list, and to disable its cache and stub listener.
 </div>
 </div>
 <div id="outline-container-org2dec986" class="outline-3">
-<h3 id="org2dec986"><span class="section-number-3">7.5.</span> Configure Netplan</h3>
-<div class="outline-text-3" id="text-7-5">
+<h3 id="org2dec986"><span class="section-number-3">8.5.</span> Configure Netplan</h3>
+<div class="outline-text-3" id="text-8-5">
 <p>
 Core's network interface is statically configured using Netplan and an
 <q>/etc/netplan/60-core.yaml</q> file.  That file provides Core's address
@@ -3222,6 +3285,18 @@ created here.  It is created by OpenVPN when Core connects to Front's
 VPN.
 </p>
 
+<p>
+Core's Netplan needs the name of its main (only) Ethernet interface,
+an example of which is given here.  (A clever way to extract that name
+from <code>ansible_facts</code> would be appreciated.  The <code>ansible_default_ipv4</code>
+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>
+</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">
 - name: Install netplan.
@@ -3235,7 +3310,7 @@ VPN.
       network:
         renderer: networkd
         ethernets:
-          {{ ansible_default_ipv4.interface }}:
+          {{ core_ethernet }}:
             dhcp4: false
             addresses: [ {{ core_addr_cidr }} ]
             nameservers:
@@ -3258,8 +3333,8 @@ VPN.
 </div>
 </div>
 <div id="outline-container-org404665f" class="outline-3">
-<h3 id="org404665f"><span class="section-number-3">7.6.</span> Configure DHCP For the Private Ethernet</h3>
-<div class="outline-text-3" id="text-7-6">
+<h3 id="org404665f"><span class="section-number-3">8.6.</span> Configure DHCP For the Private Ethernet</h3>
+<div class="outline-text-3" id="text-8-6">
 <p>
 Core speaks DHCP (Dynamic Host Configuration Protocol) using the
 Internet Software Consortium's DHCP server.  The server assigns unique
@@ -3324,7 +3399,7 @@ with the real <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></
   become: yes
   lineinfile:
     path: /etc/default/isc-dhcp-server
-    <span class="org-variable-name">line: INTERFACESv4</span>=<span class="org-string">"{{ ansible_default_ipv4.interface }}"</span>
+    <span class="org-variable-name">line: INTERFACESv4</span>=<span class="org-string">"{{ core_ethernet }}"</span>
     <span class="org-variable-name">regexp: ^INTERFACESv4</span>=
   notify: Restart DHCP server.
 
@@ -3356,8 +3431,8 @@ with the real <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></
 </div>
 </div>
 <div id="outline-container-org2134214" class="outline-3">
-<h3 id="org2134214"><span class="section-number-3">7.7.</span> Configure BIND9</h3>
-<div class="outline-text-3" id="text-7-7">
+<h3 id="org2134214"><span class="section-number-3">8.7.</span> Configure BIND9</h3>
+<div class="outline-text-3" id="text-8-7">
 <p>
 Core uses BIND9 to provide a private-view name service for the
 institute as described in <a href="#org12ea1d0">The Name Service</a>.  The configuration
@@ -3633,9 +3708,9 @@ craps up <q>/var/log/</q> and the Systemd journal.
 </div>
 </div>
 </div>
-<div id="outline-container-orgcc94373" class="outline-3">
-<h3 id="orgcc94373"><span class="section-number-3">7.8.</span> Add Administrator to System Groups</h3>
-<div class="outline-text-3" id="text-7-8">
+<div id="outline-container-orgef1243d" class="outline-3">
+<h3 id="orgef1243d"><span class="section-number-3">8.8.</span> Add Administrator to System Groups</h3>
+<div class="outline-text-3" id="text-8-8">
 <p>
 The administrator often needs to read (directories of) log files owned
 by groups <code>root</code> and <code>adm</code>.  Adding the administrator's account to
@@ -3654,9 +3729,9 @@ these groups speeds up debugging.
 </div>
 </div>
 </div>
-<div id="outline-container-org8f1faaa" class="outline-3">
-<h3 id="org8f1faaa"><span class="section-number-3">7.9.</span> Configure Monkey</h3>
-<div class="outline-text-3" id="text-7-9">
+<div id="outline-container-org14610e1" class="outline-3">
+<h3 id="org14610e1"><span class="section-number-3">8.9.</span> Configure Monkey</h3>
+<div class="outline-text-3" id="text-8-9">
 <p>
 The small institute runs cron jobs and web scripts that generate
 reports and perform checks.  The un-privileged jobs are run by a
@@ -3722,9 +3797,9 @@ described in <a href="#org1ac6235">*Configure Apache2</a>).
 </div>
 </div>
 </div>
-<div id="outline-container-org6b4e3f2" class="outline-3">
-<h3 id="org6b4e3f2"><span class="section-number-3">7.10.</span> Install <code>unattended-upgrades</code></h3>
-<div class="outline-text-3" id="text-7-10">
+<div id="outline-container-org61d58b8" class="outline-3">
+<h3 id="org61d58b8"><span class="section-number-3">8.10.</span> Install Unattended Upgrades</h3>
+<div class="outline-text-3" id="text-8-10">
 <p>
 The institute prefers to install security updates as soon as possible.
 </p>
@@ -3739,8 +3814,8 @@ The institute prefers to install security updates as soon as possible.
 </div>
 </div>
 <div id="outline-container-orgd919e4d" class="outline-3">
-<h3 id="orgd919e4d"><span class="section-number-3">7.11.</span> Install Expect</h3>
-<div class="outline-text-3" id="text-7-11">
+<h3 id="orgd919e4d"><span class="section-number-3">8.11.</span> Install Expect</h3>
+<div class="outline-text-3" id="text-8-11">
 <p>
 The <code>expect</code> program is used by <a href="#org1c6f4a8">The Institute Commands</a> to interact
 with Nextcloud on the command line.
@@ -3755,9 +3830,9 @@ with Nextcloud on the command line.
 </div>
 </div>
 </div>
-<div id="outline-container-orgf7e8da6" class="outline-3">
-<h3 id="orgf7e8da6"><span class="section-number-3">7.12.</span> Configure User Accounts</h3>
-<div class="outline-text-3" id="text-7-12">
+<div id="outline-container-org4c79c93" class="outline-3">
+<h3 id="org4c79c93"><span class="section-number-3">8.12.</span> Configure User Accounts</h3>
+<div class="outline-text-3" id="text-8-12">
 <p>
 User accounts are created immediately so that backups can begin
 restoring as soon as possible.  The <a href="#orge7fe793">Account Management</a> chapter
@@ -3798,42 +3873,9 @@ describes the <code>members</code> and <code>usernames</code> variables.
 </div>
 </div>
 </div>
-<div id="outline-container-orga70c44f" class="outline-3">
-<h3 id="orga70c44f"><span class="section-number-3">7.13.</span> Trust Institute Certificate Authority</h3>
-<div class="outline-text-3" id="text-7-13">
-<p>
-Core should recognize the institute's Certificate Authority as
-trustworthy, so its certificate is added to Core's set of trusted
-CAs.  More information about how the small institute manages its
-X.509 certificates is available in <a href="#org6519b0c">Keys</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">
-- name: Trust the institute CA.
-  become: yes
-  copy:
-    src: ../Secret/CA/pki/ca.crt
-    dest: /usr/local/share/ca-certificates/{{ domain_name }}.crt
-    <span class="org-variable-name">mode: u</span>=r,g=r,o=r
-    owner: root
-    group: root
-  notify: Update CAs.
-</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">
-- name: Update CAs.
-  become: yes
-  command: update-ca-certificates
-</pre>
-</div>
-</div>
-</div>
-<div id="outline-container-orgdce1a93" class="outline-3">
-<h3 id="orgdce1a93"><span class="section-number-3">7.14.</span> Install Server Certificate</h3>
-<div class="outline-text-3" id="text-7-14">
+<div id="outline-container-org0bff045" class="outline-3">
+<h3 id="org0bff045"><span class="section-number-3">8.13.</span> Install Server Certificate</h3>
+<div class="outline-text-3" id="text-8-13">
 <p>
 The servers on Core use the same certificate (and key) to authenticate
 themselves to institute clients.  They share the <q>/etc/server.crt</q> and
@@ -3862,8 +3904,8 @@ themselves to institute clients.  They share the <q>/etc/server.crt</q> and
 </div>
 </div>
 <div id="outline-container-org1a74046" class="outline-3">
-<h3 id="org1a74046"><span class="section-number-3">7.15.</span> Install NTP</h3>
-<div class="outline-text-3" id="text-7-15">
+<h3 id="org1a74046"><span class="section-number-3">8.14.</span> Install NTP</h3>
+<div class="outline-text-3" id="text-8-14">
 <p>
 Core uses NTP to provide a time synchronization service to the campus.
 The default daemon's default configuration is fine.
@@ -3879,8 +3921,8 @@ The default daemon's default configuration is fine.
 </div>
 </div>
 <div id="outline-container-org948efaa" class="outline-3">
-<h3 id="org948efaa"><span class="section-number-3">7.16.</span> Configure Postfix on Core</h3>
-<div class="outline-text-3" id="text-7-16">
+<h3 id="org948efaa"><span class="section-number-3">8.15.</span> Configure Postfix on Core</h3>
+<div class="outline-text-3" id="text-8-15">
 <p>
 Core uses Postfix to provide SMTP service to the campus.  The default
 Debian configuration (for an "Internet Site") is nearly sufficient.
@@ -4048,8 +4090,8 @@ enable the service.  Whenever <q>/etc/postfix/transport</q> is changed, the
 </div>
 </div>
 <div id="outline-container-orgaf844fe" class="outline-3">
-<h3 id="orgaf844fe"><span class="section-number-3">7.17.</span> Configure Private Email Aliases</h3>
-<div class="outline-text-3" id="text-7-17">
+<h3 id="orgaf844fe"><span class="section-number-3">8.16.</span> Configure Private Email Aliases</h3>
+<div class="outline-text-3" id="text-8-16">
 <p>
 The institute's Core needs to deliver email addressed to institute
 aliases including those advertised on the campus web site, in VPN
@@ -4085,9 +4127,9 @@ installed by more specialized roles.
 </div>
 </div>
 </div>
-<div id="outline-container-org23f499c" class="outline-3">
-<h3 id="org23f499c"><span class="section-number-3">7.18.</span> Configure Dovecot IMAPd</h3>
-<div class="outline-text-3" id="text-7-18">
+<div id="outline-container-org0b2a149" class="outline-3">
+<h3 id="org0b2a149"><span class="section-number-3">8.17.</span> Configure Dovecot IMAPd</h3>
+<div class="outline-text-3" id="text-8-17">
 <p>
 Core uses Dovecot's IMAPd to store and serve member emails.  As on
 Front, Core's Dovecot configuration is largely the Debian default with
@@ -4152,8 +4194,8 @@ and enables it to start at every reboot.
 </div>
 </div>
 <div id="outline-container-org5a3cd75" class="outline-3">
-<h3 id="org5a3cd75"><span class="section-number-3">7.19.</span> Configure Fetchmail</h3>
-<div class="outline-text-3" id="text-7-19">
+<h3 id="org5a3cd75"><span class="section-number-3">8.18.</span> Configure Fetchmail</h3>
+<div class="outline-text-3" id="text-8-18">
 <p>
 Core runs a <code>fetchmail</code> for each member of the institute.  Individual
 <code>fetchmail</code> jobs can run with the <code>--idle</code> option and thus can
@@ -4330,8 +4372,8 @@ Otherwise the following task might be appropriate.
 </div>
 </div>
 <div id="outline-container-org14de2c2" class="outline-3">
-<h3 id="org14de2c2"><span class="section-number-3">7.20.</span> Configure Apache2 <a id="org1ac6235"></a></h3>
-<div class="outline-text-3" id="text-7-20">
+<h3 id="org14de2c2"><span class="section-number-3">8.19.</span> Configure Apache2 <a id="org1ac6235"></a></h3>
+<div class="outline-text-3" id="text-8-19">
 <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>.
@@ -4538,6 +4580,17 @@ interfere with mapping URLs to the correct virtual host.
     name: <span class="org-string">"{{ item }}"</span>
   loop: [ userdir, cgi ]
   notify: Restart Apache2.
+  <span class="org-variable-name">when: ansible_distribution !</span>= <span class="org-string">'Debian'</span>
+        or 12 &gt; ansible_distribution_major_version|int
+
+- name: Enable Apache2 modules (Debian 12).
+  become: yes
+  apache2_module:
+    name: <span class="org-string">"{{ item }}"</span>
+  loop: [ userdir, cgid ]
+  notify: Restart Apache2.
+  <span class="org-variable-name">when: ansible_distribution</span> == <span class="org-string">'Debian'</span>
+        and 11 &lt; ansible_distribution_major_version|int
 </pre>
 </div>
 
@@ -4670,8 +4723,8 @@ The <code>a2ensite</code> command enables them.
 </div>
 </div>
 <div id="outline-container-org5eefe23" class="outline-3">
-<h3 id="org5eefe23"><span class="section-number-3">7.21.</span> Configure Website Updates</h3>
-<div class="outline-text-3" id="text-7-21">
+<h3 id="org5eefe23"><span class="section-number-3">8.20.</span> Configure Website Updates</h3>
+<div class="outline-text-3" id="text-8-20">
 <p>
 Monkey on Core runs <q>/usr/local/sbin/webupdate</q> every 15 minutes via a
 <code>cron</code> job.  The example script mirrors <q>/WWW/live/</q> on Core to
@@ -4721,8 +4774,8 @@ provided <a href="#orgbb22232">here</a>.
 </div>
 </div>
 <div id="outline-container-org0eac7f7" class="outline-3">
-<h3 id="org0eac7f7"><span class="section-number-3">7.22.</span> Configure OpenVPN Connection to Front</h3>
-<div class="outline-text-3" id="text-7-22">
+<h3 id="org0eac7f7"><span class="section-number-3">8.21.</span> Configure OpenVPN Connection to Front</h3>
+<div class="outline-text-3" id="text-8-21">
 <p>
 Core connects to Front's public VPN to provide members abroad with a
 route to the campus networks.  As described in the configuration of
@@ -4843,8 +4896,8 @@ for Core.
 </div>
 </div>
 <div id="outline-container-org517dee3" class="outline-3">
-<h3 id="org517dee3"><span class="section-number-3">7.23.</span> Configure NAGIOS</h3>
-<div class="outline-text-3" id="text-7-23">
+<h3 id="org517dee3"><span class="section-number-3">8.22.</span> Configure NAGIOS</h3>
+<div class="outline-text-3" id="text-8-22">
 <p>
 Core runs a <code>nagios4</code> server to monitor "services" on institute hosts.
 The following tasks install the necessary packages and configure the
@@ -4925,8 +4978,8 @@ Core and Campus (and thus Gate) machines.
 </div>
 </div>
 <div id="outline-container-orgda831f7" class="outline-4">
-<h4 id="orgda831f7"><span class="section-number-4">7.23.1.</span> Configure NAGIOS Monitors for Core</h4>
-<div class="outline-text-4" id="text-7-23-1">
+<h4 id="orgda831f7"><span class="section-number-4">8.22.1.</span> Configure NAGIOS Monitors for Core</h4>
+<div class="outline-text-4" id="text-8-22-1">
 <p>
 The first block in <q>nagios.cfg</q> specifies monitors for services on
 Core.  The monitors are simple, local plugins, and the block is very
@@ -5001,8 +5054,8 @@ used here <i>may</i> specify plugin arguments.
 </div>
 </div>
 <div id="outline-container-org447bb4c" class="outline-4">
-<h4 id="org447bb4c"><span class="section-number-4">7.23.2.</span> Custom NAGIOS Monitor <code>inst_sensors</code></h4>
-<div class="outline-text-4" id="text-7-23-2">
+<h4 id="org447bb4c"><span class="section-number-4">8.22.2.</span> Custom NAGIOS Monitor <code>inst_sensors</code></h4>
+<div class="outline-text-4" id="text-8-22-2">
 <p>
 The <code>check_sensors</code> plugin is included in the package
 <code>monitoring-plugins-basic</code>, but it does not report any readings.  The
@@ -5113,8 +5166,8 @@ Core.
 </div>
 </div>
 <div id="outline-container-orge20967c" class="outline-4">
-<h4 id="orge20967c"><span class="section-number-4">7.23.3.</span> Configure NAGIOS Monitors for Remote Hosts</h4>
-<div class="outline-text-4" id="text-7-23-3">
+<h4 id="orge20967c"><span class="section-number-4">8.22.3.</span> Configure NAGIOS Monitors for Remote Hosts</h4>
+<div class="outline-text-4" id="text-8-22-3">
 <p>
 The following sections contain code blocks specifying monitors for
 services on other campus hosts.  The NAGIOS server on Core will
@@ -5135,8 +5188,8 @@ on each campus host by the campus role's <a href="#orgbd0ce38">Configure NRPE</a
 </div>
 </div>
 <div id="outline-container-orgfe68c96" class="outline-4">
-<h4 id="orgfe68c96"><span class="section-number-4">7.23.4.</span> Configure NAGIOS Monitors for Gate</h4>
-<div class="outline-text-4" id="text-7-23-4">
+<h4 id="orgfe68c96"><span class="section-number-4">8.22.4.</span> Configure NAGIOS Monitors for Gate</h4>
+<div class="outline-text-4" id="text-8-22-4">
 <p>
 Define the monitored host, <code>gate</code>.  Monitor its response to network
 pings.
@@ -5267,8 +5320,8 @@ Monitor <code>inst_sensors</code> on Gate.
 </div>
 </div>
 <div id="outline-container-org04cc272" class="outline-3">
-<h3 id="org04cc272"><span class="section-number-3">7.24.</span> Configure Backups</h3>
-<div class="outline-text-3" id="text-7-24">
+<h3 id="org04cc272"><span class="section-number-3">8.23.</span> Configure Backups</h3>
+<div class="outline-text-3" id="text-8-23">
 <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>.
@@ -5287,8 +5340,8 @@ example script is provided in <a href="#org9d5954c">here</a>.
 </div>
 </div>
 <div id="outline-container-orgd97190a" class="outline-3">
-<h3 id="orgd97190a"><span class="section-number-3">7.25.</span> Configure Nextcloud</h3>
-<div class="outline-text-3" id="text-7-25">
+<h3 id="orgd97190a"><span class="section-number-3">8.24.</span> Configure Nextcloud</h3>
+<div class="outline-text-3" id="text-8-24">
 <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
@@ -5299,8 +5352,8 @@ afterwards.
 </p>
 </div>
 <div id="outline-container-orga7bf888" class="outline-4">
-<h4 id="orga7bf888"><span class="section-number-4">7.25.1.</span> Prepare Core For Nextcloud</h4>
-<div class="outline-text-4" id="text-7-25-1">
+<h4 id="orga7bf888"><span class="section-number-4">8.24.1.</span> Prepare Core For Nextcloud</h4>
+<div class="outline-text-4" id="text-8-24-1">
 <p>
 The Ansible code contained herein prepares Core to run Nextcloud by
 installing required software packages, configuring the web server, and
@@ -5493,7 +5546,7 @@ 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">7.25.5</a> subsection below, before <code>occ
+given in the <a href="#orga610911">8.24.5</a> subsection below, before <code>occ
 maintenance:install</code> can run.
 </p>
 
@@ -5532,8 +5585,8 @@ its document root.
 </div>
 </div>
 <div id="outline-container-org06f8ed1" class="outline-4">
-<h4 id="org06f8ed1"><span class="section-number-4">7.25.2.</span> Configure PHP</h4>
-<div class="outline-text-4" id="text-7-25-2">
+<h4 id="org06f8ed1"><span class="section-number-4">8.24.2.</span> Configure PHP</h4>
+<div class="outline-text-4" id="text-8-24-2">
 <p>
 The following tasks set a number of PHP parameters for better
 performance, as recommended by Nextcloud.
@@ -5547,6 +5600,17 @@ performance, as recommended by Nextcloud.
     path: /etc/php/7.4/apache2/php.ini
     <span class="org-variable-name">regexp: memory_limit *</span>=
     <span class="org-variable-name">line: memory_limit</span> = 512M
+  <span class="org-variable-name">when: ansible_distribution !</span>= <span class="org-string">'Debian'</span>
+        or 12 &gt; ansible_distribution_major_version|int
+
+- name: Set PHP memory_limit for Nextcloud (Debian 12).
+  become: yes
+  lineinfile:
+    path: /etc/php/8.2/apache2/php.ini
+    <span class="org-variable-name">regexp: memory_limit *</span>=
+    <span class="org-variable-name">line: memory_limit</span> = 512M
+  <span class="org-variable-name">when: ansible_distribution</span> == <span class="org-string">'Debian'</span>
+        and 11 &lt; ansible_distribution_major_version|int
 
 - name: Include PHP parameters for Nextcloud.
   become: yes
@@ -5576,8 +5640,8 @@ performance, as recommended by Nextcloud.
 </div>
 </div>
 <div id="outline-container-org45a4a2a" class="outline-4">
-<h4 id="org45a4a2a"><span class="section-number-4">7.25.3.</span> Create <q>/Nextcloud/</q></h4>
-<div class="outline-text-4" id="text-7-25-3">
+<h4 id="org45a4a2a"><span class="section-number-4">8.24.3.</span> Create <q>/Nextcloud/</q></h4>
+<div class="outline-text-4" id="text-8-24-3">
 <p>
 The Ansible tasks up to this point have completed Core's LAMP stack
 and made Core ready to run Nextcloud, but they have <i>not</i> installed
@@ -5635,8 +5699,8 @@ sudo mount /Nextcloud
 </div>
 </div>
 <div id="outline-container-org0568172" class="outline-4">
-<h4 id="org0568172"><span class="section-number-4">7.25.4.</span> Restore Nextcloud</h4>
-<div class="outline-text-4" id="text-7-25-4">
+<h4 id="org0568172"><span class="section-number-4">8.24.4.</span> Restore Nextcloud</h4>
+<div class="outline-text-4" id="text-8-24-4">
 <p>
 Restoring Nextcloud in the newly created <q>/Nextcloud/</q> presumably
 starts with plugging in the portable backup drive and unlocking it so
@@ -5687,8 +5751,8 @@ Overview web page.
 </div>
 </div>
 <div id="outline-container-orga610911" class="outline-4">
-<h4 id="orga610911"><span class="section-number-4">7.25.5.</span> Install Nextcloud</h4>
-<div class="outline-text-4" id="text-7-25-5">
+<h4 id="orga610911"><span class="section-number-4">8.24.5.</span> Install Nextcloud</h4>
+<div class="outline-text-4" id="text-8-24-5">
 <p>
 Installing Nextcloud in the newly created <q>/Nextcloud/</q> starts with
 downloading and verifying a recent release tarball.  The following
@@ -5759,8 +5823,8 @@ Administration &gt; Overview page.
 </div>
 </div>
 <div id="outline-container-org380598a" class="outline-4">
-<h4 id="org380598a"><span class="section-number-4">7.25.6.</span> Afterwards</h4>
-<div class="outline-text-4" id="text-7-25-6">
+<h4 id="org380598a"><span class="section-number-4">8.24.6.</span> Afterwards</h4>
+<div class="outline-text-4" id="text-8-24-6">
 <p>
 Whether Nextcloud was restored or installed, there are a few things
 Ansible can do to bolster reliability and security (aka privacy).
@@ -5942,8 +6006,8 @@ run before the next backup.
 </div>
 </div>
 <div id="outline-container-org72d6fde" class="outline-2">
-<h2 id="org72d6fde"><span class="section-number-2">8.</span> The Gate Role</h2>
-<div class="outline-text-2" id="text-8">
+<h2 id="org72d6fde"><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
@@ -5970,9 +6034,9 @@ applied first, by which Gate gets a campus machine's DNS and Postfix
 configurations, etc.
 </p>
 </div>
-<div id="outline-container-org662043e" class="outline-3">
-<h3 id="org662043e"><span class="section-number-3">8.1.</span> Include Particulars</h3>
-<div class="outline-text-3" id="text-8-1">
+<div id="outline-container-orgb5d8866" class="outline-3">
+<h3 id="orgb5d8866"><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>
@@ -5993,8 +6057,8 @@ The following should be familiar boilerplate by now.
 </div>
 </div>
 <div id="outline-container-org1e2857f" class="outline-3">
-<h3 id="org1e2857f"><span class="section-number-3">8.2.</span> Configure Netplan <a id="org176e1b0"></a></h3>
-<div class="outline-text-3" id="text-8-2">
+<h3 id="org1e2857f"><span class="section-number-3">9.2.</span> Configure Netplan <a id="org176e1b0"></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
@@ -6009,9 +6073,9 @@ 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:               ff:ff:ff:ff:ff:ff
-gate_wifi_mac:              ff:ff:ff:ff:ff:ff
-gate_isp_mac:               ff:ff:ff:ff:ff:ff
+<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
+gate_isp_mac:               08:00:27:3d:42:e5
+gate_wifi_mac:              08:00:27:4a:de:d2
 </pre>
 </div>
 
@@ -6090,8 +6154,8 @@ campus ISP without interference from Ansible.
 </div>
 </div>
 <div id="outline-container-orga752cf7" class="outline-3">
-<h3 id="orga752cf7"><span class="section-number-3">8.3.</span> UFW Rules</h3>
-<div class="outline-text-3" id="text-8-3">
+<h3 id="orga752cf7"><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
 filters at boot-time.  The institute does not use a firewall except to
@@ -6174,8 +6238,8 @@ the <code>wifi</code> device to the <code>lan</code> device, just the <code>ovpn
 </div>
 </div>
 <div id="outline-container-org092a0fa" class="outline-3">
-<h3 id="org092a0fa"><span class="section-number-3">8.4.</span> Install UFW</h3>
-<div class="outline-text-3" id="text-8-4">
+<h3 id="org092a0fa"><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
 policy in <q>/etc/default/ufw</q>, and install the above rules in
@@ -6241,8 +6305,8 @@ sudo ufw enable
 </div>
 </div>
 <div id="outline-container-org6b47f34" class="outline-3">
-<h3 id="org6b47f34"><span class="section-number-3">8.5.</span> Configure DHCP For The Gate-WiFi Ethernet</h3>
-<div class="outline-text-3" id="text-8-5">
+<h3 id="org6b47f34"><span class="section-number-3">9.5.</span> Configure DHCP For The Gate-WiFi 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
@@ -6345,9 +6409,9 @@ the daemon listens <i>only</i> on the Gate-WiFi network interface.
 </div>
 </div>
 </div>
-<div id="outline-container-orgdf7fcb2" class="outline-3">
-<h3 id="orgdf7fcb2"><span class="section-number-3">8.6.</span> Install Server Certificate</h3>
-<div class="outline-text-3" id="text-8-6">
+<div id="outline-container-orge91063f" class="outline-3">
+<h3 id="orge91063f"><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)
 to authenticate itself to its clients.  It uses the <q>/etc/server.crt</q>
@@ -6373,9 +6437,9 @@ and Front) do.
 </div>
 </div>
 </div>
-<div id="outline-container-org50c9363" class="outline-3">
-<h3 id="org50c9363"><span class="section-number-3">8.7.</span> Configure OpenVPN</h3>
-<div class="outline-text-3" id="text-8-7">
+<div id="outline-container-org0fb006b" class="outline-3">
+<h3 id="org0fb006b"><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
 clients are <i>not</i> configured to route <i>all</i> of their traffic through
@@ -6520,8 +6584,8 @@ configure the OpenVPN server on Gate.
 </div>
 </div>
 <div id="outline-container-org2d914f2" class="outline-2">
-<h2 id="org2d914f2"><span class="section-number-2">9.</span> The Campus Role</h2>
-<div class="outline-text-2" id="text-9">
+<h2 id="org2d914f2"><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
 NAS, DVRs, wireless sensors, etc.  These are simple Debian machines
@@ -6537,9 +6601,9 @@ Wireless campus devices can get a key to the campus VPN from the
 configured manually.
 </p>
 </div>
-<div id="outline-container-orgb125545" class="outline-3">
-<h3 id="orgb125545"><span class="section-number-3">9.1.</span> Include Particulars</h3>
-<div class="outline-text-3" id="text-9-1">
+<div id="outline-container-orga320cc8" class="outline-3">
+<h3 id="orga320cc8"><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>
@@ -6554,9 +6618,9 @@ The following should be familiar boilerplate by now.
 </div>
 </div>
 </div>
-<div id="outline-container-orgedbf31b" class="outline-3">
-<h3 id="orgedbf31b"><span class="section-number-3">9.2.</span> Configure Hostname</h3>
-<div class="outline-text-3" id="text-9-2">
+<div id="outline-container-orgd3bbfbb" class="outline-3">
+<h3 id="orgd3bbfbb"><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>
@@ -6582,9 +6646,9 @@ Clients should be using the expected host name.
 </div>
 </div>
 </div>
-<div id="outline-container-orgbbe5d19" class="outline-3">
-<h3 id="orgbbe5d19"><span class="section-number-3">9.3.</span> Enable Systemd Resolved</h3>
-<div class="outline-text-3" id="text-9-3">
+<div id="outline-container-orgf85cc27" class="outline-3">
+<h3 id="orgf85cc27"><span class="section-number-3">10.3.</span> Enable Systemd Resolved</h3>
+<div class="outline-text-3" id="text-10-3">
 <p>
 Campus machines start the <code>systemd-networkd</code> and <code>systemd-resolved</code>
 service units on boot.  See <a href="#org5738867">Enable Systemd Resolved</a>.
@@ -6627,9 +6691,9 @@ service units on boot.  See <a href="#org5738867">Enable Systemd Resolved</a>.
 </div>
 </div>
 </div>
-<div id="outline-container-org08eac1f" class="outline-3">
-<h3 id="org08eac1f"><span class="section-number-3">9.4.</span> Configure Systemd Resolved</h3>
-<div class="outline-text-3" id="text-9-4">
+<div id="outline-container-org2ba83cb" class="outline-3">
+<h3 id="org2ba83cb"><span class="section-number-3">10.4.</span> Configure Systemd Resolved</h3>
+<div class="outline-text-3" id="text-10-4">
 <p>
 Campus machines use the campus name server on Core (or <code>dns.google</code>),
 and include the institute's private domain in their search lists.
@@ -6669,8 +6733,8 @@ and include the institute's private domain in their search lists.
 </div>
 </div>
 <div id="outline-container-orge768e1b" class="outline-3">
-<h3 id="orge768e1b"><span class="section-number-3">9.5.</span> Configure Systemd Timesyncd</h3>
-<div class="outline-text-3" id="text-9-5">
+<h3 id="orge768e1b"><span class="section-number-3">10.5.</span> Configure Systemd Timesyncd</h3>
+<div class="outline-text-3" id="text-10-5">
 <p>
 The institute uses a common time reference throughout the campus.
 This is essential to campus security, improving the accuracy of log
@@ -6699,9 +6763,9 @@ and file timestamps.
 </div>
 </div>
 </div>
-<div id="outline-container-orgbdf09f0" class="outline-3">
-<h3 id="orgbdf09f0"><span class="section-number-3">9.6.</span> Add Administrator to System Groups</h3>
-<div class="outline-text-3" id="text-9-6">
+<div id="outline-container-org41f6c57" class="outline-3">
+<h3 id="org41f6c57"><span class="section-number-3">10.6.</span> Add Administrator to System Groups</h3>
+<div class="outline-text-3" id="text-10-6">
 <p>
 The administrator often needs to read (directories of) log files owned
 by groups <code>root</code> and <code>adm</code>.  Adding the administrator's account to
@@ -6720,42 +6784,9 @@ these groups speeds up debugging.
 </div>
 </div>
 </div>
-<div id="outline-container-orgdf9b654" class="outline-3">
-<h3 id="orgdf9b654"><span class="section-number-3">9.7.</span> Trust Institute Certificate Authority</h3>
-<div class="outline-text-3" id="text-9-7">
-<p>
-Campus hosts should recognize the institute's Certificate Authority as
-trustworthy, so its certificate is added to the host's set of trusted
-CAs.  (For more information about how the small institute manages its
-keys, certificates and passwords, see <a href="#org6519b0c">Keys</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">
-- name: Trust the institute CA.
-  become: yes
-  copy:
-    src: ../Secret/CA/pki/ca.crt
-    dest: /usr/local/share/ca-certificates/{{ domain_name }}.crt
-    <span class="org-variable-name">mode: u</span>=r,g=r,o=r
-    owner: root
-    group: root
-  notify: Update CAs.
-</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">
-- name: Update CAs.
-  become: yes
-  command: update-ca-certificates
-</pre>
-</div>
-</div>
-</div>
-<div id="outline-container-org8491295" class="outline-3">
-<h3 id="org8491295"><span class="section-number-3">9.8.</span> Install Unattended Upgrades</h3>
-<div class="outline-text-3" id="text-9-8">
+<div id="outline-container-org8cd2060" class="outline-3">
+<h3 id="org8cd2060"><span class="section-number-3">10.7.</span> Install Unattended Upgrades</h3>
+<div class="outline-text-3" id="text-10-7">
 <p>
 The institute prefers to install security updates as soon as possible.
 </p>
@@ -6770,8 +6801,8 @@ The institute prefers to install security updates as soon as possible.
 </div>
 </div>
 <div id="outline-container-orgb964f6c" class="outline-3">
-<h3 id="orgb964f6c"><span class="section-number-3">9.9.</span> Configure Postfix on Campus</h3>
-<div class="outline-text-3" id="text-9-9">
+<h3 id="orgb964f6c"><span class="section-number-3">10.8.</span> Configure Postfix on Campus</h3>
+<div class="outline-text-3" id="text-10-8">
 <p>
 The Postfix settings used by the campus include message size, queue
 times, and the <code>relayhost</code> Core.  The default Debian configuration
@@ -6835,8 +6866,8 @@ tasks below.
 </div>
 </div>
 <div id="outline-container-org546611a" class="outline-3">
-<h3 id="org546611a"><span class="section-number-3">9.10.</span> Hard-wire Important IP Addresses</h3>
-<div class="outline-text-3" id="text-9-10">
+<h3 id="org546611a"><span class="section-number-3">10.9.</span> Hard-wire Important IP Addresses</h3>
+<div class="outline-text-3" id="text-10-9">
 <p>
 For the edification of programs consulting the <q>/etc/hosts</q> file, the
 institute's domain name and public IP address are added.  The Debian
@@ -6864,8 +6895,8 @@ custom of translating the host name into <code>127.0.1.1</code> is also followed
 </div>
 </div>
 <div id="outline-container-orgbd0ce38" class="outline-3">
-<h3 id="orgbd0ce38"><span class="section-number-3">9.11.</span> Configure NRPE</h3>
-<div class="outline-text-3" id="text-9-11">
+<h3 id="orgbd0ce38"><span class="section-number-3">10.10.</span> Configure NRPE</h3>
+<div class="outline-text-3" id="text-10-10">
 <p>
 Each campus host runs an NRPE (a NAGIOS Remote Plugin Executor)
 server so that the NAGIOS4 server on Core can collect statistics.  The
@@ -6924,8 +6955,8 @@ Role</a>.
 </div>
 </div>
 <div id="outline-container-orgff33e02" class="outline-2">
-<h2 id="orgff33e02"><span class="section-number-2">10.</span> The Ansible Configuration</h2>
-<div class="outline-text-2" id="text-10">
+<h2 id="orgff33e02"><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
 servers.  The administrator keeps an Ansible inventory in <a href="hosts"><q>hosts</q></a>, and
@@ -6947,8 +6978,8 @@ separate revision history.
 </p>
 </div>
 <div id="outline-container-orgfefb674" class="outline-3">
-<h3 id="orgfefb674"><span class="section-number-3">10.1.</span> <q>ansible.cfg</q></h3>
-<div class="outline-text-3" id="text-10-1">
+<h3 id="orgfefb674"><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
@@ -6979,8 +7010,8 @@ described in <a href="#org6519b0c">Keys</a>) and thus sets this parameter to
 </div>
 </div>
 <div id="outline-container-orgb932c38" class="outline-3">
-<h3 id="orgb932c38"><span class="section-number-3">10.2.</span> <q>hosts</q></h3>
-<div class="outline-text-3" id="text-10-2">
+<h3 id="orgb932c38"><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
 machines starting with the main servers Front, Core and Gate.  It
@@ -7057,8 +7088,8 @@ the <a href="Secret/vault-password"><q>Secret/vault-password</q></a> file.
 </div>
 </div>
 <div id="outline-container-org074c362" class="outline-3">
-<h3 id="org074c362"><span class="section-number-3">10.3.</span> <q>playbooks/site.yml</q></h3>
-<div class="outline-text-3" id="text-10-3">
+<h3 id="org074c362"><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
 appropriate institutional role(s) to the hosts and groups defined in
@@ -7067,6 +7098,10 @@ the example inventory: <a href="hosts"><q>hosts</q></a>.
 
 <div class="org-src-container">
 <a href="playbooks/site.yml"><q>playbooks/site.yml</q></a><pre class="src src-conf">---
+- name: Configure All
+  hosts: all
+  roles: [ all ]
+
 - name: Configure Front
   hosts: front
   roles: [ front ]
@@ -7087,8 +7122,8 @@ the example inventory: <a href="hosts"><q>hosts</q></a>.
 </div>
 </div>
 <div id="outline-container-orge85b5b4" class="outline-3">
-<h3 id="orge85b5b4"><span class="section-number-3">10.4.</span> <q>Secret/vault-password</q></h3>
-<div class="outline-text-3" id="text-10-4">
+<h3 id="orge85b5b4"><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
 password, a "master secret", on the encrypted partition mounted at
@@ -7105,8 +7140,8 @@ example password matches the example encryptions above.
 </div>
 </div>
 <div id="outline-container-org0517849" class="outline-3">
-<h3 id="org0517849"><span class="section-number-3">10.5.</span> Creating A Working Ansible Configuration</h3>
-<div class="outline-text-3" id="text-10-5">
+<h3 id="org0517849"><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
@@ -7189,8 +7224,8 @@ super-project's directory.
 </div>
 </div>
 <div id="outline-container-orgb70ec0e" class="outline-3">
-<h3 id="orgb70ec0e"><span class="section-number-3">10.6.</span> Maintaining A Working Ansible Configuration</h3>
-<div class="outline-text-3" id="text-10-6">
+<h3 id="orgb70ec0e"><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
 ensure that debugged Ansible code in <q>roles/</q> is not clobbered by code
@@ -7209,8 +7244,8 @@ their way back to the code block in this document.
 </div>
 </div>
 <div id="outline-container-org1c6f4a8" class="outline-2">
-<h2 id="org1c6f4a8"><span class="section-number-2">11.</span> The Institute Commands</h2>
-<div class="outline-text-2" id="text-11">
+<h2 id="org1c6f4a8"><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
 execute standard procedures.  The script is run with the command name
@@ -7220,8 +7255,8 @@ 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">11.1.</span> Sub-command Blocks</h3>
-<div class="outline-text-3" id="text-11-1">
+<h3 id="orgf00b9ce"><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
 block examines the script's command line arguments to determine
@@ -7245,8 +7280,8 @@ The first code block is the header of the <code>./inst</code> script.
 </div>
 </div>
 <div id="outline-container-org20782dc" class="outline-3">
-<h3 id="org20782dc"><span class="section-number-3">11.2.</span> Sanity Check</h3>
-<div class="outline-text-3" id="text-11-2">
+<h3 id="org20782dc"><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
 part of <i>all</i> <code>./inst</code> sub-commands.  It performs a "sanity check" on
@@ -7306,8 +7341,8 @@ permissions.  It probes past the <a href="Secret/"><q>Secret/</q></a> mount poin
 </div>
 </div>
 <div id="outline-container-org10ec3d5" class="outline-3">
-<h3 id="org10ec3d5"><span class="section-number-3">11.3.</span> Importing Ansible Variables</h3>
-<div class="outline-text-3" id="text-11-3">
+<h3 id="org10ec3d5"><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
 variable values (esp. private values like network addresses), a
@@ -7356,8 +7391,8 @@ The playbook that updates <a href="private/vars.pl"><q>private/vars.pl</q></a>:
 </div>
 </div>
 <div id="outline-container-org671a111" class="outline-3">
-<h3 id="org671a111"><span class="section-number-3">11.4.</span> The CA Command</h3>
-<div class="outline-text-3" id="text-11-4">
+<h3 id="org671a111"><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
 new CA (certificate authority) in <a href="Secret/CA/"><q>Secret/CA/</q></a> as well as SSH and PGP
@@ -7465,8 +7500,8 @@ config</code>.
 </div>
 </div>
 <div id="outline-container-org5877bb0" class="outline-3">
-<h3 id="org5877bb0"><span class="section-number-3">11.5.</span> The Config Command</h3>
-<div class="outline-text-3" id="text-11-5">
+<h3 id="org5877bb0"><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
@@ -7517,8 +7552,8 @@ Example command lines:
 </div>
 </div>
 <div id="outline-container-orge7fe793" class="outline-3">
-<h3 id="orge7fe793"><span class="section-number-3">11.6.</span> Account Management</h3>
-<div class="outline-text-3" id="text-11-6">
+<h3 id="orge7fe793"><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
@@ -7721,8 +7756,8 @@ each record.
 </div>
 </div>
 <div id="outline-container-orgebc3780" class="outline-3">
-<h3 id="orgebc3780"><span class="section-number-3">11.7.</span> The New Command</h3>
-<div class="outline-text-3" id="text-11-7">
+<h3 id="orgebc3780"><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
 member to the institute's membership roll.  It runs an Ansible
@@ -7826,8 +7861,8 @@ initial, generated password.
 </div>
 </div>
 <div id="outline-container-org0a5d277" class="outline-3">
-<h3 id="org0a5d277"><span class="section-number-3">11.8.</span> The Pass Command</h3>
-<div class="outline-text-3" id="text-11-8">
+<h3 id="org0a5d277"><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
 member's desired password (hashed).  The command may update the
@@ -7841,8 +7876,8 @@ 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">11.8.1.</span> Less Aggressive passwd.</h4>
-<div class="outline-text-4" id="text-11-8-1">
+<h4 id="org1e2a891"><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.
 It is less aggressive because it just emails <code>root</code>.  It does not
@@ -7938,8 +7973,8 @@ print <span class="org-string">"</span>
 </div>
 </div>
 <div id="outline-container-org9b6d5b8" class="outline-4">
-<h4 id="org9b6d5b8"><span class="section-number-4">11.8.2.</span> Less Aggressive Pass Command</h4>
-<div class="outline-text-4" id="text-11-8-2">
+<h4 id="org9b6d5b8"><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
 the administrator to update <q>private/members.yml</q> before running
@@ -8036,8 +8071,8 @@ users:resetpassword</code> command using <code>expect(1)</code>.
 </div>
 </div>
 <div id="outline-container-org739e719" class="outline-4">
-<h4 id="org739e719"><span class="section-number-4">11.8.3.</span> Installing the Less Aggressive passwd</h4>
-<div class="outline-text-4" id="text-11-8-3">
+<h4 id="org739e719"><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>
 script in <q>/usr/local/bin/passwd</q> on Core, and a <code>sudo</code> policy file
@@ -8105,8 +8140,8 @@ configuration so that the email to root can be encrypted.
 </div>
 </div>
 <div id="outline-container-orga2f39ee" class="outline-3">
-<h3 id="orga2f39ee"><span class="section-number-3">11.9.</span> The Old Command</h3>
-<div class="outline-text-3" id="text-11-9">
+<h3 id="orga2f39ee"><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>
@@ -8151,8 +8186,8 @@ The <code>old</code> command disables a member's accounts and clients.
 </div>
 </div>
 <div id="outline-container-org0ad53cf" class="outline-3">
-<h3 id="org0ad53cf"><span class="section-number-3">11.10.</span> The Client Command</h3>
-<div class="outline-text-3" id="text-11-10">
+<h3 id="org0ad53cf"><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
 authorizing wireless devices to connect to the institute's VPNs.  The
@@ -8323,8 +8358,8 @@ up-restart
 </div>
 </div>
 <div id="outline-container-org875755b" class="outline-3">
-<h3 id="org875755b"><span class="section-number-3">11.11.</span> Institute Command Help</h3>
-<div class="outline-text-3" id="text-11-11">
+<h3 id="org875755b"><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
 catches any command lines that were not handled by a sub-command
@@ -8340,31 +8375,31 @@ above.
 </div>
 </div>
 <div id="outline-container-org74b454f" class="outline-2">
-<h2 id="org74b454f"><span class="section-number-2">12.</span> Testing</h2>
-<div class="outline-text-2" id="text-12">
+<h2 id="org74b454f"><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 a test network
-simulating a campus Ethernet, campus ISP, and commercial cloud.  With
-the test network up and running, a simulated member's notebook can be
-created, and alternately attached to the simulated campus Wi-Fi or the
-simulated Internet (as though abroad).  The administrator's notebook
-in this simulation is the VirtualBox host.
+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.
 </p>
 
 <p>
 The next two sections list the steps taken to create the simulated
-Core, Gate and Front, and connect them to a simulated campus Ethernet,
-campus ISP, and commercial cloud.  The process is similar to that
-described in <a href="#org754e9f1">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 process, simulating an administrator
-adding and removing member accounts and devices, a member's desktop
-sending and receiving email, etc.
+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
+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
+process, simulating an administrator adding and removing member
+accounts and devices, a member's desktop sending and receiving email,
+etc.
 </p>
 
 <p>
@@ -8375,8 +8410,8 @@ site at <a href="https://www.virtualbox.org/manual/UserManual.html">https://www.
 </p>
 </div>
 <div id="outline-container-org6e2b33d" class="outline-3">
-<h3 id="org6e2b33d"><span class="section-number-3">12.1.</span> The Test Networks</h3>
-<div class="outline-text-3" id="text-12-1">
+<h3 id="org6e2b33d"><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:
 </p>
@@ -8392,29 +8427,19 @@ 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><p>
-Another Host-only network, simulating the tiny
+<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
-services, no DHCP, just the host at <code>192.168.57.2</code>.  It might one
-day have a simulated access point at that address.  Currently it is
-just an interface for <code>gate</code>'s DHCP server to listen on.
-</p>
-
-<p>
-In this simulation the IP address for <code>front</code> is not a public
-address but a private address on the NAT network <code>premises</code>.  Thus
-<code>front</code> is not accessible to the administrator's notebook (the
-host).  To work around this restriction, <code>front</code> gets a second
-network interface connected to the <code>vboxnet1</code> network and used only
-for ssh access from the host.<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>
-</p></dd>
+services, no DHCP, just the host at <code>192.168.57.2</code>, simulating the
+NATed Wi-Fi network.</dd>
 </dl>
 
 <p>
-As in <a href="#org754e9f1">The Hardware</a>, all machines start with their primary Ethernet
-adapters attached to the NAT Network <code>premises</code> so that they can
-download additional packages.  Later, <code>core</code> and <code>gate</code> are moved to
-the simulated private Ethernet <code>vboxnet0</code>.
+In this simulation the IP address for <code>front</code> is not a public address
+but a private address on the NAT network <code>premises</code>.  Thus <code>front</code> is
+not accessible to the administrator's notebook (the host).  To work
+around this restriction, <code>front</code> gets a second network interface
+connected to the <code>vboxnet1</code> network and used only for ssh access from
+the host.<sup><a id="fnr.5" class="footref" href="#fn.5" role="doc-backlink">5</a></sup>
 </p>
 
 <p>
@@ -8428,37 +8453,50 @@ following <code>VBoxManage</code> commands.
                           --enable --dhcp on --ipv6 off
 VBoxManage natnetwork start --netname premises
 VBoxManage hostonlyif create <span class="org-comment-delimiter"># </span><span class="org-comment">vboxnet0</span>
-VBoxManage hostonlyif ipconfig vboxnet0 --ip 192.168.56.10 <span class="org-sh-escaped-newline">\</span>
-                                        --dhcp off --ipv6 off
+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 <span class="org-sh-escaped-newline">\</span>
-                                        --dhcp off --ipv6 off
+VBoxManage hostonlyif ipconfig vboxnet1 --ip=192.168.57.2
 </pre>
 </div>
 
 <p>
-Note that actual ISPs and clouds will provide Gate and Front with
-public network addresses but in this simulation "they" provide
-addresses in the private <code>192.168.15.0/24</code> network.
+Note that the first host-only network, <code>vboxnet0</code>, gets DHCP service
+by default, but that will interfere with the service being tested on
+<code>core</code>, so it must be explicitly disabled.  Only the NAT network
+<code>premises</code> should have a DHCP server enabled.
+</p>
+
+<p>
+Note also that actual ISPs and clouds will provide Gate and Front with
+public network addresses.  In this simulation "they" provide addresses
+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">12.2.</span> The Test Machines</h3>
-<div class="outline-text-3" id="text-12-2">
+<h3 id="org28b0352"><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-11.3.0-amd64-netinst.iso</q>) on the NAT network
-<code>premises</code>.  As in <a href="#org754e9f1">The Hardware</a> preparation process being simulated, a
-few additional software packages are installed and remote access is
-authorized before the machines are moved to their final networks,
-prepared for Ansible.
+(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>
+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.)
+</p>
+
+<p>
+Once the administrator's notebook is authorized to access the
+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">12.2.1.</span> A Test Machine</h4>
-<div class="outline-text-4" id="text-12-2-1">
+<h4 id="orgde4a074"><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>
 commands needed to create the test machines.  The name of the machine
@@ -8485,47 +8523,42 @@ taken from the <code>ISO</code> shell variable.
   VBoxManage storageattach $<span class="org-variable-name">NAME</span> --storagectl <span class="org-string">"IDE Controller"</span> <span class="org-sh-escaped-newline">\</span>
       --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
-  VBoxManage unattended install $<span class="org-variable-name">NAME</span> --iso=$<span class="org-variable-name">ISO</span> <span class="org-sh-escaped-newline">\</span>
-      --locale en_US --country US <span class="org-sh-escaped-newline">\</span>
-      --hostname $<span class="org-variable-name">NAME</span>.small.private <span class="org-sh-escaped-newline">\</span>
-      --user=sysadm --password=fubar <span class="org-sh-escaped-newline">\</span>
-      --full-user-name=System<span class="org-string">\ </span>Administrator
 }
 </pre>
 </div>
 
 <p>
 After this shell function creates a VM, its network interface is
-typically attached to the NAT network <code>premises</code>, simulating the
-Internet connected network where actual hardware will be prepared.
+attached to the default NAT network, simulating the Internet connected
+network where actual hardware is prepared.
 </p>
 
 <p>
 Here are the commands needed to create the test machine <code>front</code> with
-512MiB of RAM and 4GiB of disk and the Debian 11.3.0 release in its
-CDROM drive, to put <code>front</code> on the Internet connected NAT network
-<code>premises</code>, and to boot <code>front</code> into the Debian installer.
+512MiB of RAM and 4GiB of disk and the Debian 12.5.0 release in its
+CDROM drive.
 </p>
 
 <div class="org-src-container">
 <pre class="src src-sh"><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-11.3.0-amd64-netinst.iso
+<span class="org-variable-name">ISO</span>=~/Downloads/debian-12.5.0-amd64-netinst.iso
 create_vm
-VBoxManage modifyvm $<span class="org-variable-name">NAME</span> --nic1 natnetwork --natnetwork1 premises
-VBoxManage startvm $<span class="org-variable-name">NAME</span> --type headless
 </pre>
 </div>
 
 <p>
-The machine's console should soon show the installer's first prompt:
-to choose a system language.  The appropriate responses to the
-installer's prompts are given in the list below.
+Soon after starting, the machine console should show the installer's
+first prompt: to choose a system language.  Installation on the small
+machines, <code>front</code> and <code>gate</code>, may put the installation into "low
+memory mode", in which case the installation is textual, the system
+language is English, and the first prompt is for location.  The
+appropriate responses to the prompts are given in the list below.
 </p>
 
 <ul class="org-ul">
-<li>Select a language
+<li>Select a language (unless in low memory mode!)
 <ul class="org-ul">
 <li>Language:  English - English</li>
 </ul></li>
@@ -8586,101 +8619,76 @@ installer's prompts are given in the list below.
 </ul>
 
 <p>
-After the reboot (first boot into the installed OS) the machine's
-console should produce a <code>login:</code> prompt.  The administrator logs in
-here, with username <code>sysadm</code> and password <code>fubar</code>, before continuing
-with the specific machine's preparation (below).
+After the reboot, the machine's console should produce a <code>login:</code>
+prompt.  The administrator logs in here, with username <code>sysadm</code> and
+password <code>fubar</code>, before continuing with the specific machine's
+preparation (below).
 </p>
 </div>
 </div>
 <div id="outline-container-org96e03aa" class="outline-4">
-<h4 id="org96e03aa"><span class="section-number-4">12.2.2.</span> The Test Front Machine</h4>
-<div class="outline-text-4" id="text-12-2-2">
+<h4 id="org96e03aa"><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
-Debian 11.3.0 (recently downloaded) in its CDROM drive.  The exact
+Debian 12.5.0 (recently downloaded) in its CDROM drive.  The exact
 command lines were given in the previous section.
 </p>
 
 <p>
-After Debian is installed (as detailed in <a href="#orgde4a074">A Test Machine</a>) and the
-machine rebooted, the administrator logs in and installs several
-additional software packages.
+After Debian is installed (as detailed above) <code>front</code> is shut down and
+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>).
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo apt install netplan.io expect unattended-upgrades postfix <span class="org-sh-escaped-newline">\</span>
-                 dovecot-imapd apache2 openvpn
+<pre class="src src-sh">VBoxManage modifyvm front --nic1 natnetwork --natnetwork1 premises
+VBoxManage modifyvm front --nic2 hostonly --hostonlyadapter2 vboxnet1
 </pre>
 </div>
 
 <p>
-Note that the Postfix installation may prompt for a couple settings.
-The defaults, listed below, are fine.
-</p>
-
-<ul class="org-ul">
-<li>General type of mail configuration: Internet Site</li>
-<li>System mail name: small.example.org</li>
-</ul>
-
-<p>
-To make <code>front</code> accessible to the simulated administrator's notebook,
-it gets a second network interface attached to the host-only network
-<code>vboxnet1</code> and is given the local address <code>192.168.57.3</code>.
+After Debian is installed and the machine rebooted, the administrator
+logs in and configures the "extra" network interface with a static IP
+address using a drop-in configuration file:
+<q>/etc/network/interfaces.d/eth1</q>.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">VBoxManage modifyvm front --nic2 hostonly --hostonlyadapter2 vboxnet1
+<q>eth1</q><pre class="src src-conf">auto enp0s8
+iface enp0s8 inet static
+    address 192.168.57.3/24
 </pre>
 </div>
 
 <p>
-The second network interface is configured with an IP address via the
-Netplan configuration file <q>/etc/netplan/01-testing.yaml</q>, which is
-created with the following lines.
+A <code>sudo ifup enp0s8</code> command then brings the interface up.
 </p>
 
-<div class="org-src-container">
-<pre class="src src-conf">network:
-  ethernets:
-    enp0s8:
-      dhcp4: false
-      addresses: [ 192.168.57.3/24 ]
-</pre>
-</div>
-
 <p>
-The amended Netplan is applied immediately with the following command,
-or the machine is rebooted.
-</p>
-
-<div class="org-src-container">
-<pre class="src src-sh">sudo netplan apply
-</pre>
-</div>
-
-<p>
-Finally, the administrator authorizes remote access by following the
-instructions in the final section: <a href="#orgc910086">Ansible Test Authorization</a>.
+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
+Test Authorization</a>.
 </p>
 </div>
 </div>
 <div id="outline-container-org038abd9" class="outline-4">
-<h4 id="org038abd9"><span class="section-number-4">12.2.3.</span> The Test Gate Machine</h4>
-<div class="outline-text-4" id="text-12-2-3">
+<h4 id="org038abd9"><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
 <code>front</code>.  Assuming the <code>RAM</code>, <code>DISK</code>, and <code>ISO</code> shell variables have
-not changed, <code>gate</code> can be created with two commands, then connected
-to NAT network <code>premesis</code> and booted with two more.
+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
 create_vm
-VBoxManage modifyvm gate --nic1 natnetwork --natnetwork1 premises
-VBoxManage startvm gate --type headless
 </pre>
 </div>
 
@@ -8691,8 +8699,8 @@ additional software packages.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo apt install netplan.io ufw unattended-upgrades postfix <span class="org-sh-escaped-newline">\</span>
-                 isc-dhcp-server openvpn
+<pre class="src src-sh">sudo apt install netplan.io systemd-resolved unattended-upgrades <span class="org-sh-escaped-newline">\</span>
+                 ufw isc-dhcp-server postfix openvpn
 </pre>
 </div>
 
@@ -8707,29 +8715,26 @@ defaults, listed below, are fine.
 </ul>
 
 <p>
-<code>gate</code> can now move to the campus.  It is shut down before the
+<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>.  The <code>isp</code> and <code>wifi</code> interfaces are also
+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>,
 connected to the simulated ISP and campus wireless access point.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">VBoxManage modifyvm gate --nic1 hostonly
-VBoxManage modifyvm gate --hostonlyadapter1 vboxnet0
+<pre class="src src-sh">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 --nic3 hostonly
-VBoxManage modifyvm gate --hostonlyadapter3 vboxnet1
+VBoxManage modifyvm gate --mac-address3=0800274aded2
+VBoxManage modifyvm gate --nic3 hostonly --hostonlyadapter3 vboxnet1
 </pre>
 </div>
 
 <p>
-Before rebooting, the MAC addresses of the three network interfaces
-should be compared to the example variable settings in <a href="hosts"><q>hosts</q></a>.  The
-values of the <code>gate_lan_mac</code>, <code>gate_wifi_mac</code>, and <code>gate_isp_mac</code>
-variables <i>must</i> agree with the MAC addresses assigned to the virtual
-machine's network interfaces.  The following table assumes device
-names that may vary depending on the hypervisor, version, etc.
+The MAC addresses above were specified so they match the example
+values of the MAC address variables in this table.
 </p>
 
 <table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
@@ -8777,7 +8782,7 @@ names that may vary depending on the hypervisor, version, etc.
 </table>
 
 <p>
-After <code>gate</code> boots up with its new network connections, the primary
+After <code>gate</code> boots up with its new network interfaces, the primary
 Ethernet interface is temporarily configured with an IP address.
 (Ansible will install a Netplan soon.)
 </p>
@@ -8794,8 +8799,8 @@ instructions in the final section: <a href="#orgc910086">Ansible Test Authorizat
 </div>
 </div>
 <div id="outline-container-org18f3c58" class="outline-4">
-<h4 id="org18f3c58"><span class="section-number-4">12.2.4.</span> The Test Core Machine</h4>
-<div class="outline-text-4" id="text-12-2-4">
+<h4 id="org18f3c58"><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.
 Assuming the <code>ISO</code> shell variable has not changed, <code>core</code> can be
@@ -8807,8 +8812,6 @@ created with following commands.
 <span class="org-variable-name">RAM</span>=2048
 <span class="org-variable-name">DISK</span>=6144
 create_vm
-VBoxManage modifyvm core --nic1 natnetwork --natnetwork1 premises
-VBoxManage startvm core --type headless
 </pre>
 </div>
 
@@ -8819,14 +8822,20 @@ additional software packages.
 </p>
 
 <div class="org-src-container">
-<pre class="src src-sh">sudo apt install netplan.io unattended-upgrades postfix <span class="org-sh-escaped-newline">\</span>
-                 isc-dhcp-server bind9 fetchmail gnupg <span class="org-sh-escaped-newline">\</span>
-                 expect dovecot-imapd apache2 openvpn
+<pre class="src src-sh">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
+sudo apt install mariadb-server php php-{apcu,bcmath,curl,gd,gmp}<span class="org-sh-escaped-newline">\</span>
+                 php-{json,mysql,mbstring,intl,imagick,xml,zip} <span class="org-sh-escaped-newline">\</span>
+                 libapache2-mod-php
+sudo apt install nagios4 monitoring-plugins-basic lm-sensors <span class="org-sh-escaped-newline">\</span>
+                 nagios-nrpe-plugin
 </pre>
 </div>
 
 <p>
-Again, the Postfix installation prompts for a couple settings.  The
+Again the Postfix installation prompts for a couple settings.  The
 defaults, listed below, are fine.
 </p>
 
@@ -8835,6 +8844,13 @@ defaults, listed below, are fine.
 <li>System mail name: core.small.private</li>
 </ul>
 
+<p>
+Before shutting down, the name of the primary Ethernet interface
+should be compared to the example variable setting in
+<a href="private/vars.yml"><q>private/vars.yml</q></a>.  The value assigned to <code>core_ethernet</code> should
+match the interface name.
+</p>
+
 <p>
 <code>core</code> can now move to the campus.  It is shut down before the
 following <code>VBoxManage</code> command is executed.  The command connects the
@@ -8849,13 +8865,12 @@ Ethernet.
 
 <p>
 After <code>core</code> boots up with its new network connection, its primary NIC
-is temporarily configured with an IP address and default route (to
-<code>gate</code>).  (Ansible will install a Netplan soon.)
+is temporarily configured with an IP address.  (Ansible will install a
+Netplan soon.)
 </p>
 
 <div class="org-src-container">
 <pre class="src src-sh">sudo ip address add 192.168.56.1/24 dev enp0s3
-sudo ip route add default via 192.168.56.2 dev enp0s3
 </pre>
 </div>
 
@@ -8866,19 +8881,20 @@ instructions in the next section: <a href="#orgc910086">Ansible Test Authorizati
 </div>
 </div>
 <div id="outline-container-orgc910086" class="outline-4">
-<h4 id="orgc910086"><span class="section-number-4">12.2.5.</span> Ansible Test Authorization</h4>
-<div class="outline-text-4" id="text-12-2-5">
+<h4 id="orgc910086"><span class="section-number-4">13.2.5.</span> Ansible Test Authorization</h4>
+<div class="outline-text-4" id="text-13-2-5">
 <p>
-Before Ansible can configure the three test machines, they must allow
-remote access to their <code>sysadm</code> accounts.  The administrator must use
-IP addresses to copy the public key to each test machine.
+To authorize Ansible's access to the three test machines, they must
+allow remote access to their <code>sysadm</code> accounts.  In the following
+commands, the administrator must use IP addresses to copy the public
+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
-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>
-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.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>
 </div>
 
@@ -8892,12 +8908,48 @@ each machine).
 <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>
 </div>
+
+<p>
+The <code>front</code> machine needs a little additional preparation.  Ansible
+will configure <code>front</code> with the host keys in <q>Secret/</q>.  These should
+be installed there now so that <code>front</code> does not appear to change
+identities while Ansible is configuring.
+</p>
+
+<p>
+First, the host keys are securely copied to <code>front</code> with the following
+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>
 </div>
+
+<p>
+Then they are installed with these commands.
+</p>
+
+<div class="org-src-container">
+<pre class="src src-sh">chmod 600 ssh_host_*
+chmod 644 ssh_host_*.pub
+sudo cp -b ssh_host_* /etc/ssh/
+</pre>
 </div>
+
+<p>
+Finally, the system administrator removes the old identity of <code>front</code>.
+</p>
+
+<pre class="example">
+ssh-keygen -f ~/.ssh/known_hosts -R 192.168.57.3
+</pre>
 </div>
-<div id="outline-container-org7df36ca" class="outline-3">
-<h3 id="org7df36ca"><span class="section-number-3">12.3.</span> The Test Ansible Configuration</h3>
-<div class="outline-text-3" id="text-12-3">
+</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 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
 running fresh Debian systems with select additional packages, on their
@@ -8905,11 +8957,7 @@ final networks, with a privileged account named <code>sysadm</code> that
 authorizes password-less access from the administrator's notebook,
 ready to be configured by Ansible.
 </p>
-</div>
-</div>
-<div id="outline-container-org0e22649" class="outline-3">
-<h3 id="org0e22649"><span class="section-number-3">12.4.</span> Configure Test Machines</h3>
-<div class="outline-text-3" id="text-12-4">
+
 <p>
 To configure the test machines, the <code>./inst config</code> command is
 executed and <code>core</code> restarted.  Note that this first run should
@@ -8919,8 +8967,8 @@ not</i>.
 </div>
 </div>
 <div id="outline-container-orge71084a" class="outline-3">
-<h3 id="orge71084a"><span class="section-number-3">12.5.</span> Test Basics</h3>
-<div class="outline-text-3" id="text-12-5">
+<h3 id="orge71084a"><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>,
 no other campus servers, no members nor their VPN client devices.  On
@@ -8982,8 +9030,8 @@ instant attention).
 </div>
 </div>
 <div id="outline-container-org626187b" class="outline-3">
-<h3 id="org626187b"><span class="section-number-3">12.6.</span> The Test Nextcloud</h3>
-<div class="outline-text-3" id="text-12-6">
+<h3 id="org626187b"><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
@@ -9009,8 +9057,8 @@ using the <code>./inst new</code> command and issuing client VPN keys with the
 </div>
 </div>
 <div id="outline-container-orgf1f2447" class="outline-3">
-<h3 id="orgf1f2447"><span class="section-number-3">12.7.</span> Test New Command</h3>
-<div class="outline-text-3" id="text-12-7">
+<h3 id="orgf1f2447"><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
 authorized and then test the VPNs, Nextcloud, and the web sites.
@@ -9030,8 +9078,8 @@ Take note of Dick's initial password.
 </div>
 </div>
 <div id="outline-container-orgc9c0613" class="outline-3">
-<h3 id="orgc9c0613"><span class="section-number-3">12.8.</span> The Test Member Notebook</h3>
-<div class="outline-text-3" id="text-12-8">
+<h3 id="orgc9c0613"><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,
 except with memory and disk space doubled to 2GiB and 8GiB, and a
@@ -9045,9 +9093,8 @@ desktop VPN client and web browser test the OpenVPN configurations on
 <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> --nic1 hostonly --hostonlyadapter1 vboxnet1
 VBoxManage modifyvm $<span class="org-variable-name">NAME</span> --macaddress1 080027dc54b5
-VBoxManage startvm $<span class="org-variable-name">NAME</span> --type headless
+VBoxManage modifyvm $<span class="org-variable-name">NAME</span> --nic1 hostonly --hostonlyadapter1 vboxnet1
 </pre>
 </div>
 
@@ -9075,8 +9122,8 @@ require several more).
 </div>
 </div>
 <div id="outline-container-orgbaaca36" class="outline-3">
-<h3 id="orgbaaca36"><span class="section-number-3">12.9.</span> Test Client Command</h3>
-<div class="outline-text-3" id="text-12-9">
+<h3 id="orgbaaca36"><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
 VPNs.  The following command generates two <q>.ovpn</q> (OpenVPN
@@ -9092,8 +9139,8 @@ the test VPNs.
 </div>
 </div>
 <div id="outline-container-orgefe17f8" class="outline-3">
-<h3 id="orgefe17f8"><span class="section-number-3">12.10.</span> Test Campus VPN</h3>
-<div class="outline-text-3" id="text-12-10">
+<h3 id="orgefe17f8"><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
 Command</a>) is transferred to <code>dick</code>, which is at the Wi-Fi access
@@ -9131,8 +9178,8 @@ host www
 </div>
 </div>
 <div id="outline-container-org861e789" class="outline-3">
-<h3 id="org861e789"><span class="section-number-3">12.11.</span> Test Web Pages</h3>
-<div class="outline-text-3" id="text-12-11">
+<h3 id="org861e789"><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
 distribution) to <q>/WWW/</q> on <code>core</code> and sets the file permissions
@@ -9171,8 +9218,8 @@ will warn but allow the luser to continue.
 </div>
 </div>
 <div id="outline-container-orgbe2a118" class="outline-3">
-<h3 id="orgbe2a118"><span class="section-number-3">12.12.</span> Test Web Update</h3>
-<div class="outline-text-3" id="text-12-12">
+<h3 id="orgbe2a118"><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
 appear as <code>https://small.example.org/</code> (and in <q>/home/www/index.html</q>
@@ -9186,8 +9233,8 @@ Hack <q>/home/www/index.html</q> on <code>front</code> and observe the result at
 </div>
 </div>
 <div id="outline-container-org11876cb" class="outline-3">
-<h3 id="org11876cb"><span class="section-number-3">12.13.</span> Test Nextcloud</h3>
-<div class="outline-text-3" id="text-12-13">
+<h3 id="org11876cb"><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
 Ansible run, when <code>core</code> has Internet access via <code>gate</code>.  Until the
@@ -9196,7 +9243,7 @@ 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">7.25.6</a>.  When the <code>./inst
+and runs <code>./inst config core</code> again <a href="#org380598a">8.24.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.
@@ -9275,8 +9322,8 @@ the calendar.</li>
 </div>
 </div>
 <div id="outline-container-org10daf29" class="outline-3">
-<h3 id="org10daf29"><span class="section-number-3">12.14.</span> Test Email</h3>
-<div class="outline-text-3" id="text-12-14">
+<h3 id="org10daf29"><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
 delivery can be demonstrated.  The administrator runs the following
@@ -9304,8 +9351,8 @@ Outgoing email is also tested.  A message to
 </div>
 </div>
 <div id="outline-container-orgcb10c33" class="outline-3">
-<h3 id="orgcb10c33"><span class="section-number-3">12.15.</span> Test Public VPN</h3>
-<div class="outline-text-3" id="text-12-15">
+<h3 id="orgcb10c33"><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
 (host-only network <code>vboxnet1</code>) to the broader Internet (the NAT
@@ -9358,8 +9405,8 @@ calendar events.
 </div>
 </div>
 <div id="outline-container-org4ecdc5b" class="outline-3">
-<h3 id="org4ecdc5b"><span class="section-number-3">12.16.</span> Test Pass Command</h3>
-<div class="outline-text-3" id="text-12-16">
+<h3 id="org4ecdc5b"><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>
 as <code>dick</code> and runs <code>passwd</code>.  A random password is entered, more
@@ -9406,8 +9453,8 @@ Finally, the administrator verifies that <code>dick</code> can login on <code>co
 </div>
 </div>
 <div id="outline-container-org37b7a4b" class="outline-3">
-<h3 id="org37b7a4b"><span class="section-number-3">12.17.</span> Test Old Command</h3>
-<div class="outline-text-3" id="text-12-17">
+<h3 id="org37b7a4b"><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
 retires <code>dick</code> and his main device <code>dick</code>.
@@ -9427,16 +9474,16 @@ should fail.
 </div>
 </div>
 <div id="outline-container-orgd49e21c" class="outline-2">
-<h2 id="orgd49e21c"><span class="section-number-2">13.</span> Future Work</h2>
-<div class="outline-text-2" id="text-13">
+<h2 id="orgd49e21c"><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">13.1.</span> Deficiencies</h3>
-<div class="outline-text-3" id="text-13-1">
+<h3 id="org25c0257"><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
 love, like intrusion detection via Snort or similar.  Services on
@@ -9502,16 +9549,16 @@ Nextcloud Administration Overview page.
 </div>
 </div>
 <div id="outline-container-org252a7b9" class="outline-3">
-<h3 id="org252a7b9"><span class="section-number-3">13.2.</span> More Tests</h3>
-<div class="outline-text-3" id="text-13-2">
+<h3 id="org252a7b9"><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">13.2.1.</span> Backup</h4>
-<div class="outline-text-4" id="text-13-2-1">
+<h4 id="orgf7d014e"><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
 partition with which to sync?  And then some way to compare that to
@@ -9520,8 +9567,8 @@ partition with which to sync?  And then some way to compare that to
 </div>
 </div>
 <div id="outline-container-org2053b4a" class="outline-4">
-<h4 id="org2053b4a"><span class="section-number-4">13.2.2.</span> Restore</h4>
-<div class="outline-text-4" id="text-13-2-2">
+<h4 id="org2053b4a"><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>
 to <code>core:/</code>, but then it probably needs to fix up file ownerships,
@@ -9531,8 +9578,8 @@ perhaps permissions too.  It could also use an example
 </div>
 </div>
 <div id="outline-container-org262e2b2" class="outline-4">
-<h4 id="org262e2b2"><span class="section-number-4">13.2.3.</span> Campus Disconnect</h4>
-<div class="outline-text-4" id="text-13-2-3">
+<h4 id="org262e2b2"><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
 <code>core</code>'s fetchmails are disconnected, i.e. the whole campus is
@@ -9556,8 +9603,8 @@ could be used.</li>
 </div>
 </div>
 <div id="outline-container-orge6607e3" class="outline-2">
-<h2 id="orge6607e3"><span class="section-number-2">14.</span> Appendix: The Bootstrap</h2>
-<div class="outline-text-2" id="text-14">
+<h2 id="orge6607e3"><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
 standard distributions installed) is not straightforward.
@@ -9577,8 +9624,8 @@ get to the additional packages.
 </p>
 </div>
 <div id="outline-container-orgc34cb28" class="outline-3">
-<h3 id="orgc34cb28"><span class="section-number-3">14.1.</span> The Current Strategy</h3>
-<div class="outline-text-3" id="text-14-1">
+<h3 id="orgc34cb28"><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
 on the Internet where additional packages are accessible, then connect
@@ -9589,8 +9636,8 @@ fails), and avoid names until BIND9 is configured.
 </div>
 </div>
 <div id="outline-container-org11fbf4b" class="outline-3">
-<h3 id="org11fbf4b"><span class="section-number-3">14.2.</span> Starting With Gate</h3>
-<div class="outline-text-3" id="text-14-2">
+<h3 id="org11fbf4b"><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
 connection to the campus ISP in hope of allowing all to download
@@ -9634,8 +9681,8 @@ ansible-playbook -l core site.yml
 </div>
 </div>
 <div id="outline-container-org679fbc3" class="outline-3">
-<h3 id="org679fbc3"><span class="section-number-3">14.3.</span> Pre-provision With Ansible</h3>
-<div class="outline-text-3" id="text-14-3">
+<h3 id="org679fbc3"><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
 (and test!) lists of "additional" packages.  With Core and Gate and
@@ -9694,7 +9741,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-01-02 Tue 13:37</p>
+<p class="date">Created: 2024-02-26 Mon 19:42</p>
 <p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
 </div>
 </body>