Last active
May 17, 2022 20:01
-
-
Save trickapm/deaeffea9a45e1a6e28468b52f726c42 to your computer and use it in GitHub Desktop.
Wireguard helper script for SurfShark on OpenWRT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# For more info see: | |
# https://forum.openwrt.org/t/create-surfshark-wireguard-connection-on-openwrt-easily/ | |
# | |
config_file="config.json" | |
read_config() { | |
conf_json=$(cat "$config_file") | |
config_folder="$(echo "$conf_json" | jq -r '.config_folder')" | |
username="$(echo "$conf_json" | jq -r '.username')" | |
password="$(echo "$conf_json" | jq -r '.password')" | |
unset conf_json | |
baseurl="https://api.surfshark.com" | |
token_file="${config_folder}/token.json" | |
servers_file="${config_folder}/surfshark_servers.json" | |
wg_keys="${config_folder}/wg.json" | |
output_conf_folder="${config_folder}/conf" | |
} | |
do_login () { | |
rc=1 | |
if [ -f "$token_file" ]; then | |
echo "Token file \"$token_file\" exists, skipping login" | |
rc=0 | |
else | |
echo "Logging in..." | |
tmpfile=$(mktemp /tmp/wg-curl-res.XXXXXX) | |
url="$baseurl/v1/auth/login" | |
data="{\"username\":\"$username\", \"password\":\"$password\"}" | |
http_status=$(curl -o $tmpfile -s -w "%{http_code}" -d "$data" -H 'Content-Type: application/json' -X POST $url) | |
if [ $http_status -eq 200 ]; then | |
cp $tmpfile $token_file | |
echo " HTTP status OK" | |
rc=0 | |
elif [ $http_status -eq 429 ]; then | |
echo " HTTP status $http_status (Blocked! Too many requests)" | |
else | |
echo " HTTP status $http_status (Failed!)" | |
fi | |
rm $tmpfile | |
fi | |
if [ "$rc" -eq 0 ]; then | |
token="$(jq -r '.token' "$token_file")" | |
renewToken="$(jq -r '.renewToken' "$token_file")" | |
fi | |
return $rc | |
} | |
get_servers() { | |
echo "Retrieving servers list..." | |
tmpfile=$(mktemp /tmp/surfshark-wg-servers.XXXXXX) | |
url="$baseurl/v4/server/clusters/generic?countryCode=" | |
http_status=$(curl -o $tmpfile -s -w "%{http_code}" -H 'Content-Type: application/json' $url) | |
rc=1 | |
if [ $http_status -eq 200 ]; then | |
echo " HTTP status OK ($(jq '. | length' "$tmpfile") servers downloaded)" | |
echo -n " Selecting suitable servers..." | |
tmpfile2=$(mktemp /tmp/surfshark-wg-servers.XXXXXX) | |
jq '.[] | select(.tags as $t | ["p2p", "physical"] | index($t))' "$tmpfile" | jq -s '.' > "$tmpfile2" | |
echo " ($(jq '. | length' "$tmpfile2") servers selected)" | |
if [ -f "$servers_file" ]; then | |
echo " Servers list \"$servers_file\" already exists" | |
changes=$(diff "$servers_file" $tmpfile2) | |
if [ -z "$changes" ]; then | |
echo " No changes" | |
rm $tmpfile2 | |
else | |
echo " Servers changed! Updating servers file" | |
mv $tmpfile2 "$servers_file" | |
rc=0 | |
fi | |
else | |
mv $tmpfile2 "$servers_file" | |
rc=0 | |
fi | |
else | |
echo " HTTP status $http_status (Failed)" | |
fi | |
rm $tmpfile | |
return $rc | |
} | |
gen_keys() { | |
if [ -f "$wg_keys" ]; then | |
echo "WireGuard keys \"$wg_keys\" already exist" | |
wg_pub=$(cat $wg_keys | jq -r '.pub') | |
wg_prv=$(cat $wg_keys | jq -r '.prv') | |
else | |
echo "Generating WireGuard keys..." | |
wg_prv=$(wg genkey) | |
wg_pub=$(echo $wg_prv | wg pubkey) | |
echo "{\"pub\":\"$wg_pub\", \"prv\":\"$wg_prv\"}" > $wg_keys | |
fi | |
echo " Using public key: $wg_pub" | |
} | |
reg_pubkey() { | |
echo "Registering public key..." | |
url="$baseurl/v1/account/users/public-keys" | |
data="{\"pubKey\": \"$wg_pub\"}" | |
retry=$1 | |
tmpfile="$(mktemp /tmp/wg-curl-res.XXXXXX)" | |
http_status="$(curl -o "$tmpfile" -s -w "%{http_code}" -H "Authorization: Bearer $token" -H "Content-Type: application/json" -d "$data" -X POST $url)" | |
message="$(jq -r '.message' $tmpfile 2>/dev/null)" | |
if [ $http_status -eq 201 ]; then | |
echo " OK (expires: $(jq -r '.expiresAt' $tmpfile), id: $(jq -r '.id' $tmpfile))" | |
elif [ $http_status -eq 401 ]; then | |
echo " Access denied: $message" | |
if [ "$message" = "Expired JWT Token" ]; then | |
echo " Delete $token_file and try again!" | |
rm "$token_file" | |
if do_login; then | |
reg_pubkey 0 | |
return | |
else | |
echo " Giving up..." | |
fi | |
elif [ "$message" = "JWT Token not found" ]; then | |
if [ $retry -eq 1 ]; then | |
echo " Have some coffee and try again!" | |
sleep 5 | |
reg_pubkey 0 | |
return | |
else | |
echo " Giving up..." | |
fi | |
fi | |
elif [ $http_status -eq 409 ]; then | |
echo " Already registered" | |
url="$baseurl/v1/account/users/public-keys/validate" | |
http_status="$(curl -o "$tmpfile" -s -w "%{http_code}" -H "Authorization: Bearer $token" -H "Content-Type: application/json" -d "$data" -X POST $url)" | |
if [ $http_status -eq 200 ]; then | |
expire_date="$(jq -r '.expiresAt' $tmpfile)" | |
ed="$(date -u -d "$expire_date" -D "%Y-%m-%dT%T" +"%s")" | |
now="$(date -u +"%s")" | |
diff=$(($ed - $now)) | |
if [ $diff -eq 604800 -o $((604800 - $diff)) -lt 10 ]; then | |
echo " Renewed! (expires: $expire_date)" | |
elif [ $diff > 0 ]; then | |
echo " Expires on $expire_date)" | |
else | |
echo " Warning: key is expired! ($expire_date)" | |
fi | |
else | |
echo " HTTP status $http_status, failed to check key: $(cat $tmpfile)" | |
fi | |
else | |
echo " Failed: HTTP $http_status, $(cat $tmpfile)" | |
fi | |
rm $tmpfile | |
} | |
gen_client_confs() { | |
postf=".surfshark.com" | |
mkdir -p "$output_conf_folder" | |
servers="$(cat "$servers_file" | jq -c '.[] | [.connectionName, .pubKey]')" | |
for s in $servers; do | |
name="$(echo $s | jq -r '.[0]')" | |
pubkey="$(echo $s | jq -r '.[1]')" | |
conf="${srv_conf_file_folder}/${name%$postf}.conf" | |
echo "Generating config for $name..." | |
cat << EOF > "$conf" | |
[Interface] | |
PrivateKey=$wg_priv | |
Address=1.2.3.4 | |
MTU=1350 | |
[Peer] | |
PublicKey=o07k/2dsaQkLLSR0dCI/FUd3FLik/F/HBBcOGUkNQGo= | |
AllowedIPs=172.16.0.36/32 | |
Endpoint=wgs.prod.surfshark.com:51820 | |
PersistentKeepalive=25 | |
[Peer] | |
PublicKey=$pubkey | |
AllowedIPs=123.456.7.8 | |
Endpoint=$name:51820 | |
PersistentKeepalive=25 | |
EOF | |
done | |
} | |
echo "Running at $(date)" | |
read_config | |
gen_keys | |
if do_login; then | |
reg_pubkey 1 | |
else | |
echo "Not registering public key!" | |
fi | |
if [ "$1" == "-g" ]; then | |
if get_servers; then | |
gen_client_confs | |
else | |
echo "Not generating client configurations!" | |
fi | |
fi | |
echo "Done!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment