Compare commits

..

2 Commits

145
piawg.sh
View File

@@ -71,26 +71,35 @@ opn_curl() {
local error
local response
local http_code
path="$1"
path="$opn_endpoint/$1"
shift
error="Failed request to '$opn_endpoint/$path'"
error="Failed request to '$path'"
if ! response="$(_curl -H 'Content-Type: application/json' \
-u "$opn_key:$opn_secret" -w '\n%{http_code}' \
"$@" "$opn_endpoint/$path")"; then
"$@" "$path")"; then
err "$error"
fi
http_code="$(printf '%s' "$response" | tail -1)"
response="$(printf '%s' "$response" | sed '$d')"
if ! check_http "$http_code"; then
error_msg="$(printf '%s' "$response" |
jq -r '.errorMessage // empty' 2>/dev/null)"
[ -n "$error_msg" ] && error="$error_msg ($path)"
fi
check_http "$http_code" || err "$error"
printf '%s' "$response" | sed '$d'
printf '%s' "$response"
}
pia_addkey() {
local response
local response_gw
local key
local port
local peer_ip
local updates
local server_vip
local gateway_ip
local gateway_id
# Add pubkey via PIA API and get connection details
info "Adding '$piawg_pubkey' to PIA server $server_cn"
if ! response=$(
@@ -98,7 +107,7 @@ pia_addkey() {
--cacert ./ca.rsa.4096.crt \
--data-urlencode "pt=$pia_token" \
--data-urlencode "pubkey=$piawg_pubkey" \
"https://$server_cn:1337/addKey"
"https://$server_cn:$server_port/addKey"
); then
err "Failed connect to $server_cn to addKey"
fi
@@ -154,6 +163,34 @@ pia_addkey() {
bao_curl -p "$BAO_KV_MOUNT/data/$BAO_PATH_CONFIG" -X PATCH -d \
"$(jq -n --arg ip "$server_vip" '{data:{server_vip:$ip}}')" >/dev/null
# Update gateway address
if ! response_gw="$(opn_curl \
'routing/settings/search_gateway' -X POST -d '{}')"; then
err "Failed to search gateways"
fi
debug -f "search_gateway\n%s" "$(printf '%s' "$response_gw" | jq .)"
gateway_id="$(printf '%s' "$response_gw" | jq -r --arg name "$OPN_GW" \
'.rows[] | select(.name == $name) | .uuid')"
gateway_ip="$(printf '%s' "$response_gw" | jq -r --arg name "$OPN_GW" \
'.rows[] | select(.name == $name) | .gateway')"
if [ "$gateway_ip" != "$server_vip" ]; then
info "Updating gateway $OPN_GW address from $gateway_ip to $server_vip"
if ! update_gw="$(opn_curl \
"routing/settings/set_gateway/$gateway_id" -X POST \
-d "$(jq -nc --arg ip "$server_vip" \
'{gateway_item: {gateway: $ip}}')")"; then
err "Failed to update gateway ($gateway_id)"
fi
if [ "$(printf '%s' "$update_gw" | jq -r '.result')" != "saved" ]; then
err "Failed to save gateway update"
fi
info "Restarting WireGuard interface after gateway update"
if [ "$(opn_curl "core/service/restart/wireguard/$piawg_uuid" \
-X POST -d '{}' | jq -r '.result')" != "ok" ]; then
err "Failed to restart WireGuard interface after gateway update"
fi
fi
# Update firewall rule alias
piawg_ip_alias="$(opn_curl 'firewall/alias/searchItem' -d '{}' |
jq -r ".rows[] | select(.name == \"$OPN_ALIAS\") | .uuid")"
@@ -170,6 +207,84 @@ pia_addkey() {
fi
}
pia_forward() {
local config
local server_cn
local server_vip
local pf_signature
local pf_payload
local pf_port
local pf_expires
local pf_sig_reply
local pf_updated_at
local pf_update
local epoch_now
local epoch_expire
local epoch_diff
local bind_resp
config="$1"
server_cn="$(printf '%s' "$config" | jq -r '.data.data.server_cn')"
server_vip="$(printf '%s' "$config" | jq -r '.data.data.server_vip')"
pf_signature="$(printf '%s' "$config" | jq -r '.data.data.pf_signature')"
pf_payload="$(printf '%s' "$config" | jq -r '.data.data.pf_payload')"
pf_port="$(printf '%s' "$config" | jq -r '.data.data.pf_port')"
pf_expires="$(printf '%s' "$config" | jq -r '.data.data.pf_expires')"
pf_updated_at="$(printf '%s' "$config" | jq -r '.data.data.pf_updated_at')"
epoch_now="$(date '+%s')"
epoch_expire="$(date -j -f '%Y-%m-%dT%H:%M:%S' \
"${pf_expires%%.*}" '+%s' 2>/dev/null)"
epoch_diff=$((epoch_now - ${pf_updated_at:-0}))
if [ -z "$epoch_expire" ] || [ "$epoch_expire" -lt "$epoch_now" ]; then
info "Requesting new port forward signature"
if ! pf_sig_reply="$(_curl -G --cacert ./ca.rsa.4096.crt \
--resolve "$server_cn:19999:$server_vip" \
--data-urlencode "token=$pia_token" \
"https://$server_cn:19999/getSignature")"; then
err "Failed to connect to https://$server_cn:19999/getSignature"
fi
debug -f "getSignature\n%s" "$(printf '%s' "$pf_sig_reply" | jq .)"
[ "$(printf '%s' "$pf_sig_reply" | jq -r '.status')" != "OK" ] &&
err "getSignature failed"
pf_signature="$(printf '%s' "$pf_sig_reply" | jq -r '.signature')"
pf_payload="$(printf '%s' "$pf_sig_reply" | jq -r '.payload')"
pf_port="$(printf '%s' "$pf_payload" |
base64 -d 2>/dev/null | jq -r '.port // empty')"
pf_expires="$(printf '%s' "$pf_payload" |
base64 -d 2>/dev/null | jq -r '.expires_at // empty')"
pf_update="$(jq -n --arg v "$pf_signature" '.data.pf_signature = $v')"
pf_update="$(printf '%s' "$pf_update" |
jq --arg v "$pf_payload" '.data.pf_payload = $v')"
pf_update="$(printf '%s' "$pf_update" |
jq --arg v "$pf_port" '.data.pf_port = $v')"
pf_update="$(printf '%s' "$pf_update" |
jq --arg v "$pf_expires" '.data.pf_expires = $v')"
pf_update="$(printf '%s' "$pf_update" |
jq --arg v "$(date '+%s')" '.data.pf_updated_at = $v')"
debug -f "pf_update\n%s" "$(printf '%s' "$pf_update" | jq .)"
info "Updating $BAO_PATH_CONFIG with pf_port=$pf_port"
bao_curl -p "$BAO_KV_MOUNT/data/$BAO_PATH_CONFIG" \
-X PATCH -d "$pf_update" >/dev/null
elif [ "$epoch_diff" -ge 300 ]; then
info "Renewing port forward ($epoch_diff/300)"
if ! bind_resp="$(_curl -G --resolve "${server_cn}:19999:${server_vip}" \
--data-urlencode "payload=${pf_payload}" \
--data-urlencode "signature=${pf_signature}" \
"https://${server_cn}:19999/bindPort")"; then
err "Failed to bindPort (https://${server_cn}:19999/bindPort)"
fi
[ "$(printf '%s' "$bind_resp" | jq -r '.status')" != "OK" ] &&
err "Failed to get bindPort status"
debug -f "bind_resp\n%s" "$(printf '%s' "$bind_resp" | jq .)"
pf_update="$(jq -n --arg v "$(date '+%s')" '.data.pf_updated_at = $v')"
debug -f "pf_update\n%s" "$(printf '%s' "$pf_update" | jq .)"
info "Updating pf_updated_at $BAO_PATH_CONFIG"
bao_curl -p "$BAO_KV_MOUNT/data/$BAO_PATH_CONFIG" \
-X PATCH -d "$pf_update" >/dev/null
else
info "Port forward still valid, updated ${epoch_diff}s ago"
fi
}
check_tunnel() {
local tunneladdr
local response
@@ -282,6 +397,7 @@ _fingerprint=1fd25658456eab3041fba77ccd398ab8124edcc1b8b2fc1d55fdf6b1bbfc9d70
: "${OPN_IF:=PIAwg}"
: "${OPN_PEER:=PIAwg_srv}"
: "${OPN_ALIAS:=PIAwg_IP}"
: "${OPN_GW:=PIAWG_VPN}"
# Get ephemeral session token from AppRole login
if ! bao_token_reply=$(_curl -H 'Content-Type: application/json' \
@@ -384,18 +500,11 @@ else
fi
fi
# Optional: port forward
if conf_reply="$(bao_curl "$BAO_KV_MOUNT/data/$BAO_PATH_CONFIG")"; then
port_forward="$(printf '%s' "$conf_reply" | jq -r '.port_forward')"
if [ "$port_forward" = "true" ]; then
server_cn="$(printf '%s' "$conf_reply" | jq -r '.server_cn')"
server_vip="$(printf '%s' "$conf_reply" | jq -r '.server_vip')"
if ! pf_sig_reply="$(_curl --resolve "$server_cn:19999:$server_vip" \
--data-urlencode "token=$bao_token" \
"https://$server_cn:19999/getSignature")"; then
err "Failed to connect to https://$server_cn:19999/getSignature"
fi
debug -f "getSignature\n%s" "$(printf '%s' "$pf_sig_reply" | jq .)"
fi
fi
debug -f "Check for port_forward value in OpenBao ($BAO_PATH_CONFIG)\n%s" \
"$conf_reply"
"$(printf '%s' "$conf_reply" | jq .)"
port_forward="$(printf '%s' "$conf_reply" |
jq -r '.data.data.port_forward')"
[ "$port_forward" = "true" ] && pia_forward "$conf_reply"
fi