diff --git a/docs/CHEZMOI-INTRO.md b/docs/CHEZMOI-INTRO.md index 8ff5d67e..faa86038 100644 --- a/docs/CHEZMOI-INTRO.md +++ b/docs/CHEZMOI-INTRO.md @@ -136,3 +136,11 @@ in `.chezmoitemplates/secrets/key-surgesh-password` to leverage this functionali **Environment Variable Only** Add a Tailscale authentication key so that Tailscale can be automatically connected to your Tailscale network. * Environment Variable: `TAILSCALE_AUTH_KEY` + +### OpenVPN Username + +* Environment Variable: `OVPN_USERNAME` + +### OpenVPN Password + +* Environment Variable: `OVPN_PASSWORD` \ No newline at end of file diff --git a/home/.chezmoi.yaml.tmpl b/home/.chezmoi.yaml.tmpl index 2203e0d2..d9201d97 100644 --- a/home/.chezmoi.yaml.tmpl +++ b/home/.chezmoi.yaml.tmpl @@ -137,6 +137,10 @@ data: dns: primary: 10.0.0.1#dns.megabyte.space secondary: 1.1.1.1#cloudflare-dns.com + vpn: + excludedSubnets: + - 10.0.0.0/24 + - 10.14.50.0/24 home: "{{ .chezmoi.homeDir }}" homeParentFolder: "{{ if eq .chezmoi.os "linux" }}/home{{ else if eq .chezmoi.os "darwin" }}/Users{{ else }}C:\Users{{ end }}" hostname: "Betelgeuse" diff --git a/home/.chezmoiscripts/universal/run_onchange_after_24-vpn-darwin.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_24-vpn-darwin.tmpl index 1e5ad695..aa799859 100644 --- a/home/.chezmoiscripts/universal/run_onchange_after_24-vpn-darwin.tmpl +++ b/home/.chezmoiscripts/universal/run_onchange_after_24-vpn-darwin.tmpl @@ -1,10 +1,31 @@ -{{- if eq .host.distro.family "linux" -}} +{{- if eq .host.distro.family "darwin" -}} #!/usr/bin/env bash {{ includeTemplate "universal/profile" }} {{ includeTemplate "universal/logg" }} -# wireguard_conf_dir: /etc/wireguard -# system_connections_path: /Library/Preferences/com.apple.networkextension.plist +# TODO - What about OpenVPN profiles? Do we have an app to manage OpenVPN connections for macOS? + +### Backup previous network settings +if [ -f /Library/Preferences/com.apple.networkextension.plist ]; then + logg info 'Backing up /Library/Preferences/com.apple.networkextension.plist to /Library/Preferences/com.apple.networkextension.plist.old + sudo cp -f /Library/Preferences/com.apple.networkextension.plist /Library/Preferences/com.apple.networkextension.plist.old +else + logg info 'The /Library/Preferences/com.apple.networkextension.plist file does not exist yet' +fi + +### Ensure /etc/wireguard exists +if [ ! -d /etc/wireguard ]; then + logg info 'Creating `/etc/wireguard` since it does not exist yet' + sudo mkdir -p /etc/wireguard + sudo chmod 600 /etc/wireguard +fi + +### Add the WireGuard configurations +find "${XDG_CONFIG_HOME:-$HOME/.config}" -type f -name "*.conf" | while read WG_CONF; do + WG_FILE="$(basename "$WG_CONF")" + logg info 'Adding `'"$WG_FILE"'` to /etc/wireguard' + sudo cp -f "$WG_CONF" "/etc/wireguard/$WG_FILE" +done {{ end -}} \ No newline at end of file diff --git a/home/.chezmoiscripts/universal/run_onchange_after_24-vpn-linux.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_24-vpn-linux.tmpl index a62bddb7..b8333788 100644 --- a/home/.chezmoiscripts/universal/run_onchange_after_24-vpn-linux.tmpl +++ b/home/.chezmoiscripts/universal/run_onchange_after_24-vpn-linux.tmpl @@ -1,27 +1,96 @@ {{- if and (eq .host.distro.family "linux") (stat (joinPath .host.home ".config" "age" "chezmoi.txt")) -}} #!/usr/bin/env bash +{{ $ovpnUsername := (default (env "OVPN_USERNAME") ((includeTemplate "secrets/key-ovpn-username") | decrypt)) }} +{{ $ovpnPassword := (default (env "OVPN_PASSWORD") ((includeTemplate "secrets/key-ovpn-password") | decrypt)) }} + {{ includeTemplate "universal/profile" }} {{ includeTemplate "universal/logg" }} -if command -v nmcli > /dev/null; then - ### OpenVPN profiles - find "${XDG_CONFIG_HOME:-$HOME/.config}/vpn" -type f -name "*.ovpn" | while read OVPN_FILE; do - nmcli connection import type openvpn file '{{ vpn_connection.file }}' - nmcli connection modify '{{ ovpn_name }}' +vpn.data username={{ vpn_connection.username }} - nmcli connection modify '{{ ovpn_name }}' vpn.secrets 'password={{ vpn_connection.password }}' - nmcli connection modify '{{ ovpn_name }}' +vpn.data password-flags=0 - done +RESTART_NM=false - ### WireGuard profiles +### Ensure NetworkManager plugins are +# 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 + +### Ensures NetworkManager event config folders are created +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 +} + +### Ensure NetworkManager is installed +if command -v nmcli > /dev/null; then + ### Setup OpenVPN profiles + if [ '{{ $ovpnUsername }}' != '' ] && [ '{{ $ovpnPassword }}' != '' ]; then + find "${XDG_CONFIG_HOME:-$HOME/.config}/vpn" -type f -name "*.ovpn" | while read OVPN_FILE; do + ### Add the profile + logg info "Adding $OVPN_FILE to NetworkManager OpenVPN profiles" + OVPN_NAME="$(basename "$OVPN_FILE" | sed 's/.ovpn$//')" + nmcli connection import type openvpn file '{{ vpn_connection.file }}' + 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 + + ### Register the excluded subnets in the routeadd / routedel files + 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.' + logg info 'See the `docs/VARIABLES.md` file for details.' + fi + + ### Setup WireGuard profiles if [ -d /etc/NetworkManager/system-connections ]; then find "${XDG_CONFIG_HOME:-$HOME/.config}/vpn" -type f -name "*.nmconnection" | while read WG_FILE; do + ### Ensure the WireGuard NetworkManager plugin is available + if [ ! -d /usr/lib/NetworkManager/nm-wireguard-service ]; then + logg info 'The `nm-wireguard-service` is not present' + logg info 'Installing the `nm-wireguard-service`' + fi + + ### Add the WireGuard profile logg info "Adding $WG_FILE to /etc/NetworkManager/system-connections - chezmoi decrypt "$WG_FILE" > /etc/NetworkManager/system-connections + WG_FILENAME="$(basename "$WG_FILE")" + chezmoi decrypt "$WG_FILE" | sudo tee "/etc/NetworkManager/system-connections/$WG_FILENAME" + + ### Register the excluded subnets in the routeadd / routedel files + 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 done else logg warn '/etc/NetworkManager/system-connections is not a directory!' fi + + ### Restart NetworkManager if changes were made and environment is not WSL + if [ "$RESTART_NM" == 'true' ] && [[ ! "$(grep Microsoft /proc/version)" ]]; then + logg info 'Restarting NetworkManager since VPN profiles were updated' + sudo service NetworkManager restart + fi else logg warn '`nmcli` is unavailable' fi diff --git a/home/.chezmoitemplates/secrets/key-proton-openvpn-password b/home/.chezmoitemplates/secrets/key-openvpn-password similarity index 100% rename from home/.chezmoitemplates/secrets/key-proton-openvpn-password rename to home/.chezmoitemplates/secrets/key-openvpn-password diff --git a/home/.chezmoitemplates/secrets/key-proton-openvpn-username b/home/.chezmoitemplates/secrets/key-openvpn-username similarity index 100% rename from home/.chezmoitemplates/secrets/key-proton-openvpn-username rename to home/.chezmoitemplates/secrets/key-openvpn-username