packages. The administrator temporarily plugged Core into a cable
modem and installed them as shown below.
-: $ sudo apt install netplan.io systemd-resolved unattended-upgrades \
+: $ sudo apt install systemd-resolved unattended-upgrades \
: _ chrony isc-dhcp-server bind9 apache2 wireguard \
: _ postfix dovecot-imapd fetchmail expect rsync \
: _ gnupg openssh-server
software packages. The administrator temporarily plugged Gate into a
cable modem and installed them as shown below.
-: $ sudo apt install netplan.io systemd-resolved unattended-upgrades \
-: _ ufw isc-dhcp-server postfix wireguard \
+: $ sudo apt install systemd-resolved unattended-upgrades \
+: _ ufw postfix wireguard \
: _ openssh-server
The host then needed to be rebooted to get its name service working
campus Wi-Fi access point and the campus ISP and the values of three
variables (~gate_lan_mac~, ~gate_wild_mac~, and ~gate_isp_mac~ in
[[file:private/vars.yml][=private/vars.yml=]]) match the actual hardware MAC addresses of the
-dongles. (For more information, see the Gate role's [[netplan-gate][Configure Netplan]]
-task.)
+dongles. (For more information, see the tasks in section [[Configure
+Gate NetworkD]].)
At this point Gate was ready for provisioning with Ansible.
tags: actualizer
#+END_SRC
-** Configure Netplan
+** Configure Core NetworkD
-Core's network interface is statically configured using Netplan and an
-=/etc/netplan/60-core.yaml= file. That file provides Core's address
-on the private Ethernet, the campus name server and search domain, and
-the default route through Gate to the campus ISP. A second route,
-through Core itself to Front, is advertised to other hosts.
+Core's network interface is statically configured using the
+~systemd-networkd~ configuration file =10-ether.network= installed in
+=/etc/systemd/network/=. That file provides Core's address on the
+private Ethernet, the campus name server and search domain, and the
+default route through Gate. A second route, through Core itself to
+Front, is advertised to other hosts, and is routed through a
+WireGuard™ interface connected to Front's public WireGuard™ VPN.
-Core's Netplan needs the name of its main (only) Ethernet interface,
-an example of which is given here. (A clever way to extract that name
-from ~ansible_facts~ would be appreciated. The ~ansible_default_ipv4~
-fact was an empty hash at first boot on a simulated campus Ethernet.)
+The configuration needs the name of its main (only) Ethernet
+interface, an example of which is given here. (A clever way to
+extract that name from ~ansible_facts~ would be appreciated. The
+~ansible_default_ipv4~ fact was an empty hash at first boot on a
+simulated campus Ethernet.)
#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]]
#+BEGIN_SRC conf :tangle private/vars.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.
- become: yes
- apt: pkg=netplan.io
-
-- name: Configure netplan.
+- name: Install 10-ether.network.
become: yes
copy:
content: |
- network:
- renderer: networkd
- ethernets:
- {{ core_ethernet }}:
- dhcp4: false
- addresses: [ {{ core_addr_cidr }} ]
- nameservers:
- search: [ {{ domain_priv }} ]
- addresses: [ {{ core_addr }} ]
- routes:
- - to: default
- via: {{ gate_addr }}
- dest: /etc/netplan/60-core.yaml
- mode: u=rw,g=r,o=
- notify: Apply netplan.
-#+END_SRC
+ [Match]
+ Name={{ core_ethernet }}
-#+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.
- become: yes
- command: netplan apply
- tags: actualizer
+ [Network]
+ Address={{ core_addr_cidr }}
+ Gateway={{ gate_addr }}
+ DNS={{ core_addr }}
+ Domains={{ domain_priv }}
+ dest: /etc/systemd/network/10-ether.network
#+END_SRC
** Configure DHCP For the Private Ethernet
tags: accounts
#+END_SRC
-** Configure Netplan <<netplan-gate>>
-
-Gate's network interfaces are configured using Netplan and two files.
-=/etc/netplan/60-gate.yaml= describes the static interfaces, to the
-campus Ethernet and Wi-Fi. =/etc/netplan/60-isp.yaml= is expected to
-be revised more frequently as the campus ISP changes.
+** Configure Gate NetworkD
-Netplan is configured to identify the interfaces by their MAC
-addresses, which must be provided in [[file:private/vars.yml][=private/vars.yml=]], as in the
-example code here.
+Gate's network interfaces are configured using SystemD NetworkD
+configuration files that specify their MAC addresses. (One or more
+might be plug-and-play USB dongles.) These addresses are provided by
+the [[file:private/vars.yml][=private/vars.yml=]] file as in the example code here.
#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]]
#+BEGIN_SRC conf :tangle private/vars.yml
gate_isp_mac: 08:00:27:3d:42:e5
#+END_SRC
-The following tasks install the two configuration files and apply the
-new network plan.
+The tasks in the following sections install the necessary
+configuration files.
+
+*** Gate's ~lan~ Interface
+
+The campus Ethernet interface is named ~lan~ and configured by
+=10-lan.link= and =10-lan.network= files in =/etc/systemd/network/=.
#+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).
- become: yes
- apt: pkg=netplan.io
-
-- name: Configure netplan (gate).
+- name: Install 10-lan.link.
become: yes
copy:
content: |
- network:
- ethernets:
- lan:
- match:
- macaddress: {{ gate_lan_mac }}
- addresses: [ {{ gate_addr_cidr }} ]
- set-name: lan
- dhcp4: false
- nameservers:
- addresses: [ {{ core_addr }} ]
- search: [ {{ domain_priv }} ]
- routes:
- - to: {{ public_wg_net_cidr }}
- via: {{ core_addr }}
- wild:
- match:
- macaddress: {{ gate_wild_mac }}
- addresses: [ {{ gate_wild_addr_cidr }} ]
- set-name: wild
- dhcp4: false
- dest: /etc/netplan/60-gate.yaml
- mode: u=rw,g=r,o=
- notify: Apply netplan.
-
-- name: Install netplan (ISP).
+ [Match]
+ MACAddress={{ gate_lan_mac }}
+
+ [Link]
+ Name=lan
+ dest: /etc/systemd/network/10-lan.link
+ notify: Reload networkd.
+
+- name: Install 10-lan.network.
become: yes
copy:
content: |
- network:
- ethernets:
- isp:
- match:
- macaddress: {{ gate_isp_mac }}
- set-name: isp
- dhcp4: true
- dhcp4-overrides:
- use-dns: false
- dest: /etc/netplan/60-isp.yaml
- mode: u=rw,g=r,o=
- force: no
- notify: Apply netplan.
+ [Match]
+ MACAddress={{ gate_lan_mac }}
+ Name=lan
+
+ [Network]
+ Address={{ gate_addr_cidr }}
+ DNS={{ core_addr }}
+ Domains={{ domain_priv }}
+
+ [Route]
+ Destination={{ public_vpn_net_cidr }}
+ Gateway={{ core_addr }}
+ dest: /etc/systemd/network/10-lan.network
+ notify: Reload networkd.
#+END_SRC
#+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.
+- name: Reload networkd.
become: yes
- command: netplan apply
- tags: actualizer
+ command: networkctl reload
+#+END_SRC
+
+*** Gate's ~wild~ Interface
+
+The institute keeps the wild ones off the campus Ethernet. Its wild
+subnet is connected to Gate via a separate physical interface. To
+accommodate the wild ones without re-configuring them, the institute
+attempts to look like an up-link, e.g. a cable modem. A wild one is
+expected to chirp for DHCP service and use the private subnet address
+in its lease. Thus Gate's ~wild~ interface configuration enables the
+built-in DHCP server and lists the authorized lessees.
+
+The wild ones are not expected to number in the dozens, so they are
+simply a list of hashes in [[file:private/vars.yml][=private/vars.yml=]], as in the example code
+here. Note that host number 1 is Gate. Wild ones are assigned unique
+host numbers greater than 1.
+
+#+CAPTION: [[file:private/vars.yml][=private/vars.yml=]]
+#+BEGIN_SRC conf :tangle private/vars.yml
+wild_ones:
+- { MAC: "94:83:c4:19:7d:57", num: 2, name: wifi-ap }
+- { MAC: "94:83:c4:19:7d:58", num: 3, name: appliance }
+#+END_SRC
+
+As with the ~lan~ interface, this interface is named ~wild~ and
+configured by =10-wild.link= and =10-wild.network= files in
+=/etc/systemd/network/=. The latter is generated from the hashes in
+~wild_ones~ and the =wild.network= template file.
+
+#+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 10-wild.link.
+ become: yes
+ copy:
+ content: |
+ [Match]
+ MACAddress={{ gate_wild_mac }}
+
+ [Link]
+ Name=wild
+ dest: /etc/systemd/network/10-wild.link
+ notify: Reload networkd.
+
+- name: Install 10-wild.network.
+ become: yes
+ template:
+ src: wild.network
+ dest: /etc/systemd/network/10-wild.network
+ notify: Reload networkd.
+#+END_SRC
+
+#+CAPTION: [[file:roles_t/gate/templates/wild.network][=roles_t/gate/templates/wild.network=]]
+#+BEGIN_SRC conf :tangle roles_t/gate/templates/wild.network :mkdirp yes
+[Match]
+MACAddress={{ gate_wild_mac }}
+
+[Network]
+Address={{ gate_wild_addr_cidr }}
+DHCPServer=yes
+
+[DHCPServer]
+EmitDNS=yes
+EmitNTP=yes
+NTP={{ core_addr }}
+EmitSMTP=yes
+SMTP={{ core_addr }}
+{% for wild in wild_ones %}
+
+[DHCPServerStaticLease]
+MACAddress={{ wild.MAC }}
+Address={{ wild.num |ansible.utils.ipaddr('address') }}
+{% endfor %}
+#+END_SRC
+
+*** Gate's ~isp~ Interface
+
+The interface to the campus ISP is named ~isp~ and configured by
+=10-isp.link= and =10-isp.network= files in =/etc/systemd/network/=.
+The latter is not automatically generated, as it varies quite a bit
+depending on the connection to the ISP: Ethernet interface, USB
+tether, Wi-Fi connection, etc.
+
+#+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 10-isp.link.
+ become: yes
+ copy:
+ content: |
+ [Match]
+ MACAddress={{ gate_isp_mac }}
+
+ [Link]
+ Name=isp
+ RequiredForOnline=no
+ dest: /etc/systemd/network/10-isp.link
+ notify: Reload networkd.
+
+- name: Install 10-isp.network.
+ become: yes
+ copy:
+ src: ../private/isp.network
+ dest: /etc/systemd/network/10-isp.network
+ force: no
+ notify: Reload networkd.
#+END_SRC
Note that the =60-isp.yaml= file is only updated (created) if it does
not already exist so that it can be easily modified to debug a new
campus ISP without interference from Ansible.
+The following example =isp.network= file recognizes an Ethernet
+interface by its MAC address.
+
+#+CAPTION: [[file:private/isp.network][=private/isp.network=]]
+#+BEGIN_SRC conf :tangle private/isp.network :tangle-mode u=rw,g=,o=
+[Match]
+MACAddress=08:00:27:3d:42:e5
+
+[Network]
+DHCP=ipv4
+
+[DHCP]
+RouteMetric=100
+UseMTU=true
+UseDNS=false
+#+END_SRC
+
** UFW Rules
Gate uses the Uncomplicated FireWall (UFW) to install its packet
prepend_newline: yes
#+END_SRC
-** Configure DHCP For The Wild Ethernet
-
-To accommodate commodity Wi-Fi access points, as well as wired IoT
-appliances, without re-configuring them, the institute attempts to
-look like an up-link, an ISP, e.g. a cable modem (aka "router"). It
-expects a wireless AP (or IoT appliance) to route non-local traffic
-out its WAN (or only) Ethernet port, and to get an IP address for that
-port using DHCP. Thus Gate runs ISC's DHCP daemon configured to
-listen on one network interface, recognize a specific list of clients,
-and provide each with an IP address and customary network parameters
-(default route, time server, etc.), much as was done on Core for the
-private Ethernet.
-
-The example configuration file, [[file:private/gate-dhcpd.conf][=private/gate-dhcpd.conf=]], unlike
-[[file:private/core-dhcpd.conf][=private/core-dhcpd.conf=]], does not need RFC3442 (Classless static
-routes). The wild, wired or wireless IoT need know nothing about the
-private network(s). This is just an example file, with a MAC address
-chosen to (probably?) match a VirtualBox test machine. In actual use
-=private/core-dhcpd.conf= refers to a replacement file.
-
-#+CAPTION: [[file:private/gate-dhcpd.conf][=private/gate-dhcpd.conf=]]
-#+BEGIN_SRC conf :tangle private/gate-dhcpd.conf :tangle-mode u=rw
-default-lease-time 3600;
-max-lease-time 7200;
-
-ddns-update-style none;
-
-authoritative;
-
-log-facility daemon;
-
-subnet 192.168.57.0 netmask 255.255.255.0 {
- option subnet-mask 255.255.255.0;
- option broadcast-address 192.168.57.255;
- option routers 192.168.57.1;
-}
-
-host campus-wifi-ap {
- hardware ethernet 94:83:c4:19:7d:57;
- fixed-address 192.168.57.2;
-}
-#+END_SRC
-
-Installation and configuration of the DHCP daemon follows. Note that
-the daemon listens /only/ on the ~wild~ network interface. Also note
-the drop-in ~Requires~ dependency, without which the DHCP server
-intermittently fails, finding the ~wild~ interface has no IPv4
-addresses (or perhaps finding no ~wild~ interface at all?).
-
-#+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.
- become: yes
- apt: pkg=isc-dhcp-server
-
-- name: Configure DHCP interface.
- become: yes
- lineinfile:
- path: /etc/default/isc-dhcp-server
- line: INTERFACESv4="wild"
- regexp: ^INTERFACESv4=
- notify: Restart DHCP server.
-
-- name: Configure DHCP subnet.
- become: yes
- copy:
- src: ../private/gate-dhcpd.conf
- dest: /etc/dhcp/dhcpd.conf
- notify: Restart DHCP server.
-
-- name: Configure DHCP server dependence on interface.
- become: yes
- copy:
- content: |
- [Unit]
- Requires=network-online.target
- dest: /etc/systemd/system/isc-dhcp-server.service.d/depend.conf
- notify: Reload Systemd.
-
-- name: Start DHCP server.
- become: yes
- systemd:
- service: isc-dhcp-server
- state: started
- tags: actualizer
-
-- name: Enable DHCP server.
- become: yes
- systemd:
- service: isc-dhcp-server
- enabled: yes
-#+END_SRC
-
-#+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.
- become: yes
- systemd:
- service: isc-dhcp-server
- state: restarted
- tags: actualizer
-
-- name: Reload Systemd.
- become: yes
- systemd:
- daemon-reload: yes
- tags: actualizer
-#+END_SRC
-
-If Gate is configured with ~./abbey config gate~ and then connected to
-actual networks (i.e. /not/ rebooted), the following command is
-executed. If a new gate was configured with ~./abbey config new-gate~
-and not rebooted, the following command would also be executed.
-
-: sudo systemctl start isc-dhcp-server
-
-If physically moved or rebooted for some other reason, the above
-command would not be necessary.
-
** Configure Campus WireGuard™ Subnet
Gate uses WireGuard™ to provide a campus VPN service. Gate's routes
# kept up-to-date.
#+BEGIN_SRC sh
-sudo apt install netplan.io systemd-resolved unattended-upgrades \
- ufw isc-dhcp-server postfix wireguard
+sudo apt install systemd-resolved unattended-upgrades \
+ ufw postfix wireguard
#+END_SRC
Again, the Postfix installation prompts for a couple settings. The
After ~gate~ boots up with its new network interfaces, the primary
Ethernet interface is temporarily configured with an IP address.
-(Ansible will install a Netplan soon.)
#+BEGIN_SRC sh
sudo ip address add 192.168.56.2/24 dev enp0s3
# kept up-to-date.
#+BEGIN_SRC sh
-sudo apt install netplan.io systemd-resolved unattended-upgrades \
+sudo apt install systemd-resolved unattended-upgrades \
ntp isc-dhcp-server bind9 apache2 wireguard \
postfix dovecot-imapd fetchmail expect rsync \
gnupg
#+END_SRC
After ~core~ boots up with its new network connection, its primary NIC
-is temporarily configured with an IP address. (Ansible will install a
-Netplan soon.)
+is temporarily configured with an IP address.
#+BEGIN_SRC sh
sudo ip address add 192.168.56.1/24 dev enp0s3
include_vars: "{{ lookup('first_found', membership_rolls) }}"
tags: accounts
-- name: Install netplan (gate).
+- name: Install 10-lan.link.
become: yes
- apt: pkg=netplan.io
+ copy:
+ content: |
+ [Match]
+ MACAddress={{ gate_lan_mac }}
+
+ [Link]
+ Name=lan
+ dest: /etc/systemd/network/10-lan.link
+ notify: Reload networkd.
-- name: Configure netplan (gate).
+- name: Install 10-lan.network.
become: yes
copy:
content: |
- network:
- ethernets:
- lan:
- match:
- macaddress: {{ gate_lan_mac }}
- addresses: [ {{ gate_addr_cidr }} ]
- set-name: lan
- dhcp4: false
- nameservers:
- addresses: [ {{ core_addr }} ]
- search: [ {{ domain_priv }} ]
- routes:
- - to: {{ public_wg_net_cidr }}
- via: {{ core_addr }}
- wild:
- match:
- macaddress: {{ gate_wild_mac }}
- addresses: [ {{ gate_wild_addr_cidr }} ]
- set-name: wild
- dhcp4: false
- dest: /etc/netplan/60-gate.yaml
- mode: u=rw,g=r,o=
- notify: Apply netplan.
+ [Match]
+ MACAddress={{ gate_lan_mac }}
+ Name=lan
+
+ [Network]
+ Address={{ gate_addr_cidr }}
+ DNS={{ core_addr }}
+ Domains={{ domain_priv }}
-- name: Install netplan (ISP).
+ [Route]
+ Destination={{ public_vpn_net_cidr }}
+ Gateway={{ core_addr }}
+ dest: /etc/systemd/network/10-lan.network
+ notify: Reload networkd.
+
+- name: Install 10-wild.link.
become: yes
copy:
content: |
- network:
- ethernets:
- isp:
- match:
- macaddress: {{ gate_isp_mac }}
- set-name: isp
- dhcp4: true
- dhcp4-overrides:
- use-dns: false
- dest: /etc/netplan/60-isp.yaml
+ [Match]
+ MACAddress={{ gate_wild_mac }}
+
+ [Link]
+ Name=wild
+ dest: /etc/systemd/network/10-wild.link
+ notify: Reload networkd.
+
+- name: Install 10-wild.network.
+ become: yes
+ template:
+ src: wild.network
+ dest: /etc/systemd/network/10-wild.network
+ notify: Reload networkd.
+
+- name: Install 10-isp.link.
+ become: yes
+ copy:
+ content: |
+ [Match]
+ MACAddress={{ gate_isp_mac }}
+
+ [Link]
+ Name=isp
+ RequiredForOnline=no
+ dest: /etc/systemd/network/10-isp.link
+ notify: Reload networkd.
+
+- name: Install 10-isp.network.
+ become: yes
+ copy:
+ src: ../private/isp.network
+ dest: /etc/systemd/network/10-isp.network
mode: u=rw,g=r,o=
force: no
- notify: Apply netplan.
+ notify: Reload networkd.
- name: Install UFW.
become: yes
insertafter: EOF
prepend_newline: yes
-- name: Install DHCP server.
- become: yes
- apt: pkg=isc-dhcp-server
-
-- name: Configure DHCP interface.
- become: yes
- lineinfile:
- path: /etc/default/isc-dhcp-server
- line: INTERFACESv4="wild"
- regexp: ^INTERFACESv4=
- notify: Restart DHCP server.
-
-- name: Configure DHCP subnet.
- become: yes
- copy:
- src: ../private/gate-dhcpd.conf
- dest: /etc/dhcp/dhcpd.conf
- notify: Restart DHCP server.
-
-- name: Configure DHCP server dependence on interface.
- become: yes
- copy:
- content: |
- [Unit]
- Requires=network-online.target
- dest: /etc/systemd/system/isc-dhcp-server.service.d/depend.conf
- notify: Reload Systemd.
-
-- name: Start DHCP server.
- become: yes
- systemd:
- service: isc-dhcp-server
- state: started
- tags: actualizer
-
-- name: Enable DHCP server.
- become: yes
- systemd:
- service: isc-dhcp-server
- enabled: yes
-
- name: Enable IP forwarding.
become: yes
sysctl: