"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
-<!-- 2026-05-09 Sat 15:42 -->
+<!-- 2026-06-15 Mon 11:36 -->
<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>
secure and private campus that can function with or without the
Internet.
</p>
-<div id="outline-container-org953f84e" class="outline-2">
-<h2 id="org953f84e"><span class="section-number-2">1.</span> Overview</h2>
+<div id="outline-container-org09790c1" class="outline-2">
+<h2 id="org09790c1"><span class="section-number-2">1.</span> Overview</h2>
<div class="outline-text-2" id="text-1">
<p>
This small institute has a public server on the Internet, Front, that
members off campus.
</p>
-<pre class="example" id="org7a64759">
+<pre class="example" id="orgcb5af4c">
=
_|||_
=-The-Institute-=
</p>
</div>
</div>
-<div id="outline-container-orgbcb988b" class="outline-2">
-<h2 id="orgbcb988b"><span class="section-number-2">2.</span> Caveats</h2>
+<div id="outline-container-orgf03e592" class="outline-2">
+<h2 id="orgf03e592"><span class="section-number-2">2.</span> Caveats</h2>
<div class="outline-text-2" id="text-2">
<p>
This small institute prizes its privacy, so there is little or no
</p>
</div>
</div>
-<div id="outline-container-org8635a79" class="outline-2">
-<h2 id="org8635a79"><span class="section-number-2">3.</span> The Services</h2>
+<div id="outline-container-orgd070dc7" class="outline-2">
+<h2 id="orgd070dc7"><span class="section-number-2">3.</span> The Services</h2>
<div class="outline-text-2" id="text-3">
<p>
The small institute's network is designed to provide a number of
reference particulars first introduced in the following chapter.
</p>
</div>
-<div id="outline-container-org2b3e1ef" class="outline-3">
-<h3 id="org2b3e1ef"><span class="section-number-3">3.1.</span> The Name Service</h3>
+<div id="outline-container-org1f40fb7" class="outline-3">
+<h3 id="org1f40fb7"><span class="section-number-3">3.1.</span> The Name Service</h3>
<div class="outline-text-3" id="text-3-1">
<p>
The institute has a public domain, e.g. <code>small.example.org</code>, and a
</p>
</div>
</div>
-<div id="outline-container-org39e9ca1" class="outline-3">
-<h3 id="org39e9ca1"><span class="section-number-3">3.2.</span> The Email Service</h3>
+<div id="outline-container-org64efd10" class="outline-3">
+<h3 id="org64efd10"><span class="section-number-3">3.2.</span> The Email Service</h3>
<div class="outline-text-3" id="text-3-2">
<p>
Front provides the public SMTP (Simple Mail Transfer Protocol) service
configurations wherever <code><<postfix-message-size>></code> appears.
</p>
</div>
-<div id="outline-container-org3380242" class="outline-4">
-<h4 id="org3380242"><span class="section-number-4">3.2.1.</span> The Postfix Configurations</h4>
+<div id="outline-container-org54b4a6d" class="outline-4">
+<h4 id="org54b4a6d"><span class="section-number-4">3.2.1.</span> The Postfix Configurations</h4>
<div class="outline-text-4" id="text-3-2-1">
<p>
The institute aims to accommodate encrypted email containing short
</p>
<div class="org-src-container">
-<code>postfix-message-size</code><pre class="src src-conf" id="orgd30f2a7"><code>- { p: message_size_limit, v: 104857600 }
+<code>postfix-message-size</code><pre class="src src-conf" id="org7583474"><code>- { p: message_size_limit, v: 104857600 }
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>postfix-queue-times</code><pre class="src src-conf" id="org11939b4"><code>- { p: delay_warning_time, v: 1h }
+<code>postfix-queue-times</code><pre class="src src-conf" id="org3bdada0"><code>- { p: delay_warning_time, v: 1h }
- { p: maximal_queue_lifetime, v: 4h }
- { p: bounce_queue_lifetime, v: 4h }
</code></pre>
</p>
<div class="org-src-container">
-<code>postfix-relaying</code><pre class="src src-conf" id="orgd7a665b"><code>- p: smtpd_relay_restrictions
+<code>postfix-relaying</code><pre class="src src-conf" id="org8ac0840"><code>- p: smtpd_relay_restrictions
v: permit_mynetworks reject_unauth_destination
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>postfix-maildir</code><pre class="src src-conf" id="orgbbd9862"><code>- { p: home_mailbox, v: Maildir/ }
+<code>postfix-maildir</code><pre class="src src-conf" id="orgdc301e5"><code>- { p: home_mailbox, v: Maildir/ }
</code></pre>
</div>
</p>
</div>
</div>
-<div id="outline-container-org2ebf3bf" class="outline-4">
-<h4 id="org2ebf3bf"><span class="section-number-4">3.2.2.</span> The Dovecot Configurations</h4>
+<div id="outline-container-org8812f54" class="outline-4">
+<h4 id="org8812f54"><span class="section-number-4">3.2.2.</span> The Dovecot Configurations</h4>
<div class="outline-text-4" id="text-3-2-2">
<p>
The Dovecot settings on both Front and Core disable POP and require
</p>
<div class="org-src-container">
-<code>dovecot-tls</code><pre class="src src-conf" id="orgf11083d"><code><span class="org-variable-name">protocols</span> = imap
+<code>dovecot-tls</code><pre class="src src-conf" id="org3e41ce6"><code><span class="org-variable-name">protocols</span> = imap
<span class="org-variable-name">ssl</span> = required
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>dovecot-ports</code><pre class="src src-conf" id="orgd69d756"><code><span class="org-type">service imap-login</span> {
+<code>dovecot-ports</code><pre class="src src-conf" id="orgf26f6c4"><code><span class="org-type">service imap-login</span> {
<span class="org-type">inet_listener imap</span> {
<span class="org-variable-name">port</span> = 0
}
</p>
<div class="org-src-container">
-<code>dovecot-maildir</code><pre class="src src-conf" id="org5711c76"><code><span class="org-variable-name">mail_location</span> = maildir:~/Maildir
+<code>dovecot-maildir</code><pre class="src src-conf" id="orgc74a82b"><code><span class="org-variable-name">mail_location</span> = maildir:~/Maildir
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>dovecot-maildir</code><pre class="src src-conf" id="org1c96945"><code><span class="org-variable-name">mail_driver</span> = maildir
+<code>dovecot-maildir</code><pre class="src src-conf" id="orgb1f1799"><code><span class="org-variable-name">mail_driver</span> = maildir
<span class="org-variable-name">mail_path</span> = ~/Maildir
<span class="org-variable-name">mail_inbox_path</span> = ~/Maildir
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-orgce2848f" class="outline-3">
-<h3 id="orgce2848f"><span class="section-number-3">3.3.</span> The Web Services</h3>
+<div id="outline-container-org0f5b5dc" class="outline-3">
+<h3 id="org0f5b5dc"><span class="section-number-3">3.3.</span> The Web Services</h3>
<div class="outline-text-3" id="text-3-3">
<p>
Front provides the public HTTP service that serves institute web pages
at e.g. <code>https://small.example.org/</code>. The small institute initially
runs with a self-signed, "snake oil" server certificate, causing
browsers to warn of possible fraud, but this certificate is easily
-replaced by one signed by a recognized authority, as discussed in <a href="#org172259a">The
+replaced by one signed by a recognized authority, as discussed in <a href="#org776cd9e">The
Front Role</a>.
</p>
</p>
</div>
</div>
-<div id="outline-container-org389cdda" class="outline-3">
-<h3 id="org389cdda"><span class="section-number-3">3.4.</span> The Cloud Service</h3>
+<div id="outline-container-org772ac50" class="outline-3">
+<h3 id="org772ac50"><span class="section-number-3">3.4.</span> The Cloud Service</h3>
<div class="outline-text-3" id="text-3-4">
<p>
Core runs Nextcloud to provide a private institute cloud at
<code>https://core.small.private/nextcloud/</code>. It is managed manually per
<a href="https://docs.nextcloud.com/server/stable/admin_manual/">The Nextcloud Server Administration Guide</a>. The code <i>and</i> data,
including especially database dumps, are stored in <q>/Nextcloud/</q> which
-is included in Core's backup procedure as described in <a href="#orgec56c07">Backups</a>. The
+is included in Core's backup procedure as described in <a href="#org5528489">Backups</a>. The
default Apache2 configuration expects to find the web scripts in
<q>/var/www/nextcloud/</q>, so the institute symbolically links this to
<q>/Nextcloud/nextcloud/</q>.
</p>
</div>
</div>
-<div id="outline-container-orge0ec564" class="outline-3">
-<h3 id="orge0ec564"><span class="section-number-3">3.5.</span> Accounts</h3>
+<div id="outline-container-orgcc441b8" class="outline-3">
+<h3 id="orgcc441b8"><span class="section-number-3">3.5.</span> Accounts</h3>
<div class="outline-text-3" id="text-3-5">
<p>
A small institute has just a handful of members. For simplicity (and
thus security) static configuration files are preferred over complex
account management systems, LDAP, Active Directory, and the like. The
Ansible scripts configure the same set of user accounts on Core and
-Front. <a href="#org219b1f0">The Institute Commands</a> (e.g. <code>./inst new dick</code>) capture the
+Front. <a href="#org072ccf4">The Institute Commands</a> (e.g. <code>./inst new dick</code>) capture the
processes of enrolling, modifying and retiring members of the
institute. They update the administrator's membership roll, and run
Ansible to create (and disable) accounts on Core, Front, Nextcloud,
all be private (readable and writable only by the owner) by default.
</p>
</div>
-<div id="outline-container-org0bffc41" class="outline-4">
-<h4 id="org0bffc41"><span class="section-number-4">3.5.1.</span> The Administration Accounts</h4>
+<div id="outline-container-org87fd343" class="outline-4">
+<h4 id="org87fd343"><span class="section-number-4">3.5.1.</span> The Administration Accounts</h4>
<div class="outline-text-4" id="text-3-5-1">
<p>
The institute avoids the use of the <code>root</code> account (<code>uid 0</code>) because
and programs as <code>root</code>. When installation of a Debian OS leaves the
host with no user accounts, just the <code>root</code> account, the next step is
to create a system administrator's account named <code>sysadm</code> and to give
-it permission to use the <code>sudo</code> command (e.g. as described in <a href="#org548ba51">The
+it permission to use the <code>sudo</code> command (e.g. as described in <a href="#orgff203aa">The
Front Machine</a>). When installation prompts for the name of an
initial, privileged user account the same name is given (e.g. as
-described in <a href="#org4e25105">The Core Machine</a>). Installation may <i>not</i> prompt and
+described in <a href="#org952a147">The Core Machine</a>). Installation may <i>not</i> prompt and
still create an initial user account with a distribution specific name
(e.g. <code>pi</code>). Any name can be used as long as it is provided as the
value of <code>ansible_user</code> in <a href="hosts"><q>hosts</q></a>. Its password is specified by a
vault-encrypted variable in the <a href="Secret/become.yml"><q>Secret/become.yml</q></a> file. (The
-<a href="hosts"><q>hosts</q></a> and <a href="Secret/become.yml"><q>Secret/become.yml</q></a> files are described in <a href="#orgb99caba">The Ansible
+<a href="hosts"><q>hosts</q></a> and <a href="Secret/become.yml"><q>Secret/become.yml</q></a> files are described in <a href="#org287b3e3">The Ansible
Configuration</a>.)
</p>
</div>
</div>
-<div id="outline-container-org2ae6fca" class="outline-4">
-<h4 id="org2ae6fca"><span class="section-number-4">3.5.2.</span> The Monkey Accounts</h4>
+<div id="outline-container-orge68a1dc" class="outline-4">
+<h4 id="orge68a1dc"><span class="section-number-4">3.5.2.</span> The Monkey Accounts</h4>
<div class="outline-text-4" id="text-3-5-2">
<p>
The institute's Core uses a special account named <code>monkey</code> to run
</div>
</div>
</div>
-<div id="outline-container-org49a7a21" class="outline-3">
-<h3 id="org49a7a21"><span class="section-number-3">3.6.</span> Keys</h3>
+<div id="outline-container-org6faddb7" class="outline-3">
+<h3 id="org6faddb7"><span class="section-number-3">3.6.</span> Keys</h3>
<div class="outline-text-3" id="text-3-6">
<p>
The institute keeps its "master secrets" in an encrypted
</p>
</div>
</div>
-<div id="outline-container-orgec56c07" class="outline-3">
-<h3 id="orgec56c07"><span class="section-number-3">3.7.</span> Backups</h3>
+<div id="outline-container-org5528489" class="outline-3">
+<h3 id="org5528489"><span class="section-number-3">3.7.</span> Backups</h3>
<div class="outline-text-3" id="text-3-7">
<p>
The small institute backs up its data, but not so much so that nothing
</p>
<div class="org-src-container">
-<a href="private/backup"><q>private/backup</q></a><pre class="src src-sh" id="orgf87535e"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
+<a href="private/backup"><q>private/backup</q></a><pre class="src src-sh" id="orgadc4dfb"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
<span class="org-comment-delimiter">#</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">DO NOT EDIT.</span>
<span class="org-comment-delimiter">#</span>
</div>
</div>
</div>
-<div id="outline-container-orgb434147" class="outline-2">
-<h2 id="orgb434147"><span class="section-number-2">4.</span> The Particulars</h2>
+<div id="outline-container-org4bc42e9" class="outline-2">
+<h2 id="org4bc42e9"><span class="section-number-2">4.</span> The Particulars</h2>
<div class="outline-text-2" id="text-4">
<p>
This chapter introduces Ansible variables intended to simplify
<p>
The example settings in this document configure VirtualBox VMs as
-described in the <a href="#orga52c0d9">Testing</a> chapter. For more information about how a
+described in the <a href="#org74edc30">Testing</a> chapter. For more information about how a
small institute turns the example Ansible code into a working Ansible
-configuration, see chapter <a href="#orgb99caba">The Ansible Configuration</a>.
+configuration, see chapter <a href="#org287b3e3">The Ansible Configuration</a>.
</p>
</div>
-<div id="outline-container-org7c445bd" class="outline-3">
-<h3 id="org7c445bd"><span class="section-number-3">4.1.</span> Generic Particulars</h3>
+<div id="outline-container-orgf0c7ce8" class="outline-3">
+<h3 id="orgf0c7ce8"><span class="section-number-3">4.1.</span> Generic Particulars</h3>
<div class="outline-text-3" id="text-4-1">
<p>
The small institute's domain name is used quite frequently in the
</div>
</div>
</div>
-<div id="outline-container-orgbabb444" class="outline-3">
-<h3 id="orgbabb444"><span class="section-number-3">4.2.</span> Subnets</h3>
+<div id="outline-container-orgb1e76a5" class="outline-3">
+<h3 id="orgb1e76a5"><span class="section-number-3">4.2.</span> Subnets</h3>
<div class="outline-text-3" id="text-4-2">
<p>
The small institute uses a private Ethernet, two VPNs, and a "wild",
</code></pre>
</div>
-<div class="TEXT" id="org1884b4b">
+<div class="TEXT" id="orgb0e0f1d">
<p>
=> 10.62.17.0/24
</p>
sensitive information so again the code block below "tangles" into
<a href="private/vars.yml"><q>private/vars.yml</q></a> rather than <a href="public/vars.yml"><q>public/vars.yml</q></a>. Two of the
addresses are in <code>192.168</code> subnets because they are part of a test
-configuration using mostly-default VirtualBoxes (described <a href="#orga52c0d9">here</a>).
+configuration using mostly-default VirtualBoxes (described <a href="#org74edc30">here</a>).
</p>
<div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>
-private_net_cidr: 192.168.56.0/24
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf"><code>private_net_cidr: 192.168.56.0/24
wild_net_cidr: 192.168.57.0/24
public_wg_net_cidr: 10.177.87.0/24
campus_wg_net_cidr: 10.84.139.0/24
</p>
<div class="org-src-container">
-<code>network-vars</code><pre class="src src-conf" id="orgbf8965b"><code>private_net:
+<code>network-vars</code><pre class="src src-conf" id="org1f136b6"><code>private_net:
<span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('network') }}"</span>
private_net_mask:
<span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('netmask') }}"</span>
</p>
<div class="org-src-container">
-<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf" id="org60eec42"><code>front_addr: 192.168.15.4
+<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf" id="orgbe25a58"><code>front_addr: 192.168.15.4
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>address-vars</code><pre class="src src-conf" id="orge4324d8"><code>
-core_addr_cidr: <span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('1') }}"</span>
+<code>address-vars</code><pre class="src src-conf" id="orgf317866"><code>core_addr_cidr: <span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('1') }}"</span>
gate_addr_cidr: <span class="org-string">"{{ private_net_cidr | ansible.utils.ipaddr('2') }}"</span>
gate_wild_addr_cidr:
<span class="org-string">"{{ wild_net_cidr | ansible.utils.ipaddr('1') }}"</span>
</div>
</div>
</div>
-<div id="outline-container-orgc581563" class="outline-2">
-<h2 id="orgc581563"><span class="section-number-2">5.</span> The Hardware</h2>
+<div id="outline-container-org2b6506b" class="outline-2">
+<h2 id="org2b6506b"><span class="section-number-2">5.</span> The Hardware</h2>
<div class="outline-text-2" id="text-5">
<p>
The small institute's network was built by its system administrator
using Ansible on a trusted notebook. The Ansible configuration and
scripts were generated by "tangling" the Ansible code included here.
-(<a href="#orgb99caba">The Ansible Configuration</a> describes how to do this.) The following
+(<a href="#org287b3e3">The Ansible Configuration</a> describes how to do this.) The following
sections describe how Front, Gate and Core were prepared for Ansible.
</p>
</div>
-<div id="outline-container-org548ba51" class="outline-3">
-<h3 id="org548ba51"><span class="section-number-3">5.1.</span> The Front Machine</h3>
+<div id="outline-container-orgff203aa" class="outline-3">
+<h3 id="orgff203aa"><span class="section-number-3">5.1.</span> The Front Machine</h3>
<div class="outline-text-3" id="text-5-1">
<p>
Front is the small institute's public facing server, a virtual machine
Internet café using just the administrator's notebook.
</p>
</div>
-<div id="outline-container-org3e413ad" class="outline-4">
-<h4 id="org3e413ad"><span class="section-number-4">5.1.1.</span> A Digital Ocean Droplet</h4>
+<div id="outline-container-org8e2e4e2" class="outline-4">
+<h4 id="org8e2e4e2"><span class="section-number-4">5.1.1.</span> A Digital Ocean Droplet</h4>
<div class="outline-text-4" id="text-5-1-1">
<p>
The following example prepared a Digital Ocean droplet to be Front.
The institute administrator opened an account at Digital Ocean,
-registered an ssh key, and used a Digital Ocean control panel to
+registered an SSH key, and used a Digital Ocean control panel to
create a new machine (again, one of the cheapest, smallest available)
with Debian 13 installed, named <code>small.example.org</code>. Once created,
the machine and its IP address (<code>159.65.75.60</code>) appeared on the panel.
<p>
The freshly created Digital Ocean droplet came with just one account,
<code>root</code>, but the small institute avoids remote access to the "super
-user" account (per the policy in <a href="#org0bffc41">The Administration Accounts</a>), so the
+user" account (per the policy in <a href="#org87fd343">The Administration Accounts</a>), so the
first thing the administrator did was to create a <code>sysadm</code> account.
</p>
The password for the <code>sysadm</code> account was generated by <code>gpw</code>, saved in
the administrator's password keep, and added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as
shown below. (Producing a working Ansible configuration with
-<a href="Secret/become.yml"><q>Secret/become.yml</q></a> file is described in <a href="#orgb99caba">The Ansible Configuration</a>.)
+<a href="Secret/become.yml"><q>Secret/become.yml</q></a> file is described in <a href="#org287b3e3">The Ansible Configuration</a>.)
</p>
<pre class="example">
<p>
After creating the <code>sysadm</code> account on the droplet, the administrator
-concatenated a personal public ssh key and the key found in
-<a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org44eead9">The CA Command</a>) into an <q>admin_keys</q>
+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="#orgc5697a5">The CA Command</a>) into an <q>admin_keys</q>
file, copied it to the droplet, and installed it as the
<q>authorized_keys</q> for <code>sysadm</code>.
</p>
<p>
After installing authorized keys, the administrator verified that
-password-less ssh logins work, then disabled root logins and tested
+password-less SSH logins work, then disabled root logins and tested
that they were indeed denied.
</p>
subsequent reboot gets ResolveD configured properly (else <code>resolvectl</code>
hangs, causing <code>wg-quick@wg0</code> to hang…). The rest are included just
to speed up (re)testing of "prepared" test machines, e.g. prepared as
-described in <a href="#orgf8cddd8">The Test Front Machine</a>.
+described in <a href="#orgbae00d6">The Test Front Machine</a>.
</p>
<pre class="example">
<p>
The public key is copied and pasted into <a href="private/vars.yml"><q>private/vars.yml</q></a> as the
-value of <code>front_wg_pubkey</code> (as in the example <a href="#org4f55070">here</a>).
+value of <code>front_wg_pubkey</code> (as in the example <a href="#org0cd0d4c">here</a>).
</p>
<p>
The prospective IP address (<code>159.65.75.60</code>) is also pasted into
<a href="public/vars.yml"><q>public/vars.yml</q></a> as the value of <code>front_addr</code> (as in the example
-<a href="#org60eec42">here</a>).
+<a href="#orgbe25a58">here</a>).
</p>
<p>
-Finally, the new machine's ssh public host is copied to
+Finally, the new machine's SSH public host is copied to
<q>private/front_ed25519_key.pub</q>.
</p>
</div>
</div>
</div>
-<div id="outline-container-org4e25105" class="outline-3">
-<h3 id="org4e25105"><span class="section-number-3">5.2.</span> The Core Machine</h3>
+<div id="outline-container-org952a147" class="outline-3">
+<h3 id="org952a147"><span class="section-number-3">5.2.</span> The Core Machine</h3>
<div class="outline-text-3" id="text-5-2">
<p>
Core is the small institute's private file, email, cloud and whatnot
freshly installed. During installation, the machine was named <code>core</code>,
no desktop or server software was installed, no root password was set,
and a privileged account named <code>sysadm</code> was created (per the policy in
-<a href="#org0bffc41">The Administration Accounts</a>).
+<a href="#org87fd343">The Administration Accounts</a>).
</p>
<pre class="example">
The password was generated by <code>gpw</code>, saved in the administrator's
password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as shown below.
(Producing a working Ansible configuration with <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
-file is described in <a href="#orgb99caba">The Ansible Configuration</a>.)
+file is described in <a href="#org287b3e3">The Ansible Configuration</a>.)
</p>
<pre class="example">
</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="#org44eead9">The CA Command</a>) into an
-<q>admin_keys</q> file, copied it to Core, and installed it as the
-<q>authorized_keys</q> for <code>sysadm</code>.
+Now Core no longer needed the Internets so it was disconnected from
+the cable modem and connected to the campus Ethernet switch. Its
+primary Ethernet interface was manually configured with its private IP
+address and a default route, using commands similar to the examples
+below. In the example commands, the address <code>192.168.56.1</code> is the
+example value of <code>core_addr</code> set in <a href="#orgb1e76a5">Subnets</a>. The second address,
+<code>192.168.56.2</code>, is likewise the example value of <code>gate_addr</code>.
+</p>
+
+<pre class="example">
+sysadm@core$ sudo ip address add 192.168.56.1 dev enp82s0
+sysadm@core$ sudo ip route add default via 192.168.56.2 dev enp82s0
+</pre>
+
+<p>
+Next, the administrator connected their notebook to the campus
+Ethernet and adopted an unused IP address, e.g. <code>192.168.56.100</code>.
+</p>
+
+<pre class="example">
+notebook$ sudo ip address add 192.168.56.100 dev eth0
+</pre>
+
+<p>
+On their notebook, the administrator concatenated their personal
+public SSH key with Ansible's (found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a>, created
+by <a href="#orgc5697a5">The CA Command</a>) into an <q>admin_keys</q> file, copied the file to Core,
+and installed it as the <q>authorized_keys</q> for <code>sysadm</code>.
</p>
<pre class="example">
notebook$ cat ~/.ssh/id_ed25519.pub \
notebook_ Secret/ssh_admin/id_ed25519.pub \
notebook_ > admin_keys
-notebook$ scp admin_keys sysadm@core.lan:
-The authenticity of host 'core.lan' can't be established.
+notebook$ scp admin_keys sysadm@192.168.56.1:
+The authenticity of host '192.168.56.1' can't be established.
....
Are you sure you want to continue connecting (...)? yes
...
-sysadm@core.lan's password: oingstramextedil
-notebook$ ssh sysadm@core.lan
-sysadm@core.lan's password: oingstramextedil
+sysadm@192.168.56.1's password: oingstramextedil
+notebook$ ssh sysadm@192.168.56.1
+sysadm@192.168.56.1's password: oingstramextedil
sysadm@core$ ( umask 077; mkdir .ssh; \
sysadm@core_ cp admin_keys .ssh/authorized_keys )
sysadm@core$ rm admin_keys
notebook$
</pre>
-<p>
-Note that the name <code>core.lan</code> should be known to the cable modem's DNS
-service. An IP address might be used instead, discovered with an <code>ip
--4 a</code> command on Core.
-</p>
-
-<p>
-Now Core no longer needed the Internets so it was disconnected from
-the cable modem and connected to the campus Ethernet switch. Its
-primary Ethernet interface was temporarily (manually) configured with
-a new, private IP address and a default route.
-</p>
-
-<p>
-In the example command lines below, the address <code>10.227.248.1</code> was
-generated by the random subnet address picking procedure described in
-<a href="#orgbabb444">Subnets</a>, and is named <code>core_addr</code> in the Ansible code. The second
-address, <code>10.227.248.2</code>, is the corresponding address for Gate's
-Ethernet interface, and is named <code>gate_addr</code> in the Ansible
-code.
-</p>
-
-<pre class="example">
-sysadm@core$ sudo ip address add 10.227.248.1 dev enp82s0
-sysadm@core$ sudo ip route add default via 10.227.248.2 dev enp82s0
-</pre>
-
<p>
At this point Core was prepared for provisioning with Ansible.
</p>
</div>
</div>
-<div id="outline-container-orge906ba2" class="outline-3">
-<h3 id="orge906ba2"><span class="section-number-3">5.3.</span> The Gate Machine</h3>
+<div id="outline-container-orgfbe1689" class="outline-3">
+<h3 id="orgfbe1689"><span class="section-number-3">5.3.</span> The Gate Machine</h3>
<div class="outline-text-3" id="text-5-3">
<p>
Gate is the small institute's route to the Internet, and the campus
connected to a campground Wi-Fi access point, etc.</li>
</ol>
-<pre class="example" id="org3ed3b3d">
+<pre class="example" id="orgbf8b607">
=============== | ==================================================
| Premises
(Campus ISP)
+----Ethernet switch
</pre>
</div>
-<div id="outline-container-orgd868032" class="outline-4">
-<h4 id="orgd868032"><span class="section-number-4">5.3.1.</span> Alternate Gate Topology</h4>
+<div id="outline-container-org3477881" class="outline-4">
+<h4 id="org3477881"><span class="section-number-4">5.3.1.</span> Alternate Gate Topology</h4>
<div class="outline-text-4" id="text-5-3-1">
<p>
While Gate and Core really need to be separate machines for security
following topology.
</p>
-<pre class="example" id="org55db2af">
+<pre class="example" id="org8da7594">
=============== | ==================================================
| Premises
(House ISP)
</p>
</div>
</div>
-<div id="outline-container-org2bfcd33" class="outline-4">
-<h4 id="org2bfcd33"><span class="section-number-4">5.3.2.</span> Original Gate Topology</h4>
+<div id="outline-container-org5a924e5" class="outline-4">
+<h4 id="org5a924e5"><span class="section-number-4">5.3.2.</span> Original Gate Topology</h4>
<div class="outline-text-4" id="text-5-3-2">
<p>
The Ansible code in this document is somewhat dependent on the
-physical network shown in the <a href="#org953f84e">Overview</a> wherein Gate has three network
+physical network shown in the <a href="#org09790c1">Overview</a> wherein Gate has three network
interfaces.
</p>
<p>
-The following example prepared a new gate on a PC with Debian 11
+The following example prepared a new gate on a PC with Debian 13
freshly installed. During installation, the machine was named <code>gate</code>,
-no desktop or server software was installed, no root password was set,
-and a privileged account named <code>sysadm</code> was created (per the policy in
-<a href="#org0bffc41">The Administration Accounts</a>).
+no desktop nor server software was installed, no root password was
+set, and a privileged account named <code>sysadm</code> was created (per the
+policy in <a href="#org87fd343">The Administration Accounts</a>).
</p>
-<pre class="example">
-New password: icismassssadestm
-Retype new password: icismassssadestm
-...
- Full Name []: System Administrator
-...
-Is the information correct? [Y/n]
-</pre>
-
<p>
-The password was generated by <code>gpw</code>, saved in the administrator's
-password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as shown below.
-(Producing a working Ansible configuration with <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
-file is described in <a href="#orgb99caba">The Ansible Configuration</a>.)
+The password for <code>sysadm</code> was generated by <code>gpw</code>, saved in the
+administrator's password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
+as shown below. (Producing a working Ansible configuration with
+<a href="Secret/become.yml"><q>Secret/become.yml</q></a> file is described in <a href="#org287b3e3">The Ansible Configuration</a>.)
</p>
<pre class="example">
</pre>
<p>
-With Debian freshly installed, Gate needed a couple additional
+With Debian freshly installed, Gate just needed a few additional
software packages. The administrator temporarily plugged Gate into a
cable modem and installed them as shown below.
</p>
<pre class="example">
$ sudo apt install systemd-resolved unattended-upgrades \
_ ufw postfix wireguard lm-sensors \
-_ nagios-nrpe-server
+_ nagios-nrpe-server munin-node emacs
</pre>
<p>
-The host then needed to be rebooted to get its name service working
-again after <code>systemd-resolved</code> was installed. (Any help with this will
-be welcome!) After rebooting and re-logging in, the administrator was
-ready to proceed.
+Manual installation of Postfix prompted for configuration type and
+mail name. The answers given are listed here.
</p>
+<ul class="org-ul">
+<li>General type of mail configuration: Internet Site</li>
+<li>System mail name: gate.small.private</li>
+</ul>
+
<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="#org44eead9">The CA Command</a>) into an
-<q>admin_keys</q> file, copied it to Gate, and installed it as the
-<q>authorized_keys</q> for <code>sysadm</code>.
+Now Gate no longer needed the Internets, and needed to be rebooted to
+get its name service working again after installing
+<code>systemd-resolved</code>. (Any help with this will be welcome!) It was
+shutdown and disconnected from the cable modem, then connected to the
+campus Ethernet switch and restarted. Logged in on the console, the
+administrator configured the primary Ethernet interface with Gate's
+private IP address using a command similar to the example below. In
+the example command, the address <code>192.168.56.2</code> is the example value
+of <code>gate_addr</code>, set in <a href="#orgb1e76a5">Subnets</a>.
+</p>
+
+<pre class="example">
+sysadm@gate$ sudo ip address add 192.168.56.2 dev eth0
+</pre>
+
+<p>
+Next, the administrator connected their notebook to the campus
+Ethernet and adopted an unused IP address, e.g. <code>192.168.56.100</code>.
+</p>
+
+<pre class="example">
+notebook$ sudo ip address add 192.168.56.100 dev eth0
+</pre>
+
+<p>
+On their notebook, the administrator concatenated their personal
+public SSH key with Ansible's (found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a>, created
+by <a href="#orgc5697a5">The CA Command</a>) into an <q>admin_keys</q> file, copied the file to Gate,
+and installed it as the <q>authorized_keys</q> for <code>sysadm</code>.
</p>
<pre class="example">
notebook$ cat ~/.ssh/id_ed25519.pub \
notebook_ Secret/ssh_admin/id_ed25519.pub \
notebook_ > admin_keys
-notebook$ scp admin_keys sysadm@gate.lan:
-The authenticity of host 'gate.lan' can't be established.
+notebook$ scp admin_keys sysadm@192.168.56.2:
+The authenticity of host '192.168.56.2' can't be established.
....
Are you sure you want to continue connecting (...)? yes
...
-sysadm@gate.lan's password: icismassssadestm
-notebook$ ssh sysadm@gate.lan
-sysadm@gate.lan's password: icismassssadestm
+sysadm@192.168.56.2's password: icismassssadestm
+notebook$ ssh sysadm@192.168.56.2
+sysadm@192.168.56.2's password: icismassssadestm
sysadm@gate$ ( umask 077; mkdir .ssh; \
sysadm@gate_ cp admin_keys .ssh/authorized_keys )
-sysadm@core$ rm admin_keys
-sysadm@core$ logout
+sysadm@gate$ rm admin_keys
+sysadm@gate$ logout
notebook$ rm admin_keys
notebook$
</pre>
<p>
-Note that the name <code>gate.lan</code> should be known to the cable modem's DNS
-service. An IP address might be used instead, discovered with an <code>ip
-a</code> command on Gate.
-</p>
-
-<p>
-Now Gate no longer needed the Internets so it was disconnected from
-the cable modem and connected to the campus Ethernet switch. Its
-primary Ethernet interface was temporarily (manually) configured with
-a new, private IP address.
+Gate was also connected to the USB Ethernet dongles cabled to the
+campus Wi-Fi access point and the campus ISP, and the values of three
+variables (<code>gate_lan_mac</code>, <code>gate_wild_mac</code>, and <code>gate_isp_mac</code> in
+<a href="private/vars.yml"><q>private/vars.yml</q></a>) were set to the hardware MAC addresses of the
+dongles. (For more information, see the tasks in the <a href="#orga5f0cfe">9.3</a> section.)
</p>
<p>
-In the example command lines below, the address <code>10.227.248.2</code> was
-generated by the random subnet address picking procedure described in
-<a href="#orgbabb444">Subnets</a>, and is named <code>gate_addr</code> in the Ansible code.
+Finally, a new WireGuard™ private key was generated. The following
+commands generated the key without revealing it, and displayed the
+corresponding public key.
</p>
<pre class="example">
-$ sudo ip address add 10.227.248.2 dev eth0
+sysadm@small$ umask 077
+susadm@small$ wg genkey \
+sysadm@small_ | sudo tee /etc/wireguard/private-key \
+sysadm@small_ | wg pubkey
+S+6HaTnOwwhWgUGXjSBcPAvifKw+j8BDTRfq534gNW4=
+sysadm@small$ logout
+notebook$
</pre>
<p>
-Gate was also connected to the USB Ethernet dongles cabled to the
-campus Wi-Fi access point and the campus ISP and the values of three
-variables (<code>gate_lan_mac</code>, <code>gate_wild_mac</code>, and <code>gate_isp_mac</code> in
-<a href="private/vars.yml"><q>private/vars.yml</q></a>) match the actual hardware MAC addresses of the
-dongles. (For more information, see the tasks in the <a href="#orgbb16e96">9.3</a> section.)
+The public key is copied and pasted into <a href="private/vars.yml"><q>private/vars.yml</q></a> as the
+value of <code>front_wg_pubkey</code> (as in the example <a href="#org0cd0d4c">here</a>).
</p>
<p>
</div>
</div>
</div>
-<div id="outline-container-orga965227" class="outline-2">
-<h2 id="orga965227"><span class="section-number-2">6.</span> The All Role</h2>
+<div id="outline-container-org001e766" class="outline-2">
+<h2 id="org001e766"><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-orgad498ed" class="outline-3">
-<h3 id="orgad498ed"><span class="section-number-3">6.1.</span> Include Particulars</h3>
+<div id="outline-container-org67937c0" class="outline-3">
+<h3 id="org67937c0"><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="#orgb434147">The
+include the variables defined in this file (described in <a href="#org4bc42e9">The
Particulars</a>). The code block below is the first to tangle into
<a href="roles/all/tasks/main.yml"><q>roles/all/tasks/main.yml</q></a>.
</p>
</div>
</div>
</div>
-<div id="outline-container-orgd82af2d" class="outline-3">
-<h3 id="orgd82af2d"><span class="section-number-3">6.2.</span> Enable Systemd Resolved</h3>
+<div id="outline-container-orgdf7bdc4" class="outline-3">
+<h3 id="orgdf7bdc4"><span class="section-number-3">6.2.</span> Enable Systemd Resolved</h3>
<div class="outline-text-3" id="text-6-2">
<p>
The <code>systemd-networkd</code> and <code>systemd-resolved</code> service units are not
</p>
<div class="org-src-container">
-<a href="roles_t/all/tasks/main.yml"><q>roles_t/all/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install systemd-resolved.
+<a href="roles_t/all/tasks/main.yml"><q>roles_t/all/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install systemd-resolved.
become: yes
<span class="org-variable-name">apt: pkg</span>=systemd-resolved
when:
</div>
</div>
</div>
-<div id="outline-container-orgd8d3967" class="outline-3">
-<h3 id="orgd8d3967"><span class="section-number-3">6.3.</span> Trust Institute Certificate Authority</h3>
+<div id="outline-container-orgd5fd5d4" class="outline-3">
+<h3 id="orgd5fd5d4"><span class="section-number-3">6.3.</span> Trust Institute Certificate Authority</h3>
<div class="outline-text-3" id="text-6-3">
<p>
All servers should recognize the institute's Certificate Authority as
trustworthy, so its certificate is added to the set of trusted CAs on
each host. More information about how the small institute manages its
-X.509 certificates is available in <a href="#org49a7a21">Keys</a>.
+X.509 certificates is available in <a href="#org6faddb7">Keys</a>.
</p>
<div class="org-src-container">
-<a href="roles_t/all/tasks/main.yml"><q>roles_t/all/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Trust the institute CA.
+<a href="roles_t/all/tasks/main.yml"><q>roles_t/all/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Trust the institute CA.
become: yes
copy:
src: ../Secret/CA/pki/ca.crt
</div>
</div>
</div>
-<div id="outline-container-org172259a" class="outline-2">
-<h2 id="org172259a"><span class="section-number-2">7.</span> The Front Role</h2>
+<div id="outline-container-org776cd9e" class="outline-2">
+<h2 id="org776cd9e"><span class="section-number-2">7.</span> The Front Role</h2>
<div class="outline-text-2" id="text-7">
<p>
The <code>front</code> role installs and configures the services expected on the
institute's publicly accessible "front door": email, web, VPN. The
virtual machine is prepared with an Ubuntu Server install and remote
access to a privileged, administrator's account. (For details, see
-<a href="#org548ba51">The Front Machine</a>.)
+<a href="#orgff203aa">The Front Machine</a>.)
</p>
<p>
<q>/etc/letsencrypt/live/small.example.org/fullchain.pem</q>.
</p>
</div>
-<div id="outline-container-org2417e1f" class="outline-3">
-<h3 id="org2417e1f"><span class="section-number-3">7.1.</span> Role Defaults</h3>
+<div id="outline-container-orga48e47e" class="outline-3">
+<h3 id="orga48e47e"><span class="section-number-3">7.1.</span> Role Defaults</h3>
<div class="outline-text-3" id="text-7-1">
<p>
The <code>front</code> role sets a number of variables to default values in its
<div class="org-src-container">
<a href="roles_t/front/defaults/main.yml"><q>roles_t/front/defaults/main.yml</q></a><pre class="src src-conf"><code>---
<<network-vars>>
+
<<address-vars>>
+
<<membership-rolls>>
</code></pre>
</div>
<p>
The <code>membership-rolls</code> reference defines <code>membership_rolls</code> which is
used to select an empty membership roll if one has not been written
-yet. (See section <a href="#org8b8c94b">12.7</a>.)
+yet. (See section <a href="#org4bc24bc">12.7</a>.)
</p>
</div>
</div>
-<div id="outline-container-org39c7fe3" class="outline-3">
-<h3 id="org39c7fe3"><span class="section-number-3">7.2.</span> Include Particulars</h3>
+<div id="outline-container-org8fc8dcb" class="outline-3">
+<h3 id="org8fc8dcb"><span class="section-number-3">7.2.</span> Include Particulars</h3>
<div class="outline-text-3" id="text-7-2">
<p>
-The first task, as in <a href="#orga965227">The All Role</a>, is to include the institute
+The first task, as in <a href="#org001e766">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>
</div>
</div>
-<div id="outline-container-org6292f55" class="outline-3">
-<h3 id="org6292f55"><span class="section-number-3">7.3.</span> Configure Hostname</h3>
+<div id="outline-container-orgb1fb36d" class="outline-3">
+<h3 id="orgb1fb36d"><span class="section-number-3">7.3.</span> Configure Hostname</h3>
<div class="outline-text-3" id="text-7-3">
<p>
This task ensures that Front's <q>/etc/hostname</q> and <q>/etc/mailname</q> are
</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"><code>
-- name: Configure hostname.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure hostname.
become: yes
copy:
content: <span class="org-string">"{{ domain_name }}\n"</span>
</div>
</div>
</div>
-<div id="outline-container-orge80c89c" class="outline-3">
-<h3 id="orge80c89c"><span class="section-number-3">7.4.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-orgc46307a" class="outline-3">
+<h3 id="orgc46307a"><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
</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"><code>
-- name: Add {{ ansible_user }} to system groups.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Add {{ ansible_user }} to system groups.
become: yes
user:
name: <span class="org-string">"{{ ansible_user }}"</span>
</div>
</div>
</div>
-<div id="outline-container-org23a6207" class="outline-3">
-<h3 id="org23a6207"><span class="section-number-3">7.5.</span> Configure Monkey</h3>
+<div id="outline-container-orgbf528a2" class="outline-3">
+<h3 id="orgbf528a2"><span class="section-number-3">7.5.</span> Configure Monkey</h3>
<div class="outline-text-3" id="text-7-5">
<p>
The small institute runs cron jobs and web scripts that generate
system account named <code>monkey</code>. One of Monkey's more important jobs on
Core is to run <code>rsync</code> to update the public web site on Front. Monkey
on Core will login as <code>monkey</code> on Front to synchronize the files (as
-described in <a href="#org1cb4a91">*Configure Apache2</a>). To do that without needing a
+described in <a href="#org2598b71">*Configure Apache2</a>). To do that without needing a
password, the <code>monkey</code> account on Front should authorize Monkey's SSH
key on Core.
</p>
<div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Create monkey.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Create monkey.
become: yes
user:
name: monkey
</div>
</div>
</div>
-<div id="outline-container-org843c9b6" class="outline-3">
-<h3 id="org843c9b6"><span class="section-number-3">7.6.</span> Install Rsync</h3>
+<div id="outline-container-org5b74e4c" class="outline-3">
+<h3 id="org5b74e4c"><span class="section-number-3">7.6.</span> Install Rsync</h3>
<div class="outline-text-3" id="text-7-6">
<p>
Monkey uses Rsync to keep the institute's public web site up-to-date.
</p>
<div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install rsync.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install rsync.
become: yes
<span class="org-variable-name">apt: pkg</span>=rsync
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-org59bed61" class="outline-3">
-<h3 id="org59bed61"><span class="section-number-3">7.7.</span> Install Unattended Upgrades</h3>
+<div id="outline-container-orgd3216ee" class="outline-3">
+<h3 id="orgd3216ee"><span class="section-number-3">7.7.</span> Install Unattended Upgrades</h3>
<div class="outline-text-3" id="text-7-7">
<p>
The institute prefers to install security updates as soon as possible.
</p>
<div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install basic software.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install basic software.
become: yes
<span class="org-variable-name">apt: pkg</span>=unattended-upgrades
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-orgb83d69e" class="outline-3">
-<h3 id="orgb83d69e"><span class="section-number-3">7.8.</span> Configure User Accounts</h3>
+<div id="outline-container-org2adb537" class="outline-3">
+<h3 id="org2adb537"><span class="section-number-3">7.8.</span> Configure User Accounts</h3>
<div class="outline-text-3" id="text-7-8">
<p>
User accounts are created immediately so that Postfix and Dovecot can
start delivering email immediately, <i>without</i> returning "no such
-recipient" replies. The <a href="#org8b8c94b">Account Management</a> chapter describes the
+recipient" replies. The <a href="#org4bc24bc">Account Management</a> chapter describes the
<code>members</code> and <code>usernames</code> variables used below.
</p>
<div class="org-src-container">
-<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Create user accounts.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Create user accounts.
become: yes
user:
name: <span class="org-string">"{{ item }}"</span>
</div>
</div>
</div>
-<div id="outline-container-orgb963fa3" class="outline-3">
-<h3 id="orgb963fa3"><span class="section-number-3">7.9.</span> Install Server Certificate</h3>
+<div id="outline-container-orge97902f" class="outline-3">
+<h3 id="orge97902f"><span class="section-number-3">7.9.</span> Install Server Certificate</h3>
<div class="outline-text-3" id="text-7-9">
<p>
The servers on Front use the same certificate (and key) to
</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"><code>
-- name: Install server certificate/key.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install server certificate/key.
become: yes
copy:
src: <span class="org-string">"{{ item.src }}"</span>
</div>
</div>
</div>
-<div id="outline-container-org599719f" class="outline-3">
-<h3 id="org599719f"><span class="section-number-3">7.10.</span> Configure Postfix on Front</h3>
+<div id="outline-container-org05a8e06" class="outline-3">
+<h3 id="org05a8e06"><span class="section-number-3">7.10.</span> Configure Postfix on Front</h3>
<div class="outline-text-3" id="text-7-10">
<p>
Front uses Postfix to provide the institute's public SMTP service, and
</ul>
<p>
-As discussed in <a href="#org39e9ca1">The Email Service</a> above, Front's Postfix configuration
+As discussed in <a href="#org64efd10">The Email Service</a> above, Front's Postfix configuration
includes site-wide support for larger message sizes, shorter queue
times, the relaying configuration, and the common path to incoming
emails. These and a few Front-specific Postfix configurations
</p>
<div class="org-src-container">
-<code>postfix-front-networks</code><pre class="src src-conf" id="org1cd6345"><code>- p: mynetworks
+<code>postfix-front-networks</code><pre class="src src-conf" id="org949d077"><code>- p: mynetworks
v: >-
{{ public_wg_net_cidr }}
127.0.0.0/8
</p>
<div class="org-src-container">
-<code>postfix-front-restrictions</code><pre class="src src-conf" id="org01a1ce3"><code>- p: smtpd_recipient_restrictions
+<code>postfix-front-restrictions</code><pre class="src src-conf" id="orgc1fa767"><code>- p: smtpd_recipient_restrictions
v: >-
permit_mynetworks
reject_unauth_pipelining
</p>
<div class="org-src-container">
-<code>postfix-header-checks</code><pre class="src src-conf" id="org81a7999"><code>- p: smtp_header_checks
+<code>postfix-header-checks</code><pre class="src src-conf" id="orga516629"><code>- p: smtp_header_checks
v: regexp:/etc/postfix/header_checks.cf
</code></pre>
</div>
<div class="org-src-container">
-<code>postfix-header-checks-content</code><pre class="src src-conf" id="org5341ddf"><code>/^Received:/ IGNORE
+<code>postfix-header-checks-content</code><pre class="src src-conf" id="orgbb268c6"><code>/^Received:/ IGNORE
/^User-Agent:/ IGNORE
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>postfix-front</code><pre class="src src-conf" id="org2ad85a9"><code>- { p: smtpd_tls_cert_file, v: /etc/server.crt }
+<code>postfix-front</code><pre class="src src-conf" id="orge7a0dd3"><code>- { p: smtpd_tls_cert_file, v: /etc/server.crt }
- { p: smtpd_tls_key_file, v: /etc/server.key }
<<postfix-front-networks>>
<<postfix-front-restrictions>>
</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"><code>
-- name: Install Postfix.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Postfix.
become: yes
<span class="org-variable-name">apt: pkg</span>=postfix
</div>
</div>
</div>
-<div id="outline-container-orgc4d9612" class="outline-3">
-<h3 id="orgc4d9612"><span class="section-number-3">7.11.</span> Configure Public Email Aliases</h3>
+<div id="outline-container-org22ef008" class="outline-3">
+<h3 id="org22ef008"><span class="section-number-3">7.11.</span> Configure Public Email Aliases</h3>
<div class="outline-text-3" id="text-7-11">
<p>
The institute's Front needs to deliver email addressed to a number of
</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"><code>
-- name: New aliases.
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: New aliases.
become: yes
command: newaliases
tags: actualizer
</div>
</div>
</div>
-<div id="outline-container-org963405a" class="outline-3">
-<h3 id="org963405a"><span class="section-number-3">7.12.</span> Configure OpenDKIM</h3>
+<div id="outline-container-org2fd9e21" class="outline-3">
+<h3 id="org2fd9e21"><span class="section-number-3">7.12.</span> Configure OpenDKIM</h3>
<div class="outline-text-3" id="text-7-12">
<p>
Front uses OpenDKIM to sign outgoing emails. It does not verify
</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"><code>
-- name: Install OpenDKIM.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install OpenDKIM.
become: yes
<span class="org-variable-name">apt: pkg</span>=opendkim
</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"><code>
-- name: Restart OpenDKIM.
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart OpenDKIM.
become: yes
systemd:
service: opendkim
</div>
</div>
</div>
-<div id="outline-container-orgb886b67" class="outline-3">
-<h3 id="orgb886b67"><span class="section-number-3">7.13.</span> Configure Dovecot IMAPd</h3>
+<div id="outline-container-orgaf71ef1" class="outline-3">
+<h3 id="orgaf71ef1"><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
bit "over the top" given that Core accesses Front via VPN, but helps
to ensure privacy even when members must, in extremis, access recent
email directly from their accounts on Front. For more information
-about Front's role in the institute's email services, see <a href="#org39e9ca1">The Email
+about Front's role in the institute's email services, see <a href="#org64efd10">The Email
Service</a>.
</p>
</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"><code>
-- name: Install Dovecot IMAPd.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Dovecot IMAPd.
become: yes
<span class="org-variable-name">apt: pkg</span>=dovecot-imapd
</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"><code>
-- name: Restart Dovecot.
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart Dovecot.
become: yes
systemd:
service: dovecot
</div>
</div>
</div>
-<div id="outline-container-org8d5d29a" class="outline-3">
-<h3 id="org8d5d29a"><span class="section-number-3">7.14.</span> Configure Apache2 <a id="org1cb4a91"></a></h3>
+<div id="outline-container-org2aac112" class="outline-3">
+<h3 id="org2aac112"><span class="section-number-3">7.14.</span> Configure Apache2 <a id="org2598b71"></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,
</p>
<div class="org-src-container">
-<code>apache-ciphers</code><pre class="src src-conf" id="orgf7dd15e"><code>SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
+<code>apache-ciphers</code><pre class="src src-conf" id="orge2613ba"><code>SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder on
<span class="org-type">SSLCipherSuite {</span>{ [ <span class="org-string">'ECDHE-ECDSA-AES128-GCM-SHA256'</span>,
<span class="org-string">'ECDHE-ECDSA-AES256-GCM-SHA384'</span>,
</p>
<div class="org-src-container">
-<code>apache-userdir-front</code><pre class="src src-conf" id="org8913eee"><code>UserDir /home/www-users
+<code>apache-userdir-front</code><pre class="src src-conf" id="org2715814"><code>UserDir /home/www-users
<Directory /home/www-users/>
Require all granted
AllowOverride None
</p>
<div class="org-src-container">
-<code>apache-redirect-front</code><pre class="src src-conf" id="org951c06c"><code><VirtualHost *:80>
+<code>apache-redirect-front</code><pre class="src src-conf" id="org6d9713e"><code><VirtualHost *:80>
Redirect permanent / https://{{ domain_name }}/
</VirtualHost>
</code></pre>
</p>
<div class="org-src-container">
-<code>apache-front</code><pre class="src src-conf" id="org2914ec7"><code>ServerName {{ domain_name }}
+<code>apache-front</code><pre class="src src-conf" id="org0466689"><code>ServerName {{ domain_name }}
ServerAdmin webmaster@{{ domain_name }}
DocumentRoot /home/www
</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"><code>
-- name: Install Apache2.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Apache2.
become: yes
<span class="org-variable-name">apt: pkg</span>=apache2
</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"><code>
-- name: Restart Apache2.
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart Apache2.
become: yes
systemd:
service: apache2
</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"><code>
-- name: Disable default vhosts.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Disable default vhosts.
become: yes
file:
path: /etc/apache2/sites-enabled/{{ item }}
</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"><code>
-- name: Disable other-vhosts-access-log option.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Disable other-vhosts-access-log option.
become: yes
file:
path: /etc/apache2/conf-enabled/other-vhosts-access-log.conf
</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"><code>
-- name: Create UserDir.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Create UserDir.
become: yes
file:
path: /home/www-users/
</div>
</div>
</div>
-<div id="outline-container-orgd4aef93" class="outline-3">
-<h3 id="orgd4aef93"><span class="section-number-3">7.15.</span> Configure Public WireGuard™ Subnet</h3>
+<div id="outline-container-org5f0ea31" class="outline-3">
+<h3 id="org5f0ea31"><span class="section-number-3">7.15.</span> Configure Public WireGuard™ Subnet</h3>
<div class="outline-text-3" id="text-7-15">
<p>
Front uses WireGuard™ to provide a public (Internet accessible) VPN
</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"><code>
-- name: Enable IP forwarding.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Enable IP forwarding.
become: yes
copy:
content: <span class="org-string">"net.ipv4.ip_forward = 1\n"</span>
</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"><code>
-- name: Reload sysctl.
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload sysctl.
become: yes
systemd:
service: systemd-sysctl
</code></pre>
</div>
</div>
-<div id="outline-container-orgd6878f6" class="outline-4">
-<h4 id="orgd6878f6"><span class="section-number-4">7.15.1.</span> Example <q>private/front-wg0.conf</q></h4>
+<div id="outline-container-orgf654603" class="outline-4">
+<h4 id="orgf654603"><span class="section-number-4">7.15.1.</span> Example <q>private/front-wg0.conf</q></h4>
<div class="outline-text-4" id="text-7-15-1">
<p>
The example <q>private/front-wg0.conf</q> below recognizes Core by its
</div>
</div>
</div>
-<div id="outline-container-org7bda53c" class="outline-3">
-<h3 id="org7bda53c"><span class="section-number-3">7.16.</span> Configure Kamailio</h3>
+<div id="outline-container-org4e5067d" class="outline-3">
+<h3 id="org4e5067d"><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
</p>
<div class="org-src-container">
-<code>kamailio</code><pre class="src src-conf" id="org9268a63"><code><span class="org-variable-name">listen</span>=udp:{{ front_wg_addr }}:5060
+<code>kamailio</code><pre class="src src-conf" id="org702889b"><code><span class="org-variable-name">listen</span>=udp:{{ front_wg_addr }}:5060
</code></pre>
</div>
</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"><code>
-- name: Install Kamailio.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Kamailio.
become: yes
<span class="org-variable-name">apt: pkg</span>=kamailio
</code></pre>
</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"><code>
-- name: Create Kamailio/Systemd configuration drop.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Create Kamailio/Systemd configuration drop.
become: yes
file:
path: /etc/systemd/system/kamailio.service.d
</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"><code>
-- name: Reload Systemd.
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload Systemd.
become: yes
systemd:
daemon-reload: yes
</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"><code>
-- name: Configure Kamailio.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure Kamailio.
become: yes
copy:
content: |
</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"><code>
-- name: Restart Kamailio.
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart Kamailio.
become: yes
systemd:
service: kamailio
</div>
</div>
</div>
-<div id="outline-container-org264af3e" class="outline-2">
-<h2 id="org264af3e"><span class="section-number-2">8.</span> The Core Role</h2>
+<div id="outline-container-org60f2710" class="outline-2">
+<h2 id="org60f2710"><span class="section-number-2">8.</span> The Core Role</h2>
<div class="outline-text-2" id="text-8">
<p>
The <code>core</code> role configures many essential campus network services as
well as the institute's private cloud, so the core machine has
horsepower (CPUs and RAM) and large disks and is prepared with a
Debian install and remote access to a privileged, administrator's
-account. (For details, see <a href="#org4e25105">The Core Machine</a>.)
+account. (For details, see <a href="#org952a147">The Core Machine</a>.)
</p>
</div>
-<div id="outline-container-orgb4e2640" class="outline-3">
-<h3 id="orgb4e2640"><span class="section-number-3">8.1.</span> Role Defaults</h3>
+<div id="outline-container-org20141b2" class="outline-3">
+<h3 id="org20141b2"><span class="section-number-3">8.1.</span> Role Defaults</h3>
<div class="outline-text-3" id="text-8-1">
<p>
-As in <a href="#org172259a">The Front Role</a>, the <code>core</code> role sets a number of variables to
+As in <a href="#org776cd9e">The Front Role</a>, the <code>core</code> role sets a number of variables to
default values in its <q>defaults/main.yml</q> file.
</p>
<div class="org-src-container">
<a href="roles_t/core/defaults/main.yml"><q>roles_t/core/defaults/main.yml</q></a><pre class="src src-conf"><code>---
<<network-vars>>
+
<<address-vars>>
+
<<membership-rolls>>
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-orgeb3617e" class="outline-3">
-<h3 id="orgeb3617e"><span class="section-number-3">8.2.</span> Include Particulars</h3>
+<div id="outline-container-org4cd7dd1" class="outline-3">
+<h3 id="org4cd7dd1"><span class="section-number-3">8.2.</span> Include Particulars</h3>
<div class="outline-text-3" id="text-8-2">
<p>
-The first task, as in <a href="#org172259a">The Front Role</a>, is to include the institute
+The first task, as in <a href="#org776cd9e">The Front Role</a>, is to include the institute
particulars and membership roll.
</p>
</div>
</div>
</div>
-<div id="outline-container-org2b16642" class="outline-3">
-<h3 id="org2b16642"><span class="section-number-3">8.3.</span> Configure Hostname</h3>
+<div id="outline-container-org7ef44f6" class="outline-3">
+<h3 id="org7ef44f6"><span class="section-number-3">8.3.</span> Configure Hostname</h3>
<div class="outline-text-3" id="text-8-3">
<p>
This task ensures that Core's <q>/etc/hostname</q> and <q>/etc/mailname</q> are
</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"><code>
-- name: Configure hostname.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure hostname.
become: yes
copy:
content: <span class="org-string">"{{ item.name }}\n"</span>
</div>
</div>
</div>
-<div id="outline-container-org81703f1" class="outline-3">
-<h3 id="org81703f1"><span class="section-number-3">8.4.</span> Configure Systemd Resolved</h3>
+<div id="outline-container-orgfb87667" class="outline-3">
+<h3 id="orgfb87667"><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
</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"><code>
-- name: Configure resolved.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure resolved.
become: yes
lineinfile:
path: /etc/systemd/resolved.conf
</div>
</div>
</div>
-<div id="outline-container-org87bd414" class="outline-3">
-<h3 id="org87bd414"><span class="section-number-3">8.5.</span> Configure Core NetworkD</h3>
+<div id="outline-container-orgc54fe96" class="outline-3">
+<h3 id="orgc54fe96"><span class="section-number-3">8.5.</span> Configure Core NetworkD</h3>
<div class="outline-text-3" id="text-8-5">
<p>
Core's network interface is statically configured using the
</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"><code>
-- name: Install 10-lan.link.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install 10-lan.link.
become: yes
copy:
content: |
</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"><code>
-- name: Reload networkd.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload networkd.
become: yes
command: networkctl reload
tags: actualizer
</div>
</div>
</div>
-<div id="outline-container-org70a0b5e" class="outline-3">
-<h3 id="org70a0b5e"><span class="section-number-3">8.6.</span> Configure DHCP For the Private Ethernet</h3>
+<div id="outline-container-org278bcbf" class="outline-3">
+<h3 id="org278bcbf"><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
</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"><code>
-- name: Install DHCP server.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install DHCP server.
become: yes
<span class="org-variable-name">apt: pkg</span>=isc-dhcp-server
</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"><code>
-- name: Restart DHCP server.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart DHCP server.
become: yes
systemd:
service: isc-dhcp-server
</div>
</div>
</div>
-<div id="outline-container-org3e05bdd" class="outline-3">
-<h3 id="org3e05bdd"><span class="section-number-3">8.7.</span> Configure BIND9</h3>
+<div id="outline-container-org18cf425" class="outline-3">
+<h3 id="org18cf425"><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 name service for the institute as described
-in <a href="#org2b3e1ef">The Name Service</a>. The configuration supports reverse name lookups,
+in <a href="#org1f40fb7">The Name Service</a>. The configuration supports reverse name lookups,
resolving many private network addresses to private domain names.
</p>
</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"><code>
-- name: Install BIND9.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install BIND9.
become: yes
<span class="org-variable-name">apt: pkg</span>=bind9
</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"><code>
-- name: Reload BIND9.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload BIND9.
become: yes
systemd:
service: bind9
</p>
<div class="org-src-container">
-<code>bind-options</code><pre class="src src-conf" id="org450921f"><code><span class="org-type">acl </span><span class="org-string"><span class="org-type">"trusted"</span></span> {
+<code>bind-options</code><pre class="src src-conf" id="org4b4b3e2"><code><span class="org-type">acl </span><span class="org-string"><span class="org-type">"trusted"</span></span> {
{{ private_net_cidr }};
{{ public_wg_net_cidr }};
{{ campus_wg_net_cidr }};
</div>
<div class="org-src-container">
-<code>bind-local</code><pre class="src src-conf" id="org336a3ad"><code>include <span class="org-string">"/etc/bind/zones.rfc1918"</span>;
+<code>bind-local</code><pre class="src src-conf" id="org15ef5f9"><code>include <span class="org-string">"/etc/bind/zones.rfc1918"</span>;
<span class="org-type">zone </span><span class="org-string"><span class="org-type">"{{ domain_priv }}."</span></span> {
type master;
</div>
</div>
</div>
-<div id="outline-container-orgacb8782" class="outline-3">
-<h3 id="orgacb8782"><span class="section-number-3">8.8.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-orga35b5ca" class="outline-3">
+<h3 id="orga35b5ca"><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
</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"><code>
-- name: Add {{ ansible_user }} to system groups.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Add {{ ansible_user }} to system groups.
become: yes
user:
name: <span class="org-string">"{{ ansible_user }}"</span>
</div>
</div>
</div>
-<div id="outline-container-orgb1ab810" class="outline-3">
-<h3 id="orgb1ab810"><span class="section-number-3">8.9.</span> Configure Monkey</h3>
+<div id="outline-container-orgb56db66" class="outline-3">
+<h3 id="orgb56db66"><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
system account named <code>monkey</code>. One of Monkey's more important jobs on
Core is to run <code>rsync</code> to update the public web site on Front (as
-described in <a href="#org5d087f7">*Configure Apache2</a>).
+described in <a href="#org6507ca3">*Configure Apache2</a>).
</p>
<div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Create monkey.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Create monkey.
become: yes
user:
name: monkey
</div>
</div>
</div>
-<div id="outline-container-org46d0d46" class="outline-3">
-<h3 id="org46d0d46"><span class="section-number-3">8.10.</span> Install Unattended Upgrades</h3>
+<div id="outline-container-org3c9c181" class="outline-3">
+<h3 id="org3c9c181"><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>
<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"><code>
-- name: Install basic software.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install basic software.
become: yes
<span class="org-variable-name">apt: pkg</span>=unattended-upgrades
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-org97fa599" class="outline-3">
-<h3 id="org97fa599"><span class="section-number-3">8.11.</span> Configure User Accounts</h3>
+<div id="outline-container-orgf7ab225" class="outline-3">
+<h3 id="orgf7ab225"><span class="section-number-3">8.11.</span> Configure User Accounts</h3>
<div class="outline-text-3" id="text-8-11">
<p>
User accounts are created immediately so that backups can begin
-restoring as soon as possible. The <a href="#org8b8c94b">Account Management</a> chapter
+restoring as soon as possible. The <a href="#org4bc24bc">Account Management</a> chapter
describes the <code>members</code> and <code>usernames</code> variables.
</p>
<div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Create user accounts.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Create user accounts.
become: yes
user:
name: <span class="org-string">"{{ item }}"</span>
</div>
</div>
</div>
-<div id="outline-container-org81f1179" class="outline-3">
-<h3 id="org81f1179"><span class="section-number-3">8.12.</span> Install Server Certificate</h3>
+<div id="outline-container-org5db9796" class="outline-3">
+<h3 id="org5db9796"><span class="section-number-3">8.12.</span> Install Server Certificate</h3>
<div class="outline-text-3" id="text-8-12">
<p>
The servers on Core use the same certificate (and key) to authenticate
</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"><code>
-- name: Install server certificate/key.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install server certificate/key.
become: yes
copy:
src: <span class="org-string">"{{ item.src }}"</span>
</div>
</div>
</div>
-<div id="outline-container-org09cbc8f" class="outline-3">
-<h3 id="org09cbc8f"><span class="section-number-3">8.13.</span> Install Chrony</h3>
+<div id="outline-container-org3656c29" class="outline-3">
+<h3 id="org3656c29"><span class="section-number-3">8.13.</span> Install Chrony</h3>
<div class="outline-text-3" id="text-8-13">
<p>
Core uses Chrony to provide a time synchronization service to the campus.
</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"><code>
-- name: Install Chrony.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Chrony.
become: yes
<span class="org-variable-name">apt: pkg</span>=chrony
</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"><code>
-- name: Restart Chrony.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart Chrony.
become: yes
systemd:
service: chrony
</div>
</div>
</div>
-<div id="outline-container-org18dd6d0" class="outline-3">
-<h3 id="org18dd6d0"><span class="section-number-3">8.14.</span> Configure Postfix on Core</h3>
+<div id="outline-container-org91dc8b0" class="outline-3">
+<h3 id="org91dc8b0"><span class="section-number-3">8.14.</span> Configure Postfix on Core</h3>
<div class="outline-text-3" id="text-8-14">
<p>
Core uses Postfix to provide SMTP service to the campus. The default
</ul>
<p>
-As discussed in <a href="#org39e9ca1">The Email Service</a> above, Core delivers email addressed
+As discussed in <a href="#org64efd10">The Email Service</a> above, Core delivers email addressed
to any internal domain name locally, and uses its smarthost Front to
relay the rest. Core is reachable only on institute networks, so
there is little benefit in enabling TLS, but it does need to handle
</p>
<div class="org-src-container">
-<code>postfix-core-networks</code><pre class="src src-conf" id="orgf3985b4"><code>- p: mynetworks
+<code>postfix-core-networks</code><pre class="src src-conf" id="org827fb97"><code>- p: mynetworks
v: >-
{{ private_net_cidr }}
{{ public_wg_net_cidr }}
</p>
<div class="org-src-container">
-<code>postfix-core-relayhost</code><pre class="src src-conf" id="orgfbd5184"><code>- { p: relayhost, v: <span class="org-string">"[{{ front_wg_addr }}]"</span> }
+<code>postfix-core-relayhost</code><pre class="src src-conf" id="org59fd809"><code>- { p: relayhost, v: <span class="org-string">"[{{ front_wg_addr }}]"</span> }
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>postfix-transport</code><pre class="src src-conf" id="orga6b90fb"><code>.{{ domain_name }} local:$myhostname
+<code>postfix-transport</code><pre class="src src-conf" id="orgbe868e1"><code>.{{ domain_name }} local:$myhostname
.{{ domain_priv }} local:$myhostname
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>postfix-core</code><pre class="src src-conf" id="orgc5fe78d"><code><<postfix-relaying>>
+<code>postfix-core</code><pre class="src src-conf" id="orgd778e39"><code><<postfix-relaying>>
- { p: smtpd_tls_security_level, v: none }
- { p: smtp_tls_security_level, v: none }
<<postfix-message-size>>
</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"><code>
-- name: Install Postfix.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Postfix.
become: yes
<span class="org-variable-name">apt: pkg</span>=postfix
</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"><code>
-- name: Restart Postfix.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart Postfix.
become: yes
systemd:
service: postfix
</div>
</div>
</div>
-<div id="outline-container-orgc1274bc" class="outline-3">
-<h3 id="orgc1274bc"><span class="section-number-3">8.15.</span> Configure Private Email Aliases</h3>
+<div id="outline-container-orgd638ceb" class="outline-3">
+<h3 id="orgd638ceb"><span class="section-number-3">8.15.</span> Configure Private Email Aliases</h3>
<div class="outline-text-3" id="text-8-15">
<p>
The institute's Core needs to deliver email addressed to institute
</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"><code>
-- name: Install institute email aliases.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install institute email aliases.
become: yes
blockinfile:
block: |
</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"><code>
-- name: New aliases.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: New aliases.
become: yes
command: newaliases
tags: actualizer
</div>
</div>
</div>
-<div id="outline-container-org6ec0eef" class="outline-3">
-<h3 id="org6ec0eef"><span class="section-number-3">8.16.</span> Configure Dovecot IMAPd</h3>
+<div id="outline-container-orga6a8674" class="outline-3">
+<h3 id="orga6a8674"><span class="section-number-3">8.16.</span> Configure Dovecot IMAPd</h3>
<div class="outline-text-3" id="text-8-16">
<p>
Core uses Dovecot's IMAPd to store and serve member emails. As on
networks, but helps to ensure privacy even when members accidentally
attempt connections from outside the private networks. For more
information about Core's role in the institute's email services, see
-<a href="#org39e9ca1">The Email Service</a>.
+<a href="#org64efd10">The Email Service</a>.
</p>
<p>
<q>README.Debian</q> (in <q>/usr/share/dovecot-core/</q>) but replaces the
default "snake oil" certificate with another, signed by the institute.
(For more information about the institute's X.509 certificates, see
-<a href="#org49a7a21">Keys</a>.)
+<a href="#org6faddb7">Keys</a>.)
</p>
<p>
</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"><code>
-- name: Install Dovecot IMAPd.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Dovecot IMAPd.
become: yes
<span class="org-variable-name">apt: pkg</span>=dovecot-imapd
</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"><code>
-- name: Restart Dovecot.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart Dovecot.
become: yes
systemd:
service: dovecot
</div>
</div>
</div>
-<div id="outline-container-org2039da5" class="outline-3">
-<h3 id="org2039da5"><span class="section-number-3">8.17.</span> Configure Fetchmail</h3>
+<div id="outline-container-orgb0b9a74" class="outline-3">
+<h3 id="orgb0b9a74"><span class="section-number-3">8.17.</span> Configure Fetchmail</h3>
<div class="outline-text-3" id="text-8-17">
<p>
Core runs a <code>fetchmail</code> for each member of the institute. Individual
</p>
<div class="org-src-container">
-<code>fetchmail-config</code><pre class="src src-conf" id="orge50a8cd"><code><span class="org-comment-delimiter"># </span><span class="org-comment">Permissions on this file may be no greater than 0600.</span>
+<code>fetchmail-config</code><pre class="src src-conf" id="org2c71e92"><code><span class="org-comment-delimiter"># </span><span class="org-comment">Permissions on this file may be no greater than 0600.</span>
set no bouncemail
set no spambounce
</p>
<div class="org-src-container">
-<code>fetchmail-service</code><pre class="src src-conf" id="org3973906"><code>[<span class="org-type">Unit</span>]
+<code>fetchmail-service</code><pre class="src src-conf" id="org21cc50f"><code>[<span class="org-type">Unit</span>]
<span class="org-variable-name">Description</span>=Fetchmail --idle task for {{ item }}.
<span class="org-variable-name">AssertPathExists</span>=/home/{{ item }}/.fetchmailrc
<span class="org-variable-name">After</span>=wg-quick@wg0.service
</p>
<div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install fetchmail.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install fetchmail.
become: yes
<span class="org-variable-name">apt: pkg</span>=fetchmail
</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"><code>
-- name: Stop former user fetchmail services.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Stop former user fetchmail services.
become: yes
systemd:
service: fetchmail-{{ item }}
</p>
<div class="org-src-container">
-<pre class="src src-conf"><code>
-- name: Delete former user fetchmail services.
+<pre class="src src-conf"><code>- name: Delete former user fetchmail services.
become: yes
file:
path: /etc/systemd/system/fetchmail-{{ item }}.service
</div>
</div>
</div>
-<div id="outline-container-org36b706b" class="outline-3">
-<h3 id="org36b706b"><span class="section-number-3">8.18.</span> Configure Apache2 <a id="org5d087f7"></a></h3>
+<div id="outline-container-org0f96574" class="outline-3">
+<h3 id="org0f96574"><span class="section-number-3">8.18.</span> Configure Apache2 <a id="org6507ca3"></a></h3>
<div class="outline-text-3" id="text-8-18">
<p>
This is the small institute's campus web server. It hosts several web
-sites as described in <a href="#orgce2848f">The Web Services</a>.
+sites as described in <a href="#org0f5b5dc">The Web Services</a>.
</p>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
</p>
<div class="org-src-container">
-<code>apache-userdir-core</code><pre class="src src-conf" id="orgd4f1792"><code>UserDir Public/HTML
+<code>apache-userdir-core</code><pre class="src src-conf" id="org90750c1"><code>UserDir Public/HTML
<Directory /home/*/Public/HTML/>
Require all granted
AllowOverride None
</p>
<div class="org-src-container">
-<code>apache-live</code><pre class="src src-conf" id="org1b4affe"><code><VirtualHost *:80>
+<code>apache-live</code><pre class="src src-conf" id="orgb34034b"><code><VirtualHost *:80>
ServerName live
ServerAlias live.{{ domain_priv }}
ServerAdmin webmaster@core.{{ domain_priv }}
</p>
<div class="org-src-container">
-<code>apache-test</code><pre class="src src-conf" id="orgbdf0d5c"><code><VirtualHost *:80>
+<code>apache-test</code><pre class="src src-conf" id="org5a0c0c9"><code><VirtualHost *:80>
ServerName test
ServerAlias test.{{ domain_priv }}
ServerAdmin webmaster@core.{{ domain_priv }}
</p>
<div class="org-src-container">
-<code>apache-campus</code><pre class="src src-conf" id="orga620ee8"><code><VirtualHost *:80>
+<code>apache-campus</code><pre class="src src-conf" id="org5a2b363"><code><VirtualHost *:80>
ServerName www
ServerAlias www.{{ domain_priv }}
ServerAdmin webmaster@core.{{ domain_priv }}
</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"><code>
-- name: Install Apache2.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Apache2.
become: yes
<span class="org-variable-name">apt: pkg</span>=apache2
</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"><code>
-- name: Install live web site.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install live web site.
become: yes
copy:
content: |
</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"><code>
-- name: Restart Apache2.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart Apache2.
become: yes
systemd:
service: apache2
</div>
</div>
</div>
-<div id="outline-container-org76aee34" class="outline-3">
-<h3 id="org76aee34"><span class="section-number-3">8.19.</span> Configure Website Updates</h3>
+<div id="outline-container-org6acfa59" class="outline-3">
+<h3 id="org6acfa59"><span class="section-number-3">8.19.</span> Configure Website Updates</h3>
<div class="outline-text-3" id="text-8-19">
<p>
Monkey on Core runs <q>/usr/local/sbin/webupdate</q> every 15 minutes via a
</p>
<div class="org-src-container">
-<a href="private/webupdate"><q>private/webupdate</q></a><pre class="src src-sh" id="orge646506"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
+<a href="private/webupdate"><q>private/webupdate</q></a><pre class="src src-sh" id="orgb982013"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
<span class="org-comment-delimiter">#</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">DO NOT EDIT.</span>
<span class="org-comment-delimiter">#</span>
<p>
The following tasks install the <q>webupdate</q> script from <a href="private/"><q>private/</q></a>,
and create Monkey's <code>cron</code> job. An example <q>webupdate</q> script is
-provided <a href="#orge646506">here</a>.
+provided <a href="#orgb982013">here</a>.
</p>
<div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: <span class="org-string">"Install Monkey's webupdate script."</span>
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: <span class="org-string">"Install Monkey's webupdate script."</span>
become: yes
copy:
src: ../private/webupdate
</div>
</div>
</div>
-<div id="outline-container-org53717f4" class="outline-3">
-<h3 id="org53717f4"><span class="section-number-3">8.20.</span> Configure Core WireGuard™ Interface</h3>
+<div id="outline-container-orgbef7d11" class="outline-3">
+<h3 id="orgbef7d11"><span class="section-number-3">8.20.</span> Configure Core WireGuard™ Interface</h3>
<div class="outline-text-3" id="text-8-20">
<p>
Core connects to Front's WireGuard™ service to provide members abroad
-with a route to the campus networks. As described in <a href="#orgd4aef93">Configure Public
+with a route to the campus networks. As described in <a href="#org5f0ea31">Configure Public
WireGuard™ Subnet</a> for Front, Core is expected to forward packets from/to the
private networks.
</p>
</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"><code>
-- name: Enable IP forwarding.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Enable IP forwarding.
become: yes
copy:
content: <span class="org-string">"net.ipv4.ip_forward = 1\n"</span>
</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"><code>
-- name: Reload sysctl.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload sysctl.
become: yes
systemd:
service: systemd-sysctl
</div>
</div>
</div>
-<div id="outline-container-orgf520512" class="outline-3">
-<h3 id="orgf520512"><span class="section-number-3">8.21.</span> Configure NAGIOS</h3>
+<div id="outline-container-org6c419e4" class="outline-3">
+<h3 id="org6c419e4"><span class="section-number-3">8.21.</span> Configure NAGIOS</h3>
<div class="outline-text-3" id="text-8-21">
<p>
Core runs a <code>nagios4</code> server to monitor "services" on institute hosts.
</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"><code>
-- name: Install NAGIOS4.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install NAGIOS4.
become: yes
apt:
pkg: [ nagios4, monitoring-plugins-basic, nagios-nrpe-plugin,
</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"><code>
-- name: Reload NAGIOS4.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload NAGIOS4.
become: yes
systemd:
service: nagios4
</code></pre>
</div>
</div>
-<div id="outline-container-org300b424" class="outline-4">
-<h4 id="org300b424"><span class="section-number-4">8.21.1.</span> Configure NAGIOS Monitors for Core</h4>
+<div id="outline-container-org8f44e50" class="outline-4">
+<h4 id="org8f44e50"><span class="section-number-4">8.21.1.</span> Configure NAGIOS Monitors for Core</h4>
<div class="outline-text-4" id="text-8-21-1">
<p>
The first block in <q>nagios.cfg</q> specifies monitors for services on
</div>
</div>
</div>
-<div id="outline-container-org1f170b4" class="outline-4">
-<h4 id="org1f170b4"><span class="section-number-4">8.21.2.</span> Custom NAGIOS Monitor <code>inst_sensors</code></h4>
+<div id="outline-container-orgb19c45c" class="outline-4">
+<h4 id="orgb19c45c"><span class="section-number-4">8.21.2.</span> Custom NAGIOS Monitor <code>inst_sensors</code></h4>
<div class="outline-text-4" id="text-8-21-2">
<p>
The <code>check_sensors</code> plugin is included in the package
</p>
<div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
-<span class="org-type">define command</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define command</span> {
command_name inst_sensors
command_line /usr/local/sbin/inst_sensors
}
</div>
</div>
</div>
-<div id="outline-container-org4911d77" class="outline-4">
-<h4 id="org4911d77"><span class="section-number-4">8.21.3.</span> Configure NAGIOS Monitors for Remote Hosts</h4>
+<div id="outline-container-orgbb3ade8" class="outline-4">
+<h4 id="orgbb3ade8"><span class="section-number-4">8.21.3.</span> Configure NAGIOS Monitors for Remote Hosts</h4>
<div class="outline-text-4" id="text-8-21-3">
<p>
The following sections contain code blocks specifying monitors for
commands are defined in code blocks interleaved with the blocks that
monitor them. The command blocks are appended to <q>nrpe.cfg</q> and the
monitoring blocks to <q>nagios.cfg</q>. The <q>nrpe.cfg</q> file is installed
-on each campus host by the campus role's <a href="#org0d2271c">Configure NRPE</a> tasks.
+on each campus host by the campus role's <a href="#org9fbfb95">Configure NRPE</a> tasks.
</p>
</div>
</div>
-<div id="outline-container-org70d7102" class="outline-4">
-<h4 id="org70d7102"><span class="section-number-4">8.21.4.</span> Configure NAGIOS Monitors for Gate</h4>
+<div id="outline-container-orgc6b5a7b" class="outline-4">
+<h4 id="orgc6b5a7b"><span class="section-number-4">8.21.4.</span> Configure NAGIOS Monitors for Gate</h4>
<div class="outline-text-4" id="text-8-21-4">
<p>
Define the monitored host, <code>gate</code>. Monitor its response to network
</p>
<div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
-<span class="org-type">define host</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define host</span> {
use linux-server
host_name gate
address {{ gate_addr }}
</p>
<div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
-<span class="org-type">define service</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define service</span> {
use generic-service
host_name gate
service_description Root Partition
</p>
<div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
-<span class="org-type">define service</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define service</span> {
use generic-service
host_name gate
service_description Current Load
</p>
<div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
-<span class="org-type">define service</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define service</span> {
use generic-service
host_name gate
service_description Zombie Processes
</p>
<div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
-<span class="org-type">define service</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define service</span> {
use generic-service
host_name gate
service_description Swap Usage
</p>
<div class="org-src-container">
-<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code>
-<span class="org-type">define service</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><code><span class="org-type">define service</span> {
use generic-service
host_name gate
service_description Temperature Sensors
</div>
</div>
</div>
-<div id="outline-container-org3b45f29" class="outline-3">
-<h3 id="org3b45f29"><span class="section-number-3">8.22.</span> Configure Backups</h3>
+<div id="outline-container-org937e8a9" class="outline-3">
+<h3 id="org937e8a9"><span class="section-number-3">8.22.</span> Configure Backups</h3>
<div class="outline-text-3" id="text-8-22">
<p>
The following task installs the <q>backup</q> script from <a href="private/"><q>private/</q></a>. An
-example script is provided in <a href="#orgf87535e">here</a>.
+example script is provided in <a href="#orgadc4dfb">here</a>.
</p>
<div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install backup script.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install backup script.
become: yes
copy:
src: ../private/backup
</div>
</div>
</div>
-<div id="outline-container-org2bd90fb" class="outline-3">
-<h3 id="org2bd90fb"><span class="section-number-3">8.23.</span> Configure Nextcloud</h3>
+<div id="outline-container-org2558d39" class="outline-3">
+<h3 id="org2558d39"><span class="section-number-3">8.23.</span> Configure Nextcloud</h3>
<div class="outline-text-3" id="text-8-23">
<p>
Core runs Nextcloud to provide a private institute cloud, as described
-in <a href="#org389cdda">The Cloud Service</a>. Installing, restoring (from backup), and
+in <a href="#org772ac50">The Cloud Service</a>. Installing, restoring (from backup), and
upgrading Nextcloud are manual processes documented in <a href="https://docs.nextcloud.com/server/stable/admin_manual/maintenance/">The Nextcloud
Admin Manual, Maintenance</a>. However Ansible can help prepare Core
before an install or restore, and perform basic security checks
afterwards.
</p>
</div>
-<div id="outline-container-org26c6d0e" class="outline-4">
-<h4 id="org26c6d0e"><span class="section-number-4">8.23.1.</span> Prepare Core For Nextcloud</h4>
+<div id="outline-container-orgca014c9" class="outline-4">
+<h4 id="orgca014c9"><span class="section-number-4">8.23.1.</span> Prepare Core For Nextcloud</h4>
<div class="outline-text-4" id="text-8-23-1">
<p>
The Ansible code contained herein prepares Core to run Nextcloud by
</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"><code>
-- name: Install packages required by Nextcloud.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install packages required by Nextcloud.
become: yes
apt:
pkg: [ apache2, mariadb-server, php, php-apcu, php-bcmath,
</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"><code>
-- name: Enable Apache2 modules for Nextcloud.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Enable Apache2 modules for Nextcloud.
become: yes
apache2_module:
name: <span class="org-string">"{{ item }}"</span>
</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"><code>
-- name: Install Nextcloud web configuration.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Nextcloud web configuration.
become: yes
copy:
src: nextcloud.conf
</p>
<div class="org-src-container">
-<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf"><code>
-<Directory /var/www/html/>
+<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf"><code><Directory /var/www/html/>
<IfModule mod_rewrite.c>
RewriteEngine on
<span class="org-comment-delimiter"># </span><span class="org-comment">LogLevel alert rewrite:trace3</span>
</p>
<div class="org-src-container">
-<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf"><code>
-<IfModule mod_headers.c>
+<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf"><code><IfModule mod_headers.c>
Header always set \
Strict-Transport-Security <span class="org-string">"max-age=15552000; includeSubDomains"</span>
</IfModule>
</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"><code>
-- name: Add {{ ansible_user }} to web server group.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Add {{ ansible_user }} to web server group.
become: yes
user:
name: <span class="org-string">"{{ ansible_user }}"</span>
</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"><code>
-- name: Create Nextcloud cron job.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Create Nextcloud cron job.
become: yes
cron:
minute: 11,26,41,56
</p>
<div class="org-src-container">
-<pre class="src src-conf"><code>
-- name: Create Nextcloud DB.
+<pre class="src src-conf"><code>- name: Create Nextcloud DB.
become: yes
mysql_db:
check_implicit_admin: yes
</p>
<div class="org-src-container">
-<pre class="src src-conf"><code>
-- name: Create Nextcloud DB user.
+<pre class="src src-conf"><code>- name: Create Nextcloud DB user.
become: yes
mysql_user:
check_implicit_admin: yes
</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"><code>
-- name: Link /var/www/nextcloud.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Link /var/www/nextcloud.
become: yes
file:
path: /var/www/nextcloud
</div>
</div>
</div>
-<div id="outline-container-org2229684" class="outline-4">
-<h4 id="org2229684"><span class="section-number-4">8.23.2.</span> Configure PHP</h4>
+<div id="outline-container-org0e74a84" class="outline-4">
+<h4 id="org0e74a84"><span class="section-number-4">8.23.2.</span> Configure PHP</h4>
<div class="outline-text-4" id="text-8-23-2">
<p>
The following tasks set a number of PHP parameters for better
</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"><code>
-- name: Set PHP memory_limit for Nextcloud.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Set PHP memory_limit for Nextcloud.
become: yes
lineinfile:
path: /etc/php/8.2/apache2/php.ini
</div>
</div>
</div>
-<div id="outline-container-org04d7161" class="outline-4">
-<h4 id="org04d7161"><span class="section-number-4">8.23.3.</span> Create <q>/Nextcloud/</q></h4>
+<div id="outline-container-org5cca880" class="outline-4">
+<h4 id="org5cca880"><span class="section-number-4">8.23.3.</span> Create <q>/Nextcloud/</q></h4>
<div class="outline-text-4" id="text-8-23-3">
<p>
The Ansible tasks up to this point have completed Core's LAMP stack
</div>
</div>
</div>
-<div id="outline-container-orgf6b8a57" class="outline-4">
-<h4 id="orgf6b8a57"><span class="section-number-4">8.23.4.</span> Restore Nextcloud</h4>
+<div id="outline-container-org14483bf" class="outline-4">
+<h4 id="org14483bf"><span class="section-number-4">8.23.4.</span> Restore Nextcloud</h4>
<div class="outline-text-4" id="text-8-23-4">
<p>
Restoring Nextcloud in the newly created <q>/Nextcloud/</q> presumably
</p>
</div>
</div>
-<div id="outline-container-orgb6f2431" class="outline-4">
-<h4 id="orgb6f2431"><span class="section-number-4">8.23.5.</span> Install Nextcloud</h4>
+<div id="outline-container-org86deebd" class="outline-4">
+<h4 id="org86deebd"><span class="section-number-4">8.23.5.</span> Install Nextcloud</h4>
<div class="outline-text-4" id="text-8-23-5">
<p>
Installing Nextcloud in the newly created <q>/Nextcloud/</q> starts with
</p>
</div>
</div>
-<div id="outline-container-orge79c42a" class="outline-4">
-<h4 id="orge79c42a"><span class="section-number-4">8.23.6.</span> Afterwards</h4>
+<div id="outline-container-org7f50b94" class="outline-4">
+<h4 id="org7f50b94"><span class="section-number-4">8.23.6.</span> Afterwards</h4>
<div class="outline-text-4" id="text-8-23-6">
<p>
Whether Nextcloud was restored or installed, there are a few things
</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"><code>
-- name: Test for /Nextcloud/nextcloud/.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Test for /Nextcloud/nextcloud/.
stat:
path: /Nextcloud/nextcloud
register: nextcloud
</p>
<div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Configure Nextcloud trusted domains.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure Nextcloud trusted domains.
become: yes
replace:
path: /var/www/nextcloud/config/config.php
</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"><code>
-- name: Configure Nextcloud memcache.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure Nextcloud memcache.
become: yes
lineinfile:
path: /var/www/nextcloud/config/config.php
</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"><code>
-- name: Configure Nextcloud for Pretty URLs.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure Nextcloud for Pretty URLs.
become: yes
lineinfile:
path: /var/www/nextcloud/config/config.php
</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"><code>
-- name: Configure Nextcloud settings.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure Nextcloud settings.
become: yes
lineinfile:
path: /var/www/nextcloud/config/config.php
</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"><code>
-- name: Create /Nextcloud/dbbackup.cnf.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Create /Nextcloud/dbbackup.cnf.
no_log: yes
become: yes
copy:
</div>
</div>
</div>
-<div id="outline-container-orgb8b1253" class="outline-2">
-<h2 id="orgb8b1253"><span class="section-number-2">9.</span> The Gate Role</h2>
+<div id="outline-container-orge89e8f0" class="outline-2">
+<h2 id="orge89e8f0"><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:
access to the private Ethernet from the untrusted Ethernet (e.g. a
campus Wi-Fi AP) via VPN, and access to the Internet via NAT. The
-gate machine uses three network interfaces (see <a href="#orge906ba2">The Gate Machine</a>)
+gate machine uses three network interfaces (see <a href="#orgfbe1689">The Gate Machine</a>)
configured with persistent names used in its firewall rules.
</p>
configurations, etc.
</p>
</div>
-<div id="outline-container-orga370688" class="outline-3">
-<h3 id="orga370688"><span class="section-number-3">9.1.</span> Role Defaults</h3>
+<div id="outline-container-org15d1cf7" class="outline-3">
+<h3 id="org15d1cf7"><span class="section-number-3">9.1.</span> Role Defaults</h3>
<div class="outline-text-3" id="text-9-1">
<p>
-As in <a href="#org264af3e">The Core Role</a>, the <code>gate</code> role sets a number of variables to
+As in <a href="#org60f2710">The Core Role</a>, the <code>gate</code> role sets a number of variables to
default values in its <q>defaults/main.yml</q> file.
</p>
<div class="org-src-container">
<a href="roles_t/gate/defaults/main.yml"><q>roles_t/gate/defaults/main.yml</q></a><pre class="src src-conf"><code>---
<<network-vars>>
+
<<address-vars>>
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-org276141d" class="outline-3">
-<h3 id="org276141d"><span class="section-number-3">9.2.</span> Include Particulars</h3>
+<div id="outline-container-orgc9abc22" class="outline-3">
+<h3 id="orgc9abc22"><span class="section-number-3">9.2.</span> Include Particulars</h3>
<div class="outline-text-3" id="text-9-2">
<p>
The following should be familiar boilerplate by now.
</div>
</div>
</div>
-<div id="outline-container-orgbb16e96" class="outline-3">
-<h3 id="orgbb16e96"><span class="section-number-3">9.3.</span> Configure Gate NetworkD</h3>
+<div id="outline-container-orga5f0cfe" class="outline-3">
+<h3 id="orga5f0cfe"><span class="section-number-3">9.3.</span> Configure Gate NetworkD</h3>
<div class="outline-text-3" id="text-9-3">
<p>
Gate's network interfaces are configured by <q>.link</q> and <q>.network</q>
<p>
Note that the <q>.network</q> files do not use the interface names for
-reasons discussed in the <a href="#org87bd414">8.5</a> section.
+reasons discussed in the <a href="#orgc54fe96">8.5</a> section.
</p>
<p>
configuration files.
</p>
</div>
-<div id="outline-container-org39516f3" class="outline-4">
-<h4 id="org39516f3"><span class="section-number-4">9.3.1.</span> Gate's <code>lan</code> Interface</h4>
+<div id="outline-container-orga600fa8" class="outline-4">
+<h4 id="orga600fa8"><span class="section-number-4">9.3.1.</span> Gate's <code>lan</code> Interface</h4>
<div class="outline-text-4" id="text-9-3-1">
<p>
The campus Ethernet interface is named <code>lan</code> and configured by
</p>
<div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install 10-lan.link.
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install 10-lan.link.
become: yes
copy:
content: |
</div>
</div>
</div>
-<div id="outline-container-orga407149" class="outline-4">
-<h4 id="orga407149"><span class="section-number-4">9.3.2.</span> Gate's <code>wild</code> Interface</h4>
+<div id="outline-container-orgacded99" class="outline-4">
+<h4 id="orgacded99"><span class="section-number-4">9.3.2.</span> Gate's <code>wild</code> Interface</h4>
<div class="outline-text-4" id="text-9-3-2">
<p>
The institute keeps the wild ones off the campus Ethernet. Its wild
</p>
<div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install 10-wild.link.
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install 10-wild.link.
become: yes
copy:
content: |
</div>
</div>
</div>
-<div id="outline-container-org23a38a1" class="outline-4">
-<h4 id="org23a38a1"><span class="section-number-4">9.3.3.</span> Gate's <code>isp</code> Interface</h4>
+<div id="outline-container-orgb058dbd" class="outline-4">
+<h4 id="orgb058dbd"><span class="section-number-4">9.3.3.</span> Gate's <code>isp</code> Interface</h4>
<div class="outline-text-4" id="text-9-3-3">
<p>
The interface to the campus ISP is named <code>isp</code> and configured by
</p>
<div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install 10-isp.link.
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install 10-isp.link.
become: yes
copy:
content: |
</div>
</div>
</div>
-<div id="outline-container-org4904624" class="outline-3">
-<h3 id="org4904624"><span class="section-number-3">9.4.</span> Configure Gate ResolveD</h3>
+<div id="outline-container-org80f5012" class="outline-3">
+<h3 id="org80f5012"><span class="section-number-3">9.4.</span> Configure Gate ResolveD</h3>
<div class="outline-text-3" id="text-9-4">
<p>
Gate provides name service on the wild Ethernet by having its "stub
</p>
<div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Configure resolved.
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure resolved.
become: yes
lineinfile:
path: /etc/systemd/resolved.conf
</div>
<div class="org-src-container">
-<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf"><code>
-- name: Reload Systemd.
+<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload Systemd.
become: yes
systemd:
daemon-reload: yes
</div>
</div>
</div>
-<div id="outline-container-orgcdebc22" class="outline-3">
-<h3 id="orgcdebc22"><span class="section-number-3">9.5.</span> UFW Rules</h3>
+<div id="outline-container-org7ed94c5" class="outline-3">
+<h3 id="org7ed94c5"><span class="section-number-3">9.5.</span> UFW Rules</h3>
<div class="outline-text-3" id="text-9-5">
<p>
Gate uses the Uncomplicated FireWall (UFW) to install its packet
</p>
<div class="org-src-container">
-<code>ufw-nat</code><pre class="src src-conf" id="orgfe6b889"><code>-A POSTROUTING -s {{ private_net_cidr }} -o isp -j MASQUERADE
+<code>ufw-nat</code><pre class="src src-conf" id="org80d97ce"><code>-A POSTROUTING -s {{ private_net_cidr }} -o isp -j MASQUERADE
-A POSTROUTING -s {{ wild_net_cidr }} -o isp -j MASQUERADE
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>ufw-forward-nat</code><pre class="src src-conf" id="org955e99e"><code>-A ufw-before-forward -i lan -o isp -j ACCEPT
+<code>ufw-forward-nat</code><pre class="src src-conf" id="org845735d"><code>-A ufw-before-forward -i lan -o isp -j ACCEPT
-A ufw-before-forward -i wild -o isp -j ACCEPT
</code></pre>
</div>
</p>
<div class="org-src-container">
-<code>ufw-forward-private</code><pre class="src src-conf" id="orgd2649ac"><code>-A ufw-before-forward -i lan -o wg0 -j ACCEPT
+<code>ufw-forward-private</code><pre class="src src-conf" id="org7bbf7ab"><code>-A ufw-before-forward -i lan -o wg0 -j ACCEPT
-A ufw-before-forward -i wg0 -o lan -j ACCEPT
-A ufw-before-forward -i wg0 -o wg0 -j ACCEPT
</code></pre>
</p>
</div>
</div>
-<div id="outline-container-org52994f0" class="outline-3">
-<h3 id="org52994f0"><span class="section-number-3">9.6.</span> Configure UFW</h3>
+<div id="outline-container-orgbffa8a8" class="outline-3">
+<h3 id="orgbffa8a8"><span class="section-number-3">9.6.</span> Configure UFW</h3>
<div class="outline-text-3" id="text-9-6">
<p>
The following tasks install the Uncomplicated Firewall (UFW), set its
</p>
<div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install UFW.
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install UFW.
become: yes
<span class="org-variable-name">apt: pkg</span>=ufw
</div>
</div>
</div>
-<div id="outline-container-orgf51aad2" class="outline-3">
-<h3 id="orgf51aad2"><span class="section-number-3">9.7.</span> Configure Campus WireGuard™ Subnet</h3>
+<div id="outline-container-org408aa54" class="outline-3">
+<h3 id="org408aa54"><span class="section-number-3">9.7.</span> Configure Campus WireGuard™ Subnet</h3>
<div class="outline-text-3" id="text-9-7">
<p>
Gate uses WireGuard™ to provide a campus VPN service. Gate's routes
</p>
<div class="org-src-container">
-<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Enable IP forwarding.
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Enable IP forwarding.
become: yes
copy:
content: <span class="org-string">"net.ipv4.ip_forward = 1\n"</span>
</div>
<div class="org-src-container">
-<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf"><code>
-- name: Reload sysctl.
+<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload sysctl.
become: yes
systemd:
service: systemd-sysctl
</code></pre>
</div>
</div>
-<div id="outline-container-org8e07390" class="outline-4">
-<h4 id="org8e07390"><span class="section-number-4">9.7.1.</span> Example <q>private/gate-wg0.conf</q></h4>
+<div id="outline-container-org0d5c1e0" class="outline-4">
+<h4 id="org0d5c1e0"><span class="section-number-4">9.7.1.</span> Example <q>private/gate-wg0.conf</q></h4>
<div class="outline-text-4" id="text-9-7-1">
<p>
The example <q>private/gate-wg0.conf</q> below recognizes a wired IoT
</div>
</div>
</div>
-<div id="outline-container-orgf4b9188" class="outline-2">
-<h2 id="orgf4b9188"><span class="section-number-2">10.</span> The Campus Role</h2>
+<div id="outline-container-orgec23e39" class="outline-2">
+<h2 id="orgec23e39"><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
client</code> command which updates the WireGuard™ configuration on Gate.
</p>
</div>
-<div id="outline-container-orge095902" class="outline-3">
-<h3 id="orge095902"><span class="section-number-3">10.1.</span> Role Defaults</h3>
+<div id="outline-container-orgd58909c" class="outline-3">
+<h3 id="orgd58909c"><span class="section-number-3">10.1.</span> Role Defaults</h3>
<div class="outline-text-3" id="text-10-1">
<p>
-As in <a href="#orgb8b1253">The Gate Role</a>, the <code>campus</code> role sets a number of variables to
+As in <a href="#orge89e8f0">The Gate Role</a>, the <code>campus</code> role sets a number of variables to
default values in its <q>defaults/main.yml</q> file.
</p>
<div class="org-src-container">
<a href="roles_t/campus/defaults/main.yml"><q>roles_t/campus/defaults/main.yml</q></a><pre class="src src-conf"><code>---
<<network-vars>>
+
<<address-vars>>
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-orgceb19a3" class="outline-3">
-<h3 id="orgceb19a3"><span class="section-number-3">10.2.</span> Include Particulars</h3>
+<div id="outline-container-orgbc808fd" class="outline-3">
+<h3 id="orgbc808fd"><span class="section-number-3">10.2.</span> Include Particulars</h3>
<div class="outline-text-3" id="text-10-2">
<p>
The following should be familiar boilerplate by now.
</div>
</div>
</div>
-<div id="outline-container-orga0f1ba7" class="outline-3">
-<h3 id="orga0f1ba7"><span class="section-number-3">10.3.</span> Configure Hostname</h3>
+<div id="outline-container-org8b8ffcb" class="outline-3">
+<h3 id="org8b8ffcb"><span class="section-number-3">10.3.</span> Configure Hostname</h3>
<div class="outline-text-3" id="text-10-3">
<p>
Clients should be using the expected host name.
</p>
<div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Configure hostname.
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Configure hostname.
become: yes
copy:
content: <span class="org-string">"{{ item.content }}"</span>
</div>
</div>
</div>
-<div id="outline-container-org8a1c01a" class="outline-3">
-<h3 id="org8a1c01a"><span class="section-number-3">10.4.</span> Configure Systemd Timesyncd</h3>
+<div id="outline-container-orgd85c0fd" class="outline-3">
+<h3 id="orgd85c0fd"><span class="section-number-3">10.4.</span> Configure Systemd Timesyncd</h3>
<div class="outline-text-3" id="text-10-4">
<p>
The institute uses a common time reference throughout the campus.
</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"><code>
-- name: Install timesyncd.
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install timesyncd.
become: yes
<span class="org-variable-name">apt: pkg</span>=systemd-timesyncd
</div>
</div>
</div>
-<div id="outline-container-org902a898" class="outline-3">
-<h3 id="org902a898"><span class="section-number-3">10.5.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-org60fed13" class="outline-3">
+<h3 id="org60fed13"><span class="section-number-3">10.5.</span> Add Administrator to System Groups</h3>
<div class="outline-text-3" id="text-10-5">
<p>
The administrator often needs to read (directories of) log files owned
</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"><code>
-- name: Add {{ ansible_user }} to system groups.
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Add {{ ansible_user }} to system groups.
become: yes
user:
name: <span class="org-string">"{{ ansible_user }}"</span>
</div>
</div>
</div>
-<div id="outline-container-org4288431" class="outline-3">
-<h3 id="org4288431"><span class="section-number-3">10.6.</span> Install Unattended Upgrades</h3>
+<div id="outline-container-orgf9b7426" class="outline-3">
+<h3 id="orgf9b7426"><span class="section-number-3">10.6.</span> Install Unattended Upgrades</h3>
<div class="outline-text-3" id="text-10-6">
<p>
The institute prefers to install security updates as soon as possible.
</p>
<div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install basic software.
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install basic software.
become: yes
<span class="org-variable-name">apt: pkg</span>=unattended-upgrades
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-org942e4f6" class="outline-3">
-<h3 id="org942e4f6"><span class="section-number-3">10.7.</span> Configure Postfix on Campus</h3>
+<div id="outline-container-org4dca998" class="outline-3">
+<h3 id="org4dca998"><span class="section-number-3">10.7.</span> Configure Postfix on Campus</h3>
<div class="outline-text-3" id="text-10-7">
<p>
The Postfix settings used by the campus include message size, queue
</ul>
<div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install Postfix.
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install Postfix.
become: yes
<span class="org-variable-name">apt: pkg</span>=postfix
</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"><code>
-- name: Restart Postfix.
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Restart Postfix.
become: yes
systemd:
service: postfix
</div>
</div>
</div>
-<div id="outline-container-org7062ccb" class="outline-3">
-<h3 id="org7062ccb"><span class="section-number-3">10.8.</span> Set Domain Name</h3>
+<div id="outline-container-org75ec345" class="outline-3">
+<h3 id="org75ec345"><span class="section-number-3">10.8.</span> Set Domain Name</h3>
<div class="outline-text-3" id="text-10-8">
<p>
The host's fully qualified (private) domain name (FQDN) is set by an
</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"><code>
-- name: Set domain name.
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Set domain name.
become: yes
vars:
host: <span class="org-string">"{{ inventory_hostname }}"</span>
</div>
</div>
</div>
-<div id="outline-container-org0d2271c" class="outline-3">
-<h3 id="org0d2271c"><span class="section-number-3">10.9.</span> Configure NRPE</h3>
+<div id="outline-container-org9fbfb95" class="outline-3">
+<h3 id="org9fbfb95"><span class="section-number-3">10.9.</span> Configure NRPE</h3>
<div class="outline-text-3" id="text-10-9">
<p>
Each campus host runs an NRPE (a NAGIOS Remote Plugin Executor)
server so that the NAGIOS4 server on Core can collect statistics. The
-NAGIOS service is discussed in the <a href="#org0d2271c">Configure NRPE</a> section of <a href="#org264af3e">The Core
+NAGIOS service is discussed in the <a href="#org9fbfb95">Configure NRPE</a> section of <a href="#org60f2710">The Core
Role</a>.
</p>
<div class="org-src-container">
-<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install NRPE.
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install NRPE.
become: yes
apt:
pkg: [ nagios-nrpe-server, lm-sensors ]
</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"><code>
-- name: Reload NRPE server.
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Reload NRPE server.
become: yes
systemd:
service: nagios-nrpe-server
</div>
</div>
</div>
-<div id="outline-container-orgb99caba" class="outline-2">
-<h2 id="orgb99caba"><span class="section-number-2">11.</span> The Ansible Configuration</h2>
+<div id="outline-container-org287b3e3" class="outline-2">
+<h2 id="org287b3e3"><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
role(s) to each host. Examples of these files are included here, and
are used to test the roles. The example configuration applies the
institutional roles to VirtualBox machines prepared according to
-chapter <a href="#orga52c0d9">Testing</a>.
+chapter <a href="#org74edc30">Testing</a>.
</p>
<p>
separate revision history.
</p>
</div>
-<div id="outline-container-orgf5d2ded" class="outline-3">
-<h3 id="orgf5d2ded"><span class="section-number-3">11.1.</span> <q>ansible.cfg</q></h3>
+<div id="outline-container-orgccf288a" class="outline-3">
+<h3 id="orgccf288a"><span class="section-number-3">11.1.</span> <q>ansible.cfg</q></h3>
<div class="outline-text-3" id="text-11-1">
<p>
The Ansible configuration file <a href="ansible.cfg"><q>ansible.cfg</q></a> contains just a handful
of settings, some included just to create a test jig as described in
-<a href="#orga52c0d9">Testing</a>.
+<a href="#org74edc30">Testing</a>.
</p>
<ul class="org-ul">
that Python 3 can be expected on all institute hosts.</li>
<li><code>vault_password_file</code> is set to suppress prompts for the vault
password. The institute keeps its vault password in <a href="Secret/"><q>Secret/</q></a> (as
-described in <a href="#org49a7a21">Keys</a>) and thus sets this parameter to
+described in <a href="#org6faddb7">Keys</a>) and thus sets this parameter to
<a href="Secret/vault-password"><q>Secret/vault-password</q></a>.</li>
<li><code>inventory</code> is set to avoid specifying it on the command line.</li>
<li><code>roles_path</code> is set to the recently tangled roles files in
</div>
</div>
</div>
-<div id="outline-container-org06dd17d" class="outline-3">
-<h3 id="org06dd17d"><span class="section-number-3">11.2.</span> <q>hosts</q></h3>
+<div id="outline-container-org2179c8c" class="outline-3">
+<h3 id="org2179c8c"><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
</p>
<div class="org-src-container">
-<a href="hosts"><q>hosts</q></a><pre class="src src-conf" id="org5bba1a7"><code>all:
+<a href="hosts"><q>hosts</q></a><pre class="src src-conf" id="orgf3e619a"><code>all:
vars:
ansible_user: sysadm
ansible_ssh_extra_args: -i Secret/ssh_admin/id_ed25519
</p>
</div>
</div>
-<div id="outline-container-orgbcbc838" class="outline-3">
-<h3 id="orgbcbc838"><span class="section-number-3">11.3.</span> <q>playbooks/site.yml</q></h3>
+<div id="outline-container-orge03cabe" class="outline-3">
+<h3 id="orge03cabe"><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
</div>
</div>
</div>
-<div id="outline-container-org10c0f2b" class="outline-3">
-<h3 id="org10c0f2b"><span class="section-number-3">11.4.</span> <q>Secret/vault-password</q></h3>
+<div id="outline-container-orgdca0313" class="outline-3">
+<h3 id="orgdca0313"><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
</p>
<div class="org-src-container">
-<a href="Secret/vault-password"><q>Secret/vault-password</q></a><pre class="src src-conf" id="org822842e"><code>alitysortstagess
+<a href="Secret/vault-password"><q>Secret/vault-password</q></a><pre class="src src-conf" id="orgeee75a8"><code>alitysortstagess
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-orgc34c9ce" class="outline-3">
-<h3 id="orgc34c9ce"><span class="section-number-3">11.5.</span> Creating A Working Ansible Configuration</h3>
+<div id="outline-container-org453f75b" class="outline-3">
+<h3 id="org453f75b"><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="#orga52c0d9">Testing</a> chapter. The
+produce the test configuration described in the <a href="#org74edc30">Testing</a> chapter. The
tangling is done by Emacs's <code>org-babel-tangle</code> function and has
already been performed with the resulting tangle included in the
distribution with this document.
<q>public/</q> and <q>private/</q>.</li>
<li><q>~/network/Secret</q> would be a symbolic link to the (auto-mounted?)
location of the administrator's encrypted USB drive, as described in
-section <a href="#org49a7a21">Keys</a>.</li>
+section <a href="#org6faddb7">Keys</a>.</li>
</ul>
<p>
</div>
</div>
</div>
-<div id="outline-container-org38aff7d" class="outline-3">
-<h3 id="org38aff7d"><span class="section-number-3">11.6.</span> Maintaining A Working Ansible Configuration</h3>
+<div id="outline-container-org7c51188" class="outline-3">
+<h3 id="org7c51188"><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
</div>
</div>
</div>
-<div id="outline-container-org219b1f0" class="outline-2">
-<h2 id="org219b1f0"><span class="section-number-2">12.</span> The Institute Commands</h2>
+<div id="outline-container-org072ccf4" class="outline-2">
+<h2 id="org072ccf4"><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
to get their defaults from <q>./ansible.cfg</q>.
</p>
</div>
-<div id="outline-container-org89e47d3" class="outline-3">
-<h3 id="org89e47d3"><span class="section-number-3">12.1.</span> Sub-command Blocks</h3>
+<div id="outline-container-orgd1ddb64" class="outline-3">
+<h3 id="orgd1ddb64"><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
</div>
</div>
</div>
-<div id="outline-container-org30853b3" class="outline-3">
-<h3 id="org30853b3"><span class="section-number-3">12.2.</span> Sanity Check</h3>
+<div id="outline-container-orgb1ed2d3" class="outline-3">
+<h3 id="orgb1ed2d3"><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
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">sub</span> <span class="org-function-name">note_missing_file_p</span> ($);
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">sub</span> <span class="org-function-name">note_missing_file_p</span> ($);
<span class="org-keyword">sub</span> <span class="org-function-name">note_missing_directory_p</span> ($);
{
</div>
</div>
</div>
-<div id="outline-container-org75ed9bc" class="outline-3">
-<h3 id="org75ed9bc"><span class="section-number-3">12.3.</span> Importing Ansible Variables</h3>
+<div id="outline-container-orgcf8ccd7" class="outline-3">
+<h3 id="orgcf8ccd7"><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
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-conf"><code>
-<span class="org-type">sub mysystem (@)</span> {
+<a href="inst"><q>inst</q></a><pre class="src src-conf"><code><span class="org-type">sub mysystem (@)</span> {
<span class="org-variable-name">my $line</span> = join (<span class="org-string">" "</span>, @_);
print <span class="org-string">"$line\n"</span>;
<span class="org-variable-name">my $status</span> = system $line;
</div>
</div>
</div>
-<div id="outline-container-orgd21308e" class="outline-3">
-<h3 id="orgd21308e"><span class="section-number-3">12.4.</span> The check-inst-vars Role</h3>
+<div id="outline-container-orgac32832" class="outline-3">
+<h3 id="orgac32832"><span class="section-number-3">12.4.</span> The check-inst-vars Role</h3>
<div class="outline-text-3" id="text-12-4">
<p>
This role is executed by <q>playbooks/check-inst-vars.yml</q> and is not
<div class="org-src-container">
<a href="roles_t/check-inst-vars/defaults/main.yml"><q>roles_t/check-inst-vars/defaults/main.yml</q></a><pre class="src src-conf"><code>---
<<network-vars>>
+
<<address-vars>>
</code></pre>
</div>
</p>
<div class="org-src-container">
-<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf" id="org4f55070"><code><span class="org-variable-name">front_wg_pubkey: S+6HaTnOwwhWgUGXjSBcPAvifKw+j8BDTRfq534gNW4</span>=
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf" id="org0cd0d4c"><code><span class="org-variable-name">front_wg_pubkey: S+6HaTnOwwhWgUGXjSBcPAvifKw+j8BDTRfq534gNW4</span>=
public_wg_port: 39608
<span class="org-variable-name">gate_wg_pubkey: y3cjFnvQbylmH4lGTujpqc8rusIElmJ4Gu9hh6iR7QI</span>=
</div>
</div>
</div>
-<div id="outline-container-org44eead9" class="outline-3">
-<h3 id="org44eead9"><span class="section-number-3">12.5.</span> The CA Command</h3>
+<div id="outline-container-orgc5697a5" class="outline-3">
+<h3 id="orgc5697a5"><span class="section-number-3">12.5.</span> The CA Command</h3>
<div class="outline-text-3" id="text-12-5">
<p>
The next code block implements the <code>CA</code> sub-command, which creates a
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] && $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"CA"</span>) {
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] && $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"CA"</span>) {
<span class="org-keyword">die</span> <span class="org-string">"usage: $0 CA"</span> <span class="org-keyword">if</span> @<span class="org-perl-non-scalar-variable">ARGV</span> != 1;
<span class="org-keyword">die</span> <span class="org-string">"Secret/CA/easyrsa: not an executable\n"</span>
<span class="org-keyword">if</span> ! -x <span class="org-string">"Secret/CA/easyrsa"</span>;
</div>
</div>
</div>
-<div id="outline-container-orge8d546d" class="outline-3">
-<h3 id="orge8d546d"><span class="section-number-3">12.6.</span> The Config Command</h3>
+<div id="outline-container-org4281d9c" class="outline-3">
+<h3 id="org4281d9c"><span class="section-number-3">12.6.</span> The Config Command</h3>
<div class="outline-text-3" id="text-12-6">
<p>
The next code block implements the <code>config</code> sub-command, which
</pre>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] && $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"config"</span>) {
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] && $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"config"</span>) {
<span class="org-keyword">die</span> <span class="org-string">"Secret/CA/easyrsa: not executable\n"</span>
<span class="org-keyword">if</span> ! -x <span class="org-string">"Secret/CA/easyrsa"</span>;
shift;
</div>
</div>
</div>
-<div id="outline-container-org8b8c94b" class="outline-3">
-<h3 id="org8b8c94b"><span class="section-number-3">12.7.</span> Account Management</h3>
+<div id="outline-container-org4bc24bc" class="outline-3">
+<h3 id="org4bc24bc"><span class="section-number-3">12.7.</span> Account Management</h3>
<div class="outline-text-3" id="text-12-7">
<p>
For general information about members and their Unix accounts, see
-<a href="#orge0ec564">Accounts</a>. The account management sub-commands maintain a mapping
+<a href="#orgcc441b8">Accounts</a>. The account management sub-commands maintain a mapping
associating member "usernames" (Unix account names) with their
records. The mapping is stored among other things in
<q>private/members.yml</q> as the value associated with the key <code>members</code>.
</p>
<div class="org-src-container">
-<code>membership-rolls</code><pre class="src src-conf" id="orgf1b6e04"><code>
-membership_rolls:
+<code>membership-rolls</code><pre class="src src-conf" id="org99dcc23"><code>membership_rolls:
- <span class="org-string">"../private/members.yml"</span>
- <span class="org-string">"../private/members-empty.yml"</span>
</code></pre>
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">use</span> <span class="org-constant">YAML::XS</span> qw<span class="org-string">(LoadFile DumpFile)</span>;
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">use</span> <span class="org-constant">YAML::XS</span> qw<span class="org-string">(LoadFile DumpFile)</span>;
<span class="org-keyword">sub</span> <span class="org-function-name">read_members_yaml</span> () {
<span class="org-keyword">my</span> $<span class="org-variable-name">path</span>;
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">sub</span> <span class="org-function-name">print_member</span> ($$$) {
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">sub</span> <span class="org-function-name">print_member</span> ($$$) {
<span class="org-keyword">my</span> ($<span class="org-variable-name">out</span>, $<span class="org-variable-name">username</span>, $<span class="org-variable-name">member</span>) = @<span class="org-perl-non-scalar-variable">_</span>;
print $<span class="org-variable-name">out</span> <span class="org-string">" "</span>, $<span class="org-variable-name">username</span>, <span class="org-string">":\n"</span>;
print $<span class="org-variable-name">out</span> <span class="org-string">" status: "</span>, $<span class="org-variable-name">member</span>->{<span class="org-string">"status"</span>}, <span class="org-string">"\n"</span>;
</div>
</div>
</div>
-<div id="outline-container-org9908aac" class="outline-3">
-<h3 id="org9908aac"><span class="section-number-3">12.8.</span> The New Command</h3>
+<div id="outline-container-org1231314" class="outline-3">
+<h3 id="org1231314"><span class="section-number-3">12.8.</span> The New Command</h3>
<div class="outline-text-3" id="text-12-8">
<p>
The next code block implements the <code>new</code> sub-command. It adds a new
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">sub</span> <span class="org-function-name">valid_username</span> (@);
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">sub</span> <span class="org-function-name">valid_username</span> (@);
<span class="org-keyword">sub</span> <span class="org-function-name">shell_escape</span> ($);
<span class="org-keyword">sub</span> <span class="org-function-name">strip_vault</span> ($);
</div>
</div>
</div>
-<div id="outline-container-orgc50a9b4" class="outline-3">
-<h3 id="orgc50a9b4"><span class="section-number-3">12.9.</span> The Pass Command</h3>
+<div id="outline-container-org298f842" class="outline-3">
+<h3 id="org298f842"><span class="section-number-3">12.9.</span> The Pass Command</h3>
<div class="outline-text-3" id="text-12-9">
<p>
The institute's <code>passwd</code> command on Core securely emails <code>root</code> with a
message is sent to <code>member@core</code>.
</p>
</div>
-<div id="outline-container-org736f166" class="outline-4">
-<h4 id="org736f166"><span class="section-number-4">12.9.1.</span> Less Aggressive passwd.</h4>
+<div id="outline-container-org4c6e5fe" class="outline-4">
+<h4 id="org4c6e5fe"><span class="section-number-4">12.9.1.</span> Less Aggressive passwd.</h4>
<div class="outline-text-4" id="text-12-9-1">
<p>
The next code block implements the less aggressive <code>passwd</code> command.
</div>
</div>
</div>
-<div id="outline-container-orge67b15e" class="outline-4">
-<h4 id="orge67b15e"><span class="section-number-4">12.9.2.</span> Less Aggressive Pass Command</h4>
+<div id="outline-container-org42b3241" class="outline-4">
+<h4 id="org42b3241"><span class="section-number-4">12.9.2.</span> Less Aggressive Pass Command</h4>
<div class="outline-text-4" id="text-12-9-2">
<p>
The following code block implements the <code>./inst pass</code> command, used by
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">use</span> <span class="org-constant">MIME::Base64</span>;
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">use</span> <span class="org-constant">MIME::Base64</span>;
<span class="org-keyword">sub</span> <span class="org-function-name">write_wireguard</span> ($);
<span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] && $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"pass"</span>) {
</div>
</div>
</div>
-<div id="outline-container-orgd656360" class="outline-4">
-<h4 id="orgd656360"><span class="section-number-4">12.9.3.</span> Installing the Less Aggressive passwd</h4>
+<div id="outline-container-orgb46cbbc" class="outline-4">
+<h4 id="orgb46cbbc"><span class="section-number-4">12.9.3.</span> Installing the Less Aggressive passwd</h4>
<div class="outline-text-4" id="text-12-9-3">
<p>
The following Ansible tasks install the less aggressive <code>passwd</code>
</p>
<div class="org-src-container">
-<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>
-- name: Install institute passwd command.
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf"><code>- name: Install institute passwd command.
become: yes
template:
src: passwd
</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"><code>
-- name: Import root PGP key.
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf"><code>- name: Import root PGP key.
become: no
command: gpg --import /etc/root-pub.pem
</code></pre>
</div>
</div>
</div>
-<div id="outline-container-org0a2776e" class="outline-3">
-<h3 id="org0a2776e"><span class="section-number-3">12.10.</span> The Old Command</h3>
+<div id="outline-container-org0c2bff0" class="outline-3">
+<h3 id="org0c2bff0"><span class="section-number-3">12.10.</span> The Old Command</h3>
<div class="outline-text-3" id="text-12-10">
<p>
The <code>old</code> command disables a member's account (and thus their clients).
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] && $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"old"</span>) {
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">if</span> (defined $<span class="org-variable-name">ARGV</span>[0] && $<span class="org-variable-name">ARGV</span>[0] eq <span class="org-string">"old"</span>) {
<span class="org-keyword">my</span> $<span class="org-variable-name">user</span> = valid_username (@<span class="org-perl-non-scalar-variable">ARGV</span>);
<span class="org-keyword">my</span> $<span class="org-variable-name">yaml</span> = read_members_yaml ();
<span class="org-keyword">my</span> $<span class="org-variable-name">members</span> = $<span class="org-variable-name">yaml</span>->{<span class="org-string">"members"</span>};
</div>
</div>
</div>
-<div id="outline-container-orgf253523" class="outline-3">
-<h3 id="orgf253523"><span class="section-number-3">12.11.</span> The Client Command</h3>
+<div id="outline-container-org7f55798" class="outline-3">
+<h3 id="org7f55798"><span class="section-number-3">12.11.</span> The Client Command</h3>
<div class="outline-text-3" id="text-12-11">
<p>
The <code>client</code> command registers the public key of a client wishing to
</div>
</div>
</div>
-<div id="outline-container-org4254078" class="outline-3">
-<h3 id="org4254078"><span class="section-number-3">12.12.</span> Institute Command Help</h3>
+<div id="outline-container-orgb8df8e2" class="outline-3">
+<h3 id="orgb8df8e2"><span class="section-number-3">12.12.</span> Institute Command Help</h3>
<div class="outline-text-3" id="text-12-12">
<p>
This should be the last block tangled into the <a href="inst"><q>inst</q></a> script. It
</p>
<div class="org-src-container">
-<a href="inst"><q>inst</q></a><pre class="src src-perl"><code>
-<span class="org-keyword">die</span> <span class="org-string">"usage: $0 [CA|config|new|pass|old|client] ...\n"</span>;
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><code><span class="org-keyword">die</span> <span class="org-string">"usage: $0 [CA|config|new|pass|old|client] ...\n"</span>;
</code></pre>
</div>
</div>
</div>
</div>
-<div id="outline-container-orga52c0d9" class="outline-2">
-<h2 id="orga52c0d9"><span class="section-number-2">13.</span> Testing</h2>
+<div id="outline-container-org74edc30" class="outline-2">
+<h2 id="org74edc30"><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
<p>
The next two sections list the steps taken to create the simulated
Core, Gate and Front machines, and connect them to their networks.
-The process is similar to that described in <a href="#orgc581563">The (Actual) Hardware</a>, but
+The process is similar to that described in <a href="#org2b6506b">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
site at <a href="https://www.virtualbox.org/manual/UserManual.html">https://www.virtualbox.org/manual/UserManual.html</a>.
</p>
</div>
-<div id="outline-container-org3473387" class="outline-3">
-<h3 id="org3473387"><span class="section-number-3">13.1.</span> The Test Networks</h3>
+<div id="outline-container-org357bf07" class="outline-3">
+<h3 id="org357bf07"><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>
</div>
</div>
-<div id="outline-container-org3093f37" class="outline-3">
-<h3 id="org3093f37"><span class="section-number-3">13.2.</span> The Test Machines</h3>
+<div id="outline-container-org6fea890" class="outline-3">
+<h3 id="org6fea890"><span class="section-number-3">13.2.</span> The Test Machines</h3>
<div class="outline-text-3" id="text-13-2">
<p>
The virtual machines are created by <code>VBoxManage</code> command lines in the
following sub-sections. They each start with a recent Debian release
(e.g. <q>debian-12.5.0-amd64-netinst.iso</q>) in their simulated DVD
-drives. Preparation of <a href="#orgc581563">The Hardware</a> installed additional software
+drives. Preparation of <a href="#org2b6506b">The Hardware</a> installed additional software
packages and keys while the machines had Internet access. They were
then moved to the new campus network where Ansible completed the
configuration without Internet access.
and restarting.
</p>
</div>
-<div id="outline-container-org3ba7dc7" class="outline-4">
-<h4 id="org3ba7dc7"><span class="section-number-4">13.2.1.</span> The Test Wireguard™ Keys <a id="orgf621e7c"></a></h4>
+<div id="outline-container-orga3cceb8" class="outline-4">
+<h4 id="orga3cceb8"><span class="section-number-4">13.2.1.</span> The Test Wireguard™ Keys <a id="org2781a52"></a></h4>
<div class="outline-text-4" id="text-13-2-1">
<p>
All of the private keys used in the example/test configuration are
</table>
</div>
</div>
-<div id="outline-container-org9fd3cb4" class="outline-4">
-<h4 id="org9fd3cb4"><span class="section-number-4">13.2.2.</span> Ansible Test Authorization</h4>
+<div id="outline-container-orgc3e23c6" class="outline-4">
+<h4 id="orgc3e23c6"><span class="section-number-4">13.2.2.</span> Ansible Test Authorization</h4>
<div class="outline-text-4" id="text-13-2-2">
<p>
Part of each machine's preparation is to authorize password-less SSH
</p>
<div class="org-src-container">
-<code>test-auth</code><pre class="src src-sh" id="org12d463a"><code>( <span class="org-builtin">cd</span>
+<code>test-auth</code><pre class="src src-sh" id="orgc4031e9"><code>( <span class="org-builtin">cd</span>
<span class="org-builtin">umask</span> 077
<span class="org-keyword">if</span> [ <span class="org-negation-char">!</span> -d .ssh ]; <span class="org-keyword">then</span> mkdir .ssh; <span class="org-keyword">fi</span>
( <span class="org-builtin">echo</span> -n <span class="org-string">"ssh-rsa"</span>
</div>
</div>
</div>
-<div id="outline-container-org3b352da" class="outline-4">
-<h4 id="org3b352da"><span class="section-number-4">13.2.3.</span> A Test Machine</h4>
+<div id="outline-container-org22fb5a5" class="outline-4">
+<h4 id="org22fb5a5"><span class="section-number-4">13.2.3.</span> A Test Machine</h4>
<div class="outline-text-4" id="text-13-2-3">
<p>
The following shell function contains most of the <code>VBoxManage</code>
</p>
</div>
</div>
-<div id="outline-container-orgf8cddd8" class="outline-4">
-<h4 id="orgf8cddd8"><span class="section-number-4">13.2.4.</span> The Test Front Machine</h4>
+<div id="outline-container-orgbae00d6" class="outline-4">
+<h4 id="orgbae00d6"><span class="section-number-4">13.2.4.</span> The Test Front Machine</h4>
<div class="outline-text-4" id="text-13-2-4">
<p>
The <code>front</code> machine is created with 512MiB of RAM, 4GiB of disk, and
</p>
<div class="org-src-container">
-<a href="private/test-front-prep"><q>private/test-front-prep</q></a><pre class="src src-sh"><code>
-( <span class="org-builtin">umask</span> 377
+<a href="private/test-front-prep"><q>private/test-front-prep</q></a><pre class="src src-sh"><code>( <span class="org-builtin">umask</span> 377
<span class="org-builtin">echo</span> <span class="org-string">"AJkzVxfTm/KvRjzTN/9X2jYy+CAugiwZfN5F3JTegms="</span> <span class="org-sh-escaped-newline">\</span>
| sudo tee /etc/wireguard/private-key >/dev/null )
</p>
<div class="org-src-container">
-<a href="private/test-front-prep"><q>private/test-front-prep</q></a><pre class="src src-sh"><code>
-( <span class="org-builtin">cd</span> /etc/network/; <span class="org-sh-escaped-newline">\</span>
+<a href="private/test-front-prep"><q>private/test-front-prep</q></a><pre class="src src-sh"><code>( <span class="org-builtin">cd</span> /etc/network/; <span class="org-sh-escaped-newline">\</span>
[ -f interfaces~ ] || sudo mv interfaces interfaces~ )
cat <<EOF | sudo tee /etc/network/interfaces >/dev/null
<span class="org-sh-heredoc"># This file describes the network interfaces available on your system</span>
</p>
<div class="org-src-container">
-<a href="private/test-front-prep"><q>private/test-front-prep</q></a><pre class="src src-sh"><code>
-( <span class="org-builtin">cd</span> front_ssh/; sudo cp -b ssh_host_* /etc/ssh/ )
+<a href="private/test-front-prep"><q>private/test-front-prep</q></a><pre class="src src-sh"><code>( <span class="org-builtin">cd</span> front_ssh/; sudo cp -b ssh_host_* /etc/ssh/ )
</code></pre>
</div>
The following <code>VBoxManage</code> commands effect the move, connecting the
primary NIC to <code>public</code> and a second NIC to the host-only network
<code>vboxnet2</code> (making it directly accessible to the administrator's
-notebook as described in <a href="#org3473387">The Test Networks</a>).
+notebook as described in <a href="#org357bf07">The Test Networks</a>).
</p>
<div class="org-src-container">
</p>
</div>
</div>
-<div id="outline-container-orgab80c9a" class="outline-4">
-<h4 id="orgab80c9a"><span class="section-number-4">13.2.5.</span> The Test Gate Machine</h4>
+<div id="outline-container-org5931c83" class="outline-4">
+<h4 id="org5931c83"><span class="section-number-4">13.2.5.</span> The Test Gate Machine</h4>
<div class="outline-text-4" id="text-13-2-5">
<p>
The <code>gate</code> machine is created with the same amount of RAM and disk as
</div>
<p>
-After Debian is installed (as detailed in <a href="#org3b352da">A Test Machine</a>) and the
+After Debian is installed (as detailed in <a href="#org22fb5a5">A Test Machine</a>) and the
machine rebooted, the administrator copies the following script to the
machine and executes it.
</p>
<a href="private/test-gate-prep"><q>private/test-gate-prep</q></a><pre class="src src-sh"><code><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
sudo apt install wireguard systemd-resolved unattended-upgrades <span class="org-sh-escaped-newline">\</span>
- postfix ufw lm-sensors nagios-nrpe-server
+ postfix ufw lm-sensors nagios-nrpe-server <span class="org-sh-escaped-newline">\</span>
+ munin-node emacs
</code></pre>
</div>
</p>
<div class="org-src-container">
-<a href="private/test-gate-prep"><q>private/test-gate-prep</q></a><pre class="src src-sh"><code>
-cat <<EOD | sudo tee /etc/systemd/network/10-lan.link >/dev/null
+<a href="private/test-gate-prep"><q>private/test-gate-prep</q></a><pre class="src src-sh"><code>cat <<EOD | sudo tee /etc/systemd/network/10-lan.link >/dev/null
<span class="org-sh-heredoc">[Match]</span>
<span class="org-sh-heredoc">MACAddress=08:00:27:f3:16:79</span>
</p>
</div>
</div>
-<div id="outline-container-orgdb01a99" class="outline-4">
-<h4 id="orgdb01a99"><span class="section-number-4">13.2.6.</span> The Test Core Machine</h4>
+<div id="outline-container-org27e07ba" class="outline-4">
+<h4 id="org27e07ba"><span class="section-number-4">13.2.6.</span> The Test Core Machine</h4>
<div class="outline-text-4" id="text-13-2-6">
<p>
The <code>core</code> machine is created with 1GiB of RAM and 6GiB of disk.
</div>
<p>
-After Debian is installed (as detailed in <a href="#org3b352da">A Test Machine</a>) and the
+After Debian is installed (as detailed in <a href="#org22fb5a5">A Test Machine</a>) and the
machine rebooted, the administrator copies the following script to the
machine and executes it.
</p>
</p>
<div class="org-src-container">
-<a href="private/test-core-prep"><q>private/test-core-prep</q></a><pre class="src src-sh"><code>
-cat <<EOD | sudo tee /etc/systemd/network/10-lan.link >/dev/null
+<a href="private/test-core-prep"><q>private/test-core-prep</q></a><pre class="src src-sh"><code>cat <<EOD | sudo tee /etc/systemd/network/10-lan.link >/dev/null
<span class="org-sh-heredoc">[Match]</span>
<span class="org-sh-heredoc">MACAddress=08:00:27:b3:e5:5f</span>
</div>
</div>
</div>
-<div id="outline-container-orgf736f93" class="outline-3">
-<h3 id="orgf736f93"><span class="section-number-3">13.3.</span> Configure Test Machines</h3>
+<div id="outline-container-orgd490aa7" class="outline-3">
+<h3 id="orgd490aa7"><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
</p>
</div>
</div>
-<div id="outline-container-org185f439" class="outline-3">
-<h3 id="org185f439"><span class="section-number-3">13.4.</span> Test Basics</h3>
+<div id="outline-container-org71c69ab" class="outline-3">
+<h3 id="org71c69ab"><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>,
</p>
</div>
</div>
-<div id="outline-container-org5728825" class="outline-3">
-<h3 id="org5728825"><span class="section-number-3">13.5.</span> The Test Nextcloud</h3>
+<div id="outline-container-org89c0119" class="outline-3">
+<h3 id="org89c0119"><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="#orgb6f2431">Install Nextcloud</a>. Once
+installed on <code>core</code> as described in <a href="#org86deebd">Install Nextcloud</a>. Once
<q>/Nextcloud/</q> is created, <code>./inst config core</code> will validate
or update its configuration files.
</p>
</p>
</div>
</div>
-<div id="outline-container-org04f7f13" class="outline-3">
-<h3 id="org04f7f13"><span class="section-number-3">13.6.</span> Test New Command</h3>
+<div id="outline-container-org066b6f2" class="outline-3">
+<h3 id="org066b6f2"><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
</p>
</div>
</div>
-<div id="outline-container-orgcb5ff30" class="outline-3">
-<h3 id="orgcb5ff30"><span class="section-number-3">13.7.</span> The Test Member Notebook</h3>
+<div id="outline-container-orgf7ee4a6" class="outline-3">
+<h3 id="orgf7ee4a6"><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,
</p>
<p>
-Debian is installed much as detailed in <a href="#org3b352da">A Test Machine</a> <i>except</i> that
+Debian is installed much as detailed in <a href="#org22fb5a5">A Test Machine</a> <i>except</i> that
the SSH server option is <i>not</i> needed and the GNOME desktop option
<i>is</i>. When the machine reboots, the administrator logs into the
desktop and installs a couple additional software packages (which
</div>
</div>
</div>
-<div id="outline-container-org5c2ece5" class="outline-3">
-<h3 id="org5c2ece5"><span class="section-number-3">13.8.</span> Test Client Command</h3>
+<div id="outline-container-org97ed2af" class="outline-3">
+<h3 id="org97ed2af"><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 register the public key of a
</div>
</div>
</div>
-<div id="outline-container-org16e738d" class="outline-3">
-<h3 id="org16e738d"><span class="section-number-3">13.9.</span> Test Campus WireGuard™ Subnet</h3>
+<div id="outline-container-orgd5744ff" class="outline-3">
+<h3 id="orgd5744ff"><span class="section-number-3">13.9.</span> Test Campus WireGuard™ Subnet</h3>
<div class="outline-text-3" id="text-13-9">
<p>
A few basic tests are then performed in a terminal.
</div>
</div>
</div>
-<div id="outline-container-orga9d6332" class="outline-3">
-<h3 id="orga9d6332"><span class="section-number-3">13.10.</span> Test Web Pages</h3>
+<div id="outline-container-org798cf08" class="outline-3">
+<h3 id="org798cf08"><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
</p>
</div>
</div>
-<div id="outline-container-org6c698c5" class="outline-3">
-<h3 id="org6c698c5"><span class="section-number-3">13.11.</span> Test Nextcloud</h3>
+<div id="outline-container-org1393481" class="outline-3">
+<h3 id="org1393481"><span class="section-number-3">13.11.</span> Test Nextcloud</h3>
<div class="outline-text-3" id="text-13-11">
<p>
Using the browser on the simulated member notebook, the Nextcloud
</ul>
</div>
</div>
-<div id="outline-container-orgb81a9f1" class="outline-3">
-<h3 id="orgb81a9f1"><span class="section-number-3">13.12.</span> Test Email</h3>
+<div id="outline-container-org1847126" class="outline-3">
+<h3 id="org1847126"><span class="section-number-3">13.12.</span> Test Email</h3>
<div class="outline-text-3" id="text-13-12">
<p>
With Evolution running on the member notebook <code>dick</code>, one second email
</p>
</div>
</div>
-<div id="outline-container-orgbec2047" class="outline-3">
-<h3 id="orgbec2047"><span class="section-number-3">13.13.</span> Test Public VPN</h3>
+<div id="outline-container-orgf34901c" class="outline-3">
+<h3 id="orgf34901c"><span class="section-number-3">13.13.</span> Test Public VPN</h3>
<div class="outline-text-3" id="text-13-13">
<p>
At this point, <code>dick</code> can move abroad, from the campus Wi-Fi
</p>
</div>
</div>
-<div id="outline-container-org9528cec" class="outline-3">
-<h3 id="org9528cec"><span class="section-number-3">13.14.</span> Test Pass Command</h3>
+<div id="outline-container-orga48a91c" class="outline-3">
+<h3 id="orga48a91c"><span class="section-number-3">13.14.</span> Test Pass Command</h3>
<div class="outline-text-3" id="text-13-14">
<p>
To test the <code>./inst pass</code> command, the administrator logs in to <code>core</code>
</p>
</div>
</div>
-<div id="outline-container-orga994875" class="outline-3">
-<h3 id="orga994875"><span class="section-number-3">13.15.</span> Test Old Command</h3>
+<div id="outline-container-orgb8ebaf6" class="outline-3">
+<h3 id="orgb8ebaf6"><span class="section-number-3">13.15.</span> Test Old Command</h3>
<div class="outline-text-3" id="text-13-15">
<p>
One more institute command is left to exercise. The administrator
</div>
</div>
</div>
-<div id="outline-container-org04df873" class="outline-2">
-<h2 id="org04df873"><span class="section-number-2">14.</span> Future Work</h2>
+<div id="outline-container-org69007e6" class="outline-2">
+<h2 id="org69007e6"><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-org7154c20" class="outline-3">
-<h3 id="org7154c20"><span class="section-number-3">14.1.</span> Deficiencies</h3>
+<div id="outline-container-orga603b8f" class="outline-3">
+<h3 id="orga603b8f"><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
</p>
</div>
</div>
-<div id="outline-container-org93ef5f2" class="outline-3">
-<h3 id="org93ef5f2"><span class="section-number-3">14.2.</span> More Tests</h3>
+<div id="outline-container-org5115b60" class="outline-3">
+<h3 id="org5115b60"><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-orgae7b885" class="outline-4">
-<h4 id="orgae7b885"><span class="section-number-4">14.2.1.</span> Backup</h4>
+<div id="outline-container-orgecab6e0" class="outline-4">
+<h4 id="orgecab6e0"><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
</p>
</div>
</div>
-<div id="outline-container-orgd09df1f" class="outline-4">
-<h4 id="orgd09df1f"><span class="section-number-4">14.2.2.</span> Restore</h4>
+<div id="outline-container-orgfe70fe2" class="outline-4">
+<h4 id="orgfe70fe2"><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>
</p>
</div>
</div>
-<div id="outline-container-org6ca2a7c" class="outline-4">
-<h4 id="org6ca2a7c"><span class="section-number-4">14.2.3.</span> Campus Disconnect</h4>
+<div id="outline-container-orgc50414b" class="outline-4">
+<h4 id="orgc50414b"><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… difficult to test unless
</div>
</div>
</div>
-<div id="outline-container-org06ad937" class="outline-2">
-<h2 id="org06ad937"><span class="section-number-2">15.</span> Appendix: The Bootstrap</h2>
+<div id="outline-container-org769d3c0" class="outline-2">
+<h2 id="org769d3c0"><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
get to the additional packages.
</p>
</div>
-<div id="outline-container-orgaff7fb7" class="outline-3">
-<h3 id="orgaff7fb7"><span class="section-number-3">15.1.</span> The Current Strategy</h3>
+<div id="outline-container-org4f87791" class="outline-3">
+<h3 id="org4f87791"><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="#orgc581563">The Hardware</a> is two phase: prepare the servers
+The strategy pursued in <a href="#org2b6506b">The Hardware</a> is two phase: prepare the servers
on the Internet where additional packages are accessible, then connect
them to the campus facilities (the private Ethernet switch, Wi-Fi AP,
ISP), manually configure IP addresses (while the DHCP client silently
</p>
</div>
</div>
-<div id="outline-container-orga8307c3" class="outline-3">
-<h3 id="orga8307c3"><span class="section-number-3">15.2.</span> Starting With Gate</h3>
+<div id="outline-container-org5f0d415" class="outline-3">
+<h3 id="org5f0d415"><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
</ul>
</div>
</div>
-<div id="outline-container-orgd31e7be" class="outline-3">
-<h3 id="orgd31e7be"><span class="section-number-3">15.3.</span> Pre-provision With Ansible</h3>
+<div id="outline-container-orged46089" class="outline-3">
+<h3 id="orged46089"><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
</div></div>
<div id="postamble" class="status">
<p class="author">Author: Matt Birkholz</p>
-<p class="date">Created: 2026-05-09 Sat 15:42</p>
+<p class="date">Created: 2026-06-15 Mon 11:36</p>
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>