From 322e008479980c599e9559aeeaee9091bf417ba6 Mon Sep 17 00:00:00 2001 From: Matt Birkholz Date: Wed, 27 Dec 2023 23:20:54 -0700 Subject: [PATCH] Turn many relative filenames into links. --- README.org | 512 ++++++++++++++++++++++++++--------------------------- 1 file changed, 256 insertions(+), 256 deletions(-) diff --git a/README.org b/README.org index 5476d1f..c12e708 100644 --- a/README.org +++ b/README.org @@ -314,8 +314,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). Core's web sites: @@ -489,9 +489,9 @@ initial, privileged user account the same name is given (e.g. as described in [[*The Core Machine][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 Configuration][The Ansible +value of ~ansible_user~ in [[file:hosts][=hosts=]]. Its password is specified by a +vault-encrypted variable in the [[file:Secret/become.yml][=Secret/become.yml=]] file. (The +[[file:hosts][=hosts=]] and [[file:Secret/become.yml][=Secret/become.yml=]] files are described in [[*The Ansible Configuration][The Ansible Configuration]].) *** The Monkey Accounts @@ -505,43 +505,43 @@ 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 [[file:Secret/][=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 [[file:Secret/][=Secret/=]], none of the ~./inst~ commands will work. 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 +is stored in [[file:Secret/ssh_admin/id_rsa][=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 + - [[file:Secret/ssh_admin/][=Secret/ssh_admin/=]] :: The SSH key pair for A Small Institute Administrator. - - =Secret/ssh_monkey/= :: The key pair used by Monkey to update the + - [[file:Secret/ssh_monkey/][=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 + - [[file:Secret/ssh_front/][=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 [[file:Secret/CA/][=Secret/CA/=]]. - - =Secret/CA/pki/ca.crt= :: The institute CA certificate, used to + - [[file:Secret/CA/pki/ca.crt][=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, + - [[file:Secret/CA/pki/issued/small.example.org.crt][=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 + - [[file:Secret/CA/pki/issued/gate.small.private.crt][=Secret/CA/pki/issued/gate.small.private.crt=]] :: The campus OpenVPN server on Gate. - - =Secret/CA/pki/issued/core.small.private.crt= :: The campus + - [[file:Secret/CA/pki/issued/core.small.private.crt][=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 + - [[file:Secret/CA/pki/issued/core.crt][=Secret/CA/pki/issued/core.crt=]] :: Core's client certificate, by which it authenticates to Front. The ~./inst client~ command creates client certificates and keys, and @@ -555,15 +555,15 @@ membership roll (in =private/members.yml= as the value of ~revoked~). Finally, the institute uses an OpenPGP key to secure sensitive emails (containing passwords or private keys) to Core. - - =Secret/root.gnupg/= :: The "home directory" used to create the + - [[file:Secret/root.gnupg/][=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 + - [[file:Secret/root-pub.pem][=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. + - [[file:Secret/root-sec.pem][=Secret/root-sec.pem=]] :: The ASCII armored OpenPGP secret key. -When [[*The CA Command][The CA Command]] sees an empty =Secret/CA/= directory, as +When [[*The CA Command][The CA Command]] sees an empty [[file:Secret/CA/][=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 +[[file:Secret/][=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. @@ -607,7 +607,7 @@ backup~ (/without/ ~-n~) produces the complete copy (with all the files mentioned in the Nextcloud database dump). #+NAME: backup -#+CAPTION: =private/backup= +#+CAPTION: [[file:private/backup][=private/backup=]] #+BEGIN_SRC sh :tangle private/backup :mkdirp yes :tangle-mode u=rw #!/bin/bash -e # @@ -716,7 +716,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: [[file:public/vars.yml][=public/vars.yml=]] and [[file:private/var.yml][=private/vars.yml=]]. The example settings in this document configure VirtualBox VMs as described in the [[*Testing][Testing]] chapter. For more information about how a @@ -730,7 +730,7 @@ Ansible code. The example used here is ~small.example.org~. The following line sets ~domain_name~ to that value. (Ansible will then replace ~{{ domain_name }}~ in the code with ~small.example.org~.) -#+CAPTION: =public/vars.yml= +#+CAPTION: [[file:public/vars.yml][=public/vars.yml=]] #+BEGIN_SRC conf :tangle public/vars.yml :mkdirp yes --- domain_name: small.example.org @@ -792,11 +792,11 @@ example result follows the code. 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 +[[file:private/vars.yml][=private/vars.yml=]] rather than [[file:public/vars.yml][=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 [[*Testing][here]]). -#+CAPTION: =private/vars.yml= +#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]] #+BEGIN_SRC conf :tangle private/vars.yml :tangle-mode u=rw --- private_net_cidr: 192.168.56.0/24 @@ -811,7 +811,7 @@ following boilerplate uses Ansible's ~ipaddr~ filter to set several corresponding variables, each with an appropriate suffix, e.g. ~_net_and_mask~ rather than ~_net_cidr~. -#+CAPTION: =private/vars.yml= +#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]] #+BEGIN_SRC conf :tangle private/vars.yml private_net: "{{ private_net_cidr | ipaddr('network') }}" private_net_mask: "{{ private_net_cidr | ipaddr('netmask') }}" @@ -836,7 +836,7 @@ rather than domain names, and one of the most important for secure and reliable operation is Front's public IP address known to the world by the institute's Internet domain name. -#+CAPTION: =public/vars.yml= +#+CAPTION: [[file:public/vars.yml][=public/vars.yml=]] #+BEGIN_SRC conf :tangle public/vars.yml front_addr: 192.168.15.5 #+END_SRC @@ -856,7 +856,7 @@ address on the public VPN, perversely called ~front_private_addr~. The following code block picks the obvious IP addresses for Core (host 1) and Gate (host 2). -#+CAPTION: =private/vars.yml= +#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]] #+BEGIN_SRC conf :tangle private/vars.yml core_addr_cidr: "{{ private_net_cidr | ipaddr('1') }}" gate_addr_cidr: "{{ private_net_cidr | ipaddr('2') }}" @@ -926,8 +926,8 @@ escalated privileges via the ~sudo~ command. : 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 [[file:Secret/become.yml][=Secret/become.yml=]] as shown below. +(Producing a working Ansible configuration with [[file:Secret/become.yml][=Secret/become.yml=]] file is described in [[*The Ansible Configuration][The Ansible Configuration]].) : notebook$ gpw 1 16 @@ -938,7 +938,7 @@ file is described in [[*The Ansible Configuration][The Ansible Configuration]].) 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][The CA Command]]) into an =admin_keys= +[[file:Secret/ssh_admin/][=Secret/ssh_admin/=]] (created by [[*The CA Command][The CA Command]]) into an =admin_keys= file, copied it to the droplet, and installed it as the =authorized_keys= for ~sysadm~. @@ -1011,8 +1011,8 @@ and a privileged account named ~sysadm~ was created (per the policy in : 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 [[file:Secret/become.yml][=Secret/become.yml=]] as shown below. +(Producing a working Ansible configuration with [[file:Secret/become.yml][=Secret/become.yml=]] file is described in [[*The Ansible Configuration][The Ansible Configuration]].) : notebook$ gpw 1 16 @@ -1037,7 +1037,7 @@ final configuration "in position" (on a frontier). : _ 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][The CA Command]]) into an +key found in [[file:Secret/ssh_admin/][=Secret/ssh_admin/=]] (created by [[*The CA Command][The CA Command]]) into an =admin_keys= file, copied it to Core, and installed it as the =authorized_keys= for ~sysadm~. @@ -1156,8 +1156,8 @@ and a privileged account named ~sysadm~ was created (per the policy in : 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 [[file:Secret/become.yml][=Secret/become.yml=]] as shown below. +(Producing a working Ansible configuration with [[file:Secret/become.yml][=Secret/become.yml=]] file is described in [[*The Ansible Configuration][The Ansible Configuration]].) : notebook$ gpw 1 16 @@ -1173,7 +1173,7 @@ cable modem and installed them as shown below. : $ 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][The CA Command]]) into an +key found in [[file:Secret/ssh_admin/][=Secret/ssh_admin/=]] (created by [[*The CA Command][The CA Command]]) into an =admin_keys= file, copied it to Gate, and installed it as the =authorized_keys= for ~sysadm~. @@ -1249,9 +1249,9 @@ first ~front~ role tasks are to include these files (described in [[*The Particu Particulars]] and [[*Account Management][Account Management]]). The code block below is the first to tangle into -=roles/front/tasks/main.yml=. +[[file:roles/front/tasks/main.yml][=roles/front/tasks/main.yml=]]. -#+CAPTION: =roles/front/tasks/main.yml= +#+CAPTION: [[file:roles/front/tasks/main.yml][=roles/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml :mkdirp yes --- - name: Include public variables. @@ -1273,7 +1273,7 @@ This task ensures that Front's =/etc/hostname= and =/etc/mailname= are correct. The correct =/etc/mailname= is essential to proper email delivery. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Configure hostname. become: yes @@ -1286,7 +1286,7 @@ delivery. notify: Update hostname. #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml :mkdirp yes --- - name: Update hostname. @@ -1310,7 +1310,7 @@ to enable "persistent logging", yet). In Debian 12 there is a These tasks are included in all of the roles, and so are given in a separate code block named ~enable-resolved~.[fn:1] -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml :noweb yes <> #+END_SRC @@ -1358,7 +1358,7 @@ The administrator often needs to read (directories of) log files owned by groups ~root~ and ~adm~. Adding the administrator's account to these groups speeds up debugging. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Add {{ ansible_user }} to system groups. @@ -1373,9 +1373,9 @@ 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 [[file:Secret/ssh_front/etc/ssh/][=Secret/ssh_front/etc/ssh/=]] and restarting the server. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Install SSH host keys. @@ -1394,7 +1394,7 @@ those stored in =Secret/ssh_front/etc/ssh/= and restarting the server. notify: Reload SSH server. #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: Reload SSH server. @@ -1415,7 +1415,7 @@ described in [[apache2-front][*Configure Apache2]]). To do that without needing password, the ~monkey~ account on Front should authorize Monkey's SSH key on Core. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Create monkey. @@ -1445,7 +1445,7 @@ key on Core. Monkey uses Rsync to keep the institute's public web site up-to-date. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Install rsync. @@ -1457,7 +1457,7 @@ Monkey uses Rsync to keep the institute's public web site up-to-date. The institute prefers to install security updates as soon as possible. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Install basic software. @@ -1472,7 +1472,7 @@ start delivering email immediately, /without/ returning "no such recipient" replies. The [[*Account Management][Account Management]] chapter describes the ~members~ and ~usernames~ variables used below. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Create user accounts. @@ -1512,7 +1512,7 @@ trustworthy, so its certificate is added to Front's set of trusted CAs. More information about how the small institute manages its X.509 certificates is available in [[*Keys][Keys]]. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Trust the institute CA. @@ -1526,7 +1526,7 @@ X.509 certificates is available in [[*Keys][Keys]]. notify: Update CAs. #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: Update CAs. @@ -1541,7 +1541,7 @@ authenticate themselves to institute clients. They share the =/etc/server.crt= and =/etc/server.key= files, the latter only readable by ~root~. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Install server certificate/key. @@ -1653,7 +1653,7 @@ The following Ansible tasks install Postfix, modify =/etc/postfix/main.cf= according to the settings given above, and start and enable the service. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml :noweb yes - name: Install Postfix. @@ -1686,7 +1686,7 @@ start and enable the service. state: started #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: Restart Postfix. @@ -1717,7 +1717,7 @@ do /not/ include the crucial ~root~ alias that forwards to the administrator. It could be included here or in a separate block created by a more specialized role. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Install institute email aliases. become: yes @@ -1733,7 +1733,7 @@ created by a more specialized role. notify: New aliases. #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: New aliases. @@ -1762,7 +1762,7 @@ The following Ansible tasks install Dovecot's IMAP daemon and its =/etc/dovecot/local.conf= configuration file, then starts the service and enables it to start at every reboot. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml :noweb yes - name: Install Dovecot IMAPd. @@ -1789,7 +1789,7 @@ and enables it to start at every reboot. state: started #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: Restart Dovecot. @@ -1955,7 +1955,7 @@ Ansible installs the configuration above in e.g. =/etc/apache2/sites-available/small.example.org.conf= and runs ~a2ensite -q small.example.org~ to enable it. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml :noweb yes - name: Install Apache2. @@ -2000,7 +2000,7 @@ e.g. =/etc/apache2/sites-available/small.example.org.conf= and runs state: started #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: Restart Apache2. @@ -2013,7 +2013,7 @@ e.g. =/etc/apache2/sites-available/small.example.org.conf= and runs Furthermore, the default web site and its HTTPS version is disabled so that it does not interfere with its replacement. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Disable default vhosts. @@ -2029,7 +2029,7 @@ The redundant default =other-vhosts-access-log= configuration option is also disabled. There are no other virtual hosts, and it stores the same records as =access.log=. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Disable other-vhosts-access-log option. @@ -2043,7 +2043,7 @@ same records as =access.log=. Finally, the ~UserDir~ is created and populated with symbolic links to the users' =~/Public/HTML/= directories. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Create UserDir. @@ -2135,7 +2135,7 @@ tls-auth ta.key 0 Finally, here are the tasks (and handler) required to install and configure the OpenVPN server on Front. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml :noweb yes - name: Install OpenVPN. @@ -2213,7 +2213,7 @@ configure the OpenVPN server on Front. state: started #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: Restart OpenVPN. @@ -2253,7 +2253,7 @@ starts). The first step is to install Kamailio. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml :noweb yes - name: Install Kamailio. @@ -2266,7 +2266,7 @@ Kamailio will be listening, the ~tun~ device created by OpenVPN. The added configuration settings inform Systemd that Kamailio should not be started before the ~tun~ device has appeared. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml - name: Create Kamailio/Systemd configuration drop. @@ -2286,7 +2286,7 @@ be started before the ~tun~ device has appeared. notify: Reload Systemd. #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: Reload Systemd. @@ -2296,7 +2296,7 @@ be started before the ~tun~ device has appeared. Finally, Kamailio can be configured and started. -#+CAPTION: =roles_t/front/tasks/main.yml= +#+CAPTION: [[file:roles_t/front/tasks/main.yml][=roles_t/front/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/tasks/main.yml :noweb yes - name: Configure Kamailio. @@ -2315,7 +2315,7 @@ Finally, Kamailio can be configured and started. state: started #+END_SRC -#+CAPTION: =roles_t/front/handlers/main.yml= +#+CAPTION: [[file:roles_t/front/handlers/main.yml][=roles_t/front/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/front/handlers/main.yml - name: Restart Kamailio. @@ -2339,7 +2339,7 @@ account. (For details, see [[*The Core Machine][The Core Machine]].) The first task, as in [[*The Front Role][The Front Role]], is to include the institute particulars and membership roll. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :mkdirp yes --- - name: Include public variables. @@ -2361,7 +2361,7 @@ private domain names, e.g. to ~dick@small.example.org~ as well as ~dick@small.private~. The correct =/etc/mailname= is essential to proper email delivery. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Configure hostname. @@ -2375,7 +2375,7 @@ proper email delivery. notify: Update hostname. #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml :mkdirp yes --- - name: Update hostname. @@ -2388,7 +2388,7 @@ proper email delivery. Core starts the ~systemd-networkd~ and ~systemd-resolved~ service units on boot. See [[resolved-front][Enable Systemd Resolved]]. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :noweb yes <> #+END_SRC @@ -2399,7 +2399,7 @@ Core runs the campus name server, so Resolved is configured to use it (or ~dns.google~), to include the institute's domain in its search list, and to disable its cache and stub listener. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Configure resolved. @@ -2419,7 +2419,7 @@ list, and to disable its cache and stub listener. - Restart Systemd resolved. #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Reload Systemd. @@ -2443,7 +2443,7 @@ through Core itself to Front, is advertised to other hosts, but is not created here. It is created by OpenVPN when Core connects to Front's VPN. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install netplan. @@ -2469,7 +2469,7 @@ VPN. notify: Apply netplan. #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Apply netplan. @@ -2485,14 +2485,14 @@ network addresses to hosts plugged into the private Ethernet as well as advertising local net services, especially the local Domain Name Service. -The example configuration file, =private/core-dhcpd.conf=, uses +The example configuration file, [[file:private/core-dhcpd.conf][=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 [[file:private/core-dhcpd.conf][=private/core-dhcpd.conf=]] file. -#+CAPTION: =private/core-dhcpd.conf= +#+CAPTION: [[file:private/core-dhcpd.conf][=private/core-dhcpd.conf=]] #+BEGIN_SRC conf :tangle private/core-dhcpd.conf :tangle-mode u=rw option domain-name "small.private"; option domain-name-servers 192.168.56.1; @@ -2525,9 +2525,9 @@ host server { #+END_SRC 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 [[file:private/core-dhcpd.conf][=private/core-dhcpd.conf=]] (/not/ the example above). -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install DHCP server. @@ -2557,7 +2557,7 @@ with the real =private/core-dhcpd.conf= (/not/ the example above). state: started #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Restart DHCP server. @@ -2576,7 +2576,7 @@ addresses to private domain names. The following tasks install and configure BIND9 on Core. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :noweb yes - name: Install BIND9. @@ -2615,7 +2615,7 @@ The following tasks install and configure BIND9 on Core. state: started #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Reload BIND9. @@ -2699,7 +2699,7 @@ zone "{{ campus_vpn_net_cidr | ipaddr('revdns') }; #+END_SRC -#+CAPTION: =private/db.domain= +#+CAPTION: [[file:private/db.domain][=private/db.domain=]] #+BEGIN_SRC conf :tangle private/db.domain :tangle-mode u=rw ; ; BIND data file for a small institute's PRIVATE domain names. @@ -2727,7 +2727,7 @@ core IN A 192.168.56.1 gate IN A 192.168.56.2 #+END_SRC -#+CAPTION: =private/db.private= +#+CAPTION: [[file:private/db.private][=private/db.private=]] #+BEGIN_SRC conf :tangle private/db.private :tangle-mode u=rw ; ; BIND reverse data file for a small institute's private Ethernet. @@ -2746,7 +2746,7 @@ $TTL 7200 2 IN PTR gate.small.private. #+END_SRC -#+CAPTION: =private/db.public_vpn= +#+CAPTION: [[file:private/db.public_vpn][=private/db.public_vpn=]] #+BEGIN_SRC conf :tangle private/db.public_vpn :tangle-mode u=rw ; ; BIND reverse data file for a small institute's public VPN. @@ -2765,7 +2765,7 @@ $TTL 7200 2 IN PTR core-p.small.private. #+END_SRC -#+CAPTION: =private/db.campus_vpn= +#+CAPTION: [[file:private/db.campus_vpn][=private/db.campus_vpn=]] #+BEGIN_SRC conf :tangle private/db.campus_vpn :tangle-mode u=rw ; ; BIND reverse data file for a small institute's campus VPN. @@ -2789,7 +2789,7 @@ The administrator often needs to read (directories of) log files owned by groups ~root~ and ~adm~. Adding the administrator's account to these groups speeds up debugging. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Add {{ ansible_user }} to system groups. @@ -2808,7 +2808,7 @@ system account named ~monkey~. One of Monkey's more important jobs on Core is to run ~rsync~ to update the public web site on Front (as described in [[apache2-core][*Configure Apache2]]). -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Create monkey. @@ -2868,7 +2868,7 @@ described in [[apache2-core][*Configure Apache2]]). The institute prefers to install security updates as soon as possible. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install basic software. @@ -2881,7 +2881,7 @@ The institute prefers to install security updates as soon as possible. The ~expect~ program is used by [[* The Institute Commands][The Institute Commands]] to interact with Nextcloud on the command line. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install expect. @@ -2895,7 +2895,7 @@ User accounts are created immediately so that backups can begin restoring as soon as possible. The [[*Account Management][Account Management]] chapter describes the ~members~ and ~usernames~ variables. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Create user accounts. @@ -2935,7 +2935,7 @@ trustworthy, so its certificate is added to Core's set of trusted CAs. More information about how the small institute manages its X.509 certificates is available in [[*Keys][Keys]]. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Trust the institute CA. @@ -2949,7 +2949,7 @@ X.509 certificates is available in [[*Keys][Keys]]. notify: Update CAs. #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Update CAs. @@ -2963,7 +2963,7 @@ The servers on Core use the same certificate (and key) to authenticate themselves to institute clients. They share the =/etc/server.crt= and =/etc/server.key= files, the latter only readable by ~root~. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install server certificate/key. @@ -2988,7 +2988,7 @@ themselves to institute clients. They share the =/etc/server.crt= and Core uses NTP to provide a time synchronization service to the campus. The default daemon's default configuration is fine. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :noweb yes - name: Install NTP. @@ -3071,7 +3071,7 @@ The following Ansible tasks install Postfix, modify enable the service. Whenever =/etc/postfix/transport= is changed, the ~postmap transport~ command must also be run. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :noweb yes - name: Install Postfix. @@ -3105,7 +3105,7 @@ enable the service. Whenever =/etc/postfix/transport= is changed, the state: started #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Restart Postfix. @@ -3131,7 +3131,7 @@ to e.g. ~monkey~. The following aliases are installed in =/etc/aliases= with a special marker so that additional blocks can be installed by more specialized roles. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install institute email aliases. @@ -3148,7 +3148,7 @@ installed by more specialized roles. notify: New aliases. #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: New aliases. @@ -3177,7 +3177,7 @@ The following Ansible tasks install Dovecot's IMAP daemon and its =/etc/dovecot/local.conf= configuration file, then starts the service and enables it to start at every reboot. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :noweb yes - name: Install Dovecot IMAPd. @@ -3203,7 +3203,7 @@ and enables it to start at every reboot. state: started #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Restart Dovecot. @@ -3270,7 +3270,7 @@ institute who may wish to run their own fetchmail job on their notebook, only members with a ~fetchmail_password~ key will be provided the Core service. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :noweb yes - name: Install fetchmail. @@ -3320,7 +3320,7 @@ provided the Core service. Finally, any former member's Fetchmail service on Core should be stopped and disabled from restarting at boot, deleted even. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Stop former user fetchmail services. @@ -3479,7 +3479,7 @@ The tasks below install Apache2 and edit its default configuration. The global ~ServerName~ directive must be deleted because it seems to interfere with mapping URLs to the correct virtual host. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install Apache2. @@ -3507,7 +3507,7 @@ With Apache installed there is a =/etc/apache/sites-available/= directory into which the above site configurations can be installed. The ~a2ensite~ command enables them. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :noweb yes - name: Install live web site. @@ -3553,7 +3553,7 @@ The ~a2ensite~ command enables them. state: started #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Restart Apache2. @@ -3570,7 +3570,7 @@ Monkey on Core runs =/usr/local/sbin/webupdate= every 15 minutes via a =/home/www/= on Front. #+NAME: webupdate -#+CAPTION: =private/webupdate= +#+CAPTION: [[file:private/webupdate][=private/webupdate=]] #+BEGIN_SRC sh #!/bin/bash -e # @@ -3584,11 +3584,11 @@ rsync -avz --delete --chmod=g-w \ ./ {{ domain_name }}:/home/www/ #+END_SRC -The following tasks install the =webupdate= script from =private/=, +The following tasks install the =webupdate= script from [[file:private/][=private/=]], and create Monkey's ~cron~ job. An example =webupdate= script is provided [[webupdate][here]]. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: "Install Monkey's webupdate script." @@ -3643,7 +3643,7 @@ tls-auth ta.key 1 The tasks that install and configure the OpenVPN client configuration for Core. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml :noweb yes - name: Install OpenVPN. @@ -3693,7 +3693,7 @@ for Core. enabled: yes #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Restart OpenVPN. @@ -3718,7 +3718,7 @@ on the ~sensors~ command (from the ~lm-sensors~ package). The custom version (below) is installed in =/usr/local/sbin/inst_sensors= on both Core and Campus (and thus Gate) machines. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install NAGIOS4. @@ -3770,7 +3770,7 @@ Core and Campus (and thus Gate) machines. state: started #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Reload NAGIOS4. @@ -3787,7 +3787,7 @@ Core. The monitors are simple, local plugins, and the block is very similar to the default =objects/localhost.cfg= file. The commands used here /may/ specify plugin arguments. -#+CAPTION: =roles_t/core/templates/nagios.cfg= +#+CAPTION: [[file:roles_t/core/templates/nagios.cfg][=roles_t/core/templates/nagios.cfg=]] #+BEGIN_SRC conf :tangle roles_t/core/templates/nagios.cfg :mkdirp yes define host { use linux-server @@ -3859,7 +3859,7 @@ The ~check_sensors~ plugin is included in the package small institute substitutes a slightly modified version, ~inst_sensors~, that reports core CPU temperatures. -#+CAPTION: =roles_t/core/files/inst_sensors= +#+CAPTION: [[file:roles_t/core/files/inst_sensors][=roles_t/core/files/inst_sensors=]] #+BEGIN_SRC sh :tangle roles_t/core/files/inst_sensors #!/bin/sh @@ -3942,7 +3942,7 @@ esac The following block defines the command and monitors it (locally) on Core. -#+CAPTION: =roles_t/core/templates/nagios.cfg= +#+CAPTION: [[file:roles_t/core/templates/nagios.cfg][=roles_t/core/templates/nagios.cfg=]] #+BEGIN_SRC conf :tangle roles_t/core/templates/nagios.cfg define command { @@ -3979,7 +3979,7 @@ on each campus host by the campus role's [[*Configure NRPE][Configure NRPE]] tas Define the monitored host, ~gate~. Monitor its response to network pings. -#+CAPTION: =roles_t/core/templates/nagios.cfg= +#+CAPTION: [[file:roles_t/core/templates/nagios.cfg][=roles_t/core/templates/nagios.cfg=]] #+BEGIN_SRC conf :tangle roles_t/core/templates/nagios.cfg define host { @@ -3992,14 +3992,14 @@ define host { For all campus NRPE servers: an ~inst_root~ command to check the free space on the root partition. -#+CAPTION: =roles_t/campus/files/nrpe.cfg= +#+CAPTION: [[file:roles_t/campus/files/nrpe.cfg][=roles_t/campus/files/nrpe.cfg=]] #+BEGIN_SRC conf :tangle roles_t/campus/files/nrpe.cfg :mkdirp yes command[inst_root]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p / #+END_SRC Monitor ~inst_root~ on Gate. -#+CAPTION: =roles_t/core/templates/nagios.cfg= +#+CAPTION: [[file:roles_t/core/templates/nagios.cfg][=roles_t/core/templates/nagios.cfg=]] #+BEGIN_SRC conf :tangle roles_t/core/templates/nagios.cfg define service { @@ -4012,7 +4012,7 @@ define service { Monitor ~check_load~ on Gate. -#+CAPTION: =roles_t/core/templates/nagios.cfg= +#+CAPTION: [[file:roles_t/core/templates/nagios.cfg][=roles_t/core/templates/nagios.cfg=]] #+BEGIN_SRC conf :tangle roles_t/core/templates/nagios.cfg define service { @@ -4025,7 +4025,7 @@ define service { Monitor ~check_zombie_procs~ and ~check_total_procs~ on Gate. -#+CAPTION: =roles_t/core/templates/nagios.cfg= +#+CAPTION: [[file:roles_t/core/templates/nagios.cfg][=roles_t/core/templates/nagios.cfg=]] #+BEGIN_SRC conf :tangle roles_t/core/templates/nagios.cfg define service { @@ -4046,14 +4046,14 @@ define service { For all campus NRPE servers: an ~inst_swap~ command to check the swap usage. -#+CAPTION: =roles_t/campus/files/nrpe.cfg= +#+CAPTION: [[file:roles_t/campus/files/nrpe.cfg][=roles_t/campus/files/nrpe.cfg=]] #+BEGIN_SRC conf :tangle roles_t/campus/files/nrpe.cfg command[inst_swap]=/usr/lib/nagios/plugins/check_swap -w 20% -c 10% #+END_SRC Monitor ~inst_swap~ on Gate. -#+CAPTION: =roles_t/core/templates/nagios.cfg= +#+CAPTION: [[file:roles_t/core/templates/nagios.cfg][=roles_t/core/templates/nagios.cfg=]] #+BEGIN_SRC conf :tangle roles_t/core/templates/nagios.cfg define service { @@ -4067,14 +4067,14 @@ define service { For all campus NRPE servers: an ~inst_sensors~ command to report core CPU temperatures. -#+CAPTION: =roles_t/campus/files/nrpe.cfg= +#+CAPTION: [[file:roles_t/campus/files/nrpe.cfg][=roles_t/campus/files/nrpe.cfg=]] #+BEGIN_SRC conf :tangle roles_t/campus/files/nrpe.cfg command[inst_sensors]=/usr/local/sbin/inst_sensors #+END_SRC Monitor ~inst_sensors~ on Gate. -#+CAPTION: =roles_t/core/templates/nagios.cfg= +#+CAPTION: [[file:roles_t/core/templates/nagios.cfg][=roles_t/core/templates/nagios.cfg=]] #+BEGIN_SRC conf :tangle roles_t/core/templates/nagios.cfg define service { @@ -4087,10 +4087,10 @@ define service { ** Configure Backups -The following task installs the =backup= script from =private/=. An +The following task installs the =backup= script from [[file:private/][=private/=]]. An example script is provided in [[backup][here]]. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install backup script. @@ -4116,7 +4116,7 @@ The Ansible code contained herein prepares Core to run Nextcloud by installing required software packages, configuring the web server, and installing a cron job. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install packages required by Nextcloud. @@ -4130,7 +4130,7 @@ installing a cron job. Next, a number of Apache2 modules are enabled. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Enable Apache2 modules for Nextcloud. @@ -4146,7 +4146,7 @@ and enabled with ~a2ensite~. The same configuration lines are given in the "Installation on Linux" section of the Nextcloud Server Administration Guide (sub-section [[https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html][Apache Web server configuration]]). -#+CAPTION: =roles_t/core/files/nextcloud.conf= +#+CAPTION: [[file:roles_t/core/files/nextcloud.conf][=roles_t/core/files/nextcloud.conf=]] #+BEGIN_SRC conf :tangle roles_t/core/files/nextcloud.conf Alias /nextcloud "/var/www/nextcloud/" @@ -4161,7 +4161,7 @@ Alias /nextcloud "/var/www/nextcloud/" #+END_SRC -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install Nextcloud web configuration. @@ -4184,7 +4184,7 @@ of the "Apache Web server configuration" subsection. The prescribed rewrite rules are included in a ~Directory~ block for the default virtual host's document root. -#+CAPTION: =roles_t/core/files/nextcloud.conf= +#+CAPTION: [[file:roles_t/core/files/nextcloud.conf][=roles_t/core/files/nextcloud.conf=]] #+BEGIN_SRC conf :tangle roles_t/core/files/nextcloud.conf @@ -4208,7 +4208,7 @@ recommended by Nextcloud 20's Settings > Administration > Overview web page. The following portion of =nextcloud.conf= sets a ~Strict-Transport-Security~ header with a ~max-age~ of 6 months. -#+CAPTION: =roles_t/core/files/nextcloud.conf= +#+CAPTION: [[file:roles_t/core/files/nextcloud.conf][=roles_t/core/files/nextcloud.conf=]] #+BEGIN_SRC conf :tangle roles_t/core/files/nextcloud.conf @@ -4222,7 +4222,7 @@ web server's user ~www-data~ and the ~www-data~ group. The administrator is added to this group to ease (speed) the debugging of cloud FUBARs. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Add {{ ansible_user }} to web server group. @@ -4236,7 +4236,7 @@ cloud FUBARs. Nextcloud is configured with a cron job to run periodic background jobs. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Create Nextcloud cron job. @@ -4252,10 +4252,10 @@ 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 [[file:private/vars.yml][=private/vars.yml=]], and generated e.g. with the ~apg -n 1 -x 12 -m 12~ command. -#+CAPTION: =private/vars.yml= +#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]] #+BEGIN_SRC conf :tangle private/vars.yml nextcloud_dbpass: ippAgmaygyob #+END_SRC @@ -4302,7 +4302,7 @@ Finally, a symbolic link positions =/Nextcloud/nextcloud/= at Nextcloud itself should always believe that =/var/www/nextcloud/= is its document root. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Link /var/www/nextcloud. @@ -4320,7 +4320,7 @@ its document root. The following tasks set a number of PHP parameters for better performance, as recommended by Nextcloud. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Set PHP memory_limit for Nextcloud. @@ -4507,7 +4507,7 @@ Nextcloud was installed, so the first "afterwards" task probes for ~nextcloud~ variable. The ~nextcloud.stat.exists~ condition on the afterwards tasks causes them to skip rather than fail. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Test for /Nextcloud/nextcloud/. @@ -4534,7 +4534,7 @@ variables ~domain_priv~ and ~nextcloud_dbpass~. The ~overwrite.cli.url~ setting is fixed by the tasks that implement Pretty URLs (below). -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Configure Nextcloud trusted domains. @@ -4564,7 +4564,7 @@ The institute uses the ~php-apcu~ package to provide Nextcloud with a local memory cache. The following ~memcache.local~ Nextcloud setting enables it. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Configure Nextcloud memcache. @@ -4584,7 +4584,7 @@ and server configuration" chapter in the Nextcloud 22 Server Administration Guide. Two settings are updated: ~overwrite.cli.url~ and ~htaccess.RewriteBase~. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Configure Nextcloud for Pretty URLs. @@ -4608,12 +4608,12 @@ and ~htaccess.RewriteBase~. The institute sets Nextcloud's ~default_phone_region~ mainly to avoid a complaint on the Settings > Administration > Overview web page. -#+CAPTION: =private/vars.yml= +#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]] #+BEGIN_SRC conf :tangle private/vars.yml nextcloud_region: US #+END_SRC -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Configure Nextcloud phone region. @@ -4634,7 +4634,7 @@ readable). This file is needed by the institute's ~backup~ command, so ~./inst config~ and in particular these next two tasks need to run before the next backup. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Create /Nextcloud/dbbackup.cnf. @@ -4687,7 +4687,7 @@ configurations, etc. The following should be familiar boilerplate by now. -#+CAPTION: =roles_t/gate/tasks/main.yml= +#+CAPTION: [[file:roles_t/gate/tasks/main.yml][=roles_t/gate/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/tasks/main.yml :mkdirp yes --- - name: Include public variables. @@ -4709,10 +4709,10 @@ campus Ethernet and WiFi. =/etc/netplan/60-isp.yaml= is expected to 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 [[file:private/vars.yml][=private/vars.yml=]], as in the example code here. -#+CAPTION: =private/vars.yml= +#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]] #+BEGIN_SRC conf :tangle private/vars.yml gate_lan_mac: ff:ff:ff:ff:ff:ff gate_wifi_mac: ff:ff:ff:ff:ff:ff @@ -4722,7 +4722,7 @@ gate_isp_mac: ff:ff:ff:ff:ff:ff The following tasks install the two configuration files and apply the new network plan. -#+CAPTION: =roles_t/gate/tasks/main.yml= +#+CAPTION: [[file:roles_t/gate/tasks/main.yml][=roles_t/gate/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/tasks/main.yml - name: Install netplan (gate). @@ -4776,7 +4776,7 @@ new network plan. notify: Apply netplan. #+END_SRC -#+CAPTION: =roles_t/gate/handlers/main.yml= +#+CAPTION: [[file:roles_t/gate/handlers/main.yml][=roles_t/gate/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/handlers/main.yml :mkdirp yes --- - name: Apply netplan. @@ -4871,7 +4871,7 @@ command after Gate is configured or new gate is "in position" : sudo ufw enable -#+CAPTION: =roles_t/gate/tasks/main.yml= +#+CAPTION: [[file:roles_t/gate/tasks/main.yml][=roles_t/gate/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/tasks/main.yml :noweb yes - name: Install UFW. @@ -4927,7 +4927,7 @@ specifically the sole subnet host: ~wifi_wan_name~ is any word appropriate for identifying the Wi-Fi AP, and ~wifi_wan_mac~ is the AP's MAC address. -#+CAPTION: =private/vars.yml= +#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]] #+BEGIN_SRC conf :tangle private/vars.yml wifi_wan_mac: 94:83:c4:19:7d:57 wifi_wan_name: campus-wifi-ap @@ -4946,7 +4946,7 @@ command would not be necessary. Installation and configuration of the DHCP daemon follows. Note that the daemon listens /only/ on the Gate-WiFi network interface. -#+CAPTION: =roles_t/gate/tasks/main.yml= +#+CAPTION: [[file:roles_t/gate/tasks/main.yml][=roles_t/gate/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/tasks/main.yml - name: Install DHCP server. @@ -4991,7 +4991,7 @@ the daemon listens /only/ on the Gate-WiFi network interface. enabled: yes #+END_SRC -#+CAPTION: =roles_t/gate/handlers/main.yml= +#+CAPTION: [[file:roles_t/gate/handlers/main.yml][=roles_t/gate/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/handlers/main.yml - name: Restart DHCP server. @@ -5008,7 +5008,7 @@ to authenticate itself to its clients. It uses the =/etc/server.crt= and =/etc/server.key= files just because the other servers (on Core and Front) do. -#+CAPTION: =roles_t/gate/tasks/main.yml= +#+CAPTION: [[file:roles_t/gate/tasks/main.yml][=roles_t/gate/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/tasks/main.yml - name: Install server certificate/key. @@ -5067,7 +5067,7 @@ tls-auth ta.key 0 Finally, here are the tasks (and handler) required to install and configure the OpenVPN server on Gate. -#+CAPTION: =roles_t/gate/tasks/main.yml= +#+CAPTION: [[file:roles_t/gate/tasks/main.yml][=roles_t/gate/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/tasks/main.yml :noweb yes - name: Install OpenVPN. @@ -5118,7 +5118,7 @@ configure the OpenVPN server on Gate. notify: Restart OpenVPN. #+END_SRC -#+CAPTION: =roles_t/gate/handlers/main.yml= +#+CAPTION: [[file:roles_t/gate/handlers/main.yml][=roles_t/gate/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/gate/handlers/main.yml - name: Restart OpenVPN. @@ -5146,7 +5146,7 @@ configured manually. The following should be familiar boilerplate by now. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml :mkdirp yes --- - name: Include public variables. @@ -5159,7 +5159,7 @@ The following should be familiar boilerplate by now. Clients should be using the expected host name. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml - name: Configure hostname. @@ -5177,7 +5177,7 @@ Clients should be using the expected host name. #+END_SRC -#+CAPTION: =roles_t/campus/handlers/main.yml= +#+CAPTION: [[file:roles_t/campus/handlers/main.yml][=roles_t/campus/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/handlers/main.yml :mkdirp yes --- - name: Update hostname. @@ -5190,7 +5190,7 @@ Clients should be using the expected host name. Campus machines start the ~systemd-networkd~ and ~systemd-resolved~ service units on boot. See [[resolved-front][Enable Systemd Resolved]]. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml :noweb yes <> #+END_SRC @@ -5200,7 +5200,7 @@ service units on boot. See [[resolved-front][Enable Systemd Resolved]]. Campus machines use the campus name server on Core (or ~dns.google~), and include the institute's private domain in their search lists. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml - name: Configure resolved. @@ -5218,7 +5218,7 @@ and include the institute's private domain in their search lists. - Restart Systemd resolved. #+END_SRC -#+CAPTION: =roles_t/campus/handlers/main.yml= +#+CAPTION: [[file:roles_t/campus/handlers/main.yml][=roles_t/campus/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/handlers/main.yml - name: Reload Systemd. @@ -5238,7 +5238,7 @@ The institute uses a common time reference throughout the campus. This is essential to campus security, improving the accuracy of log and file timestamps. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml - name: Configure timesyncd. @@ -5249,7 +5249,7 @@ and file timestamps. notify: Restart systemd-timesyncd. #+END_SRC -#+CAPTION: =roles_t/campus/handlers/main.yml= +#+CAPTION: [[file:roles_t/campus/handlers/main.yml][=roles_t/campus/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/handlers/main.yml - name: Restart systemd-timesyncd. @@ -5265,7 +5265,7 @@ The administrator often needs to read (directories of) log files owned by groups ~root~ and ~adm~. Adding the administrator's account to these groups speeds up debugging. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml - name: Add {{ ansible_user }} to system groups. @@ -5283,7 +5283,7 @@ trustworthy, so its certificate is added to the host's set of trusted CAs. (For more information about how the small institute manages its keys, certificates and passwords, see [[*Keys][Keys]].) -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml - name: Trust the institute CA. @@ -5297,7 +5297,7 @@ keys, certificates and passwords, see [[*Keys][Keys]].) notify: Update CAs. #+END_SRC -#+CAPTION: =roles_t/campus/handlers/main.yml= +#+CAPTION: [[file:roles_t/campus/handlers/main.yml][=roles_t/campus/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/handlers/main.yml - name: Update CAs. @@ -5309,7 +5309,7 @@ keys, certificates and passwords, see [[*Keys][Keys]].) The institute prefers to install security updates as soon as possible. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml - name: Install basic software. @@ -5329,7 +5329,7 @@ tasks below. - General type of mail configuration: Internet Site - System mail name: new.small.private -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml :noweb yes - name: Install Postfix. @@ -5363,7 +5363,7 @@ tasks below. state: started #+END_SRC -#+CAPTION: =roles_t/campus/handlers/main.yml= +#+CAPTION: [[file:roles_t/campus/handlers/main.yml][=roles_t/campus/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/handlers/main.yml - name: Restart Postfix. @@ -5379,7 +5379,7 @@ For the edification of programs consulting the =/etc/hosts= file, the institute's domain name and public IP address are added. The Debian custom of translating the host name into ~127.0.1.1~ is also followed. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml - name: Hard-wire important IP addresses. @@ -5405,7 +5405,7 @@ server so that the NAGIOS4 server on Core can collect statistics. The NAGIOS service is discussed in the [[*Configure NRPE][Configure NRPE]] section of [[*The Core Role][The Core Role]]. -#+CAPTION: =roles_t/campus/tasks/main.yml= +#+CAPTION: [[file:roles_t/campus/tasks/main.yml][=roles_t/campus/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/tasks/main.yml - name: Install NRPE. @@ -5443,7 +5443,7 @@ Role]]. state: started #+END_SRC -#+CAPTION: =roles_t/campus/handlers/main.yml= +#+CAPTION: [[file:roles_t/campus/handlers/main.yml][=roles_t/campus/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/campus/handlers/main.yml - name: Reload NRPE server. @@ -5457,16 +5457,16 @@ Role]]. * The Ansible Configuration 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 [[file:hosts][=hosts=]], and +runs playbook [[file:playbook/site.yml][=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 chapter [[*Testing][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 [[file:hosts][=hosts=]] inventory and +[[file:playbooks/site.yml][=site.yml=]] playbook, as well as the [[file:public/][=public/=]] and [[file:private/][=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 @@ -5474,7 +5474,7 @@ separate revision history. ** =ansible.cfg= -The Ansible configuration file =ansible.cfg= contains just a handful +The Ansible configuration file [[file:ansible.cfg][=ansible.cfg=]] contains just a handful of settings, some included just to create a test jig as described in [[*Testing][Testing]]. @@ -5482,14 +5482,14 @@ of settings, some included just to create a test jig as described in "automatic interpreter discovery" (described [[https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html][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 [[file:Secret/][=Secret/=]] (as described in [[*Keys][Keys]]) and thus sets this parameter to - =Secret/vault-password=. + [[file: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. + [[file:roles_t/][=roles_t/=]] which are preferred in the test configuration. -#+CAPTION: =ansible.cfg= +#+CAPTION: [[file:ansible.cfg][=ansible.cfg=]] #+BEGIN_SRC conf :tangle ansible.cfg [defaults] interpreter_python=/usr/bin/python3 @@ -5500,7 +5500,7 @@ roles_path=roles_t ** =hosts= -The Ansible inventory file =hosts= describes all of the institute's +The Ansible inventory file [[file:hosts][=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 @@ -5508,7 +5508,7 @@ addresses except Front's public IP. The following example host file describes three test servers named ~front~, ~core~ and ~gate~. #+NAME: hosts -#+CAPTION: =hosts= +#+CAPTION: [[file:hosts][=hosts=]] #+BEGIN_SRC conf :tangle hosts all: vars: @@ -5531,11 +5531,11 @@ all: #+END_SRC The values of the ~ansible_become_password~ key are references to -variables defined in =Secret/become.yml=, which is loaded as +variables defined in [[file:Secret/become.yml][=Secret/become.yml=]], which is loaded as "extra" variables by a ~-e~ option on the ~ansible-playbook~ command line. -#+CAPTION: =Secret/become.yml= +#+CAPTION: [[file:Secret/become.yml][=Secret/become.yml=]] #+BEGIN_SRC conf :tangle Secret/become.yml :tangle-mode u=rw become_front: !vault | $ANSIBLE_VAULT;1.1;AES256 @@ -5566,16 +5566,16 @@ 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 [[file:ansible.cfg][=ansible.cfg=]] file and thus +the [[file:Secret/vault-password][=Secret/vault-password=]] file. ** =playbooks/site.yml= -The example =playbooks/site.yml= playbook (below) applies the +The example [[file:playbooks/site.yml][=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: [[file:hosts][=hosts=]]. -#+CAPTION: =playbooks/site.yml= +#+CAPTION: [[file:playbooks/site.yml][=playbooks/site.yml=]] #+BEGIN_SRC conf :tangle playbooks/site.yml :mkdirp yes --- - name: Configure Front @@ -5599,13 +5599,13 @@ 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 +[[file:Secret/][=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. #+NAME: vault-password -#+CAPTION: =Secret/vault-password= +#+CAPTION: [[file:Secret/vault-password][=Secret/vault-password=]] #+BEGIN_SRC conf :tangle Secret/vault-password :tangle-mode u=r :mkdirp yes alitysortstagess #+END_SRC @@ -5677,9 +5677,9 @@ super-project's directory. ** Maintaining A Working Ansible Configuration -The Ansible roles currently tangle into the =roles_t/= directory to +The Ansible roles currently tangle into the [[file:roles_t/][=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 [[file:roles_t/][=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/=. @@ -5699,14 +5699,14 @@ to get their defaults from =./ansible.cfg=. ** Sub-command Blocks -The code blocks in this chapter tangle into the =inst= script. Each +The code blocks in this chapter tangle into the [[file:inst][=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. The first code block is the header of the ~./inst~ script. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst :tangle-mode u=rwx,g=rx #!/usr/bin/perl -w # @@ -5721,11 +5721,11 @@ use IO::File; 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 [[file:private/][=private/=]] have appropriate +permissions. It probes past the [[file:Secret/][=Secret/=]] mount point (probing for +[[file:Secret/become.yml][=Secret/become.yml=]]) to ensure the volume is mounted. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst sub note_missing_file_p ($); @@ -5777,12 +5777,12 @@ sub note_missing_directory_p ($) { 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 +[[file:playbooks/check-inst-vars.yml][=check-inst-vars.yml=]] playbook is used to update the Perl syntax file +[[file:private/vars.pl][=private/vars.pl=]] before ~./inst~ loads it. The Perl code in [[file:inst][=inst=]] +declares the necessary global variables and [[file:private/vars.pl][=private/vars.pl=]] sets them. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC conf :tangle inst sub mysystem (@) { @@ -5798,9 +5798,9 @@ our ($domain_name, $domain_priv, $front_addr, $gate_wifi_addr); do "./private/vars.pl"; #+END_SRC -The playbook that updates =private/vars.pl=: +The playbook that updates [[file:private/vars.pl][=private/vars.pl=]]: -#+CAPTION: =playbooks/check-inst-vars.yml= +#+CAPTION: [[file:playbooks/check-inst-vars.yml][=playbooks/check-inst-vars.yml=]] #+BEGIN_SRC conf :tangle playbooks/check-inst-vars.yml - hosts: localhost gather_facts: no @@ -5820,25 +5820,25 @@ The playbook that updates =private/vars.pl=: ** The CA Command 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 [[file:Secret/CA/][=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 [[file:Secret/][=Secret/=]]. The CA is created with the "common name" provided by the ~full_name~ variable. An example is given here. -#+CAPTION: =public/vars.yml= +#+CAPTION: [[file:public/vars.yml][=public/vars.yml=]] #+BEGIN_SRC conf :tangle public/vars.yml full_name: Small Institute LLC #+END_SRC -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 [[file:Secret/][=Secret/=]] directory is on an off-line, encrypted volume plugged in +just for the duration of ~./inst~ commands, so [[file:Secret/][=Secret/=]] is actually a symbolic link to a volume's automount location. : 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 [[file:Secret/CA/][=Secret/CA/=]] directory is prepared using Easy RSA's ~make-cadir~ +command. The [[file:Secret/CA/vars][=Secret/CA/vars=]] file thus created is edited to contain the appropriate names (or just to set ~EASYRSA_DN~ to ~cn_only~). : sudo apt install easy-rsa @@ -5852,7 +5852,7 @@ LLC~. The CA is used to issue certificates for ~front~, ~gate~ and ~core~, which are installed on the servers during the next ~./inst config~. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst if (defined $ARGV[0] && $ARGV[0] eq "CA") { @@ -5871,8 +5871,8 @@ if (defined $ARGV[0] && $ARGV[0] eq "CA") { 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"; @@ -5923,7 +5923,7 @@ Example command lines: : ./inst config HOST : ./inst config -n HOST -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst if (defined $ARGV[0] && $ARGV[0] eq "config") { @@ -6001,12 +6001,12 @@ revoked: #+END_SRC The test campus starts with the empty membership roll found in -=private/members-empty.yml= and saved in =private/members.yml= +[[file:private/members-empty.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. -#+CAPTION: =private/members-empty.yml= +#+CAPTION: [[file:private/members-empty.yml][=private/members-empty.yml=]] #+BEGIN_SRC conf :tangle private/members-empty.yml :tangle-mode u=rw --- members: @@ -6017,7 +6017,7 @@ revoked: [] Both locations go on the ~membership_rolls~ variable used by the ~include_vars~ tasks. -#+CAPTION: =private/vars.yml= +#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]] #+BEGIN_SRC conf :tangle private/vars.yml membership_rolls: - "../private/members.yml" @@ -6028,7 +6028,7 @@ Using the standard Perl library ~YAML::XS~, the subroutine for reading the membership roll is simple, returning the top-level hash read from the file. The dump subroutine is another story (below). -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst use YAML::XS qw(LoadFile DumpFile); @@ -6102,7 +6102,7 @@ produced by the for-the-purpose printer makes the resulting membership roll easier to read, with the ~username~ and ~status~ at the top of each record. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst sub print_member ($$) { @@ -6144,13 +6144,13 @@ sub print_member ($$) { 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 [[file:playbooks/site.yml][=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 initial, generated password. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst sub valid_username (@); @@ -6213,7 +6213,7 @@ sub strip_vault ($) { } #+END_SRC -#+CAPTION: =playbooks/nextcloud-new.yml= +#+CAPTION: [[file:playbooks/nextcloud-new.yml][=playbooks/nextcloud-new.yml=]] #+BEGIN_SRC conf :tangle playbooks/nextcloud-new.yml - hosts: core no_log: yes @@ -6249,7 +6249,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 [[file:playbooks/site.yml][=site.yml=]] playbook to update the servers. If all goes well a message is sent to ~member@core~. *** Less Aggressive passwd. @@ -6261,9 +6261,9 @@ 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 [[file:Secret/][=Secret/=]]. -#+CAPTION: =roles_t/core/templates/passwd= +#+CAPTION: [[file:roles_t/core/templates/passwd][=roles_t/core/templates/passwd=]] #+BEGIN_SRC perl :tangle roles_t/core/templates/passwd :mkdirp yes #!/bin/perl -wT @@ -6349,9 +6349,9 @@ exit; 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. +[[file:playbooks/site.yml][=playbooks/site.yml=]] and emailing the concerned member. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst use MIME::Base64; @@ -6408,7 +6408,7 @@ As always: please email root with any questions or concerns.\n"; And here is the playbook that interacts with Nextcloud's ~occ users:resetpassword~ command using ~expect(1)~. -#+CAPTION: =playbooks/nextcloud-pass.yml= +#+CAPTION: [[file:playbooks/nextcloud-pass.yml][=playbooks/nextcloud-pass.yml=]] #+BEGIN_SRC conf :tangle playbooks/nextcloud-pass.yml - hosts: core no_log: yes @@ -6447,7 +6447,7 @@ admin user is added to the shadow group so that the script can read key for ~root@core~ is also imported into the admin user's GnuPG configuration so that the email to root can be encrypted. -#+CAPTION: =roles_t/core/tasks/main.yml= +#+CAPTION: [[file:roles_t/core/tasks/main.yml][=roles_t/core/tasks/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/tasks/main.yml - name: Install institute passwd command. @@ -6493,7 +6493,7 @@ configuration so that the email to root can be encrypted. notify: Import root PGP key. #+END_SRC -#+CAPTION: =roles_t/core/handlers/main.yml= +#+CAPTION: [[file:roles_t/core/handlers/main.yml][=roles_t/core/handlers/main.yml=]] #+BEGIN_SRC conf :tangle roles_t/core/handlers/main.yml - name: Import root PGP key. @@ -6505,7 +6505,7 @@ configuration so that the email to root can be encrypted. The ~old~ command disables a member's accounts and clients. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst if (defined $ARGV[0] && $ARGV[0] eq "old") { @@ -6527,7 +6527,7 @@ if (defined $ARGV[0] && $ARGV[0] eq "old") { } #+END_SRC -#+CAPTION: =playbooks/nextcloud-old.yml= +#+CAPTION: [[file:playbooks/nextcloud-old.yml][=playbooks/nextcloud-old.yml=]] #+BEGIN_SRC conf :tangle playbooks/nextcloud-old.yml - hosts: core tasks: @@ -6547,7 +6547,7 @@ if (defined $ARGV[0] && $ARGV[0] eq "old") { 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 [[file:Secret/][=Secret/=]]. The generated configuration is slightly different depending on the type of host, given as the first argument to the command. @@ -6589,7 +6589,7 @@ up /etc/openvpn/update-systemd-resolved up-restart #+END_SRC -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst :noweb yes sub write_template ($$$$$$$$$); sub read_file ($); @@ -6702,11 +6702,11 @@ sub read_file ($) { ** Institute Command Help -This should be the last block tangled into the =inst= script. It +This should be the last block tangled into the [[file:inst][=inst=]] script. It catches any command lines that were not handled by a sub-command above. -#+CAPTION: =inst= +#+CAPTION: [[file:inst][=inst=]] #+BEGIN_SRC perl :tangle inst die "usage: $0 [CA|config|new|pass|old|client] ...\n"; @@ -6715,10 +6715,10 @@ die "usage: $0 [CA|config|new|pass|old|client] ...\n"; * 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, [[file:ansible.cfg][=ansible.cfg=]] and [[file:hosts][=hosts=]] as +well as those in [[file:public/][=public/=]] and [[file:private/][=private/=]], along with the matching EasyRSA certificate authority and GnuPG key-ring in -=Secret/= (included in the distribution), can be used to configure +[[file:Secret/][=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 @@ -7000,7 +7000,7 @@ VBoxManage modifyvm gate --hostonlyadapter3 vboxnet1 #+END_SRC 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 [[file:hosts][=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 @@ -7269,7 +7269,7 @@ host www ** Test Web Pages -Next, the administrator copies =Backup/WWW/= (included in the +Next, the administrator copies [[file:Backup/WWW/][=Backup/WWW/=]] (included in the distribution) to =/WWW/= on ~core~ and sets the file permissions appropriately. @@ -7552,11 +7552,11 @@ 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/=? +[[file:Backup/][=Backup/=]]? *** Restore -The restore process has not been tested. It might just copy =Backup/= +The restore process has not been tested. It might just copy [[file:Backup/][=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=. -- 2.25.1