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:
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
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
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.
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
#
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
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
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
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') }}"
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
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') }}"
: 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
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~.
: 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
: _ 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~.
: 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
: $ 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~.
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.
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
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.
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
<<enable-resolved>>
#+END_SRC
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.
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.
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.
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.
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.
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.
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.
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.
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.
=/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.
=/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.
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.
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
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.
=/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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
~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.
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.
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
<<enable-resolved>>
#+END_SRC
(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.
- 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.
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.
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.
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;
#+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.
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.
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.
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.
};
#+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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
=/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.
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.
=/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.
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.
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.
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.
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.
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.
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.
=/home/www/= on Front.
#+NAME: webupdate
-#+CAPTION: =private/webupdate=
+#+CAPTION: [[file:private/webupdate][=private/webupdate=]]
#+BEGIN_SRC sh
#!/bin/bash -e
#
./ {{ 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."
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.
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.
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.
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.
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
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
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 {
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 {
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 {
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 {
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 {
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 {
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 {
** 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.
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.
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.
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/"
</Directory>
#+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.
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
<Directory /var/www/html/>
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
<IfModule mod_headers.c>
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.
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.
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
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.
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.
~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/.
~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.
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.
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.
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.
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.
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.
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
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).
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.
: 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.
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
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.
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.
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.
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.
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.
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.
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.
#+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.
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
<<enable-resolved>>
#+END_SRC
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.
- 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.
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.
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.
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.
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.
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.
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.
- 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.
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.
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.
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.
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.
* 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
** =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]].
"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
** =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
describes three test servers named ~front~, ~core~ and ~gate~.
#+NAME: hosts
-#+CAPTION: =hosts=
+#+CAPTION: [[file:hosts][=hosts=]]
#+BEGIN_SRC conf :tangle hosts
all:
vars:
#+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
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
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
** 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/=.
** 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
#
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 ($);
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 (@) {
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
** 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
~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") {
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";
: ./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") {
#+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:
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"
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);
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 ($$) {
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 (@);
}
#+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
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.
(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
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;
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
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.
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.
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") {
}
#+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:
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.
up-restart
#+END_SRC
-#+CAPTION: =inst=
+#+CAPTION: [[file:inst][=inst=]]
#+BEGIN_SRC perl :tangle inst :noweb yes
sub write_template ($$$$$$$$$);
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";
* 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
#+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
** 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.
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=.