Skip to content

Instantly share code, notes, and snippets.

@Boilerplate4u
Forked from p3nj/mullvad-wg-pfctl-ks.sh
Created October 14, 2020 06:52
Show Gist options
  • Save Boilerplate4u/f060241164278c219c62bc5598dc8c52 to your computer and use it in GitHub Desktop.
Save Boilerplate4u/f060241164278c219c62bc5598dc8c52 to your computer and use it in GitHub Desktop.
Mullvad-WireGuard Script with macOS pfctl killswitch implant
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2016-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
die() {
echo "[-] Error: $1" >&2
exit 1
}
# Change this to your condition.
WIFI="en0"
VPN="utun3"
PROGRAM="${0##*/}"
ARGS=( "$@" )
SELF="${BASH_SOURCE[0]}"
[[ $SELF == */* ]] || SELF="./$SELF"
SELF="$(cd "${SELF%/*}" && pwd -P)/${SELF##*/}"
[[ $UID == 0 ]] || exec sudo -p "[?] $PROGRAM must be run as root. Please enter the password for %u to continue: " -- "$BASH" -- "$SELF" "${ARGS[@]}"
[[ ${BASH_VERSINFO[0]} -ge 4 ]] || die "bash ${BASH_VERSINFO[0]} detected, when bash 4+ required"
type curl >/dev/null || die "Please install curl and then try again."
type jq >/dev/null || die "Please install jq and then try again."
set -e
read -p "[?] Please enter your Mullvad account number: " -r ACCOUNT
echo "[+] Contacting Mullvad API for server locations."
declare -A SERVER_ENDPOINTS_IPV4
declare -A SERVER_ENDPOINTS
declare -A SERVER_PUBLIC_KEYS
declare -A SERVER_LOCATIONS
declare -a SERVER_CODES
RESPONSE="$(curl -LsS https://api.mullvad.net/public/relays/wireguard/v1/)" || die "Unable to connect to Mullvad API."
FIELDS="$(jq -r 'foreach .countries[] as $country (.; .; foreach $country.cities[] as $city (.; .; foreach $city.relays[] as $relay (.; .; $country.name, $city.name, $relay.hostname, $relay.public_key, $relay.ipv4_addr_in)))' <<<"$RESPONSE")" || die "Unable to parse response."
while read -r COUNTRY && read -r CITY && read -r HOSTNAME && read -r PUBKEY && read -r IPADDR; do
CODE="${HOSTNAME%-wireguard}"
SERVER_CODES+=( "$CODE" )
SERVER_LOCATIONS["$CODE"]="$CITY, $COUNTRY"
SERVER_PUBLIC_KEYS["$CODE"]="$PUBKEY"
SERVER_ENDPOINTS["$CODE"]="$IPADDR:51820"
SERVER_ENDPOINTS_IPV4["$CODE"]="$IPADDR"
done <<<"$FIELDS"
shopt -s nocasematch
for CODE in "${SERVER_CODES[@]}"; do
CONFIGURATION_FILE="/etc/wireguard/mullvad-$CODE.conf"
[[ -f $CONFIGURATION_FILE ]] || continue
while read -r line; do
[[ $line =~ ^PrivateKey\ *=\ *([a-zA-Z0-9+/]{43}=)\ *$ ]] && PRIVATE_KEY="${BASH_REMATCH[1]}" && break
done < "$CONFIGURATION_FILE"
[[ -n $PRIVATE_KEY ]] && echo "[+] Using existing private key." && break
done
shopt -u nocasematch
if [[ -z $PRIVATE_KEY ]]; then
echo "[+] Generating new private key."
PRIVATE_KEY="$(wg genkey)"
fi
echo "[+] Contacting Mullvad API."
RESPONSE="$(curl -sSL https://api.mullvad.net/wg/ -d account="$ACCOUNT" --data-urlencode pubkey="$(wg pubkey <<<"$PRIVATE_KEY")")" || die "Could not talk to Mullvad API."
[[ $RESPONSE =~ ^[0-9a-f:/.,]+$ ]] || die "$RESPONSE"
ADDRESS="$RESPONSE"
DNS="193.138.219.228"
echo "[+] Writing WriteGuard configuration files."
for CODE in "${SERVER_CODES[@]}"; do
CONFIGURATION_FILE_KS="/etc/wireguard/killswitch/mullvad-$CODE.conf"
CONFIGURATION_FILE="/etc/wireguard/mullvad-$CODE.conf"
umask 077
mkdir -p /etc/wireguard/
mkdir -p /etc/wireguard/killswitch/
rm -f "$CONFIGURATION_FILE.tmp"
cat > "$CONFIGURATION_FILE.tmp" <<-_EOF
[Interface]
PrivateKey = $PRIVATE_KEY
Address = $ADDRESS
DNS = $DNS
PostUp = pfctl -e -Fa -f /etc/wireguard/killswitch/mullvad-$CODE.conf
PostDown = pfctl -Fa -f /etc/pf.conf
[Peer]
PublicKey = ${SERVER_PUBLIC_KEYS["$CODE"]}
Endpoint = ${SERVER_ENDPOINTS["$CODE"]}
AllowedIPs = 0.0.0.0/0, ::/0
_EOF
mv "$CONFIGURATION_FILE.tmp" "$CONFIGURATION_FILE"
rm -f "$CONFIGURATION_FILE_KS.tmp"
cat > "$CONFIGURATION_FILE_KS.tmp" <<-_EOF
set block-policy drop
set ruleset-optimization basic
set skip on lo0
block out all
block in all
pass out on $WIFI proto {tcp, udp} from any to ${SERVER_ENDPOINTS_IPV4["$CODE"]}
pass out on $VPN all
_EOF
mv "$CONFIGURATION_FILE_KS.tmp" "$CONFIGURATION_FILE_KS"
done
echo "[+] Success. The following commands may be run for connecting to Mullvad:"
for CODE in "${SERVER_CODES[@]}"; do
echo "- ${SERVER_LOCATIONS["$CODE"]}:"
echo " \$ wg-quick up mullvad-$CODE"
done
echo "Please wait up to 60 seconds for your public key to be added to the servers."
@adnausea
Copy link

This is perfect but you should also check whether wireguard-tools is installed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment