From c0cc0ed8f0092c0ad80d407fefc7a2d20b3c4db8 Mon Sep 17 00:00:00 2001
From: Matt Birkholz
+= _|||_ =-The-Institute-= @@ -1022,7 +1022,7 @@ example result follows the code.-+-=> 10.62.17.0/24
@@ -1475,7 +1475,7 @@ USB-Ethernet adapter, or a wireless adapter connected to a campground Wi-Fi access point, etc. -+=============== | ================================================== | Premises (Campus ISP) @@ -1498,7 +1498,7 @@ This avoids the need for a second Wi-Fi access point and leads to the following topology. -+=============== | ================================================== | Premises (House ISP) @@ -1651,8 +1651,8 @@ Theall
role contains tasks that are executed on all of the institute's servers. At the moment there is just the one.-6.1. Include Particulars
++6.1. Include Particulars
-The
all
role's task contains a reference to a common institute @@ -1793,8 +1793,8 @@ uses the institute's CA and server certificates, and expects client certificates signed by the institute CA.--7.1. Include Particulars
++7.1. Include Particulars
The first task, as in The All Role, is to include the institute @@ -1819,8 +1819,8 @@ membership roll, so these are included was well.
--7.2. Configure Hostname
++7.2. Configure Hostname
This task ensures that Front's
/etc/hostnameand/etc/mailnameare @@ -1850,8 +1850,8 @@ delivery.--7.3. Add Administrator to System Groups
++7.3. Add Administrator to System Groups
The administrator often needs to read (directories of) log files owned @@ -1910,8 +1910,8 @@ those stored in
Secret/ssh_front/etc/ssh/--7.5. Configure Monkey
++7.5. Configure Monkey
The small institute runs cron jobs and web scripts that generate @@ -1967,8 +1967,8 @@ Monkey uses Rsync to keep the institute's public web site up-to-date.
--7.7. Install Unattended Upgrades
++7.7. Install Unattended Upgrades
The institute prefers to install security updates as soon as possible. @@ -1983,8 +1983,8 @@ The institute prefers to install security updates as soon as possible.
--7.8. Configure User Accounts
++7.8. Configure User Accounts
User accounts are created immediately so that Postfix and Dovecot can @@ -2027,8 +2027,8 @@ recipient" replies. The Account Management chapter de
--7.9. Install Server Certificate
++7.9. Install Server Certificate
The servers on Front use the same certificate (and key) to @@ -2255,8 +2255,8 @@ created by a more specialized role.
--7.12. Configure Dovecot IMAPd
++7.12. Configure Dovecot IMAPd
Front uses Dovecot's IMAPd to allow user Fetchmail jobs on Core to @@ -2612,8 +2612,8 @@ the users'
~/Public/HTML/directories.-7.14. Configure OpenVPN
++7.14. Configure OpenVPN
-Front uses OpenVPN to provide the institute's public VPN service. The @@ -2896,8 +2896,8 @@ Debian install and remote access to a privileged, administrator's account. (For details, see The Core Machine.)
--8.1. Include Particulars
++8.1. Include Particulars
The first task, as in The Front Role, is to include the institute @@ -2919,8 +2919,8 @@ particulars and membership roll.
--8.2. Configure Hostname
++8.2. Configure Hostname
This task ensures that Core's
/etc/hostnameand/etc/mailnameare @@ -2953,8 +2953,8 @@ proper email delivery.--8.3. Configure Systemd Resolved
++8.3. Configure Systemd Resolved
Core runs the campus name server, so Resolved is configured to use it @@ -3367,8 +3367,8 @@ probably be used as forwarders rather than Google.
--8.7. Add Administrator to System Groups
++8.7. Add Administrator to System Groups
The administrator often needs to read (directories of) log files owned @@ -3388,8 +3388,8 @@ these groups speeds up debugging.
--8.8. Configure Monkey
++8.8. Configure Monkey
The small institute runs cron jobs and web scripts that generate @@ -3456,8 +3456,8 @@ described in *Configure Apache2).
--8.9. Install Unattended Upgrades
++8.9. Install Unattended Upgrades
The institute prefers to install security updates as soon as possible. @@ -3489,8 +3489,8 @@ with Nextcloud on the command line.
--8.11. Configure User Accounts
++8.11. Configure User Accounts
User accounts are created immediately so that backups can begin @@ -3532,8 +3532,8 @@ describes the
members
andusernames
variables.--8.12. Install Server Certificate
++8.12. Install Server Certificate
The servers on Core use the same certificate (and key) to authenticate @@ -3757,8 +3757,8 @@ installed by more specialized roles.
-8.16. Configure Dovecot IMAPd
++8.16. Configure Dovecot IMAPd
@@ -5091,22 +5080,11 @@ performance, as recommended by Nextcloud.Core uses Dovecot's IMAPd to store and serve member emails. As on @@ -4157,22 +4157,11 @@ The tasks below install Apache2 and edit its default configuration. apt: pkg=apache2 - name: Enable Apache2 modules. - become: yes - apache2_module: - name: "{{ item }}" - loop: [ userdir, cgi ] - notify: Restart Apache2. - when: ansible_distribution != 'Debian' - or 12 > ansible_distribution_major_version|int - -- name: Enable Apache2 modules (Debian 12). become: yes apache2_module: name: "{{ item }}" loop: [ userdir, cgid ] notify: Restart Apache2. - when: ansible_distribution == 'Debian' - and 11 < ansible_distribution_major_version|int
-roles_t/core/tasks/main.yml- name: Set PHP memory_limit for Nextcloud. - become: yes - lineinfile: - path: /etc/php/7.4/apache2/php.ini - regexp: memory_limit *= - line: memory_limit = 512M - when: ansible_distribution != 'Debian' - or 12 > ansible_distribution_major_version|int - -- name: Set PHP memory_limit for Nextcloud (Debian 12). become: yes lineinfile: path: /etc/php/8.2/apache2/php.ini regexp: memory_limit *= line: memory_limit = 512M - when: ansible_distribution == 'Debian' - and 11 < ansible_distribution_major_version|int - name: Include PHP parameters for Nextcloud. become: yes @@ -5116,12 +5094,12 @@ performance, as recommended by Nextcloud. apc.enable_cli=1 opcache.enable=1 opcache.enable_cli=1 - opcache.interned_strings_buffer=8 + opcache.interned_strings_buffer=12 opcache.max_accelerated_files=10000 opcache.memory_consumption=128 opcache.save_comments=1 opcache.revalidate_freq=1 - dest: /etc/php/7.4/mods-available/nextcloud.ini + dest: /etc/php/8.2/mods-available/nextcloud.ini notify: Restart Apache2. - name: Enable Nextcloud PHP modules. @@ -5530,8 +5508,8 @@ applied first, by which Gate gets a campus machine's DNS and Postfix configurations, etc.--9.1. Include Particulars
++9.1. Include Particulars
The following should be familiar boilerplate by now. @@ -5900,8 +5878,8 @@ the daemon listens only on the Gate-WiFi network interface.
--9.6. Install Server Certificate
++9.6. Install Server Certificate
The (OpenVPN) server on Gate uses an institute certificate (and key) @@ -5928,8 +5906,8 @@ and Front) do.
-9.7. Configure OpenVPN
++9.7. Configure OpenVPN
-Gate uses OpenVPN to provide the institute's campus VPN service. Its @@ -6056,8 +6034,8 @@ Wireless campus devices can get a key to the campus VPN from the configured manually.
--10.1. Include Particulars
++10.1. Include Particulars
The following should be familiar boilerplate by now. @@ -6073,8 +6051,8 @@ The following should be familiar boilerplate by now.
--10.2. Configure Hostname
++10.2. Configure Hostname
Clients should be using the expected host name. @@ -6101,8 +6079,8 @@ Clients should be using the expected host name.
--10.3. Configure Systemd Resolved
++10.3. Configure Systemd Resolved
Campus machines use the campus name server on Core (or
dns.google
), @@ -6173,8 +6151,8 @@ and file timestamps.--10.5. Add Administrator to System Groups
++10.5. Add Administrator to System Groups
The administrator often needs to read (directories of) log files owned @@ -6194,8 +6172,8 @@ these groups speeds up debugging.
-10.6. Install Unattended Upgrades
++@@ -6699,7 +6677,7 @@ permissions. It probes past the10.6. Install Unattended Upgrades
The institute prefers to install security updates as soon as possible. @@ -6675,8 +6653,8 @@ The first code block is the header of the
./inst
script. # # DO NOT EDIT. This file was tangled from an institute.org file. -use strict; -use IO::File; +use strict; +use IO::File;Secret/mount poin sub note_missing_directory_p ($); { - my $missing = 0; + my $missing = 0; if (note_missing_file_p "ansible.cfg") { $missing += 1; } if (note_missing_file_p "hosts") { $missing += 1; } if (note_missing_directory_p "Secret") { $missing += 1; } @@ -6710,8 +6688,8 @@ permissions. It probes past theSecret/mount poin if (note_missing_directory_p "public") { $missing += 1; } if (note_missing_directory_p "private") { $missing += 1; } - for my $filename (glob "private/*") { - my $perm = (stat $filename)[2]; + for my $filename (glob "private/*") { + my $perm = (stat $filename)[2]; if ($perm & 077) { print "$filename: not private\n"; } @@ -6720,7 +6698,7 @@ permissions. It probes past theSecret/mount poin } sub note_missing_file_p ($) { - my ($filename) = @_; + my ($filename) = @_; if (! -f $filename) { print "$filename: missing\n"; return 1; @@ -6730,7 +6708,7 @@ permissions. It probes past theSecret/mount poin } sub note_missing_directory_p ($) { - my ($dirname) = @_; + my ($dirname) = @_; if (! -d $dirname) { print "$dirname: missing\n"; return 1; @@ -6845,7 +6823,7 @@ config.instif (defined $ARGV[0] && $ARGV[0] eq "CA") { - die "usage: $0 CA" if @ARGV != 1; + die "usage: $0 CA" if @ARGV != 1; die "Secret/CA/easyrsa: not an executable\n" if ! -x "Secret/CA/easyrsa"; die "Secret/CA/pki/: already exists\n" if -e "Secret/CA/pki"; @@ -6855,8 +6833,8 @@ config. mysystem "cd Secret/CA; ./easyrsa build-ca nopass"; # Common Name: small.example.org - my $dom = $domain_name; - my $pvt = $domain_priv; + my $dom = $domain_name; + my $pvt = $domain_priv; mysystem "cd Secret/CA; ./easyrsa build-server-full $dom nopass"; mysystem "cd Secret/CA; ./easyrsa build-server-full gate.$pvt nopass"; mysystem "cd Secret/CA; ./easyrsa build-server-full core.$pvt nopass"; @@ -6930,15 +6908,15 @@ Example command lines: die "Secret/CA/easyrsa: not executable\n" if ! -x "Secret/CA/easyrsa"; shift; - my $cmd = "ansible-playbook -e \@Secret/become.yml"; + my $cmd = "ansible-playbook -e \@Secret/become.yml"; if (defined $ARGV[0] && $ARGV[0] eq "-n") { shift; $cmd .= " --check --diff" } - if (@ARGV == 0) { + if (@ARGV == 0) { ; } elsif (defined $ARGV[0]) { - my $hosts = lc $ARGV[0]; + my $hosts = lc $ARGV[0]; die "$hosts: contains illegal characters" if $hosts !~ /^!?[a-z][-a-z0-9,!]+$/; $cmd .= " -l $hosts"; @@ -7045,10 +7023,10 @@ read from the file. The dump subroutine is another story (below).inst-use YAML::XS qw(LoadFile DumpFile); +use YAML::XS qw(LoadFile DumpFile); sub read_members_yaml () { - my $path; + my $path; $path = "private/members.yml"; if (-e $path) { return LoadFile ($path); } $path = "private/members-empty.yml"; @@ -7057,15 +7035,15 @@ read from the file. The dump subroutine is another story (below). } sub write_members_yaml ($) { - my ($yaml) = @_; - my $old_umask = umask 077; - my $path = "private/members.yml"; + my ($yaml) = @_; + my $old_umask = umask 077; + my $path = "private/members.yml"; print "$path: "; STDOUT->flush; eval { #DumpFile ("$path.tmp", $yaml); dump_members_yaml ("$path.tmp", $yaml); rename ("$path.tmp", $path) or die "Could not rename $path.tmp: $!\n"; }; - my $err = $@; + my $err = $@; umask $old_umask; if ($err) { print "ERROR\n"; @@ -7076,17 +7054,17 @@ read from the file. The dump subroutine is another story (below). } sub dump_members_yaml ($$) { - my ($pathname, $yaml) = @_; - my $O = new IO::File; + my ($pathname, $yaml) = @_; + my $O = new IO::File; open ($O, ">$pathname") or die "Could not open $pathname: $!\n"; print $O "---\n"; if (keys %{$yaml->{"members"}}) { print $O "members:\n"; - for my $user (sort keys %{$yaml->{"members"}}) { + for my $user (sort keys %{$yaml->{"members"}}) { print_member ($O, $yaml->{"members"}->{$user}); } print $O "usernames:\n"; - for my $user (sort keys %{$yaml->{"members"}}) { + for my $user (sort keys %{$yaml->{"members"}}) { print $O "- $user\n"; } } else { @@ -7095,7 +7073,7 @@ read from the file. The dump subroutine is another story (below). } if (@{$yaml->{"revoked"}}) { print $O "revoked:\n"; - for my $name (@{$yaml->{"revoked"}}) { + for my $name (@{$yaml->{"revoked"}}) { print $O "- $name\n"; } } else { @@ -7122,13 +7100,13 @@ each record.@@ -7294,11 +7272,11 @@ ininstsub print_member ($$) { - my ($out, $member) = @_; + my ($out, $member) = @_; print $out " ", $member->{"username"}, ":\n"; print $out " username: ", $member->{"username"}, "\n"; print $out " status: ", $member->{"status"}, "\n"; if (@{$member->{"clients"} || []}) { print $out " clients:\n"; - for my $name (@{$member->{"clients"} || []}) { + for my $name (@{$member->{"clients"} || []}) { print $out " - ", $name, "\n"; } } else { @@ -7138,18 +7116,18 @@ each record. print $out " password_core: ", $member->{"password_core"}, "\n"; if (defined $member->{"password_fetchmail"}) { print $out " password_fetchmail: !vault |\n"; - for my $line (split /\n/, $member->{"password_fetchmail"}) { + for my $line (split /\n/, $member->{"password_fetchmail"}) { print $out " $line\n"; } } - my @standard_keys = ( "username", "status", "clients", + my @standard_keys = ( "username", "status", "clients", "password_front", "password_core", "password_fetchmail" ); - my @other_keys = (sort - grep { my $k = $_; - ! grep { $_ eq $k } @standard_keys } + my @other_keys = (sort + grep { my $k = $_; + ! grep { $_ eq $k } @standard_keys } keys %$member); - for my $key (@other_keys) { + for my $key (@other_keys) { print $out " $key: ", $member->{$key}, "\n"; } } @@ -7178,17 +7156,17 @@ initial, generated password. sub strip_vault ($); if (defined $ARGV[0] && $ARGV[0] eq "new") { - my $user = valid_username (@ARGV); - my $yaml = read_members_yaml (); - my $members = $yaml->{"members"}; + my $user = valid_username (@ARGV); + my $yaml = read_members_yaml (); + my $members = $yaml->{"members"}; die "$user: already exists\n" if defined $members->{$user}; - my $pass = `apg -n 1 -x 12 -m 12`; chomp $pass; + my $pass = `apg -n 1 -x 12 -m 12`; chomp $pass; print "Initial password: $pass\n"; - my $epass = shell_escape $pass; - my $front = `mkpasswd -m sha-512 "$epass"`; chomp $front; - my $core = `mkpasswd -m sha-512 "$epass"`; chomp $core; - my $vault = strip_vault `ansible-vault encrypt_string "$epass"`; + my $epass = shell_escape $pass; + my $front = `mkpasswd -m sha-512 "$epass"`; chomp $front; + my $core = `mkpasswd -m sha-512 "$epass"`; chomp $core; + my $vault = strip_vault `ansible-vault encrypt_string "$epass"`; mysystem ("ansible-playbook -e \@Secret/become.yml", " playbooks/nextcloud-new.yml", " -e user=$user", " -e pass=\"$epass\""); @@ -7206,10 +7184,10 @@ initial, generated password. } sub valid_username (@) { - my $sub = $_[0]; + my $sub = $_[0]; die "usage: $0 $sub USER\n" - if @_ != 2; - my $username = lc $_[1]; + if @_ != 2; + my $username = lc $_[1]; die "$username: does not begin with an alphabetic character\n" if $username !~ /^[a-z]/; die "$username: contains non-alphanumeric character(s)\n" @@ -7218,18 +7196,18 @@ initial, generated password. } sub shell_escape ($) { - my ($string) = @_; - my $result = "$string"; + my ($string) = @_; + my $result = "$string"; $result =~ s/([\$`"\\ ])/\\$1/g; return ($result); } sub strip_vault ($) { - my ($string) = @_; + my ($string) = @_; die "Unexpected result from ansible-vault: $string\n" if $string !~ /^ *!vault [|]/; - my @lines = split /^ */m, $string; - return (join "", @lines[1..$#lines]); + my @lines = split /^ */m, $string; + return (join "", @lines[1..$#lines]); }Secret/.-- 2.25.1 -roles_t/core/templates/passwd#!/bin/perl -wT -use strict; +use strict; $ENV{PATH} = "/usr/sbin:/usr/bin:/bin"; -my ($username) = getpwuid $<; +my ($username) = getpwuid $<; if ($username ne "{{ ansible_user }}") { { exec ("sudo", "-u", "{{ ansible_user }}", "/usr/local/bin/passwd", $username) }; @@ -7307,11 +7285,11 @@ $ENV{PATH} = "/u } $username = $ARGV[0]; -my $passwd; +my $passwd; { - my $SHADOW = new IO::File; + my $SHADOW = new IO::File; open $SHADOW, "</etc/shadow" or die "Cannot read /etc/shadow: $!\n"; - my ($line) = grep /^$username:/, <$SHADOW>; + my ($line) = grep /^$username:/, <$SHADOW>; close $SHADOW; die "No /etc/shadow record found: $username\n" if ! defined $line; (undef, $passwd) = split ":", $line; @@ -7321,9 +7299,9 @@ system "stty -echo"; END { system "stty echo"; } print "Current password: "; -my $pass = <STDIN>; chomp $pass; +my $pass = <STDIN>; chomp $pass; print "\n"; -my $hash = crypt($pass, $passwd); +my $hash = crypt($pass, $passwd); die "Sorry...\n" if $hash ne $passwd; print "New password: "; @@ -7331,36 +7309,36 @@ $pass = <ST die "Passwords must be at least 10 characters long.\n" if length $pass < 10; print "\nRetype password: "; -my $pass2 = <STDIN>; chomp($pass2); +my $pass2 = <STDIN>; chomp($pass2); print "\n"; die "New passwords do not match!\n" if $pass2 ne $pass; -use MIME::Base64; -my $epass = encode_base64 $pass; +use MIME::Base64; +my $epass = encode_base64 $pass; -use File::Temp qw(tempfile); -my ($TMP, $tmp) = tempfile; +use File::Temp qw(tempfile); +my ($TMP, $tmp) = tempfile; close $TMP; -my $O = new IO::File; +my $O = new IO::File; open $O, ("| gpg --encrypt --armor" ." --trust-model always --recipient root\@core" ." > $tmp") or die "Error running gpg > $tmp: $!\n"; print $O <<EOD; -username: $username -password: $epass -EOD +username: $username +password: $epass +EOD close $O or die "Error closing pipe to gpg: $!\n"; -use File::Copy; +use File::Copy; open ($O, "| sendmail root"); print $O <<EOD; -From: root -To: root -Subject: New password. +From: root +To: root +Subject: New password. -EOD +EOD $O->flush; copy $tmp, $O; #print $O `cat $tmp`; @@ -7385,32 +7363,32 @@ the administrator to updateprivate/members.ymlbefore runninginst-use MIME::Base64; +use MIME::Base64; if (defined $ARGV[0] && $ARGV[0] eq "pass") { - my $I = new IO::File; + my $I = new IO::File; open $I, "gpg --homedir Secret/root.gnupg --quiet --decrypt |" or die "Error running gpg: $!\n"; - my $msg_yaml = LoadFile ($I); + my $msg_yaml = LoadFile ($I); close $I or die "Error closing pipe from gpg: $!\n"; - my $user = $msg_yaml->{"username"}; + my $user = $msg_yaml->{"username"}; die "Could not find a username in the decrypted input.\n" if ! defined $user; - my $pass64 = $msg_yaml->{"password"}; + my $pass64 = $msg_yaml->{"password"}; die "Could not find a password in the decrypted input.\n" if ! defined $pass64; - my $mem_yaml = read_members_yaml (); - my $members = $mem_yaml->{"members"}; - my $member = $members->{$user}; + my $mem_yaml = read_members_yaml (); + my $members = $mem_yaml->{"members"}; + my $member = $members->{$user}; die "No such member: $user\n" if ! defined $member; - my $pass = decode_base64 $pass64; - my $epass = shell_escape $pass; - my $front = `mkpasswd -m sha-512 "$epass"`; chomp $front; - my $core = `mkpasswd -m sha-512 "$epass"`; chomp $core; - my $vault = strip_vault `ansible-vault encrypt_string "$epass"`; + my $pass = decode_base64 $pass64; + my $epass = shell_escape $pass; + my $front = `mkpasswd -m sha-512 "$epass"`; chomp $front; + my $core = `mkpasswd -m sha-512 "$epass"`; chomp $core; + my $vault = strip_vault `ansible-vault encrypt_string "$epass"`; $member->{"password_front"} = $front; $member->{"password_core"} = $core; $member->{"password_fetchmail"} = $vault; @@ -7421,7 +7399,7 @@ the administrator to updateprivate/members.ymlbefore running write_members_yaml $mem_yaml; mysystem ("ansible-playbook -e \@Secret/become.yml", "-t accounts playbooks/site.yml"); - my $O = new IO::File; + my $O = new IO::File; open ($O, "| sendmail $user\@$domain_priv") or die "Could not pipe to sendmail: $!\n"; print $O "From: <root> @@ -7551,10 +7529,10 @@ Theold
command disables a member's accounts and clients.@@ -9130,7 +9108,7 @@ routes on Front and Gate, making the simulation less… similar.instif (defined $ARGV[0] && $ARGV[0] eq "old") { - my $user = valid_username (@ARGV); - my $yaml = read_members_yaml (); - my $members = $yaml->{"members"}; - my $member = $members->{$user}; + my $user = valid_username (@ARGV); + my $yaml = read_members_yaml (); + my $members = $yaml->{"members"}; + my $member = $members->{$user}; die "$user: does not exist\n" if ! defined $member; mysystem ("ansible-playbook -e \@Secret/become.yml", @@ -7648,29 +7626,29 @@ up-restart if (defined $ARGV[0] && $ARGV[0] eq "client") { die "Secret/CA/easyrsa: not found\n" if ! -x "Secret/CA/easyrsa"; - my $type = $ARGV[1]||""; - my $name = $ARGV[2]||""; - my $user = $ARGV[3]||""; + my $type = $ARGV[1]||""; + my $name = $ARGV[2]||""; + my $user = $ARGV[3]||""; if ($type eq "campus") { - die "usage: $0 client campus NAME\n" if @ARGV != 3; + die "usage: $0 client campus NAME\n" if @ARGV != 3; die "$name: invalid host name\n" if $name !~ /^[a-z][-a-z0-9]+$/; } elsif ($type eq "android" || $type eq "debian") { - die "usage: $0 client $type NAME USER\n" if @ARGV != 4; + die "usage: $0 client $type NAME USER\n" if @ARGV != 4; die "$name: invalid host name\n" if $name !~ /^[a-z][-a-z0-9]+$/; } else { - die "usage: $0 client [debian|android|campus]\n" if @ARGV != 4; + die "usage: $0 client [debian|android|campus]\n" if @ARGV != 4; } - my $yaml; - my $member; + my $yaml; + my $member; if ($type ne "campus") { $yaml = read_members_yaml; - my $members = $yaml->{"members"}; - if (@ARGV == 4) { + my $members = $yaml->{"members"}; + if (@ARGV == 4) { $member = $members->{$user}; die "$user: does not exist\n" if ! defined $member; } if (defined $member) { - my ($owner) = grep { grep { $_ eq $name } @{$_->{"clients"}} } + my ($owner) = grep { grep { $_ eq $name } @{$_->{"clients"}} } values %{$members}; die "$name: owned by $owner->{username}\n" if defined $owner && $owner->{username} ne $member->{username}; @@ -7687,7 +7665,7 @@ up-restart } if ($type ne "campus") { - my $clients = $member->{"clients"}; + my $clients = $member->{"clients"}; if (! grep { $_ eq $name } @$clients) { $member->{"clients"} = [ $name, @$clients ]; write_members_yaml $yaml; @@ -7695,20 +7673,20 @@ up-restart } umask 077; - my $DEV = $type eq "android" ? "tun" : "ovpn"; - my $CA = read_file "Secret/CA/pki/ca.crt"; - my $CRT = read_file "Secret/CA/pki/issued/$name.crt"; - my $KEY = read_file "Secret/CA/pki/private/$name.key"; - my $UP = $type eq "android" ? "" : " + my $DEV = $type eq "android" ? "tun" : "ovpn"; + my $CA = read_file "Secret/CA/pki/ca.crt"; + my $CRT = read_file "Secret/CA/pki/issued/$name.crt"; + my $KEY = read_file "Secret/CA/pki/private/$name.key"; + my $UP = $type eq "android" ? "" : " <<openvpn-up>>"; if ($type ne "campus") { - my $TA = read_file "Secret/front-ta.key"; + my $TA = read_file "Secret/front-ta.key"; write_template ($DEV,$UP,$CA,$CRT,$KEY,$TA, $front_addr, $domain_name, "public.ovpn"); print "Wrote public VPN configuration to public.ovpn.\n"; } - my $TA = read_file "Secret/gate-ta.key"; + my $TA = read_file "Secret/gate-ta.key"; write_template ($DEV,$UP,$CA,$CRT,$KEY,$TA, $gate_wifi_addr, "gate.$domain_priv", "campus.ovpn"); print "Wrote campus VPN configuration to campus.ovpn.\n"; @@ -7717,8 +7695,8 @@ up-restart } sub write_template ($$$$$$$$$) { - my ($DEV,$UP,$CA,$CRT,$KEY,$TA,$ADDR,$NAME,$FILE) = @_; - my $O = new IO::File; + my ($DEV,$UP,$CA,$CRT,$KEY,$TA,$ADDR,$NAME,$FILE) = @_; + my $O = new IO::File; open ($O, ">$FILE.tmp") or die "Could not open $FILE.tmp: $!\n"; print $O "client dev-type tun @@ -7741,11 +7719,11 @@ up-restart } sub read_file ($) { - my ($path) = @_; - my $I = new IO::File; + my ($path) = @_; + my $I = new IO::File; open ($I, "<$path") or die "$path: could not read: $!\n"; - local $/; - my $c = <$I>; + local $/; + my $c = <$I>; close $I or die "$path: could not close: $!\n"; return $c; } @@ -8511,8 +8489,8 @@ require several more).sudo apt install network-manager-openvpn-gnome \ - openvpn-systemd-resolved \ - nextcloud-desktop evolution + openvpn-systemd-resolved \ + nextcloud-desktop evolution