testing
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
ca.rsa.4096.crt
|
||||
.ca.rsa.4096.crt
|
||||
@@ -1,5 +1,5 @@
|
||||
# piawg
|
||||
|
||||
POSIX shell script for OPNsense that manages Private Internet Access next-gen
|
||||
Shell script for OPNsense that manages Private Internet Access next-gen
|
||||
WireGuard tunnels using credentials and configuration stored in OpenBao.
|
||||
Licensed under 0BSD.
|
||||
|
||||
82
piawg.sh
82
piawg.sh
@@ -2,6 +2,9 @@
|
||||
# SPDX-License-Identifier: 0BSD
|
||||
# SPDX-FileCopyrightText: 2026 Kris Lamoureux <kris@lamoureux.io>
|
||||
|
||||
# Allow local variable scoping, therefore not strictly POSIX
|
||||
# shellcheck disable=SC3043
|
||||
|
||||
err() {
|
||||
printf '[ERROR]: %s\n' "$1" >&2
|
||||
exit 1
|
||||
@@ -14,6 +17,11 @@ check_http() {
|
||||
esac
|
||||
}
|
||||
|
||||
# Check for plausible looking PIA token
|
||||
check_token() {
|
||||
printf '%s\n' "$1" | grep -q '^[0-9A-Fa-f]\{128\}$'
|
||||
}
|
||||
|
||||
bao_curl() {
|
||||
curl -sS --connect-timeout 5 --max-time 20 --retry 5 --retry-delay 2 \
|
||||
-H 'Content-Type: application/json' \
|
||||
@@ -22,43 +30,51 @@ bao_curl() {
|
||||
"$@"
|
||||
}
|
||||
|
||||
# Fetch latest token in OpenBao
|
||||
# Fetch latest PIA token in OpenBao
|
||||
get_token() {
|
||||
local pia_token_reply
|
||||
if ! pia_token_reply=$(bao_curl \
|
||||
"$BAO_ADDR/v1/$BAO_KV_MOUNT/data/$BAO_PATH_TOKEN"); then
|
||||
err "Failed to fetch PIA token from '$BAO_ADDR'"
|
||||
fi
|
||||
printf '%s' "$pia_token_reply"
|
||||
unset pia_token_reply
|
||||
}
|
||||
|
||||
# Get a new PIA token and store
|
||||
renew_token() {
|
||||
login_response="$(bao_curl "$BAO_ADDR/v1/$BAO_KV_MOUNT/data/$BAO_PATH_LOGIN")"
|
||||
local login_response
|
||||
local update_response
|
||||
local token_response
|
||||
local http_code
|
||||
local pia_user
|
||||
local pia_pass
|
||||
local pia_token
|
||||
|
||||
login_response="$(bao_curl \
|
||||
"$BAO_ADDR/v1/$BAO_KV_MOUNT/data/$BAO_PATH_LOGIN"
|
||||
)"
|
||||
|
||||
http_code="$(printf '%s' "$login_response" | tail -1)"
|
||||
if ! check_http "$http_code"; then
|
||||
err "Failed to get PIA login details (HTTP $http_code)"
|
||||
fi
|
||||
unset http_code
|
||||
|
||||
login_response="$(printf '%s' "$login_response" | sed '$d')"
|
||||
pia_user="$(printf '%s' "$login_response" | jq -r '.data.data.username')"
|
||||
pia_pass="$(printf '%s' "$login_response" | jq -r '.data.data.password')"
|
||||
unset login_response
|
||||
if ! token_reply="$(curl -s -X POST "$PIA_API" \
|
||||
if ! token_response="$(curl -s -X POST "$PIA_API" \
|
||||
-F "username=$pia_user" \
|
||||
-F "password=$pia_pass")"; then
|
||||
err "Failed to get a new PIA token"
|
||||
fi
|
||||
unset pia_pass
|
||||
unset pia_user
|
||||
pia_token="$(echo "$token_reply" | jq -r .token)"
|
||||
unset token_reply
|
||||
if ! printf '%s' "$pia_token" | grep -Eq '^[0-9A-Fa-f]{128}$'; then
|
||||
err "Invalid token found during renewal attempt"
|
||||
fi
|
||||
if ! update_response="$(bao_curl -X POST -d "$(jq -n --arg t "$pia_token" '{data:{token:$t}}')" \
|
||||
pia_token="$(echo "$token_response" | jq -r .token)"
|
||||
unset token_response
|
||||
check_token "$pia_token" || err "Invalid token found during renewal attempt"
|
||||
if ! update_response="$(bao_curl -X POST -d \
|
||||
"$(jq -n --arg t "$pia_token" '{data:{token:$t}}')" \
|
||||
"$BAO_ADDR/v1/$BAO_KV_MOUNT/data/$BAO_PATH_TOKEN")"; then
|
||||
err "Failed to save PIA token to '$BAO_ADDR'"
|
||||
fi
|
||||
@@ -70,7 +86,7 @@ renew_token() {
|
||||
}
|
||||
|
||||
# Check for required external commands
|
||||
for rbin in curl jq; do
|
||||
for rbin in curl jq openssl; do
|
||||
command -v "$rbin" >/dev/null 2>&1 ||
|
||||
err "Required binary '$rbin' not found"
|
||||
done
|
||||
@@ -100,8 +116,12 @@ fi
|
||||
|
||||
# Overridable defaults
|
||||
: "${PIA_API:=https://www.privateinternetaccess.com/api/client/v2/token}"
|
||||
: "${PIA_CRT:=https://www.privateinternetaccess.com/openvpn/ca.rsa.4096.crt}"
|
||||
: "${PIA_HASH:=1fd25658456eab3041fba77ccd398ab8\
|
||||
124edcc1b8b2fc1d55fdf6b1bbfc9d70}"
|
||||
: "${BAO_AUTH_PATH:=approle}"
|
||||
: "${BAO_KV_MOUNT:=kv}"
|
||||
: "${BAO_PATH_CONFIG:=piawg/config/wireguard}"
|
||||
: "${BAO_PATH_LOGIN:=piawg/creds/login}"
|
||||
: "${BAO_PATH_TOKEN:=piawg/session/token}"
|
||||
|
||||
@@ -125,6 +145,16 @@ bao_token=$(printf '%s' "$bao_token_reply" | jq -er '.auth.client_token')
|
||||
unset bao_token_reply
|
||||
[ -n "$bao_token" ] || err "Failed to get token from '$BAO_ADDR'"
|
||||
|
||||
# Get target server IP, common name, and OPNsense WG pubkey
|
||||
if ! wireguard_reply=$(bao_curl \
|
||||
"$BAO_ADDR/v1/$BAO_KV_MOUNT/data/$BAO_PATH_CONFIG"); then
|
||||
err "Failed to fetch wireguard configuration from '$BAO_ADDR'"
|
||||
fi
|
||||
server_ip="$(printf '%s' "$wireguard_reply" | jq -r .data.data.server_ip)"
|
||||
server_cn="$(printf '%s' "$wireguard_reply" | jq -r .data.data.server_cn)"
|
||||
peer_pubkey="$(printf '%s' "$wireguard_reply" |
|
||||
jq -r .data.data.peer_pubkey)"
|
||||
|
||||
# Get latest PIA token
|
||||
get_token_reply="$(get_token)"
|
||||
http_code="$(printf '%s' "$get_token_reply" | tail -1)"
|
||||
@@ -143,5 +173,29 @@ elif ! check_http "$http_code"; then
|
||||
err "Failed to get PIA token from '$BAO_ADDR' (HTTP $http_code)"
|
||||
fi
|
||||
|
||||
printf '%s\n' "$get_token_reply"
|
||||
exit 0
|
||||
pia_token="$(printf '%s' "$get_token_reply" | jq -r .data.data.token)"
|
||||
check_token "$pia_token" || err "Failed to get valid PIA token"
|
||||
|
||||
# Get new Wireguard config
|
||||
if ! WG_JSON=$(
|
||||
curl -sS -G --connect-timeout 5 --max-time 20 --retry 5 --retry-delay 2 \
|
||||
--cacert ./ca.rsa.4096.crt --resolve "$server_cn:1337:$server_ip" \
|
||||
--data-urlencode "pt=$pia_token" \
|
||||
--data-urlencode "pubkey=$peer_pubkey" \
|
||||
"https://$server_cn:1337/addKey"
|
||||
); then
|
||||
echo "[ERROR]: Failed to get WG config from PIA"
|
||||
exit 1
|
||||
fi
|
||||
printf '%s' "$WG_JSON" | jq .
|
||||
|
||||
# Download PIA RSA CA certificate
|
||||
if [ ! -f ./ca.rsa.4096.crt ]; then
|
||||
[ -f ./.ca.rsa.4096.crt ] && rm ./.ca.rsa.4096.crt
|
||||
curl -sS --connect-timeout 5 --max-time 20 --retry 5 --retry-delay 2 \
|
||||
-o ./.ca.rsa.4096.crt "$PIA_CRT"
|
||||
pia_file_hash="$(openssl x509 -in ./.ca.rsa.4096.crt -outform DER |
|
||||
openssl dgst -sha256 -r | awk '{print $1}')"
|
||||
[ "$pia_file_hash" != "$PIA_HASH" ] && err "PIA CA fingerprint mismatch"
|
||||
mv ./.ca.rsa.4096.crt ./ca.rsa.4096.crt
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user