"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
-<!-- 2023-12-17 Sun 16:05 -->
+<!-- 2023-12-28 Thu 16:07 -->
<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>
members off campus.
</p>
-<pre class="example" id="org6dd28f2">
+<pre class="example" id="org212bb48">
=
_|||_
=-The-Institute-=
<div class="outline-text-2" id="text-3">
<p>
The small institute's network is designed to provide a number of
-services. An understanding of how institute hosts co-operate is
-essential to understanding the configuration of specific hosts. This
-chapter covers institute services from a network wide perspective, and
-gets right down in its subsections to the Ansible code that enforces
-its policies. On first reading, those subsections should be skipped;
-they reference particulars first introduced in the following chapter.
+services. Understanding how institute hosts co-operate is essential
+to understanding the configuration of specific hosts. This chapter
+covers institute services from a network wide perspective, and gets
+right down in its subsections to the Ansible code that enforces its
+policies. On first reading, those subsections should be skipped; they
+reference particulars first introduced in the following chapter.
</p>
</div>
<div id="outline-container-org12ea1d0" class="outline-3">
to be the only legitimate sender of institute emails. Thus the
Internet sees the institute's outgoing email coming from a server at
an address matching the domain's SPF record. The institute does <i>not</i>
-sign outgoing emails per DKIM (Domain Keys Identified Mail), yet.
+sign outgoing emails per DKIM (Domain Keys Identified Mail) yet.
</p>
<div class="org-src-container">
Core provides a campus HTTP service with several virtual hosts.
These web sites can only be accessed via the campus Ethernet or an
institute VPN. In either situation Core's many private domain names
-become available, e.g. <q>www.small.private</q>. In many cases these
-domain names can be shortened e.g. to <q>www</q>. Thus the campus home
+become available, e.g. <code>www.small.private</code>. In many cases these
+domain names can be shortened e.g. to <code>www</code>. Thus the campus home
page is accessible in a dozen keystrokes: <code>http://www/</code> (plus Enter).
</p>
described in <a href="#org8d60b7b">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 <q>hosts</q>. Its password is specified by a
-vault-encrypted variable in the <q>Secret/become.yml</q> file. (The
-<q>hosts</q> and <q>Secret/become.yml</q> files are described in <a href="#orgff33e02">The Ansible
+value of <code>ansible_user</code> in <a href="hosts"><q>hosts</q></a>. Its password is specified by a
+vault-encrypted variable in the <a href="Secret/become.yml"><q>Secret/become.yml</q></a> file. (The
+<a href="hosts"><q>hosts</q></a> and <a href="Secret/become.yml"><q>Secret/become.yml</q></a> files are described in <a href="#orgff33e02">The Ansible
Configuration</a>.)
</p>
</div>
<p>
The institute keeps its "master secrets" in an encrypted
volume on an off-line hard drive, e.g. a LUKS (Linux Unified Key
-Setup) format partition on a USB pen/stick. The <q>Secret/</q>
+Setup) format partition on a USB pen/stick. The <a href="Secret/"><q>Secret/</q></a>
sub-directory is actually a symbolic link to this partition's
automatic mount point, e.g. <q>/media/sysadm/ADE7-F866/</q>. Unless this
-volume is mounted (unlocked) at <q>Secret/</q>, none of the <code>./inst</code>
+volume is mounted (unlocked) at <a href="Secret/"><q>Secret/</q></a>, none of the <code>./inst</code>
commands will work.
</p>
<p>
-Chief among the institute's master secrets is the SSH key to the
-privileged accounts on <i>all</i> of the institute servers. It is stored
-in <q>Secret/ssh_admin/id_rsa</q>. The institute uses several more SSH
-keys listed here:
+Chief among the institute's master secrets is the SSH key authorized
+to access privileged accounts on <i>all</i> of the institute servers. It
+is stored in <a href="Secret/ssh_admin/id_rsa"><q>Secret/ssh_admin/id_rsa</q></a>. The complete list of the
+institute's SSH keys:
</p>
<dl class="org-dl">
-<dt><q>Secret/ssh_admin/</q></dt><dd>The SSH key pair for A Small Institute
+<dt><a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a></dt><dd>The SSH key pair for A Small Institute
Administrator.</dd>
-<dt><q>Secret/ssh_monkey/</q></dt><dd>The key pair used by Monkey to update the
+<dt><a href="Secret/ssh_monkey/"><q>Secret/ssh_monkey/</q></a></dt><dd>The key pair used by Monkey to update the
website on Front (and other unprivileged tasks).</dd>
-<dt><q>Secret/ssh_front/</q></dt><dd>The host key pair used by Front to
-authenticate itself.</dd>
+<dt><a href="Secret/ssh_front/"><q>Secret/ssh_front/</q></a></dt><dd>The host key pair used by Front to
+authenticate itself. The automatically generated key pair is
+<i>not</i> used. (Thus Core's configuration does not depend on
+Front's.)</dd>
</dl>
<p>
The institute uses a number of X.509 certificates to authenticate VPN
clients and servers. They are created by the EasyRSA Certificate
-Authority stored in <q>Secret/CA/</q>.
+Authority stored in <a href="Secret/CA/"><q>Secret/CA/</q></a>.
</p>
<dl class="org-dl">
-<dt><q>Secret/CA/pki/ca.crt</q></dt><dd>The institute CA (certificate
-authority).</dd>
+<dt><a href="Secret/CA/pki/ca.crt"><q>Secret/CA/pki/ca.crt</q></a></dt><dd>The institute CA certificate, used to
+sign the other certificates.</dd>
-<dt><q>Secret/CA/pki/issued/small.example.org.crt</q></dt><dd>The public Apache,
+<dt><a href="Secret/CA/pki/issued/small.example.org.crt"><q>Secret/CA/pki/issued/small.example.org.crt</q></a></dt><dd>The public Apache,
Postfix, and OpenVPN servers on Front.</dd>
-<dt><q>Secret/CA/pki/issued/gate.small.private.crt</q></dt><dd>The campus
+<dt><a href="Secret/CA/pki/issued/gate.small.private.crt"><q>Secret/CA/pki/issued/gate.small.private.crt</q></a></dt><dd>The campus
OpenVPN server on Gate.</dd>
-<dt><q>Secret/CA/pki/issued/core.small.private.crt</q></dt><dd>The campus
+<dt><a href="Secret/CA/pki/issued/core.small.private.crt"><q>Secret/CA/pki/issued/core.small.private.crt</q></a></dt><dd>The campus
Apache (thus Nextcloud), and Dovecot-IMAPd servers.</dd>
-<dt><q>Secret/CA/pki/issued/core.crt</q></dt><dd>Core's client certificate by
+<dt><a href="Secret/CA/pki/issued/core.crt"><q>Secret/CA/pki/issued/core.crt</q></a></dt><dd>Core's client certificate, by
which it authenticates to Front.</dd>
</dl>
</p>
<dl class="org-dl">
-<dt><q>Secret/root.gnupg/</q></dt><dd>The "home directory" used to create the
+<dt><a href="Secret/root.gnupg/"><q>Secret/root.gnupg/</q></a></dt><dd>The "home directory" used to create the
public/secret key pair.</dd>
-<dt><q>Secret/root-pub.pem</q></dt><dd>The ASCII armored OpenPGP public key for
+<dt><a href="Secret/root-pub.pem"><q>Secret/root-pub.pem</q></a></dt><dd>The ASCII armored OpenPGP public key for
e.g. <code>root@core.small.private</code>.</dd>
-<dt><q>Secret/root-sec.pem</q></dt><dd>The ASCII armored OpenPGP secret key.</dd>
+<dt><a href="Secret/root-sec.pem"><q>Secret/root-sec.pem</q></a></dt><dd>The ASCII armored OpenPGP secret key.</dd>
</dl>
<p>
-When <a href="#org671a111">The CA Command</a> sees an empty <q>Secret/CA/</q> directory, as
+When <a href="#org671a111">The CA Command</a> sees an empty <a href="Secret/CA/"><q>Secret/CA/</q></a> directory, as
though just created by running the EasyRSA <code>make-cadir</code> command in
-<q>Secret/</q> (a new, encrypted volume), the <code>./inst CA</code> command creates
+<a href="Secret/"><q>Secret/</q></a> (a new, encrypted volume), the <code>./inst CA</code> command creates
all of the certificates and keys mentioned above. It may prompt for
the institute's full name.
</p>
</p>
<div class="org-src-container">
-<q>private/backup</q><pre class="src src-sh" id="org9d5954c"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
+<a href="private/backup"><q>private/backup</q></a><pre class="src src-sh" id="org9d5954c"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
<span class="org-comment-delimiter">#</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">DO NOT EDIT. Maintained (will be replaced) by Ansible.</span>
<span class="org-comment-delimiter">#</span>
changes, like customization for another institute's particulars. The
variables are separated into <i>public</i> information (e.g. an institute's
name) or <i>private</i> information (e.g. a network interface address), and
-stored in separate files: <q>public/vars.yml</q> and <q>private/vars.yml</q>.
+stored in separate files: <a href="public/vars.yml"><q>public/vars.yml</q></a> and <a href="private/var.yml"><q>private/vars.yml</q></a>.
</p>
<p>
</p>
<div class="org-src-container">
-<q>public/vars.yml</q><pre class="src src-conf">---
+<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf">---
domain_name: small.example.org
domain_priv: small.private
</pre>
<p>
The private version of the institute's domain name should end with one
-of the top-level domains expected for this purpose: <q>.intranet</q>,
-<q>.internal</q>, <q>.private</q>, <q>.corp</q>, <q>.home</q> or <q>.lan</q>.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
+of the top-level domains expected for this purpose: <code>.intranet</code>,
+<code>.internal</code>, <code>.private</code>, <code>.corp</code>, <code>.home</code> or <code>.lan</code>.<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>
</p>
</div>
</div>
</pre>
</div>
+<div class="TEXT" id="orgb4a45be">
+<p>
+=> 10.62.17.0/24
+</p>
+
+</div>
+
<p>
The four private networks are named and given example CIDRs in the
code block below. The small institute treats these addresses as
sensitive information so the code block below "tangles" into
-<q>private/vars.yml</q> rather than <q>public/vars.yml</q>. Two of the
+<a href="private/vars.yml"><q>private/vars.yml</q></a> rather than <a href="public/vars.yml"><q>public/vars.yml</q></a>. Two of the
addresses are in <code>192.168</code> subnets because they are part of a test
configuration using mostly-default VirtualBoxes (described <a href="#org74b454f">here</a>).
</p>
<div class="org-src-container">
-<q>private/vars.yml</q><pre class="src src-conf">---
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">---
private_net_cidr: 192.168.56.0/24
public_vpn_net_cidr: 10.177.86.0/24
campus_vpn_net_cidr: 10.84.138.0/24
</p>
<div class="org-src-container">
-<q>private/vars.yml</q><pre class="src src-conf">private_net: <span class="org-string">"{{ private_net_cidr | ipaddr('network') }}"</span>
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">private_net: <span class="org-string">"{{ private_net_cidr | ipaddr('network') }}"</span>
private_net_mask: <span class="org-string">"{{ private_net_cidr | ipaddr('netmask') }}"</span>
private_net_and_mask: <span class="org-string">"{{ private_net }} {{ private_net_mask }}"</span>
public_vpn_net: <span class="org-string">"{{ public_vpn_net_cidr | ipaddr('network') }}"</span>
</p>
<div class="org-src-container">
-<q>public/vars.yml</q><pre class="src src-conf">front_addr: 192.168.15.5
+<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf">front_addr: 192.168.15.5
</pre>
</div>
</p>
<div class="org-src-container">
-<q>private/vars.yml</q><pre class="src src-conf">core_addr_cidr: <span class="org-string">"{{ private_net_cidr | ipaddr('1') }}"</span>
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">core_addr_cidr: <span class="org-string">"{{ private_net_cidr | ipaddr('1') }}"</span>
gate_addr_cidr: <span class="org-string">"{{ private_net_cidr | ipaddr('2') }}"</span>
gate_wifi_addr_cidr: <span class="org-string">"{{ gate_wifi_net_cidr | ipaddr('1') }}"</span>
wifi_wan_addr_cidr: <span class="org-string">"{{ gate_wifi_net_cidr | ipaddr('2') }}"</span>
<p>
The password was generated by <code>gpw</code>, saved in the administrator's
-password keep, and later added to <q>Secret/become.yml</q> as shown below.
-(Producing a working Ansible configuration with <q>Secret/become.yml</q>
+password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as shown below.
+(Producing a working Ansible configuration with <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
file is described in <a href="#orgff33e02">The Ansible Configuration</a>.)
</p>
<p>
After creating the <code>sysadm</code> account on the droplet, the administrator
concatenated a personal public ssh key and the key found in
-<q>Secret/ssh_admin/</q> (created by <a href="#org671a111">The CA Command</a>) into an <q>admin_keys</q>
+<a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org671a111">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>
The password was generated by <code>gpw</code>, saved in the administrator's
-password keep, and later added to <q>Secret/become.yml</q> as shown below.
-(Producing a working Ansible configuration with <q>Secret/become.yml</q>
+password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as shown below.
+(Producing a working Ansible configuration with <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
file is described in <a href="#orgff33e02">The Ansible Configuration</a>.)
</p>
<p>
Next, the administrator concatenated a personal public ssh key and the
-key found in <q>Secret/ssh_admin/</q> (created by <a href="#org671a111">The CA Command</a>) into an
+key found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org671a111">The CA Command</a>) into an
<q>admin_keys</q> file, copied it to Core, and installed it as the
<q>authorized_keys</q> for <code>sysadm</code>.
</p>
campground Wi-Fi access point, etc.</li>
</ol>
-<pre class="example" id="org7728728">
+<pre class="example" id="org0804a36">
=============== | ==================================================
| Premises
(Campus ISP)
following topology.
</p>
-<pre class="example" id="orga571414">
+<pre class="example" id="orgc8b61ff">
=============== | ==================================================
| Premises
(House ISP)
<p>
The password was generated by <code>gpw</code>, saved in the administrator's
-password keep, and later added to <q>Secret/become.yml</q> as shown below.
-(Producing a working Ansible configuration with <q>Secret/become.yml</q>
+password keep, and later added to <a href="Secret/become.yml"><q>Secret/become.yml</q></a> as shown below.
+(Producing a working Ansible configuration with <a href="Secret/become.yml"><q>Secret/become.yml</q></a>
file is described in <a href="#orgff33e02">The Ansible Configuration</a>.)
</p>
<p>
Next, the administrator concatenated a personal public ssh key and the
-key found in <q>Secret/ssh_admin/</q> (created by <a href="#org671a111">The CA Command</a>) into an
+key found in <a href="Secret/ssh_admin/"><q>Secret/ssh_admin/</q></a> (created by <a href="#org671a111">The CA Command</a>) into an
<q>admin_keys</q> file, copied it to Gate, and installed it as the
<q>authorized_keys</q> for <code>sysadm</code>.
</p>
certificates signed by the institute CA.
</p>
</div>
-<div id="outline-container-orgd751f3c" class="outline-3">
-<h3 id="orgd751f3c"><span class="section-number-3">6.1.</span> Include Particulars</h3>
+<div id="outline-container-orgf58fc42" class="outline-3">
+<h3 id="orgf58fc42"><span class="section-number-3">6.1.</span> Include Particulars</h3>
<div class="outline-text-3" id="text-6-1">
<p>
The <code>front</code> role's tasks contain references to several common
<p>
The code block below is the first to tangle into
-<q>roles/front/tasks/main.yml</q>.
+<a href="roles/front/tasks/main.yml"><q>roles/front/tasks/main.yml</q></a>.
</p>
<div class="org-src-container">
-<q>roles/front/tasks/main.yml</q><pre class="src src-conf">---
+<a href="roles/front/tasks/main.yml"><q>roles/front/tasks/main.yml</q></a><pre class="src src-conf">---
- name: Include public variables.
include_vars: ../public/vars.yml
tags: accounts
</div>
</div>
</div>
-<div id="outline-container-orgd9ea791" class="outline-3">
-<h3 id="orgd9ea791"><span class="section-number-3">6.2.</span> Configure Hostname</h3>
+<div id="outline-container-org2cdf742" class="outline-3">
+<h3 id="org2cdf742"><span class="section-number-3">6.2.</span> Configure Hostname</h3>
<div class="outline-text-3" id="text-6-2">
<p>
This task ensures that Front's <q>/etc/hostname</q> and <q>/etc/mailname</q> are
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">- name: Configure hostname.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">- name: Configure hostname.
become: yes
copy:
content: <span class="org-string">"{{ domain_name }}\n"</span>
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">---
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">---
- name: Update hostname.
become: yes
command: hostname -F /etc/hostname
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install systemd-resolved.
become: yes
<span class="org-variable-name">apt: pkg</span>=systemd-resolved
</div>
</div>
</div>
-<div id="outline-container-orgb4fc0b7" class="outline-3">
-<h3 id="orgb4fc0b7"><span class="section-number-3">6.4.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-org7985220" class="outline-3">
+<h3 id="org7985220"><span class="section-number-3">6.4.</span> Add Administrator to System Groups</h3>
<div class="outline-text-3" id="text-6-4">
<p>
The administrator often needs to read (directories of) log files owned
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Add {{ ansible_user }} to system groups.
become: yes
user:
<p>
The SSH service on Front needs to be known to Monkey. The following
tasks ensure this by replacing the automatically generated keys with
-those stored in <q>Secret/ssh_front/etc/ssh/</q> and restarting the server.
+those stored in <a href="Secret/ssh_front/etc/ssh/"><q>Secret/ssh_front/etc/ssh/</q></a> and restarting the server.
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install SSH host keys.
become: yes
copy:
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: Reload SSH server.
become: yes
systemd:
</div>
</div>
</div>
-<div id="outline-container-org79a6c80" class="outline-3">
-<h3 id="org79a6c80"><span class="section-number-3">6.6.</span> Configure Monkey</h3>
+<div id="outline-container-orgce99e39" class="outline-3">
+<h3 id="orgce99e39"><span class="section-number-3">6.6.</span> Configure Monkey</h3>
<div class="outline-text-3" id="text-6-6">
<p>
The small institute runs cron jobs and web scripts that generate
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Create monkey.
become: yes
user:
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install rsync.
become: yes
<span class="org-variable-name">apt: pkg</span>=rsync
</div>
</div>
</div>
-<div id="outline-container-orge48632b" class="outline-3">
-<h3 id="orge48632b"><span class="section-number-3">6.8.</span> Install Unattended Upgrades</h3>
+<div id="outline-container-orgf6a2764" class="outline-3">
+<h3 id="orgf6a2764"><span class="section-number-3">6.8.</span> Install Unattended Upgrades</h3>
<div class="outline-text-3" id="text-6-8">
<p>
The institute prefers to install security updates as soon as possible.
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install basic software.
become: yes
<span class="org-variable-name">apt: pkg</span>=unattended-upgrades
</div>
</div>
</div>
-<div id="outline-container-org3664329" class="outline-3">
-<h3 id="org3664329"><span class="section-number-3">6.9.</span> Configure User Accounts</h3>
+<div id="outline-container-org754e3d3" class="outline-3">
+<h3 id="org754e3d3"><span class="section-number-3">6.9.</span> Configure User Accounts</h3>
<div class="outline-text-3" id="text-6-9">
<p>
User accounts are created immediately so that Postfix and Dovecot can
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Create user accounts.
become: yes
user:
</div>
</div>
</div>
-<div id="outline-container-org725ad2b" class="outline-3">
-<h3 id="org725ad2b"><span class="section-number-3">6.10.</span> Trust Institute Certificate Authority</h3>
+<div id="outline-container-org615c988" class="outline-3">
+<h3 id="org615c988"><span class="section-number-3">6.10.</span> Trust Institute Certificate Authority</h3>
<div class="outline-text-3" id="text-6-10">
<p>
Front should recognize the institute's Certificate Authority as
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Trust the institute CA.
become: yes
copy:
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: Update CAs.
become: yes
command: update-ca-certificates
</div>
</div>
</div>
-<div id="outline-container-org507cda2" class="outline-3">
-<h3 id="org507cda2"><span class="section-number-3">6.11.</span> Install Server Certificate</h3>
+<div id="outline-container-org8773a2c" class="outline-3">
+<h3 id="org8773a2c"><span class="section-number-3">6.11.</span> Install Server Certificate</h3>
<div class="outline-text-3" id="text-6-11">
<p>
The servers on Front use the same certificate (and key) to
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install server certificate/key.
become: yes
copy:
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Postfix.
become: yes
<span class="org-variable-name">apt: pkg</span>=postfix
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart Postfix.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">- name: Install institute email aliases.
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">- name: Install institute email aliases.
become: yes
blockinfile:
block: |
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: New aliases.
become: yes
command: newaliases
</div>
</div>
</div>
-<div id="outline-container-orgc81ba1c" class="outline-3">
-<h3 id="orgc81ba1c"><span class="section-number-3">6.14.</span> Configure Dovecot IMAPd</h3>
+<div id="outline-container-org3ff50b5" class="outline-3">
+<h3 id="org3ff50b5"><span class="section-number-3">6.14.</span> Configure Dovecot IMAPd</h3>
<div class="outline-text-3" id="text-6-14">
<p>
Front uses Dovecot's IMAPd to allow user Fetchmail jobs on Core to
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Dovecot IMAPd.
become: yes
<span class="org-variable-name">apt: pkg</span>=dovecot-imapd
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart Dovecot.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Apache2.
become: yes
<span class="org-variable-name">apt: pkg</span>=apache2
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart Apache2.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Disable default vhosts.
become: yes
file:
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Disable other-vhosts-access-log option.
become: yes
file:
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Create UserDir.
become: yes
file:
</div>
</div>
</div>
-<div id="outline-container-orgb08da16" class="outline-3">
-<h3 id="orgb08da16"><span class="section-number-3">6.16.</span> Configure OpenVPN</h3>
+<div id="outline-container-org567b473" class="outline-3">
+<h3 id="org567b473"><span class="section-number-3">6.16.</span> Configure OpenVPN</h3>
<div class="outline-text-3" id="text-6-16">
<p>
Front uses OpenVPN to provide the institute's public VPN service. The
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install OpenVPN.
become: yes
<span class="org-variable-name">apt: pkg</span>=openvpn
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart OpenVPN.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Kamailio.
become: yes
<span class="org-variable-name">apt: pkg</span>=kamailio
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Create Kamailio/Systemd configuration drop.
become: yes
file:
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: Reload Systemd.
become: yes
command: systemctl daemon-reload
</p>
<div class="org-src-container">
-<q>roles_t/front/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/tasks/main.yml"><q>roles_t/front/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure Kamailio.
become: yes
copy:
</div>
<div class="org-src-container">
-<q>roles_t/front/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/front/handlers/main.yml"><q>roles_t/front/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart Kamailio.
become: yes
systemd:
account. (For details, see <a href="#org8d60b7b">The Core Machine</a>.)
</p>
</div>
-<div id="outline-container-org70b2741" class="outline-3">
-<h3 id="org70b2741"><span class="section-number-3">7.1.</span> Include Particulars</h3>
+<div id="outline-container-orga90d99c" class="outline-3">
+<h3 id="orga90d99c"><span class="section-number-3">7.1.</span> Include Particulars</h3>
<div class="outline-text-3" id="text-7-1">
<p>
The first task, as in <a href="#org9240129">The Front Role</a>, is to include the institute
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">---
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">---
- name: Include public variables.
include_vars: ../public/vars.yml
tags: accounts
</div>
</div>
</div>
-<div id="outline-container-org488abe5" class="outline-3">
-<h3 id="org488abe5"><span class="section-number-3">7.2.</span> Configure Hostname</h3>
+<div id="outline-container-orgf87fff2" class="outline-3">
+<h3 id="orgf87fff2"><span class="section-number-3">7.2.</span> Configure Hostname</h3>
<div class="outline-text-3" id="text-7-2">
<p>
This task ensures that Core's <q>/etc/hostname</q> and <q>/etc/mailname</q> are
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure hostname.
become: yes
copy:
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">---
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">---
- name: Update hostname.
become: yes
command: hostname -F /etc/hostname
</div>
</div>
</div>
-<div id="outline-container-org87143f0" class="outline-3">
-<h3 id="org87143f0"><span class="section-number-3">7.3.</span> Enable Systemd Resolved</h3>
+<div id="outline-container-org04ee34b" class="outline-3">
+<h3 id="org04ee34b"><span class="section-number-3">7.3.</span> Enable Systemd Resolved</h3>
<div class="outline-text-3" id="text-7-3">
<p>
Core starts the <code>systemd-networkd</code> and <code>systemd-resolved</code> service
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install systemd-resolved.
become: yes
<span class="org-variable-name">apt: pkg</span>=systemd-resolved
</div>
</div>
</div>
-<div id="outline-container-org223a52e" class="outline-3">
-<h3 id="org223a52e"><span class="section-number-3">7.4.</span> Configure Systemd Resolved</h3>
+<div id="outline-container-org31aa8c4" class="outline-3">
+<h3 id="org31aa8c4"><span class="section-number-3">7.4.</span> Configure Systemd Resolved</h3>
<div class="outline-text-3" id="text-7-4">
<p>
Core runs the campus name server, so Resolved is configured to use it
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure resolved.
become: yes
lineinfile:
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Reload Systemd.
become: yes
command: systemctl daemon-reload
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install netplan.
become: yes
<span class="org-variable-name">apt: pkg</span>=netplan.io
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Apply netplan.
become: yes
command: netplan apply
</p>
<p>
-The example configuration file, <q>private/core-dhcpd.conf</q>, uses
+The example configuration file, <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a>, uses
RFC3442's extension to encode a second (non-default) static route.
The default route is through the campus ISP at Gate. A second route
directs campus traffic to the Front VPN through Core. This is just an
example file. The administrator adds and removes actual machines from
-the actual <q>private/core-dhcpd.conf</q> file.
+the actual <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a> file.
</p>
<div class="org-src-container">
-<q>private/core-dhcpd.conf</q><pre class="src src-conf">option domain-name <span class="org-string">"small.private"</span>;
+<a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a><pre class="src src-conf">option domain-name <span class="org-string">"small.private"</span>;
option domain-name-servers 192.168.56.1;
default-lease-time 3600;
<p>
The following tasks install the ISC's DHCP server and configure it
-with the real <q>private/core-dhcpd.conf</q> (<i>not</i> the example above).
+with the real <a href="private/core-dhcpd.conf"><q>private/core-dhcpd.conf</q></a> (<i>not</i> the example above).
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install DHCP server.
become: yes
<span class="org-variable-name">apt: pkg</span>=isc-dhcp-server
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart DHCP server.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install BIND9.
become: yes
<span class="org-variable-name">apt: pkg</span>=bind9
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Reload BIND9.
become: yes
systemd:
</div>
<div class="org-src-container">
-<q>private/db.domain</q><pre class="src src-conf">;
+<a href="private/db.domain"><q>private/db.domain</q></a><pre class="src src-conf">;
; BIND data file for a small institute<span class="org-string">'s PRIVATE domain names.</span>
<span class="org-string">;</span>
<span class="org-string">$TTL 604800</span>
</div>
<div class="org-src-container">
-<q>private/db.private</q><pre class="src src-conf">;
+<a href="private/db.private"><q>private/db.private</q></a><pre class="src src-conf">;
; BIND reverse data file for a small institute<span class="org-string">'s private Ethernet.</span>
<span class="org-string">;</span>
<span class="org-string">$TTL 604800</span>
</div>
<div class="org-src-container">
-<q>private/db.public_vpn</q><pre class="src src-conf">;
+<a href="private/db.public_vpn"><q>private/db.public_vpn</q></a><pre class="src src-conf">;
; BIND reverse data file for a small institute<span class="org-string">'s public VPN.</span>
<span class="org-string">;</span>
<span class="org-string">$TTL 604800</span>
</div>
<div class="org-src-container">
-<q>private/db.campus_vpn</q><pre class="src src-conf">;
+<a href="private/db.campus_vpn"><q>private/db.campus_vpn</q></a><pre class="src src-conf">;
; BIND reverse data file for a small institute<span class="org-string">'s campus VPN.</span>
<span class="org-string">;</span>
<span class="org-string">$TTL 604800</span>
</div>
</div>
</div>
-<div id="outline-container-orgcd8e7d5" class="outline-3">
-<h3 id="orgcd8e7d5"><span class="section-number-3">7.8.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-org6baad6a" class="outline-3">
+<h3 id="org6baad6a"><span class="section-number-3">7.8.</span> Add Administrator to System Groups</h3>
<div class="outline-text-3" id="text-7-8">
<p>
The administrator often needs to read (directories of) log files owned
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Add {{ ansible_user }} to system groups.
become: yes
user:
</div>
</div>
</div>
-<div id="outline-container-org55c2979" class="outline-3">
-<h3 id="org55c2979"><span class="section-number-3">7.9.</span> Configure Monkey</h3>
+<div id="outline-container-org718cfbd" class="outline-3">
+<h3 id="org718cfbd"><span class="section-number-3">7.9.</span> Configure Monkey</h3>
<div class="outline-text-3" id="text-7-9">
<p>
The small institute runs cron jobs and web scripts that generate
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Create monkey.
become: yes
user:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install basic software.
become: yes
<span class="org-variable-name">apt: pkg</span>=unattended-upgrades
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install expect.
become: yes
<span class="org-variable-name">apt: pkg</span>=expect
</div>
</div>
</div>
-<div id="outline-container-org3283a63" class="outline-3">
-<h3 id="org3283a63"><span class="section-number-3">7.12.</span> Configure User Accounts</h3>
+<div id="outline-container-org55ba8e2" class="outline-3">
+<h3 id="org55ba8e2"><span class="section-number-3">7.12.</span> Configure User Accounts</h3>
<div class="outline-text-3" id="text-7-12">
<p>
User accounts are created immediately so that backups can begin
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Create user accounts.
become: yes
user:
</div>
</div>
</div>
-<div id="outline-container-orgeee8ad5" class="outline-3">
-<h3 id="orgeee8ad5"><span class="section-number-3">7.13.</span> Trust Institute Certificate Authority</h3>
+<div id="outline-container-org36bf9fc" class="outline-3">
+<h3 id="org36bf9fc"><span class="section-number-3">7.13.</span> Trust Institute Certificate Authority</h3>
<div class="outline-text-3" id="text-7-13">
<p>
Core should recognize the institute's Certificate Authority as
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Trust the institute CA.
become: yes
copy:
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Update CAs.
become: yes
command: update-ca-certificates
</div>
</div>
</div>
-<div id="outline-container-org47f3ff1" class="outline-3">
-<h3 id="org47f3ff1"><span class="section-number-3">7.14.</span> Install Server Certificate</h3>
+<div id="outline-container-org22d2cc7" class="outline-3">
+<h3 id="org22d2cc7"><span class="section-number-3">7.14.</span> Install Server Certificate</h3>
<div class="outline-text-3" id="text-7-14">
<p>
The servers on Core use the same certificate (and key) to authenticate
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install server certificate/key.
become: yes
copy:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install NTP.
become: yes
<span class="org-variable-name">apt: pkg</span>=ntp
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Postfix.
become: yes
<span class="org-variable-name">apt: pkg</span>=postfix
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart Postfix.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install institute email aliases.
become: yes
blockinfile:
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: New aliases.
become: yes
command: newaliases
</div>
</div>
</div>
-<div id="outline-container-org47b61d3" class="outline-3">
-<h3 id="org47b61d3"><span class="section-number-3">7.18.</span> Configure Dovecot IMAPd</h3>
+<div id="outline-container-org49d8726" class="outline-3">
+<h3 id="org49d8726"><span class="section-number-3">7.18.</span> Configure Dovecot IMAPd</h3>
<div class="outline-text-3" id="text-7-18">
<p>
Core uses Dovecot's IMAPd to store and serve member emails. As on
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Dovecot IMAPd.
become: yes
<span class="org-variable-name">apt: pkg</span>=dovecot-imapd
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart Dovecot.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install fetchmail.
become: yes
<span class="org-variable-name">apt: pkg</span>=fetchmail
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Stop former user fetchmail services.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Apache2.
become: yes
<span class="org-variable-name">apt: pkg</span>=apache2
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install live web site.
become: yes
copy:
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart Apache2.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>private/webupdate</q><pre class="src src-sh" id="orgbb22232"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
+<a href="private/webupdate"><q>private/webupdate</q></a><pre class="src src-sh" id="orgbb22232"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">bash</span><span class="org-comment"> -e</span>
<span class="org-comment-delimiter">#</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">DO NOT EDIT. This file was tangled from institute.org.</span>
</div>
<p>
-The following tasks install the <q>webupdate</q> script from <q>private/</q>,
+The following tasks install the <q>webupdate</q> script from <a href="private/"><q>private/</q></a>,
and create Monkey's <code>cron</code> job. An example <q>webupdate</q> script is
provided <a href="#orgbb22232">here</a>.
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: <span class="org-string">"Install Monkey's webupdate script."</span>
become: yes
copy:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install OpenVPN.
become: yes
<span class="org-variable-name">apt: pkg</span>=openvpn
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart OpenVPN.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install NAGIOS4.
become: yes
apt:
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Reload NAGIOS4.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf"><span class="org-type">define host</span> {
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf"><span class="org-type">define host</span> {
use linux-server
host_name core
address 127.0.0.1
</p>
<div class="org-src-container">
-<q>roles_t/core/files/inst_sensors</q><pre class="src src-sh"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">sh</span>
+<a href="roles_t/core/files/inst_sensors"><q>roles_t/core/files/inst_sensors</q></a><pre class="src src-sh"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/</span><span class="org-keyword">sh</span>
<span class="org-variable-name">PATH</span>=<span class="org-string">"/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"</span>
<span class="org-builtin">export</span> PATH
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
<span class="org-type">define command</span> {
command_name inst_sensors
command_line /usr/local/sbin/inst_sensors
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
<span class="org-type">define host</span> {
use linux-server
host_name gate
address {{ gate_addr }}
}
-
-<span class="org-type">define service</span> {
- use local-service
- host_name gate
- service_description PING
- check_command check_ping!100.0,20%!500.0,60%
-}
</pre>
</div>
</p>
<div class="org-src-container">
-<q>roles_t/campus/files/nrpe.cfg</q><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_root</span>]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
+<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_root</span>]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
</pre>
</div>
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
<span class="org-type">define service</span> {
use generic-service
host_name gate
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
<span class="org-type">define service</span> {
use generic-service
host_name gate
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
<span class="org-type">define service</span> {
use generic-service
host_name gate
</p>
<div class="org-src-container">
-<q>roles_t/campus/files/nrpe.cfg</q><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_swap</span>]=/usr/lib/nagios/plugins/check_swap -w 20% -c 10%
+<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_swap</span>]=/usr/lib/nagios/plugins/check_swap -w 20% -c 10%
</pre>
</div>
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
<span class="org-type">define service</span> {
use generic-service
host_name gate
</pre>
</div>
-<p>
-Monitor Gate's SSH service.
-</p>
-
-<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf">
-<span class="org-type">define service</span> {
- use generic-service
- host_name gate
- service_description SSH
- check_command check_ssh
-}
-</pre>
-</div>
-
<p>
For all campus NRPE servers: an <code>inst_sensors</code> command to report core
CPU temperatures.
</p>
<div class="org-src-container">
-<q>roles_t/campus/files/nrpe.cfg</q><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_sensors</span>]=/usr/local/sbin/inst_sensors
+<a href="roles_t/campus/files/nrpe.cfg"><q>roles_t/campus/files/nrpe.cfg</q></a><pre class="src src-conf"><span class="org-variable-name">command</span>[<span class="org-constant">inst_sensors</span>]=/usr/local/sbin/inst_sensors
</pre>
</div>
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/nagios.cfg</q><pre class="src src-conf">
+<a href="roles_t/core/templates/nagios.cfg"><q>roles_t/core/templates/nagios.cfg</q></a><pre class="src src-conf">
<span class="org-type">define service</span> {
use generic-service
host_name gate
<h3 id="org04cc272"><span class="section-number-3">7.24.</span> Configure Backups</h3>
<div class="outline-text-3" id="text-7-24">
<p>
-The following task installs the <q>backup</q> script from <q>private/</q>. An
+The following task installs the <q>backup</q> script from <a href="private/"><q>private/</q></a>. An
example script is provided in <a href="#org9d5954c">here</a>.
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install backup script.
become: yes
copy:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install packages required by Nextcloud.
become: yes
apt:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Enable Apache2 modules for Nextcloud.
become: yes
apache2_module:
</p>
<div class="org-src-container">
-<q>roles_t/core/files/nextcloud.conf</q><pre class="src src-conf">Alias /nextcloud <span class="org-string">"/var/www/nextcloud/"</span>
+<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf">Alias /nextcloud <span class="org-string">"/var/www/nextcloud/"</span>
<Directory /var/www/nextcloud/>
Require all granted
</div>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Nextcloud web configuration.
become: yes
copy:
</p>
<div class="org-src-container">
-<q>roles_t/core/files/nextcloud.conf</q><pre class="src src-conf">
+<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf">
<Directory /var/www/html/>
<IfModule mod_rewrite.c>
RewriteEngine on
</p>
<div class="org-src-container">
-<q>roles_t/core/files/nextcloud.conf</q><pre class="src src-conf">
+<a href="roles_t/core/files/nextcloud.conf"><q>roles_t/core/files/nextcloud.conf</q></a><pre class="src src-conf">
<IfModule mod_headers.c>
Header always set \
Strict-Transport-Security <span class="org-string">"max-age=15552000; includeSubDomains"</span>
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Add {{ ansible_user }} to web server group.
become: yes
user:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Create Nextcloud cron job.
become: yes
cron:
<p>
Nextcloud's MariaDB database (and user) are created by the following
tasks. The user's password is taken from the <code>nextcloud_dbpass</code>
-variable, kept in <q>private/vars.yml</q>, and generated e.g. with
+variable, kept in <a href="private/vars.yml"><q>private/vars.yml</q></a>, and generated e.g. with
the <code>apg -n 1 -x 12 -m 12</code> command.
</p>
<div class="org-src-container">
-<q>private/vars.yml</q><pre class="src src-conf">nextcloud_dbpass: ippAgmaygyob
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">nextcloud_dbpass: ippAgmaygyob
</pre>
</div>
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Link /var/www/nextcloud.
become: yes
file:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Set PHP memory_limit for Nextcloud.
become: yes
lineinfile:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Test for /Nextcloud/nextcloud/.
stat:
path: /Nextcloud/nextcloud
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure Nextcloud trusted domains.
become: yes
replace:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure Nextcloud memcache.
become: yes
lineinfile:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure Nextcloud for Pretty URLs.
become: yes
lineinfile:
</p>
<div class="org-src-container">
-<q>private/vars.yml</q><pre class="src src-conf">nextcloud_region: US
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">nextcloud_region: US
</pre>
</div>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure Nextcloud phone region.
become: yes
lineinfile:
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Create /Nextcloud/dbbackup.cnf.
no_log: yes
become: yes
configurations, etc.
</p>
</div>
-<div id="outline-container-org7683327" class="outline-3">
-<h3 id="org7683327"><span class="section-number-3">8.1.</span> Include Particulars</h3>
+<div id="outline-container-org0fd1c05" class="outline-3">
+<h3 id="org0fd1c05"><span class="section-number-3">8.1.</span> Include Particulars</h3>
<div class="outline-text-3" id="text-8-1">
<p>
The following should be familiar boilerplate by now.
</p>
<div class="org-src-container">
-<q>roles_t/gate/tasks/main.yml</q><pre class="src src-conf">---
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">---
- name: Include public variables.
include_vars: ../public/vars.yml
tags: accounts
<p>
Netplan is configured to identify the interfaces by their MAC
-addresses, which must be provided in <q>private/vars.yml</q>, as in the
+addresses, which must be provided in <a href="private/vars.yml"><q>private/vars.yml</q></a>, as in the
example code here.
</p>
<div class="org-src-container">
-<q>private/vars.yml</q><pre class="src src-conf">gate_lan_mac: ff:ff:ff:ff:ff:ff
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">gate_lan_mac: ff:ff:ff:ff:ff:ff
gate_wifi_mac: ff:ff:ff:ff:ff:ff
gate_isp_mac: ff:ff:ff:ff:ff:ff
</pre>
</p>
<div class="org-src-container">
-<q>roles_t/gate/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install netplan (gate).
become: yes
<span class="org-variable-name">apt: pkg</span>=netplan.io
</div>
<div class="org-src-container">
-<q>roles_t/gate/handlers/main.yml</q><pre class="src src-conf">---
+<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf">---
- name: Apply netplan.
become: yes
command: netplan apply
<div class="org-src-container">
-<q>roles_t/gate/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install UFW.
become:
<span class="org-variable-name">apt: pkg</span>=ufw
</p>
<div class="org-src-container">
-<q>private/vars.yml</q><pre class="src src-conf">wifi_wan_mac: 94:83:c4:19:7d:57
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">wifi_wan_mac: 94:83:c4:19:7d:57
wifi_wan_name: campus-wifi-ap
</pre>
</div>
</p>
<div class="org-src-container">
-<q>roles_t/gate/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install DHCP server.
become: yes
<span class="org-variable-name">apt: pkg</span>=isc-dhcp-server
</div>
<div class="org-src-container">
-<q>roles_t/gate/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart DHCP server.
become: yes
systemd:
</div>
</div>
</div>
-<div id="outline-container-orga5d4d07" class="outline-3">
-<h3 id="orga5d4d07"><span class="section-number-3">8.6.</span> Install Server Certificate</h3>
+<div id="outline-container-org203c172" class="outline-3">
+<h3 id="org203c172"><span class="section-number-3">8.6.</span> Install Server Certificate</h3>
<div class="outline-text-3" id="text-8-6">
<p>
The (OpenVPN) server on Gate uses an institute certificate (and key)
</p>
<div class="org-src-container">
-<q>roles_t/gate/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install server certificate/key.
become: yes
copy:
</div>
</div>
</div>
-<div id="outline-container-orga85e634" class="outline-3">
-<h3 id="orga85e634"><span class="section-number-3">8.7.</span> Configure OpenVPN</h3>
+<div id="outline-container-org760a95a" class="outline-3">
+<h3 id="org760a95a"><span class="section-number-3">8.7.</span> Configure OpenVPN</h3>
<div class="outline-text-3" id="text-8-7">
<p>
Gate uses OpenVPN to provide the institute's campus VPN service. Its
</p>
<div class="org-src-container">
-<q>roles_t/gate/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/gate/tasks/main.yml"><q>roles_t/gate/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install OpenVPN.
become: yes
<span class="org-variable-name">apt: pkg</span>=openvpn
</div>
<div class="org-src-container">
-<q>roles_t/gate/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/gate/handlers/main.yml"><q>roles_t/gate/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart OpenVPN.
become: yes
systemd:
configured manually.
</p>
</div>
-<div id="outline-container-orgc2b5a03" class="outline-3">
-<h3 id="orgc2b5a03"><span class="section-number-3">9.1.</span> Include Particulars</h3>
+<div id="outline-container-org9d81c0f" class="outline-3">
+<h3 id="org9d81c0f"><span class="section-number-3">9.1.</span> Include Particulars</h3>
<div class="outline-text-3" id="text-9-1">
<p>
The following should be familiar boilerplate by now.
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">---
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">---
- name: Include public variables.
include_vars: ../public/vars.yml
- name: Include private variables.
</div>
</div>
</div>
-<div id="outline-container-org3acf8ab" class="outline-3">
-<h3 id="org3acf8ab"><span class="section-number-3">9.2.</span> Configure Hostname</h3>
+<div id="outline-container-orgcc676de" class="outline-3">
+<h3 id="orgcc676de"><span class="section-number-3">9.2.</span> Configure Hostname</h3>
<div class="outline-text-3" id="text-9-2">
<p>
Clients should be using the expected host name.
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure hostname.
become: yes
copy:
</div>
<div class="org-src-container">
-<q>roles_t/campus/handlers/main.yml</q><pre class="src src-conf">---
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">---
- name: Update hostname.
become: yes
command: hostname -F /etc/hostname
</div>
</div>
</div>
-<div id="outline-container-orgfb12bf4" class="outline-3">
-<h3 id="orgfb12bf4"><span class="section-number-3">9.3.</span> Enable Systemd Resolved</h3>
+<div id="outline-container-orge776843" class="outline-3">
+<h3 id="orge776843"><span class="section-number-3">9.3.</span> Enable Systemd Resolved</h3>
<div class="outline-text-3" id="text-9-3">
<p>
Campus machines start the <code>systemd-networkd</code> and <code>systemd-resolved</code>
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install systemd-resolved.
become: yes
<span class="org-variable-name">apt: pkg</span>=systemd-resolved
</div>
</div>
</div>
-<div id="outline-container-org4977a1c" class="outline-3">
-<h3 id="org4977a1c"><span class="section-number-3">9.4.</span> Configure Systemd Resolved</h3>
+<div id="outline-container-org85c46f2" class="outline-3">
+<h3 id="org85c46f2"><span class="section-number-3">9.4.</span> Configure Systemd Resolved</h3>
<div class="outline-text-3" id="text-9-4">
<p>
Campus machines use the campus name server on Core (or <code>dns.google</code>),
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure resolved.
become: yes
lineinfile:
</div>
<div class="org-src-container">
-<q>roles_t/campus/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">
- name: Reload Systemd.
become: yes
command: systemctl daemon-reload
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Configure timesyncd.
become: yes
lineinfile:
</div>
<div class="org-src-container">
-<q>roles_t/campus/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart systemd-timesyncd.
become: yes
systemd:
</div>
</div>
</div>
-<div id="outline-container-orged16e9b" class="outline-3">
-<h3 id="orged16e9b"><span class="section-number-3">9.6.</span> Add Administrator to System Groups</h3>
+<div id="outline-container-orga3a919f" class="outline-3">
+<h3 id="orga3a919f"><span class="section-number-3">9.6.</span> Add Administrator to System Groups</h3>
<div class="outline-text-3" id="text-9-6">
<p>
The administrator often needs to read (directories of) log files owned
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Add {{ ansible_user }} to system groups.
become: yes
user:
</div>
</div>
</div>
-<div id="outline-container-org3c2f09d" class="outline-3">
-<h3 id="org3c2f09d"><span class="section-number-3">9.7.</span> Trust Institute Certificate Authority</h3>
+<div id="outline-container-orgfab713c" class="outline-3">
+<h3 id="orgfab713c"><span class="section-number-3">9.7.</span> Trust Institute Certificate Authority</h3>
<div class="outline-text-3" id="text-9-7">
<p>
Campus hosts should recognize the institute's Certificate Authority as
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Trust the institute CA.
become: yes
copy:
</div>
<div class="org-src-container">
-<q>roles_t/campus/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">
- name: Update CAs.
become: yes
command: update-ca-certificates
</div>
</div>
</div>
-<div id="outline-container-org0cf8be6" class="outline-3">
-<h3 id="org0cf8be6"><span class="section-number-3">9.8.</span> Install Unattended Upgrades</h3>
+<div id="outline-container-orgb504c59" class="outline-3">
+<h3 id="orgb504c59"><span class="section-number-3">9.8.</span> Install Unattended Upgrades</h3>
<div class="outline-text-3" id="text-9-8">
<p>
The institute prefers to install security updates as soon as possible.
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install basic software.
become: yes
<span class="org-variable-name">apt: pkg</span>=unattended-upgrades
</ul>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install Postfix.
become: yes
<span class="org-variable-name">apt: pkg</span>=postfix
</div>
<div class="org-src-container">
-<q>roles_t/campus/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">
- name: Restart Postfix.
become: yes
systemd:
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Hard-wire important IP addresses.
become: yes
lineinfile:
</p>
<div class="org-src-container">
-<q>roles_t/campus/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/tasks/main.yml"><q>roles_t/campus/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install NRPE.
become: yes
apt:
</div>
<div class="org-src-container">
-<q>roles_t/campus/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/campus/handlers/main.yml"><q>roles_t/campus/handlers/main.yml</q></a><pre class="src src-conf">
- name: Reload NRPE server.
become: yes
systemd:
<div class="outline-text-2" id="text-10">
<p>
The small institute uses Ansible to maintain the configuration of its
-servers. The administrator keeps an Ansible inventory in <q>hosts</q>, and
-runs the playbook <q>site.yml</q> to apply the appropriate institutional
+servers. The administrator keeps an Ansible inventory in <a href="hosts"><q>hosts</q></a>, and
+runs playbook <a href="playbook/site.yml"><q>site.yml</q></a> to apply the appropriate institutional
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
<p>
The <i>actual</i> Ansible configuration is kept in a Git "superproject"
-containing replacements for the example <q>hosts</q> inventory and
-<q>site.yml</q> playbook, as well as the <q>public/</q> and <q>private/</q>
+containing replacements for the example <a href="hosts"><q>hosts</q></a> inventory and
+<a href="playbooks/site.yml"><q>site.yml</q></a> playbook, as well as the <a href="public/"><q>public/</q></a> and <a href="private/"><q>private/</q></a>
particulars. Thus changes to this document and its tangle are easily
merged with <code>git pull --recurse-submodules</code> or <code>git submodule update</code>,
while changes to the institute's particulars are committed to a
separate revision history.
</p>
</div>
-<div id="outline-container-orgc1588c7" class="outline-3">
-<h3 id="orgc1588c7"><span class="section-number-3">10.1.</span> <q>ansible.cfg</q></h3>
+<div id="outline-container-orgfefb674" class="outline-3">
+<h3 id="orgfefb674"><span class="section-number-3">10.1.</span> <q>ansible.cfg</q></h3>
<div class="outline-text-3" id="text-10-1">
<p>
-The Ansible configuration file <q>ansible.cfg</q> contains just a handful
+The Ansible configuration file <a href="ansible.cfg"><q>ansible.cfg</q></a> contains just a handful
of settings, some included just to create a test jig as described in
<a href="#org74b454f">Testing</a>.
</p>
"automatic interpreter discovery" (described <a href="https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html">here</a>). It declares
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 <q>Secret/</q> (as
+password. The institute keeps its vault password in <a href="Secret/"><q>Secret/</q></a> (as
described in <a href="#org6519b0c">Keys</a>) and thus sets this parameter to
-<q>Secret/vault-password</q>.</li>
+<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
-<q>roles_t/</q> which are preferred in the test configuration.</li>
+<a href="roles_t/"><q>roles_t/</q></a> which are preferred in the test configuration.</li>
</ul>
<div class="org-src-container">
-<q>ansible.cfg</q><pre class="src src-conf">[<span class="org-type">defaults</span>]
+<a href="ansible.cfg"><q>ansible.cfg</q></a><pre class="src src-conf">[<span class="org-type">defaults</span>]
<span class="org-variable-name">interpreter_python</span>=/usr/bin/python3
<span class="org-variable-name">vault_password_file</span>=Secret/vault-password
<span class="org-variable-name">inventory</span>=hosts
<h3 id="orgb932c38"><span class="section-number-3">10.2.</span> <q>hosts</q></h3>
<div class="outline-text-3" id="text-10-2">
<p>
-The Ansible inventory file <q>hosts</q> describes all of the institute's
+The Ansible inventory file <a href="hosts"><q>hosts</q></a> describes all of the institute's
machines starting with the main servers Front, Core and Gate. It
provides the IP addresses, administrator account names and passwords
for each machine. The IP addresses are all private, campus network
</p>
<div class="org-src-container">
-<q>hosts</q><pre class="src src-conf" id="orgafeb78d">all:
+<a href="hosts"><q>hosts</q></a><pre class="src src-conf" id="orgafeb78d">all:
vars:
ansible_user: sysadm
ansible_ssh_extra_args: -i Secret/ssh_admin/id_rsa
<p>
The values of the <code>ansible_become_password</code> key are references to
-variables defined in <q>Secret/become.yml</q>, which is loaded as
+variables defined in <a href="Secret/become.yml"><q>Secret/become.yml</q></a>, which is loaded as
"extra" variables by a <code>-e</code> option on the <code>ansible-playbook</code> command
line.
</p>
<div class="org-src-container">
-<q>Secret/become.yml</q><pre class="src src-conf">become_front: !vault |
+<a href="Secret/become.yml"><q>Secret/become.yml</q></a><pre class="src src-conf">become_front: !vault |
$ANSIBLE_VAULT;1.1;AES256
3563626131333733666466393166323135383838666338666131336335326
3656437663032653333623461633866653462636664623938356563306264
The passwords are individually encrypted just to make it difficult to
acquire a list of all institute privileged account passwords in one
glance. The multi-line values are generated by the <code>ansible-vault
-encrypt_string</code> command, which uses the <q>ansible.cfg</q> file and thus
-the <q>Secret/vault-password</q> file.
+encrypt_string</code> command, which uses the <a href="ansible.cfg"><q>ansible.cfg</q></a> file and thus
+the <a href="Secret/vault-password"><q>Secret/vault-password</q></a> file.
</p>
</div>
</div>
<h3 id="org074c362"><span class="section-number-3">10.3.</span> <q>playbooks/site.yml</q></h3>
<div class="outline-text-3" id="text-10-3">
<p>
-The example <q>playbooks/site.yml</q> playbook (below) applies the
+The example <a href="playbooks/site.yml"><q>playbooks/site.yml</q></a> playbook (below) applies the
appropriate institutional role(s) to the hosts and groups defined in
-the example inventory: <q>hosts</q>.
+the example inventory: <a href="hosts"><q>hosts</q></a>.
</p>
<div class="org-src-container">
-<q>playbooks/site.yml</q><pre class="src src-conf">---
+<a href="playbooks/site.yml"><q>playbooks/site.yml</q></a><pre class="src src-conf">---
- name: Configure Front
hosts: front
roles: [ front ]
<p>
As already mentioned, the small institute keeps its Ansible vault
password, a "master secret", on the encrypted partition mounted at
-<q>Secret/</q> in a file named <q>vault-password</q>. The administrator
+<a href="Secret/"><q>Secret/</q></a> in a file named <q>vault-password</q>. The administrator
generated a 16 character pronounceable password with <code>gpw 1 16</code> and
saved it like so: <code>gpw 1 16 >Secret/vault-password</code>. The following
example password matches the example encryptions above.
</p>
<div class="org-src-container">
-<q>Secret/vault-password</q><pre class="src src-conf" id="org3cd4611">alitysortstagess
+<a href="Secret/vault-password"><q>Secret/vault-password</q></a><pre class="src src-conf" id="org3cd4611">alitysortstagess
</pre>
</div>
</div>
<h3 id="orgb70ec0e"><span class="section-number-3">10.6.</span> Maintaining A Working Ansible Configuration</h3>
<div class="outline-text-3" id="text-10-6">
<p>
-The Ansible roles currently tangle into the <q>roles_t/</q> directory to
+The Ansible roles currently tangle into the <a href="roles_t/"><q>roles_t/</q></a> directory to
ensure that debugged Ansible code in <q>roles/</q> is not clobbered by code
-tangled from this document. Comparing <q>roles_t/</q> with <q>roles/</q> will
+tangled from this document. Comparing <a href="roles_t/"><q>roles_t/</q></a> with <q>roles/</q> will
reveal any changes made to <q>roles/</q> during debugging that need to be
reconciled with this document <i>as well as</i> any policy changes in this
document that require changes to the current <q>roles/</q>.
<h3 id="orgf00b9ce"><span class="section-number-3">11.1.</span> Sub-command Blocks</h3>
<div class="outline-text-3" id="text-11-1">
<p>
-The code blocks in this chapter tangle into the <q>inst</q> script. Each
+The code blocks in this chapter tangle into the <a href="inst"><q>inst</q></a> script. Each
block examines the script's command line arguments to determine
whether its sub-command was intended to run, and exits with an
appropriate code when it is done.
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl"><span class="org-comment-delimiter">#</span><span class="org-comment">!/usr/bin/perl -w</span>
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><span class="org-comment-delimiter">#</span><span class="org-comment">!/usr/bin/perl -w</span>
<span class="org-comment-delimiter">#</span>
<span class="org-comment-delimiter"># </span><span class="org-comment">DO NOT EDIT. This file was tangled from an institute.org file.</span>
The next code block does not implement a sub-command; it implements
part of <i>all</i> <code>./inst</code> sub-commands. It performs a "sanity check" on
the current directory, warning of missing files or directories, and
-especially checking that all files in <q>private/</q> have appropriate
-permissions. It probes past the <q>Secret/</q> mount point (probing for
-<q>Secret/become.yml</q>) to ensure the volume is mounted.
+especially checking that all files in <a href="private/"><q>private/</q></a> have appropriate
+permissions. It probes past the <a href="Secret/"><q>Secret/</q></a> mount point (probing for
+<a href="Secret/become.yml"><q>Secret/become.yml</q></a>) to ensure the volume is mounted.
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<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> ($);
<p>
To ensure that Ansible and <code>./inst</code> are sympatico vis-a-vi certain
variable values (esp. private values like network addresses), a
-<q>check-inst-vars.yml</q> playbook is used to update the Perl syntax file
-<q>private/vars.pl</q> before <code>./inst</code> loads it. The Perl code in <q>inst</q>
-declares the necessary global variables and <q>private/vars.pl</q> sets
+<a href="playbooks/check-inst-vars.yml"><q>check-inst-vars.yml</q></a> playbook is used to update the Perl syntax file
+<a href="private/vars.pl"><q>private/vars.pl</q></a> before <code>./inst</code> loads it. The Perl code in <a href="inst"><q>inst</q></a>
+declares the necessary global variables and <a href="private/vars.pl"><q>private/vars.pl</q></a> sets
them.
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-conf">
+<a href="inst"><q>inst</q></a><pre class="src src-conf">
<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>;
</div>
<p>
-The playbook that updates <q>private/vars.pl</q>:
+The playbook that updates <a href="private/vars.pl"><q>private/vars.pl</q></a>:
</p>
<div class="org-src-container">
-<q>playbooks/check-inst-vars.yml</q><pre class="src src-conf">- hosts: localhost
+<a href="playbooks/check-inst-vars.yml"><q>playbooks/check-inst-vars.yml</q></a><pre class="src src-conf">- hosts: localhost
gather_facts: no
tasks:
- include_vars: ../public/vars.yml
<div class="outline-text-3" id="text-11-4">
<p>
The next code block implements the <code>CA</code> sub-command, which creates a
-new CA (certificate authority) in <q>Secret/CA/</q> as well as SSH and PGP
+new CA (certificate authority) in <a href="Secret/CA/"><q>Secret/CA/</q></a> as well as SSH and PGP
keys for the administrator, Monkey, Front and <code>root</code>, also in
-sub-directories of <q>Secret/</q>. The CA is created with the "common
+sub-directories of <a href="Secret/"><q>Secret/</q></a>. The CA is created with the "common
name" provided by the <code>full_name</code> variable. An example is given
here.
</p>
<div class="org-src-container">
-<q>public/vars.yml</q><pre class="src src-conf">full_name: Small Institute LLC
+<a href="public/vars.yml"><q>public/vars.yml</q></a><pre class="src src-conf">full_name: Small Institute LLC
</pre>
</div>
<p>
-The <q>Secret/</q> directory is on an off-line, encrypted volume plugged in
-just for the duration of <code>./inst</code> commands, so <q>Secret/</q> is actually a
+The <a href="Secret/"><q>Secret/</q></a> directory is on an off-line, encrypted volume plugged in
+just for the duration of <code>./inst</code> commands, so <a href="Secret/"><q>Secret/</q></a> is actually a
symbolic link to a volume's automount location.
</p>
<p>
-The <q>Secret/CA/</q> directory is prepared using Easy RSA's <code>make-cadir</code>
-command. The <q>Secret/CA/vars</q> file thus created is edited to contain
+The <a href="Secret/CA/"><q>Secret/CA/</q></a> directory is prepared using Easy RSA's <code>make-cadir</code>
+command. The <a href="Secret/CA/vars"><q>Secret/CA/vars</q></a> file thus created is edited to contain
the appropriate names (or just to set <code>EASYRSA_DN</code> to <code>cn_only</code>).
</p>
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<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-underline"><span class="org-variable-name">ARGV</span></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>;
<span class="org-keyword">die</span> <span class="org-string">"Secret/CA/pki/: already exists\n"</span> <span class="org-keyword">if</span> -e <span class="org-string">"Secret/CA/pki"</span>;
+
+ umask 077;
mysystem <span class="org-string">"cd Secret/CA; ./easyrsa init-pki"</span>;
mysystem <span class="org-string">"cd Secret/CA; ./easyrsa build-ca nopass"</span>;
<span class="org-comment"># Common Name: small.example.org</span>
mysystem <span class="org-string">"cd Secret/CA; ./easyrsa build-server-full core.$pvt nopass"</span>;
mysystem <span class="org-string">"cd Secret/CA; ./easyrsa build-client-full core nopass"</span>;
umask 077;
- mysystem <span class="org-string">"openvpn --genkey --secret Secret/front-ta.key"</span>;
- mysystem <span class="org-string">"openvpn --genkey --secret Secret/gate-ta.key"</span>;
+ mysystem <span class="org-string">"openvpn --genkey secret Secret/front-ta.key"</span>;
+ mysystem <span class="org-string">"openvpn --genkey secret Secret/gate-ta.key"</span>;
mysystem <span class="org-string">"openssl dhparam -out Secret/front-dh2048.pem 2048"</span>;
mysystem <span class="org-string">"openssl dhparam -out Secret/gate-dh2048.pem 2048"</span>;
<span class="org-string">" --batch --quick-generate-key --passphrase ''"</span>,
<span class="org-string">" root\@core.$pvt"</span>);
mysystem (<span class="org-string">"gpg --homedir Secret/root.gnupg"</span>,
- <span class="org-string">" --export --armor --output root-pub.pem"</span>,
+ <span class="org-string">" --export --armor --output Secret/root-pub.pem"</span>,
<span class="org-string">" root\@core.$pvt"</span>);
chmod 0440, <span class="org-string">"root-pub.pem"</span>;
mysystem (<span class="org-string">"gpg --homedir Secret/root.gnupg"</span>,
- <span class="org-string">" --export-secret-key --armor --output root-sec.pem"</span>,
+ <span class="org-string">" --export-secret-key --armor --output Secret/root-sec.pem"</span>,
<span class="org-string">" root\@core.$pvt"</span>);
chmod 0400, <span class="org-string">"root-sec.pem"</span>;
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<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>;
<p>
The test campus starts with the empty membership roll found in
-<q>private/members-empty.yml</q> and saved in <q>private/members.yml</q>
+<a href="private/members-empty.yml"><q>private/members-empty.yml</q></a> and saved in <q>private/members.yml</q>
(which is <i>not</i> tangled from this document, thus <i>not</i> over-written
during testing). If <q>members.yml</q> is not found, <q>members-empty.yml</q>
is used instead.
</p>
<div class="org-src-container">
-<q>private/members-empty.yml</q><pre class="src src-conf">---
+<a href="private/members-empty.yml"><q>private/members-empty.yml</q></a><pre class="src src-conf">---
members:
usernames: []
revoked: []
</p>
<div class="org-src-container">
-<q>private/vars.yml</q><pre class="src src-conf">membership_rolls:
+<a href="private/vars.yml"><q>private/vars.yml</q></a><pre class="src src-conf">membership_rolls:
- <span class="org-string">"../private/members.yml"</span>
- <span class="org-string">"../private/members-empty.yml"</span>
</pre>
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<span class="org-constant">use</span> YAML::XS qw<span class="org-string">(LoadFile DumpFile)</span>;
<span class="org-keyword">sub</span> <span class="org-function-name">read_members_yaml</span> () {
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<span class="org-keyword">sub</span> <span class="org-function-name">print_member</span> ($$) {
<span class="org-type">my</span> ($<span class="org-variable-name">out</span>, $<span class="org-variable-name">member</span>) = @<span class="org-underline"><span class="org-variable-name">_</span></span>;
print $<span class="org-variable-name">out</span> <span class="org-string">" "</span>, $<span class="org-variable-name">member</span>->{<span class="org-string">"username"</span>}, <span class="org-string">":\n"</span>;
The next code block implements the <code>new</code> sub-command. It adds a new
member to the institute's membership roll. It runs an Ansible
playbook to create the member's Nextcloud user, updates
-<q>private/members.yml</q>, and runs the <q>site.yml</q> playbook. The site
+<q>private/members.yml</q>, and runs the <a href="playbooks/site.yml"><q>site.yml</q></a> playbook. The site
playbook (re)creates the member's accounts on Core and Front,
(re)installs the member's personal homepage on Front, and the member's
Fetchmail service on Core. All services are configured with an
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<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 class="org-src-container">
-<q>playbooks/nextcloud-new.yml</q><pre class="src src-conf">- hosts: core
+<a href="playbooks/nextcloud-new.yml"><q>playbooks/nextcloud-new.yml</q></a><pre class="src src-conf">- hosts: core
no_log: yes
tasks:
- name: Run occ user:add.
membership roll, and so receives an encrypted email, which gets piped
into <code>./inst pass</code>. This command decrypts the message, parses the
(YAML) content, updates <q>private/members.yml</q>, and runs the full
-Ansible <q>site.yml</q> playbook to update the servers. If all goes well a
+Ansible <a href="playbooks/site.yml"><q>site.yml</q></a> playbook to update the servers. If all goes well a
message is sent to <code>member@core</code>.
</p>
</div>
(nor equivalent) on Core. It <i>is</i> a set-UID <code>shadow</code> script so it can
read <q>/etc/shadow</q>. The member will need to wait for confirmation
from the administrator, but <i>all</i> keys to <code>root</code> at the institute stay
-in <q>Secret/</q>.
+in <a href="Secret/"><q>Secret/</q></a>.
</p>
<div class="org-src-container">
-<q>roles_t/core/templates/passwd</q><pre class="src src-perl"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/perl -wT</span>
+<a href="roles_t/core/templates/passwd"><q>roles_t/core/templates/passwd</q></a><pre class="src src-perl"><span class="org-comment-delimiter">#</span><span class="org-comment">!/bin/perl -wT</span>
<span class="org-constant">use</span> strict;
<p>
The following code block implements the <code>./inst pass</code> command, used by
the administrator to update <q>private/members.yml</q> before running
-<q>playbooks/site.yml</q> and emailing the concerned member.
+<a href="playbooks/site.yml"><q>playbooks/site.yml</q></a> and emailing the concerned member.
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<span class="org-constant">use</span> MIME::Base64;
<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>) {
</p>
<div class="org-src-container">
-<q>playbooks/nextcloud-pass.yml</q><pre class="src src-conf">- hosts: core
+<a href="playbooks/nextcloud-pass.yml"><q>playbooks/nextcloud-pass.yml</q></a><pre class="src src-conf">- hosts: core
no_log: yes
tasks:
- name: Run occ user:resetpassword.
</p>
<div class="org-src-container">
-<q>roles_t/core/tasks/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/tasks/main.yml"><q>roles_t/core/tasks/main.yml</q></a><pre class="src src-conf">
- name: Install institute passwd command.
become: yes
template:
</div>
<div class="org-src-container">
-<q>roles_t/core/handlers/main.yml</q><pre class="src src-conf">
+<a href="roles_t/core/handlers/main.yml"><q>roles_t/core/handlers/main.yml</q></a><pre class="src src-conf">
- name: Import root PGP key.
become: no
command: gpg --import ~/.gnupg-root-pub.pem
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<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-type">my</span> $<span class="org-variable-name">user</span> = valid_username (@<span class="org-underline"><span class="org-variable-name">ARGV</span></span>);
<span class="org-type">my</span> $<span class="org-variable-name">yaml</span> = read_members_yaml ();
</div>
<div class="org-src-container">
-<q>playbooks/nextcloud-old.yml</q><pre class="src src-conf">- hosts: core
+<a href="playbooks/nextcloud-old.yml"><q>playbooks/nextcloud-old.yml</q></a><pre class="src src-conf">- hosts: core
tasks:
- name: Run occ user:disable.
shell: |
<p>
The <code>client</code> command creates an OpenVPN configuration (<q>.ovpn</q>) file
authorizing wireless devices to connect to the institute's VPNs. The
-command uses the EasyRSA CA in <q>Secret/</q>. The generated configuration
+command uses the EasyRSA CA in <a href="Secret/"><q>Secret/</q></a>. The generated configuration
is slightly different depending on the type of host, given as the
first argument to the command.
</p>
<p>
The OpenVPN configurations generated for Debian hosts specify an <code>up</code>
-script, <q>update-systemd-resolved</q>, installed in <q>/etc/openvpn/</q> by the
+script, <code>update-systemd-resolved</code>, installed in <q>/etc/openvpn/</q> by the
<code>openvpn-systemd-resolved</code> package. The following configuration lines
instruct the OpenVPN clients to run this script whenever the
connection is restarted.
</div>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl"><span class="org-keyword">sub</span> <span class="org-function-name">write_template</span> ($$$$$$$$$);
+<a href="inst"><q>inst</q></a><pre class="src src-perl"><span class="org-keyword">sub</span> <span class="org-function-name">write_template</span> ($$$$$$$$$);
<span class="org-keyword">sub</span> <span class="org-function-name">read_file</span> ($);
<span class="org-keyword">sub</span> <span class="org-function-name">add_client</span> ($$$);
<h3 id="org875755b"><span class="section-number-3">11.11.</span> Institute Command Help</h3>
<div class="outline-text-3" id="text-11-11">
<p>
-This should be the last block tangled into the <q>inst</q> script. It
+This should be the last block tangled into the <a href="inst"><q>inst</q></a> script. It
catches any command lines that were not handled by a sub-command
above.
</p>
<div class="org-src-container">
-<q>inst</q><pre class="src src-perl">
+<a href="inst"><q>inst</q></a><pre class="src src-perl">
<span class="org-keyword">die</span> <span class="org-string">"usage: $0 [CA|config|new|pass|old|client] ...\n"</span>;
</pre>
</div>
<h2 id="org74b454f"><span class="section-number-2">12.</span> Testing</h2>
<div class="outline-text-2" id="text-12">
<p>
-The example files in this document, <q>ansible.cfg</q> and <q>hosts</q> as
-well as those in <q>public/</q> and <q>private/</q>, along with the
+The example files in this document, <a href="ansible.cfg"><q>ansible.cfg</q></a> and <a href="hosts"><q>hosts</q></a> as
+well as those in <a href="public/"><q>public/</q></a> and <a href="private/"><q>private/</q></a>, along with the
matching EasyRSA certificate authority and GnuPG key-ring in
-<q>Secret/</q> (included in the distribution), can be used to configure
+<a href="Secret/"><q>Secret/</q></a> (included in the distribution), can be used to configure
three VirtualBox VMs simulating Core, Gate and Front in a test network
simulating a campus Ethernet, campus ISP, and commercial cloud. With
the test network up and running, a simulated member's notebook can be
<p>
Before rebooting, the MAC addresses of the three network interfaces
-should be compared to the example variable settings in <q>hosts</q>. The
+should be compared to the example variable settings in <a href="hosts"><q>hosts</q></a>. The
values of the <code>gate_lan_mac</code>, <code>gate_wifi_mac</code>, and <code>gate_isp_mac</code>
variables <i>must</i> agree with the MAC addresses assigned to the virtual
machine's network interfaces. The following table assumes device
The administrator will need a desktop system in the test campus
networks (using the campus name server). The test Nextcloud
configuration requires that it be accessed with the domain name
-<q>core.small.private</q>. The following sections describe how a client
+<code>core.small.private</code>. The following sections describe how a client
desktop is simulated and connected to the test VPNs (and test campus
-name server). Its browser can then connect to <q>core.small.private</q> to
+name server). Its browser can then connect to <code>core.small.private</code> to
exercise the test Nextcloud.
</p>
<h3 id="org861e789"><span class="section-number-3">12.11.</span> Test Web Pages</h3>
<div class="outline-text-3" id="text-12-11">
<p>
-Next, the administrator copies <q>Backup/WWW/</q> (included in the
+Next, the administrator copies <a href="Backup/WWW/"><q>Backup/WWW/</q></a> (included in the
distribution) to <q>/WWW/</q> on <code>core</code> and sets the file permissions
appropriately.
</p>
<p>
The <code>backup</code> command has not been tested. It needs an encrypted
partition with which to sync? And then some way to compare that to
-<q>Backup/</q>?
+<a href="Backup/"><q>Backup/</q></a>?
</p>
</div>
</div>
<h4 id="org2053b4a"><span class="section-number-4">13.2.2.</span> Restore</h4>
<div class="outline-text-4" id="text-13-2-2">
<p>
-The restore process has not been tested. It might just copy <q>Backup/</q>
+The restore process has not been tested. It might just copy <a href="Backup/"><q>Backup/</q></a>
to <code>core:/</code>, but then it probably needs to fix up file ownerships,
perhaps permissions too. It could also use an example
<q>Backup/Nextcloud/20220622.bak</q>.
</div></div>
<div id="postamble" class="status">
<p class="author">Author: Matt Birkholz</p>
-<p class="date">Created: 2023-12-17 Sun 16:05</p>
+<p class="date">Created: 2023-12-28 Thu 16:07</p>
<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>