From 86964fe9486c73c726b8ae0eb537d7956e17f81d Mon Sep 17 00:00:00 2001 From: Matt Birkholz Date: Thu, 28 Dec 2023 16:07:43 -0700 Subject: [PATCH] Update README.html. --- README.html | 717 ++++++++++++++++++++++++++-------------------------- 1 file changed, 353 insertions(+), 364 deletions(-) diff --git a/README.html b/README.html index e8d92c4..dd4aae3 100644 --- a/README.html +++ b/README.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + A Small Institute @@ -48,7 +48,7 @@ connects to Front making the institute email, cloud, etc. available to members off campus.

-
+
                 =                                                   
               _|||_                                                 
         =-The-Institute-=                                           
@@ -149,12 +149,12 @@ month) because of this assumption.
 

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.

@@ -227,7 +227,7 @@ declared by the institute's SPF (Sender Policy Framework) DNS record 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 not -sign outgoing emails per DKIM (Domain Keys Identified Mail), yet. +sign outgoing emails per DKIM (Domain Keys Identified Mail) yet.

@@ -398,8 +398,8 @@ PHP) stack. 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. www.small.private. In many cases these -domain names can be shortened e.g. to www. Thus the campus home +become available, e.g. www.small.private. In many cases these +domain names can be shortened e.g. to www. Thus the campus home page is accessible in a dozen keystrokes: http://www/ (plus Enter).

@@ -607,9 +607,9 @@ initial, privileged user account the same name is given (e.g. as described in The Core Machine). Installation may not prompt and still create an initial user account with a distribution specific name (e.g. pi). Any name can be used as long as it is provided as the -value of ansible_user in hosts. Its password is specified by a -vault-encrypted variable in the Secret/become.yml file. (The -hosts and Secret/become.yml files are described in The Ansible +value of ansible_user in hosts. Its password is specified by a +vault-encrypted variable in the Secret/become.yml file. (The +hosts and Secret/become.yml files are described in The Ansible Configuration.)

@@ -632,49 +632,51 @@ account is created on Front as well.

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 Secret/ +Setup) format partition on a USB pen/stick. The Secret/ sub-directory is actually a symbolic link to this partition's automatic mount point, e.g. /media/sysadm/ADE7-F866/. Unless this -volume is mounted (unlocked) at Secret/, none of the ./inst +volume is mounted (unlocked) at Secret/, none of the ./inst commands will work.

-Chief among the institute's master secrets is the SSH key to the -privileged accounts on all of the institute servers. It is stored -in Secret/ssh_admin/id_rsa. 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 all of the institute servers. It +is stored in Secret/ssh_admin/id_rsa. The complete list of the +institute's SSH keys:

-
Secret/ssh_admin/
The SSH key pair for A Small Institute +
Secret/ssh_admin/
The SSH key pair for A Small Institute Administrator.
-
Secret/ssh_monkey/
The key pair used by Monkey to update the +
Secret/ssh_monkey/
The key pair used by Monkey to update the website on Front (and other unprivileged tasks).
-
Secret/ssh_front/
The host key pair used by Front to -authenticate itself.
+
Secret/ssh_front/
The host key pair used by Front to +authenticate itself. The automatically generated key pair is +not used. (Thus Core's configuration does not depend on +Front's.)

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 Secret/CA/. +Authority stored in Secret/CA/.

-
Secret/CA/pki/ca.crt
The institute CA (certificate -authority).
+
Secret/CA/pki/ca.crt
The institute CA certificate, used to +sign the other certificates.
-
Secret/CA/pki/issued/small.example.org.crt
The public Apache, +
Secret/CA/pki/issued/small.example.org.crt
The public Apache, Postfix, and OpenVPN servers on Front.
-
Secret/CA/pki/issued/gate.small.private.crt
The campus +
Secret/CA/pki/issued/gate.small.private.crt
The campus OpenVPN server on Gate.
-
Secret/CA/pki/issued/core.small.private.crt
The campus +
Secret/CA/pki/issued/core.small.private.crt
The campus Apache (thus Nextcloud), and Dovecot-IMAPd servers.
-
Secret/CA/pki/issued/core.crt
Core's client certificate by +
Secret/CA/pki/issued/core.crt
Core's client certificate, by which it authenticates to Front.
@@ -694,17 +696,17 @@ Finally, the institute uses an OpenPGP key to secure sensitive emails

-
Secret/root.gnupg/
The "home directory" used to create the +
Secret/root.gnupg/
The "home directory" used to create the public/secret key pair.
-
Secret/root-pub.pem
The ASCII armored OpenPGP public key for +
Secret/root-pub.pem
The ASCII armored OpenPGP public key for e.g. root@core.small.private.
-
Secret/root-sec.pem
The ASCII armored OpenPGP secret key.
+
Secret/root-sec.pem
The ASCII armored OpenPGP secret key.

-When The CA Command sees an empty Secret/CA/ directory, as +When The CA Command sees an empty Secret/CA/ directory, as though just created by running the EasyRSA make-cadir command in -Secret/ (a new, encrypted volume), the ./inst CA command creates +Secret/ (a new, encrypted volume), the ./inst CA command creates all of the certificates and keys mentioned above. It may prompt for the institute's full name.

@@ -766,7 +768,7 @@ files mentioned in the Nextcloud database dump).

-private/backup
#!/bin/bash -e
+private/backup
#!/bin/bash -e
 #
 # DO NOT EDIT.  Maintained (will be replaced) by Ansible.
 #
@@ -877,7 +879,7 @@ This chapter introduces Ansible variables intended to simplify
 changes, like customization for another institute's particulars.  The
 variables are separated into public information (e.g. an institute's
 name) or private information (e.g. a network interface address), and
-stored in separate files: public/vars.yml and private/vars.yml.
+stored in separate files: public/vars.yml and private/vars.yml.
 

@@ -898,7 +900,7 @@ replace {{ domain_name }} in the code with small.example.org<

-public/vars.yml
---
+public/vars.yml
---
 domain_name: small.example.org
 domain_priv: small.private
 
@@ -906,8 +908,8 @@ domain_priv: small.private

The private version of the institute's domain name should end with one -of the top-level domains expected for this purpose: .intranet, -.internal, .private, .corp, .home or .lan.1 +of the top-level domains expected for this purpose: .intranet, +.internal, .private, .corp, .home or .lan.1

@@ -1012,17 +1014,24 @@ example result follows the code.
+
+

+=> 10.62.17.0/24 +

+ +
+

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 -private/vars.yml rather than public/vars.yml. Two of the +private/vars.yml rather than public/vars.yml. Two of the addresses are in 192.168 subnets because they are part of a test configuration using mostly-default VirtualBoxes (described here).

-private/vars.yml
---
+private/vars.yml
---
 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
@@ -1039,7 +1048,7 @@ e.g. _net_and_mask rather than _net_cidr.
 

-private/vars.yml
private_net:             "{{ private_net_cidr | ipaddr('network') }}"
+private/vars.yml
private_net:             "{{ private_net_cidr | ipaddr('network') }}"
 private_net_mask:        "{{ private_net_cidr | ipaddr('netmask') }}"
 private_net_and_mask:      "{{ private_net }} {{ private_net_mask }}"
 public_vpn_net:       "{{ public_vpn_net_cidr | ipaddr('network') }}"
@@ -1066,7 +1075,7 @@ the institute's Internet domain name.
 

-public/vars.yml
front_addr: 192.168.15.5
+public/vars.yml
front_addr: 192.168.15.5
 
@@ -1090,7 +1099,7 @@ The following code block picks the obvious IP addresses for Core

-private/vars.yml
core_addr_cidr:             "{{ private_net_cidr | ipaddr('1') }}"
+private/vars.yml
core_addr_cidr:             "{{ private_net_cidr | ipaddr('1') }}"
 gate_addr_cidr:             "{{ private_net_cidr | ipaddr('2') }}"
 gate_wifi_addr_cidr:        "{{ gate_wifi_net_cidr | ipaddr('1') }}"
 wifi_wan_addr_cidr:         "{{ gate_wifi_net_cidr | ipaddr('2') }}"
