2023-03-19 23:38:30 -07:00
{{- if (eq .host.distro.family "linux") -}}
2023-01-26 00:50:54 -08:00
#!/usr/bin/env bash
2023-04-15 21:10:10 -07:00
# @file Linux OpenVPN / WireGuard Profiles
2023-03-30 22:08:20 -07:00
# @brief Installs both OpenVPN and WireGuard VPN profiles on Linux devices.
# @description
# This script installs OpenVPN and WireGuard VPN profiles. It does a few things to install the profiles and make sure
# they are usable by desktop users:
#
# 1. It ensures OpenVPN and `NetworkManager-*` plugins are installed (this allows you to see all the different VPN profile types available when you try to import a VPN profile on Linux devices)
# 2. Imports the OpenVPN profiles stored in ` ${ XDG_CONFIG_HOME : - $ HOME / . config } /vpn`
# 3. Applies the OpenVPN username and password to all the OpenVPN profiles (which can be passed in as `OVPN_USERNAME` and `OVPN_PASSWORD` if you use the environment variable method)
# 4. Bypasses the OpenVPN connection for all the networks defined in `.host.vpn.excludedSubnets` (in the `home/.chezmoi.yaml.tmpl` file)
# 5. Repeats the process for WireGuard by looping through all the `*.nmconnection` files stored in ` ${ XDG_CONFIG_HOME : - $ HOME / . config } /vpn` (username and password should already be stored in the encrypted files)
#
# ## Creating VPN Profiles
#
# More details on embedding your VPN profiles into your Install Doctor fork can be found by reading the [Secrets documentation](https://install.doctor/docs/customization/secrets #vpn - profiles ) .
#
# ## Links
#
# * [VPN profile folder](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/vpn)
# * [VPN profile documentation](https://install.doctor/docs/customization/secrets #vpn - profiles )
2023-01-26 00:50:54 -08:00
2023-03-26 23:09:59 -07:00
{{ $ ovpnUsername := (env "OVPN_USERNAME") }}
2023-03-19 23:38:30 -07:00
{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "OVPN_USERNAME")) }}
2023-06-18 20:30:41 -07:00
{{ $ ovpnUsername := (includeTemplate "secrets/OVPN_USERNAME" | decrypt | trim) }}
2023-03-19 23:38:30 -07:00
{{ end }}
2023-03-26 23:09:59 -07:00
{{ $ ovpnPassword := (env "OVPN_PASSWORD") }}
2023-03-19 23:38:30 -07:00
{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "OVPN_PASSWORD")) }}
2023-06-18 20:30:41 -07:00
{{ $ ovpnPassword := (includeTemplate "secrets/OVPN_PASSWORD" | decrypt | trim) }}
2023-03-19 23:38:30 -07:00
{{ end }}
2023-01-26 23:13:53 -08:00
2023-01-26 00:50:54 -08:00
{{ includeTemplate "universal/profile" }}
{{ includeTemplate "universal/logg" }}
2023-01-26 23:13:53 -08:00
RESTART_NM=false
2023-03-30 22:08:20 -07:00
# @description Ensure `NetworkManager` plugins are
2023-01-26 23:13:53 -08:00
# NOTE: By default, all the NetworkManager plugins are installed.
if command -v apt-get > /dev/null; then
sudo apt-get install -y network-manager*
elif command -v dnf > /dev/null; then
sudo dnf install -y openvpn NetworkManager*
elif command -v pacman > /dev/null; then
sudo pacman -Syu openvpn networkmanager*
else
logg warn 'Unknown package manager - install OpenVPN / WireGuard / NetworkManager plugins individually'
fi
function ensureNetworkConfigs() {
if [ ! -d /etc/network/if-up.d ]; then
logg info 'Creating /etc/network/if-up.d folder'
sudo mkdir -p /etc/network/if-up.d
fi
if [ ! -d /etc/network/if-post-down.d ]; then
logg info 'Creating /etc/network/if-post.d folder'
sudo mkdir -p /etc/network/if-post.d
fi
}
2023-03-30 22:08:20 -07:00
# @description Ensures `nmcli` (the CLI for NetworkManager) is available in the `PATH`
2023-01-26 00:50:54 -08:00
if command -v nmcli > /dev/null; then
2023-03-30 22:08:20 -07:00
# @description Sets up OpenVPN profiles
2023-01-26 23:13:53 -08:00
if [ '{{ $ ovpnUsername }}' != '' ] && [ '{{ $ ovpnPassword }}' != '' ]; then
find " ${ XDG_CONFIG_HOME : - $ HOME / . config } /vpn" -type f -name "*.ovpn" | while read OVPN_FILE; do
2023-03-30 22:08:20 -07:00
# @description Adds the OpenVPN profiles by importing the `*.ovpn` files in ` ${ XDG_CONFIG_HOME : - $ HOME / . config } /vpn` and then applying the OpenVPN username and password
2023-01-26 23:13:53 -08:00
logg info "Adding $ OVPN_FILE to NetworkManager OpenVPN profiles"
OVPN_NAME="$(basename " $ OVPN_FILE " | sed 's/.ovpn$//')"
2023-01-30 00:06:59 -08:00
nmcli connection import type openvpn file " $ OVPN_FILE "
2023-01-26 23:13:53 -08:00
nmcli connection modify " $ OVPN_NAME " +vpn.data 'username={{- $ ovpnUsername }}'
nmcli connection modify " $ OVPN_NAME " vpn.secrets 'password={{- $ ovpnPassword }}'
nmcli connection modify " $ OVPN_NAME " +vpn.data password-flags=0
2023-03-30 22:08:20 -07:00
# @description Register the excluded subnets in the routeadd / routedel files
2023-01-26 23:13:53 -08:00
for EXCLUDED_SUBNET in '{{ $ removeShortcuts := join "' '" .host.vpn.excludedSubnets }}'; do
ensureNetworkConfigs
nmcli connection modify " $ OVPN_NAME " +ipv4.routes " $ EXCLUDED_SUBNET " | sudo tee -a /etc/network/if-up.d/routeadd
nmcli connection modify " $ OVPN_NAME " -ipv4.routes " $ EXCLUDED_SUBNET " | sudo tee -a /etc/network/if-post-down.d/routedel
fi
RESTART_NM=true
done
else
logg info 'Either the OpenVPN username or password is undefined.'
2023-11-04 18:46:18 -07:00
logg info 'See the docs/VARIABLES.md file for details.'
2023-01-26 23:13:53 -08:00
fi
2023-03-19 23:38:30 -07:00
{{ if (stat (joinPath .host.home ".config" "age" "chezmoi.txt")) }}
2023-03-30 22:08:20 -07:00
# @description Setup WireGuard profiles
2023-01-26 14:56:49 -08:00
if [ -d /etc/NetworkManager/system-connections ]; then
find " ${ XDG_CONFIG_HOME : - $ HOME / . config } /vpn" -type f -name "*.nmconnection" | while read WG_FILE; do
2023-03-30 22:08:20 -07:00
# @description Ensure the WireGuard NetworkManager plugin is available
2023-01-26 23:13:53 -08:00
if [ ! -d /usr/lib/NetworkManager/nm-wireguard-service ]; then
2023-11-04 18:46:18 -07:00
logg info 'The nm-wireguard-service is not present'
logg info 'Installing the nm-wireguard-service'
2023-01-26 23:13:53 -08:00
fi
2023-03-30 22:08:20 -07:00
# @description Add the WireGuard profiles
2023-01-26 14:56:49 -08:00
logg info "Adding $ WG_FILE to /etc/NetworkManager/system-connections
2023-01-26 23:13:53 -08:00
WG_FILENAME="$(basename " $ WG_FILE ")"
chezmoi decrypt " $ WG_FILE " | sudo tee "/etc/NetworkManager/system-connections/ $ WG_FILENAME "
2023-02-15 19:14:33 -08:00
2023-03-30 22:08:20 -07:00
# @description Register the excluded subnets in the routeadd / routedel files
2023-01-26 23:13:53 -08:00
for EXCLUDED_SUBNET in '{{ $ removeShortcuts := join "' '" .host.vpn.excludedSubnets }}'; do
ensureNetworkConfigs
WG_PROFILE_NAME="$(echo " $ WG_FILENAME " | sed 's/.nmconnection$//')"
nmcli connection modify " $ WG_PROFILE_NAME " +ipv4.routes " $ EXCLUDED_SUBNET " | sudo tee -a /etc/network/if-up.d/routeadd
nmcli connection modify " $ WG_PROFILE_NAME " -ipv4.routes " $ EXCLUDED_SUBNET " | sudo tee -a /etc/network/if-post-down.d/routedel
fi
RESTART_NM=true
2023-01-26 14:56:49 -08:00
done
else
logg warn '/etc/NetworkManager/system-connections is not a directory!'
fi
2023-03-19 23:38:30 -07:00
{{ end -}}
2023-01-26 23:13:53 -08:00
2023-03-30 22:08:20 -07:00
# @description Restart NetworkManager if changes were made and environment is not WSL
2023-02-15 19:14:33 -08:00
if [ " $ RESTART_NM " == 'true' ] && [[ ! "$(test -d proc && grep Microsoft /proc/version > /dev/null)" ]]; then
2023-01-26 23:13:53 -08:00
logg info 'Restarting NetworkManager since VPN profiles were updated'
sudo service NetworkManager restart
fi
2023-01-26 00:50:54 -08:00
else
2023-11-04 18:46:18 -07:00
logg warn 'nmcli is unavailable'
2023-01-26 00:50:54 -08:00
fi
{{ end -}}