@@ -1180,8 +1189,8 @@ notebook$
 
 

The password was generated by gpw, saved in the administrator's -password keep, and later added to Secret/become.yml as shown below. -(Producing a working Ansible configuration with Secret/become.yml +password keep, and later added to Secret/become.yml as shown below. +(Producing a working Ansible configuration with Secret/become.yml file is described in The Ansible Configuration.)

@@ -1197,7 +1206,7 @@ notebook_ >>Secret/become.yml

After creating the sysadm account on the droplet, the administrator concatenated a personal public ssh key and the key found in -Secret/ssh_admin/ (created by The CA Command) into an admin_keys +Secret/ssh_admin/ (created by The CA Command) into an admin_keys file, copied it to the droplet, and installed it as the authorized_keys for sysadm.

@@ -1299,8 +1308,8 @@ Is the information correct? [Y/n]

The password was generated by gpw, saved in the administrator's -password keep, and later added to Secret/become.yml as shown below. -(Producing a working Ansible configuration with Secret/become.yml +password keep, and later added to Secret/become.yml as shown below. +(Producing a working Ansible configuration with Secret/become.yml file is described in The Ansible Configuration.)

@@ -1340,7 +1349,7 @@ _ libapache2-mod-php

Next, the administrator concatenated a personal public ssh key and the -key found in Secret/ssh_admin/ (created by The CA Command) into an +key found in Secret/ssh_admin/ (created by The CA Command) into an admin_keys file, copied it to Core, and installed it as the authorized_keys for sysadm.

@@ -1420,7 +1429,7 @@ USB-Ethernet adapter, or a wireless adapter connected to a campground Wi-Fi access point, etc. -
+
 =============== | ==================================================
                 |                                           Premises
           (Campus ISP)                                              
@@ -1443,7 +1452,7 @@ This avoids the need for a second Wi-Fi access point and leads to the
 following topology.
 

-
+
 =============== | ==================================================
                 |                                           Premises
            (House ISP)                                              
@@ -1495,8 +1504,8 @@ Is the information correct? [Y/n]
 
 

The password was generated by gpw, saved in the administrator's -password keep, and later added to Secret/become.yml as shown below. -(Producing a working Ansible configuration with Secret/become.yml +password keep, and later added to Secret/become.yml as shown below. +(Producing a working Ansible configuration with Secret/become.yml file is described in The Ansible Configuration.)

@@ -1522,7 +1531,7 @@ $ sudo apt install openssh-server isc-dhcp-server netplan.io

Next, the administrator concatenated a personal public ssh key and the -key found in Secret/ssh_admin/ (created by The CA Command) into an +key found in Secret/ssh_admin/ (created by The CA Command) into an admin_keys file, copied it to Gate, and installed it as the authorized_keys for sysadm.

@@ -1615,8 +1624,8 @@ uses the institute's CA and server certificates, and expects client certificates signed by the institute CA.

-
-

6.1. Include Particulars

+
+

6.1. Include Particulars

The front role's tasks contain references to several common @@ -1628,11 +1637,11 @@ Particulars and Account Management).

The code block below is the first to tangle into -roles/front/tasks/main.yml. +roles/front/tasks/main.yml.

-roles/front/tasks/main.yml
---
+roles/front/tasks/main.yml
---
 - name: Include public variables.
   include_vars: ../public/vars.yml
   tags: accounts
@@ -1648,8 +1657,8 @@ The code block below is the first to tangle into
 
-
-

6.2. Configure Hostname

+
+

6.2. Configure Hostname

This task ensures that Front's /etc/hostname and /etc/mailname are @@ -1658,7 +1667,7 @@ delivery.

-roles_t/front/tasks/main.yml
- name: Configure hostname.
+roles_t/front/tasks/main.yml
- name: Configure hostname.
   become: yes
   copy:
     content: "{{ domain_name }}\n"
@@ -1671,7 +1680,7 @@ delivery.
 
-roles_t/front/handlers/main.yml
---
+roles_t/front/handlers/main.yml
---
 - name: Update hostname.
   become: yes
   command: hostname -F /etc/hostname
@@ -1701,7 +1710,7 @@ separate code block named enable-resolved.
 
 
-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install systemd-resolved.
   become: yes
   apt: pkg=systemd-resolved
@@ -1773,8 +1782,8 @@ separate code block named enable-resolved.
 
-
-

6.4. Add Administrator to System Groups

+
+

6.4. Add Administrator to System Groups

The administrator often needs to read (directories of) log files owned @@ -1783,7 +1792,7 @@ these groups speeds up debugging.

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Add {{ ansible_user }} to system groups.
   become: yes
   user:
@@ -1800,11 +1809,11 @@ these groups speeds up debugging.
 

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 Secret/ssh_front/etc/ssh/ and restarting the server. +those stored in Secret/ssh_front/etc/ssh/ and restarting the server.

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install SSH host keys.
   become: yes
   copy:
@@ -1823,7 +1832,7 @@ those stored in Secret/ssh_front/etc/ssh/ and restarting the server.
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: Reload SSH server.
   become: yes
   systemd:
@@ -1833,8 +1842,8 @@ those stored in Secret/ssh_front/etc/ssh/ and restarting the server.
 
-
-

6.6. Configure Monkey

+
+

6.6. Configure Monkey

The small institute runs cron jobs and web scripts that generate @@ -1848,7 +1857,7 @@ key on Core.

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Create monkey.
   become: yes
   user:
@@ -1882,7 +1891,7 @@ Monkey uses Rsync to keep the institute's public web site up-to-date.
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install rsync.
   become: yes
   apt: pkg=rsync
@@ -1890,15 +1899,15 @@ Monkey uses Rsync to keep the institute's public web site up-to-date.
 
-
-

6.8. Install Unattended Upgrades

+
+

6.8. Install Unattended Upgrades

The institute prefers to install security updates as soon as possible.

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install basic software.
   become: yes
   apt: pkg=unattended-upgrades
@@ -1906,8 +1915,8 @@ The institute prefers to install security updates as soon as possible.
 
-
-

6.9. Configure User Accounts

+
+

6.9. Configure User Accounts

User accounts are created immediately so that Postfix and Dovecot can @@ -1917,7 +1926,7 @@ recipient" replies. The Account Management chapter de

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Create user accounts.
   become: yes
   user:
@@ -1950,8 +1959,8 @@ recipient" replies.  The Account Management chapter de
 
-
-

6.10. Trust Institute Certificate Authority

+
+

6.10. Trust Institute Certificate Authority

Front should recognize the institute's Certificate Authority as @@ -1961,7 +1970,7 @@ X.509 certificates is available in Keys.

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Trust the institute CA.
   become: yes
   copy:
@@ -1975,7 +1984,7 @@ X.509 certificates is available in Keys.
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: Update CAs.
   become: yes
   command: update-ca-certificates
@@ -1983,8 +1992,8 @@ X.509 certificates is available in Keys.
 
-
-

6.11. Install Server Certificate

+
+

6.11. Install Server Certificate

The servers on Front use the same certificate (and key) to @@ -1994,7 +2003,7 @@ readable by root.

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install server certificate/key.
   become: yes
   copy:
@@ -2133,7 +2142,7 @@ start and enable the service.
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install Postfix.
   become: yes
   apt: pkg=postfix
@@ -2189,7 +2198,7 @@ start and enable the service.
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: Restart Postfix.
   become: yes
   systemd:
@@ -2224,7 +2233,7 @@ created by a more specialized role.
 

-roles_t/front/tasks/main.yml
- name: Install institute email aliases.
+roles_t/front/tasks/main.yml
- name: Install institute email aliases.
   become: yes
   blockinfile:
     block: |
@@ -2240,7 +2249,7 @@ created by a more specialized role.
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: New aliases.
   become: yes
   command: newaliases
@@ -2248,8 +2257,8 @@ created by a more specialized role.
 
-
-

6.14. Configure Dovecot IMAPd

+
+

6.14. Configure Dovecot IMAPd

Front uses Dovecot's IMAPd to allow user Fetchmail jobs on Core to @@ -2277,7 +2286,7 @@ and enables it to start at every reboot.

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install Dovecot IMAPd.
   become: yes
   apt: pkg=dovecot-imapd
@@ -2309,7 +2318,7 @@ and enables it to start at every reboot.
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: Restart Dovecot.
   become: yes
   systemd:
@@ -2530,7 +2539,7 @@ e.g. /etc/apache2/sites-available/small.example.org.conf and runs
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install Apache2.
   become: yes
   apt: pkg=apache2
@@ -2634,7 +2643,7 @@ e.g. /etc/apache2/sites-available/small.example.org.conf and runs
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: Restart Apache2.
   become: yes
   systemd:
@@ -2649,7 +2658,7 @@ that it does not interfere with its replacement.
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Disable default vhosts.
   become: yes
   file:
@@ -2667,7 +2676,7 @@ same records as access.log.
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Disable other-vhosts-access-log option.
   become: yes
   file:
@@ -2683,7 +2692,7 @@ the users' ~/Public/HTML/ directories.
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Create UserDir.
   become: yes
   file:
@@ -2713,8 +2722,8 @@ the users' ~/Public/HTML/ directories.
 
-
-

6.16. Configure OpenVPN

+
+

6.16. Configure OpenVPN

Front uses OpenVPN to provide the institute's public VPN service. The @@ -2795,7 +2804,7 @@ configure the OpenVPN server on Front.

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install OpenVPN.
   become: yes
   apt: pkg=openvpn
@@ -2901,7 +2910,7 @@ configure the OpenVPN server on Front.
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: Restart OpenVPN.
   become: yes
   systemd:
@@ -2950,7 +2959,7 @@ The first step is to install Kamailio.
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Install Kamailio.
   become: yes
   apt: pkg=kamailio
@@ -2965,7 +2974,7 @@ be started before the tun device has appeared.
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Create Kamailio/Systemd configuration drop.
   become: yes
   file:
@@ -2985,7 +2994,7 @@ be started before the tun device has appeared.
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: Reload Systemd.
   become: yes
   command: systemctl daemon-reload
@@ -2997,7 +3006,7 @@ Finally, Kamailio can be configured and started.
 

-roles_t/front/tasks/main.yml
+roles_t/front/tasks/main.yml
 - name: Configure Kamailio.
   become: yes
   copy:
@@ -3016,7 +3025,7 @@ Finally, Kamailio can be configured and started.
 
-roles_t/front/handlers/main.yml
+roles_t/front/handlers/main.yml
 - name: Restart Kamailio.
   become: yes
   systemd:
@@ -3038,8 +3047,8 @@ Debian install and remote access to a privileged, administrator's
 account.  (For details, see The Core Machine.)
 

-
-

7.1. Include Particulars

+
+

7.1. Include Particulars

The first task, as in The Front Role, is to include the institute @@ -3047,7 +3056,7 @@ particulars and membership roll.

-roles_t/core/tasks/main.yml
---
+roles_t/core/tasks/main.yml
---
 - name: Include public variables.
   include_vars: ../public/vars.yml
   tags: accounts
@@ -3061,8 +3070,8 @@ particulars and membership roll.
 
-
-

7.2. Configure Hostname

+
+

7.2. Configure Hostname

This task ensures that Core's /etc/hostname and /etc/mailname are @@ -3073,7 +3082,7 @@ proper email delivery.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Configure hostname.
   become: yes
   copy:
@@ -3087,7 +3096,7 @@ proper email delivery.
 
-roles_t/core/handlers/main.yml
---
+roles_t/core/handlers/main.yml
---
 - name: Update hostname.
   become: yes
   command: hostname -F /etc/hostname
@@ -3095,8 +3104,8 @@ proper email delivery.
 
-
-

7.3. Enable Systemd Resolved

+
+

7.3. Enable Systemd Resolved

Core starts the systemd-networkd and systemd-resolved service @@ -3104,7 +3113,7 @@ units on boot. See Enable Systemd Resolved.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install systemd-resolved.
   become: yes
   apt: pkg=systemd-resolved
@@ -3140,8 +3149,8 @@ units on boot.  See Enable Systemd Resolved.
 
-
-

7.4. Configure Systemd Resolved

+
+

7.4. Configure Systemd Resolved

Core runs the campus name server, so Resolved is configured to use it @@ -3150,7 +3159,7 @@ list, and to disable its cache and stub listener.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Configure resolved.
   become: yes
   lineinfile:
@@ -3170,7 +3179,7 @@ list, and to disable its cache and stub listener.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Reload Systemd.
   become: yes
   command: systemctl daemon-reload
@@ -3198,7 +3207,7 @@ VPN.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install netplan.
   become: yes
   apt: pkg=netplan.io
@@ -3224,7 +3233,7 @@ VPN.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Apply netplan.
   become: yes
   command: netplan apply
@@ -3244,16 +3253,16 @@ Service.
 

-The example configuration file, private/core-dhcpd.conf, uses +The example configuration file, private/core-dhcpd.conf, 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 private/core-dhcpd.conf file. +the actual private/core-dhcpd.conf file.

-private/core-dhcpd.conf
option domain-name "small.private";
+private/core-dhcpd.conf
option domain-name "small.private";
 option domain-name-servers 192.168.56.1;
 
 default-lease-time 3600;
@@ -3286,11 +3295,11 @@ log-facility daemon;
 
 

The following tasks install the ISC's DHCP server and configure it -with the real private/core-dhcpd.conf (not the example above). +with the real private/core-dhcpd.conf (not the example above).

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install DHCP server.
   become: yes
   apt: pkg=isc-dhcp-server
@@ -3320,7 +3329,7 @@ with the real private/core-dhcpd.conf (not the example above).
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Restart DHCP server.
   become: yes
   systemd:
@@ -3345,7 +3354,7 @@ The following tasks install and configure BIND9 on Core.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install BIND9.
   become: yes
   apt: pkg=bind9
@@ -3440,7 +3449,7 @@ The following tasks install and configure BIND9 on Core.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Reload BIND9.
   become: yes
   systemd:
@@ -3524,7 +3533,7 @@ craps up /var/log/ and the Systemd journal.
 
-private/db.domain
;
+private/db.domain
;
 ; BIND data file for a small institute's PRIVATE domain names.
 ;
 $TTL    604800
@@ -3552,7 +3561,7 @@ craps up /var/log/ and the Systemd journal.
 
-private/db.private
;
+private/db.private
;
 ; BIND reverse data file for a small institute's private Ethernet.
 ;
 $TTL    604800
@@ -3571,7 +3580,7 @@ craps up /var/log/ and the Systemd journal.
 
-private/db.public_vpn
;
+private/db.public_vpn
;
 ; BIND reverse data file for a small institute's public VPN.
 ;
 $TTL    604800
@@ -3590,7 +3599,7 @@ craps up /var/log/ and the Systemd journal.
 
-private/db.campus_vpn
;
+private/db.campus_vpn
;
 ; BIND reverse data file for a small institute's campus VPN.
 ;
 $TTL    604800
@@ -3608,8 +3617,8 @@ craps up /var/log/ and the Systemd journal.
 
-
-

7.8. Add Administrator to System Groups

+
+

7.8. Add Administrator to System Groups

The administrator often needs to read (directories of) log files owned @@ -3618,7 +3627,7 @@ these groups speeds up debugging.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Add {{ ansible_user }} to system groups.
   become: yes
   user:
@@ -3629,8 +3638,8 @@ these groups speeds up debugging.
 
-
-

7.9. Configure Monkey

+
+

7.9. Configure Monkey

The small institute runs cron jobs and web scripts that generate @@ -3641,7 +3650,7 @@ described in *Configure Apache2).

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Create monkey.
   become: yes
   user:
@@ -3705,7 +3714,7 @@ The institute prefers to install security updates as soon as possible.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install basic software.
   become: yes
   apt: pkg=unattended-upgrades
@@ -3722,7 +3731,7 @@ with Nextcloud on the command line.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install expect.
   become: yes
   apt: pkg=expect
@@ -3730,8 +3739,8 @@ with Nextcloud on the command line.
 
-
-

7.12. Configure User Accounts

+
+

7.12. Configure User Accounts

User accounts are created immediately so that backups can begin @@ -3740,7 +3749,7 @@ describes the members and usernames variables.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Create user accounts.
   become: yes
   user:
@@ -3773,8 +3782,8 @@ describes the members and usernames variables.
 
-
-

7.13. Trust Institute Certificate Authority

+
+

7.13. Trust Institute Certificate Authority

Core should recognize the institute's Certificate Authority as @@ -3784,7 +3793,7 @@ X.509 certificates is available in Keys.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Trust the institute CA.
   become: yes
   copy:
@@ -3798,7 +3807,7 @@ X.509 certificates is available in Keys.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Update CAs.
   become: yes
   command: update-ca-certificates
@@ -3806,8 +3815,8 @@ X.509 certificates is available in Keys.
 
-
-

7.14. Install Server Certificate

+
+

7.14. Install Server Certificate

The servers on Core use the same certificate (and key) to authenticate @@ -3816,7 +3825,7 @@ themselves to institute clients. They share the /etc/server.crt and

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install server certificate/key.
   become: yes
   copy:
@@ -3845,7 +3854,7 @@ The default daemon's default configuration is fine.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install NTP.
   become: yes
   apt: pkg=ntp
@@ -3952,7 +3961,7 @@ enable the service.  Whenever /etc/postfix/transport is changed, the
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install Postfix.
   become: yes
   apt: pkg=postfix
@@ -4005,7 +4014,7 @@ enable the service.  Whenever /etc/postfix/transport is changed, the
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Restart Postfix.
   become: yes
   systemd:
@@ -4035,7 +4044,7 @@ installed by more specialized roles.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install institute email aliases.
   become: yes
   blockinfile:
@@ -4052,7 +4061,7 @@ installed by more specialized roles.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: New aliases.
   become: yes
   command: newaliases
@@ -4060,8 +4069,8 @@ installed by more specialized roles.
 
-
-

7.18. Configure Dovecot IMAPd

+
+

7.18. Configure Dovecot IMAPd

Core uses Dovecot's IMAPd to store and serve member emails. As on @@ -4089,7 +4098,7 @@ and enables it to start at every reboot.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install Dovecot IMAPd.
   become: yes
   apt: pkg=dovecot-imapd
@@ -4116,7 +4125,7 @@ and enables it to start at every reboot.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Restart Dovecot.
   become: yes
   systemd:
@@ -4191,7 +4200,7 @@ provided the Core service.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install fetchmail.
   become: yes
   apt: pkg=fetchmail
@@ -4267,7 +4276,7 @@ stopped and disabled from restarting at boot, deleted even.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Stop former user fetchmail services.
   become: yes
   systemd:
@@ -4493,7 +4502,7 @@ interfere with mapping URLs to the correct virtual host.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install Apache2.
   become: yes
   apt: pkg=apache2
@@ -4523,7 +4532,7 @@ The a2ensite command enables them.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install live web site.
   become: yes
   copy:
@@ -4634,7 +4643,7 @@ The a2ensite command enables them.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Restart Apache2.
   become: yes
   systemd:
@@ -4654,7 +4663,7 @@ Monkey on Core runs /usr/local/sbin/webupdate every 15 minutes via a
 

-private/webupdate
#!/bin/bash -e
+private/webupdate
#!/bin/bash -e
 #
 # DO NOT EDIT.  This file was tangled from institute.org.
 
@@ -4668,13 +4677,13 @@ rsync -avz --delete --chmod=g-w         \
 
 

-The following tasks install the webupdate script from private/, +The following tasks install the webupdate script from private/, and create Monkey's cron job. An example webupdate script is provided here.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: "Install Monkey's webupdate script."
   become: yes
   copy:
@@ -4740,7 +4749,7 @@ for Core.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install OpenVPN.
   become: yes
   apt: pkg=openvpn
@@ -4807,7 +4816,7 @@ for Core.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Restart OpenVPN.
   become: yes
   systemd:
@@ -4838,7 +4847,7 @@ Core and Campus (and thus Gate) machines.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install NAGIOS4.
   become: yes
   apt:
@@ -4890,7 +4899,7 @@ Core and Campus (and thus Gate) machines.
 
-roles_t/core/handlers/main.yml
+roles_t/core/handlers/main.yml
 - name: Reload NAGIOS4.
   become: yes
   systemd:
@@ -4910,7 +4919,7 @@ used here may specify plugin arguments.
 

-roles_t/core/templates/nagios.cfg
define host {
+roles_t/core/templates/nagios.cfg
define host {
     use                     linux-server
     host_name               core
     address                 127.0.0.1
@@ -4986,7 +4995,7 @@ small institute substitutes a slightly modified version,
 

-roles_t/core/files/inst_sensors
#!/bin/sh
+roles_t/core/files/inst_sensors
#!/bin/sh
 
 PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
 export PATH
@@ -5071,7 +5080,7 @@ Core.
 

-roles_t/core/templates/nagios.cfg
+roles_t/core/templates/nagios.cfg
 define command {
     command_name            inst_sensors
     command_line            /usr/local/sbin/inst_sensors
@@ -5118,19 +5127,12 @@ pings.
 

-roles_t/core/templates/nagios.cfg
+roles_t/core/templates/nagios.cfg
 define host {
     use                     linux-server
     host_name               gate
     address                 {{ gate_addr }}
 }
-
-define service {
-    use                     local-service
-    host_name               gate
-    service_description     PING
-    check_command           check_ping!100.0,20%!500.0,60%
-}
 
@@ -5140,7 +5142,7 @@ space on the root partition.

-roles_t/campus/files/nrpe.cfg
command[inst_root]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
+roles_t/campus/files/nrpe.cfg
command[inst_root]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
 
@@ -5149,7 +5151,7 @@ Monitor inst_root on Gate.

-roles_t/core/templates/nagios.cfg
+roles_t/core/templates/nagios.cfg
 define service {
     use                     generic-service
     host_name               gate
@@ -5164,7 +5166,7 @@ Monitor check_load on Gate.
 

-roles_t/core/templates/nagios.cfg
+roles_t/core/templates/nagios.cfg
 define service {
     use                     generic-service
     host_name               gate
@@ -5179,7 +5181,7 @@ Monitor check_zombie_procs and check_total_procs on Ga
 

-roles_t/core/templates/nagios.cfg
+roles_t/core/templates/nagios.cfg
 define service {
     use                     generic-service
     host_name               gate
@@ -5202,7 +5204,7 @@ usage.
 

-roles_t/campus/files/nrpe.cfg
command[inst_swap]=/usr/lib/nagios/plugins/check_swap -w 20% -c 10%
+roles_t/campus/files/nrpe.cfg
command[inst_swap]=/usr/lib/nagios/plugins/check_swap -w 20% -c 10%
 
@@ -5211,7 +5213,7 @@ Monitor inst_swap on Gate.

-roles_t/core/templates/nagios.cfg
+roles_t/core/templates/nagios.cfg
 define service {
     use                     generic-service
     host_name               gate
@@ -5221,28 +5223,13 @@ Monitor inst_swap on Gate.
 
-

-Monitor Gate's SSH service. -

- -
-roles_t/core/templates/nagios.cfg
-define service {
-    use                     generic-service
-    host_name               gate
-    service_description     SSH
-    check_command           check_ssh
-}
-
-
-

For all campus NRPE servers: an inst_sensors command to report core CPU temperatures.

-roles_t/campus/files/nrpe.cfg
command[inst_sensors]=/usr/local/sbin/inst_sensors
+roles_t/campus/files/nrpe.cfg
command[inst_sensors]=/usr/local/sbin/inst_sensors
 
@@ -5251,7 +5238,7 @@ Monitor inst_sensors on Gate.

-roles_t/core/templates/nagios.cfg
+roles_t/core/templates/nagios.cfg
 define service {
     use                     generic-service
     host_name               gate
@@ -5267,12 +5254,12 @@ Monitor inst_sensors on Gate.
 

7.24. Configure Backups

-The following task installs the backup script from private/. An +The following task installs the backup script from private/. An example script is provided in here.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install backup script.
   become: yes
   copy:
@@ -5305,7 +5292,7 @@ installing a cron job.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install packages required by Nextcloud.
   become: yes
   apt:
@@ -5321,7 +5308,7 @@ Next, a number of Apache2 modules are enabled.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Enable Apache2 modules for Nextcloud.
   become: yes
   apache2_module:
@@ -5339,7 +5326,7 @@ Administration Guide (sub-section 
-roles_t/core/files/nextcloud.conf
Alias /nextcloud "/var/www/nextcloud/"
+roles_t/core/files/nextcloud.conf
Alias /nextcloud "/var/www/nextcloud/"
 
 <Directory /var/www/nextcloud/>
     Require all granted
@@ -5354,7 +5341,7 @@ Administration Guide (sub-section 
-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Install Nextcloud web configuration.
   become: yes
   copy:
@@ -5379,7 +5366,7 @@ virtual host's document root.
 

-roles_t/core/files/nextcloud.conf
+roles_t/core/files/nextcloud.conf
 <Directory /var/www/html/>
     <IfModule mod_rewrite.c>
         RewriteEngine on
@@ -5405,7 +5392,7 @@ page.  The following portion of nextcloud.conf sets a
 

-roles_t/core/files/nextcloud.conf
+roles_t/core/files/nextcloud.conf
 <IfModule mod_headers.c>
     Header always set \
         Strict-Transport-Security "max-age=15552000; includeSubDomains"
@@ -5421,7 +5408,7 @@ cloud FUBARs.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Add {{ ansible_user }} to web server group.
   become: yes
   user:
@@ -5437,7 +5424,7 @@ jobs.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Create Nextcloud cron job.
   become: yes
   cron:
@@ -5453,12 +5440,12 @@ jobs.
 

Nextcloud's MariaDB database (and user) are created by the following tasks. The user's password is taken from the nextcloud_dbpass -variable, kept in private/vars.yml, and generated e.g. with +variable, kept in private/vars.yml, and generated e.g. with the apg -n 1 -x 12 -m 12 command.

-private/vars.yml
nextcloud_dbpass:           ippAgmaygyob
+private/vars.yml
nextcloud_dbpass:           ippAgmaygyob
 
@@ -5515,7 +5502,7 @@ its document root.

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Link /var/www/nextcloud.
   become: yes
   file:
@@ -5537,7 +5524,7 @@ performance, as recommended by Nextcloud.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Set PHP memory_limit for Nextcloud.
   become: yes
   lineinfile:
@@ -5769,7 +5756,7 @@ afterwards tasks causes them to skip rather than fail.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Test for /Nextcloud/nextcloud/.
   stat:
     path: /Nextcloud/nextcloud
@@ -5800,7 +5787,7 @@ Pretty URLs (below).
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Configure Nextcloud trusted domains.
   become: yes
   replace:
@@ -5832,7 +5819,7 @@ enables it.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Configure Nextcloud memcache.
   become: yes
   lineinfile:
@@ -5854,7 +5841,7 @@ and htaccess.RewriteBase.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Configure Nextcloud for Pretty URLs.
   become: yes
   lineinfile:
@@ -5880,12 +5867,12 @@ a complaint on the Settings > Administration > Overview web page.
 

-private/vars.yml
nextcloud_region:           US
+private/vars.yml
nextcloud_region:           US
 
-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Configure Nextcloud phone region.
   become: yes
   lineinfile:
@@ -5908,7 +5895,7 @@ run before the next backup.
 

-roles_t/core/tasks/main.yml
+roles_t/core/tasks/main.yml
 - name: Create /Nextcloud/dbbackup.cnf.
   no_log: yes
   become: yes
@@ -5967,15 +5954,15 @@ applied first, by which Gate gets a campus machine's DNS and Postfix
 configurations, etc.
 

-
-

8.1. Include Particulars

+
+

8.1. Include Particulars

The following should be familiar boilerplate by now.

-roles_t/gate/tasks/main.yml
---
+roles_t/gate/tasks/main.yml
---
 - name: Include public variables.
   include_vars: ../public/vars.yml
   tags: accounts
@@ -6001,12 +5988,12 @@ be revised more frequently as the campus ISP changes.
 
 

Netplan is configured to identify the interfaces by their MAC -addresses, which must be provided in private/vars.yml, as in the +addresses, which must be provided in private/vars.yml, as in the example code here.

-private/vars.yml
gate_lan_mac:               ff:ff:ff:ff:ff:ff
+private/vars.yml
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
 
@@ -6018,7 +6005,7 @@ new network plan.

-roles_t/gate/tasks/main.yml
+roles_t/gate/tasks/main.yml
 - name: Install netplan (gate).
   become: yes
   apt: pkg=netplan.io
@@ -6072,7 +6059,7 @@ new network plan.
 
-roles_t/gate/handlers/main.yml
---
+roles_t/gate/handlers/main.yml
---
 - name: Apply netplan.
   become: yes
   command: netplan apply
@@ -6192,7 +6179,7 @@ sudo ufw enable
 
 
 
-roles_t/gate/tasks/main.yml
+roles_t/gate/tasks/main.yml
 - name: Install UFW.
   become:
   apt: pkg=ufw
@@ -6259,7 +6246,7 @@ AP's MAC address.
 

-private/vars.yml
wifi_wan_mac:               94:83:c4:19:7d:57
+private/vars.yml
wifi_wan_mac:               94:83:c4:19:7d:57
 wifi_wan_name:              campus-wifi-ap
 
@@ -6287,7 +6274,7 @@ the daemon listens only on the Gate-WiFi network interface.

-roles_t/gate/tasks/main.yml
+roles_t/gate/tasks/main.yml
 - name: Install DHCP server.
   become: yes
   apt: pkg=isc-dhcp-server
@@ -6332,7 +6319,7 @@ the daemon listens only on the Gate-WiFi network interface.
 
-roles_t/gate/handlers/main.yml
+roles_t/gate/handlers/main.yml
 - name: Restart DHCP server.
   become: yes
   systemd:
@@ -6342,8 +6329,8 @@ the daemon listens only on the Gate-WiFi network interface.
 
-
-

8.6. Install Server Certificate

+
+

8.6. Install Server Certificate

The (OpenVPN) server on Gate uses an institute certificate (and key) @@ -6353,7 +6340,7 @@ and Front) do.

-roles_t/gate/tasks/main.yml
+roles_t/gate/tasks/main.yml
 - name: Install server certificate/key.
   become: yes
   copy:
@@ -6370,8 +6357,8 @@ and Front) do.
 
-
-

8.7. Configure OpenVPN

+
+

8.7. Configure OpenVPN

Gate uses OpenVPN to provide the institute's campus VPN service. Its @@ -6429,7 +6416,7 @@ configure the OpenVPN server on Gate.

-roles_t/gate/tasks/main.yml
+roles_t/gate/tasks/main.yml
 - name: Install OpenVPN.
   become: yes
   apt: pkg=openvpn
@@ -6505,7 +6492,7 @@ configure the OpenVPN server on Gate.
 
-roles_t/gate/handlers/main.yml
+roles_t/gate/handlers/main.yml
 - name: Restart OpenVPN.
   become: yes
   systemd:
@@ -6534,15 +6521,15 @@ Wireless campus devices can get a key to the campus VPN from the
 configured manually.
 

-
-

9.1. Include Particulars

+
+

9.1. Include Particulars

The following should be familiar boilerplate by now.

-roles_t/campus/tasks/main.yml
---
+roles_t/campus/tasks/main.yml
---
 - name: Include public variables.
   include_vars: ../public/vars.yml
 - name: Include private variables.
@@ -6551,15 +6538,15 @@ The following should be familiar boilerplate by now.
 
-
-

9.2. Configure Hostname

+
+

9.2. Configure Hostname

Clients should be using the expected host name.

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Configure hostname.
   become: yes
   copy:
@@ -6577,7 +6564,7 @@ Clients should be using the expected host name.
 
-roles_t/campus/handlers/main.yml
---
+roles_t/campus/handlers/main.yml
---
 - name: Update hostname.
   become: yes
   command: hostname -F /etc/hostname
@@ -6585,8 +6572,8 @@ Clients should be using the expected host name.
 
-
-

9.3. Enable Systemd Resolved

+
+

9.3. Enable Systemd Resolved

Campus machines start the systemd-networkd and systemd-resolved @@ -6594,7 +6581,7 @@ service units on boot. See Enable Systemd Resolved.

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Install systemd-resolved.
   become: yes
   apt: pkg=systemd-resolved
@@ -6630,8 +6617,8 @@ service units on boot.  See Enable Systemd Resolved.
 
-
-

9.4. Configure Systemd Resolved

+
+

9.4. Configure Systemd Resolved

Campus machines use the campus name server on Core (or dns.google), @@ -6639,7 +6626,7 @@ and include the institute's private domain in their search lists.

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Configure resolved.
   become: yes
   lineinfile:
@@ -6657,7 +6644,7 @@ and include the institute's private domain in their search lists.
 
-roles_t/campus/handlers/main.yml
+roles_t/campus/handlers/main.yml
 - name: Reload Systemd.
   become: yes
   command: systemctl daemon-reload
@@ -6681,7 +6668,7 @@ and file timestamps.
 

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Configure timesyncd.
   become: yes
   lineinfile:
@@ -6692,7 +6679,7 @@ and file timestamps.
 
-roles_t/campus/handlers/main.yml
+roles_t/campus/handlers/main.yml
 - name: Restart systemd-timesyncd.
   become: yes
   systemd:
@@ -6702,8 +6689,8 @@ and file timestamps.
 
-
-

9.6. Add Administrator to System Groups

+
+

9.6. Add Administrator to System Groups

The administrator often needs to read (directories of) log files owned @@ -6712,7 +6699,7 @@ these groups speeds up debugging.

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Add {{ ansible_user }} to system groups.
   become: yes
   user:
@@ -6723,8 +6710,8 @@ these groups speeds up debugging.
 
-
-

9.7. Trust Institute Certificate Authority

+
+

9.7. Trust Institute Certificate Authority

Campus hosts should recognize the institute's Certificate Authority as @@ -6734,7 +6721,7 @@ keys, certificates and passwords, see Keys.)

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Trust the institute CA.
   become: yes
   copy:
@@ -6748,7 +6735,7 @@ keys, certificates and passwords, see Keys.)
 
-roles_t/campus/handlers/main.yml
+roles_t/campus/handlers/main.yml
 - name: Update CAs.
   become: yes
   command: update-ca-certificates
@@ -6756,15 +6743,15 @@ keys, certificates and passwords, see Keys.)
 
-
-

9.8. Install Unattended Upgrades

+
+

9.8. Install Unattended Upgrades

The institute prefers to install security updates as soon as possible.

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Install basic software.
   become: yes
   apt: pkg=unattended-upgrades
@@ -6790,7 +6777,7 @@ tasks below.
 
 
 
-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Install Postfix.
   become: yes
   apt: pkg=postfix
@@ -6827,7 +6814,7 @@ tasks below.
 
-roles_t/campus/handlers/main.yml
+roles_t/campus/handlers/main.yml
 - name: Restart Postfix.
   become: yes
   systemd:
@@ -6847,7 +6834,7 @@ custom of translating the host name into 127.0.1.1 is also followed
 

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Hard-wire important IP addresses.
   become: yes
   lineinfile:
@@ -6877,7 +6864,7 @@ Role.
 

-roles_t/campus/tasks/main.yml
+roles_t/campus/tasks/main.yml
 - name: Install NRPE.
   become: yes
   apt:
@@ -6915,7 +6902,7 @@ Role.
 
-roles_t/campus/handlers/main.yml
+roles_t/campus/handlers/main.yml
 - name: Reload NRPE server.
   become: yes
   systemd:
@@ -6931,8 +6918,8 @@ Role.
 

The small institute uses Ansible to maintain the configuration of its -servers. The administrator keeps an Ansible inventory in hosts, and -runs the playbook site.yml to apply the appropriate institutional +servers. The administrator keeps an Ansible inventory in hosts, and +runs playbook site.yml 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 @@ -6941,19 +6928,19 @@ chapter Testing.

The actual Ansible configuration is kept in a Git "superproject" -containing replacements for the example hosts inventory and -site.yml playbook, as well as the public/ and private/ +containing replacements for the example hosts inventory and +site.yml playbook, as well as the public/ and private/ particulars. Thus changes to this document and its tangle are easily merged with git pull --recurse-submodules or git submodule update, while changes to the institute's particulars are committed to a separate revision history.

-
-

10.1. ansible.cfg

+
+

10.1. ansible.cfg

-The Ansible configuration file ansible.cfg contains just a handful +The Ansible configuration file ansible.cfg contains just a handful of settings, some included just to create a test jig as described in Testing.

@@ -6963,16 +6950,16 @@ of settings, some included just to create a test jig as described in "automatic interpreter discovery" (described here). It declares that Python 3 can be expected on all institute hosts.
  • vault_password_file is set to suppress prompts for the vault -password. The institute keeps its vault password in Secret/ (as +password. The institute keeps its vault password in Secret/ (as described in Keys) and thus sets this parameter to -Secret/vault-password.
  • +Secret/vault-password.
  • inventory is set to avoid specifying it on the command line.
  • roles_path is set to the recently tangled roles files in -roles_t/ which are preferred in the test configuration.
  • +roles_t/ which are preferred in the test configuration.
    -ansible.cfg
    [defaults]
    +ansible.cfg
    [defaults]
     interpreter_python=/usr/bin/python3
     vault_password_file=Secret/vault-password
     inventory=hosts
    @@ -6985,7 +6972,7 @@ described in Keys) and thus sets this parameter to
     

    10.2. hosts

    -The Ansible inventory file hosts describes all of the institute's +The Ansible inventory file hosts 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 @@ -6994,7 +6981,7 @@ describes three test servers named front, core and

    -hosts
    all:
    +hosts
    all:
       vars:
         ansible_user: sysadm
         ansible_ssh_extra_args: -i Secret/ssh_admin/id_rsa
    @@ -7017,13 +7004,13 @@ describes three test servers named front, core and 
     The values of the ansible_become_password key are references to
    -variables defined in Secret/become.yml, which is loaded as
    +variables defined in Secret/become.yml, which is loaded as
     "extra" variables by a -e option on the ansible-playbook command
     line.
     

    -Secret/become.yml
    become_front: !vault |
    +Secret/become.yml
    become_front: !vault |
             $ANSIBLE_VAULT;1.1;AES256
             3563626131333733666466393166323135383838666338666131336335326
             3656437663032653333623461633866653462636664623938356563306264
    @@ -7054,8 +7041,8 @@ become_gate: !vault |
     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 ansible-vault
    -encrypt_string command, which uses the ansible.cfg file and thus
    -the Secret/vault-password file.
    +encrypt_string command, which uses the ansible.cfg file and thus
    +the Secret/vault-password file.
     

    @@ -7063,13 +7050,13 @@ the Secret/vault-password file.

    10.3. playbooks/site.yml

    -The example playbooks/site.yml playbook (below) applies the +The example playbooks/site.yml playbook (below) applies the appropriate institutional role(s) to the hosts and groups defined in -the example inventory: hosts. +the example inventory: hosts.

    -playbooks/site.yml
    ---
    +playbooks/site.yml
    ---
     - name: Configure Front
       hosts: front
       roles: [ front ]
    @@ -7095,14 +7082,14 @@ the example inventory: hosts.
     

    As already mentioned, the small institute keeps its Ansible vault password, a "master secret", on the encrypted partition mounted at -Secret/ in a file named vault-password. The administrator +Secret/ in a file named vault-password. The administrator generated a 16 character pronounceable password with gpw 1 16 and saved it like so: gpw 1 16 >Secret/vault-password. The following example password matches the example encryptions above.

    -Secret/vault-password
    alitysortstagess
    +Secret/vault-password
    alitysortstagess
     
    @@ -7195,9 +7182,9 @@ super-project's directory.

    10.6. Maintaining A Working Ansible Configuration

    -The Ansible roles currently tangle into the roles_t/ directory to +The Ansible roles currently tangle into the roles_t/ directory to ensure that debugged Ansible code in roles/ is not clobbered by code -tangled from this document. Comparing roles_t/ with roles/ will +tangled from this document. Comparing roles_t/ with roles/ will reveal any changes made to roles/ during debugging that need to be reconciled with this document as well as any policy changes in this document that require changes to the current roles/. @@ -7226,7 +7213,7 @@ to get their defaults from ./ansible.cfg.

    11.1. Sub-command Blocks

    -The code blocks in this chapter tangle into the inst script. Each +The code blocks in this chapter tangle into the inst 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. @@ -7237,7 +7224,7 @@ The first code block is the header of the ./inst script.

    -inst
    #!/usr/bin/perl -w
    +inst
    #!/usr/bin/perl -w
     #
     # DO NOT EDIT.  This file was tangled from an institute.org file.
     
    @@ -7254,13 +7241,13 @@ The first code block is the header of the ./inst script.
     The next code block does not implement a sub-command; it implements
     part of all ./inst sub-commands.  It performs a "sanity check" on
     the current directory, warning of missing files or directories, and
    -especially checking that all files in private/ have appropriate
    -permissions.  It probes past the Secret/ mount point (probing for
    -Secret/become.yml) to ensure the volume is mounted.
    +especially checking that all files in private/ have appropriate
    +permissions.  It probes past the Secret/ mount point (probing for
    +Secret/become.yml) to ensure the volume is mounted.
     

    -inst
    +inst
     sub note_missing_file_p ($);
     sub note_missing_directory_p ($);
     
    @@ -7314,14 +7301,14 @@ permissions.  It probes past the Secret/ mount point (probing for
     

    To ensure that Ansible and ./inst are sympatico vis-a-vi certain variable values (esp. private values like network addresses), a -check-inst-vars.yml playbook is used to update the Perl syntax file -private/vars.pl before ./inst loads it. The Perl code in inst -declares the necessary global variables and private/vars.pl sets +check-inst-vars.yml playbook is used to update the Perl syntax file +private/vars.pl before ./inst loads it. The Perl code in inst +declares the necessary global variables and private/vars.pl sets them.

    -inst
    +inst
     sub mysystem (@) {
       my $line = join (" ", @_);
       print "$line\n";
    @@ -7337,11 +7324,11 @@ do "./private/vars.pl";
     

    -The playbook that updates private/vars.pl: +The playbook that updates private/vars.pl:

    -playbooks/check-inst-vars.yml
    - hosts: localhost
    +playbooks/check-inst-vars.yml
    - hosts: localhost
       gather_facts: no
       tasks:
       - include_vars: ../public/vars.yml
    @@ -7363,21 +7350,21 @@ The playbook that updates private/vars.pl:
     

    The next code block implements the CA sub-command, which creates a -new CA (certificate authority) in Secret/CA/ as well as SSH and PGP +new CA (certificate authority) in Secret/CA/ as well as SSH and PGP keys for the administrator, Monkey, Front and root, also in -sub-directories of Secret/. The CA is created with the "common +sub-directories of Secret/. The CA is created with the "common name" provided by the full_name variable. An example is given here.

    -public/vars.yml
    full_name: Small Institute LLC
    +public/vars.yml
    full_name: Small Institute LLC
     

    -The Secret/ directory is on an off-line, encrypted volume plugged in -just for the duration of ./inst commands, so Secret/ is actually a +The Secret/ directory is on an off-line, encrypted volume plugged in +just for the duration of ./inst commands, so Secret/ is actually a symbolic link to a volume's automount location.

    @@ -7387,8 +7374,8 @@ ln -s /media/sysadm/ADE7-F866/ Secret

    -The Secret/CA/ directory is prepared using Easy RSA's make-cadir -command. The Secret/CA/vars file thus created is edited to contain +The Secret/CA/ directory is prepared using Easy RSA's make-cadir +command. The Secret/CA/vars file thus created is edited to contain the appropriate names (or just to set EASYRSA_DN to cn_only).

    @@ -7409,12 +7396,14 @@ config.

    -inst
    +inst
     if (defined $ARGV[0] && $ARGV[0] eq "CA") {
       die "usage: $0 CA" if @ARGV != 1;
       die "Secret/CA/easyrsa: not an executable\n"
         if ! -x "Secret/CA/easyrsa";
       die "Secret/CA/pki/: already exists\n" if -e "Secret/CA/pki";
    +
    +  umask 077;
       mysystem "cd Secret/CA; ./easyrsa init-pki";
       mysystem "cd Secret/CA; ./easyrsa build-ca nopass";
       # Common Name: small.example.org
    @@ -7426,8 +7415,8 @@ config.
       mysystem "cd Secret/CA; ./easyrsa build-server-full core.$pvt nopass";
       mysystem "cd Secret/CA; ./easyrsa build-client-full core nopass";
       umask 077;
    -  mysystem "openvpn --genkey --secret Secret/front-ta.key";
    -  mysystem "openvpn --genkey --secret Secret/gate-ta.key";
    +  mysystem "openvpn --genkey secret Secret/front-ta.key";
    +  mysystem "openvpn --genkey secret Secret/gate-ta.key";
       mysystem "openssl dhparam -out Secret/front-dh2048.pem 2048";
       mysystem "openssl dhparam -out Secret/gate-dh2048.pem 2048";
     
    @@ -7436,11 +7425,11 @@ config.
                 " --batch --quick-generate-key --passphrase ''",
                 " root\@core.$pvt");
       mysystem ("gpg --homedir Secret/root.gnupg",
    -            " --export --armor --output root-pub.pem",
    +            " --export --armor --output Secret/root-pub.pem",
                 " root\@core.$pvt");
       chmod 0440, "root-pub.pem";
       mysystem ("gpg --homedir Secret/root.gnupg",
    -            " --export-secret-key --armor --output root-sec.pem",
    +            " --export-secret-key --armor --output Secret/root-sec.pem",
                 " root\@core.$pvt");
       chmod 0400, "root-sec.pem";
     
    @@ -7489,7 +7478,7 @@ Example command lines:
     
     
     
    -inst
    +inst
     if (defined $ARGV[0] && $ARGV[0] eq "config") {
       die "Secret/CA/easyrsa: not executable\n"
         if ! -x "Secret/CA/easyrsa";
    @@ -7575,14 +7564,14 @@ revoked:
     
     

    The test campus starts with the empty membership roll found in -private/members-empty.yml and saved in private/members.yml +private/members-empty.yml and saved in private/members.yml (which is not tangled from this document, thus not over-written during testing). If members.yml is not found, members-empty.yml is used instead.

    -private/members-empty.yml
    ---
    +private/members-empty.yml
    ---
     members:
     usernames: []
     revoked: []
    @@ -7595,7 +7584,7 @@ Both locations go on the membership_rolls variable used by the
     

    -private/vars.yml
    membership_rolls:
    +private/vars.yml
    membership_rolls:
     - "../private/members.yml"
     - "../private/members-empty.yml"
     
    @@ -7608,7 +7597,7 @@ read from the file. The dump subroutine is another story (below).

    -inst
    +inst
     use YAML::XS qw(LoadFile DumpFile);
     
     sub read_members_yaml () {
    @@ -7684,7 +7673,7 @@ each record.
     

    -inst
    +inst
     sub print_member ($$) {
       my ($out, $member) = @_;
       print $out "  ", $member->{"username"}, ":\n";
    @@ -7728,7 +7717,7 @@ each record.
     The next code block implements the new 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
    -private/members.yml, and runs the site.yml playbook.  The site
    +private/members.yml, and runs the site.yml 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
    @@ -7736,7 +7725,7 @@ initial, generated password.
     

    -inst
    +inst
     sub valid_username (@);
     sub shell_escape ($);
     sub strip_vault ($);
    @@ -7799,7 +7788,7 @@ initial, generated password.
     
    -playbooks/nextcloud-new.yml
    - hosts: core
    +playbooks/nextcloud-new.yml
    - hosts: core
       no_log: yes
       tasks:
       - name: Run occ user:add.
    @@ -7837,7 +7826,7 @@ pass command.  In either case, the administrator needs to update the
     membership roll, and so receives an encrypted email, which gets piped
     into ./inst pass.  This command decrypts the message, parses the
     (YAML) content, updates private/members.yml, and runs the full
    -Ansible site.yml playbook to update the servers.  If all goes well a
    +Ansible site.yml playbook to update the servers.  If all goes well a
     message is sent to member@core.
     

    @@ -7852,11 +7841,11 @@ update the servers, so it does not need an SSH key and password to (nor equivalent) on Core. It is a set-UID shadow script so it can read /etc/shadow. The member will need to wait for confirmation from the administrator, but all keys to root at the institute stay -in Secret/. +in Secret/.

    -roles_t/core/templates/passwd
    #!/bin/perl -wT
    +roles_t/core/templates/passwd
    #!/bin/perl -wT
     
     use strict;
     
    @@ -7944,11 +7933,11 @@ print "
     

    The following code block implements the ./inst pass command, used by the administrator to update private/members.yml before running -playbooks/site.yml and emailing the concerned member. +playbooks/site.yml and emailing the concerned member.

    -inst
    +inst
     use MIME::Base64;
     
     if (defined $ARGV[0] && $ARGV[0] eq "pass") {
    @@ -8007,7 +7996,7 @@ users:resetpassword command using expect(1).
     

    -playbooks/nextcloud-pass.yml
    - hosts: core
    +playbooks/nextcloud-pass.yml
    - hosts: core
       no_log: yes
       tasks:
       - name: Run occ user:resetpassword.
    @@ -8050,7 +8039,7 @@ configuration so that the email to root can be encrypted.
     

    -roles_t/core/tasks/main.yml
    +roles_t/core/tasks/main.yml
     - name: Install institute passwd command.
       become: yes
       template:
    @@ -8096,7 +8085,7 @@ configuration so that the email to root can be encrypted.
     
    -roles_t/core/handlers/main.yml
    +roles_t/core/handlers/main.yml
     - name: Import root PGP key.
       become: no
       command: gpg --import ~/.gnupg-root-pub.pem
    @@ -8113,7 +8102,7 @@ The old command disables a member's accounts and clients.
     

    -inst
    +inst
     if (defined $ARGV[0] && $ARGV[0] eq "old") {
       my $user = valid_username (@ARGV);
       my $yaml = read_members_yaml ();
    @@ -8135,7 +8124,7 @@ The old command disables a member's accounts and clients.
     
    -playbooks/nextcloud-old.yml
    - hosts: core
    +playbooks/nextcloud-old.yml
    - hosts: core
       tasks:
       - name: Run occ user:disable.
         shell: |
    @@ -8157,7 +8146,7 @@ The old command disables a member's accounts and clients.
     

    The client command creates an OpenVPN configuration (.ovpn) file authorizing wireless devices to connect to the institute's VPNs. The -command uses the EasyRSA CA in Secret/. The generated configuration +command uses the EasyRSA CA in Secret/. The generated configuration is slightly different depending on the type of host, given as the first argument to the command.

    @@ -8192,7 +8181,7 @@ copies the campus.ovpn file to /etc/openvpn/campus.conf.

    The OpenVPN configurations generated for Debian hosts specify an up -script, update-systemd-resolved, installed in /etc/openvpn/ by the +script, update-systemd-resolved, installed in /etc/openvpn/ by the openvpn-systemd-resolved package. The following configuration lines instruct the OpenVPN clients to run this script whenever the connection is restarted. @@ -8206,7 +8195,7 @@ up-restart

    -inst
    sub write_template ($$$$$$$$$);
    +inst
    sub write_template ($$$$$$$$$);
     sub read_file ($);
     sub add_client ($$$);
     
    @@ -8327,13 +8316,13 @@ up-restart
     

    11.11. Institute Command Help

    -This should be the last block tangled into the inst script. It +This should be the last block tangled into the inst script. It catches any command lines that were not handled by a sub-command above.

    -inst
    +inst
     die "usage: $0 [CA|config|new|pass|old|client] ...\n";
     
    @@ -8344,10 +8333,10 @@ above.

    12. Testing

    -The example files in this document, ansible.cfg and hosts as -well as those in public/ and private/, along with the +The example files in this document, ansible.cfg and hosts as +well as those in public/ and private/, along with the matching EasyRSA certificate authority and GnuPG key-ring in -Secret/ (included in the distribution), can be used to configure +Secret/ (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 @@ -8729,7 +8718,7 @@ VBoxManage modifyvm gate --hostonlyadapter3 vboxnet1

    Before rebooting, the MAC addresses of the three network interfaces -should be compared to the example variable settings in hosts. The +should be compared to the example variable settings in hosts. The values of the gate_lan_mac, gate_wifi_mac, and gate_isp_mac variables must agree with the MAC addresses assigned to the virtual machine's network interfaces. The following table assumes device @@ -8999,9 +8988,9 @@ or update its configuration files. 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 -core.small.private. The following sections describe how a client +core.small.private. 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 core.small.private to +name server). Its browser can then connect to core.small.private to exercise the test Nextcloud.

    @@ -9138,7 +9127,7 @@ host www

    12.11. Test Web Pages

    -Next, the administrator copies Backup/WWW/ (included in the +Next, the administrator copies Backup/WWW/ (included in the distribution) to /WWW/ on core and sets the file permissions appropriately.

    @@ -9520,7 +9509,7 @@ complete. Additional tests are needed.

    The backup command has not been tested. It needs an encrypted partition with which to sync? And then some way to compare that to -Backup/? +Backup/?

    @@ -9528,7 +9517,7 @@ partition with which to sync? And then some way to compare that to

    13.2.2. Restore

    -The restore process has not been tested. It might just copy Backup/ +The restore process has not been tested. It might just copy Backup/ to core:/, but then it probably needs to fix up file ownerships, perhaps permissions too. It could also use an example Backup/Nextcloud/20220622.bak. @@ -9698,7 +9687,7 @@ routes on Front and Gate, making the simulation less… similar.

    Author: Matt Birkholz

    -

    Created: 2023-12-17 Sun 16:05

    +

    Created: 2023-12-28 Thu 16:07

    Validate

    -- 2.25.1