Create Surfshark wireguard connection on OpenWrt easily

Updated Script

**Deprecated**

Greetings!
From a clean OpenWRT image I followed the official OpenWRT guide to get the client wireguard baselined. Your choice may differ..
I deviated slightly and gave my WG_IF="vpn" the name WG_IF="SSWG"
https://openwrt.org/docs/guide-user/services/vpn/wireguard/start >> client

This baseline install is vanilla without luci YET! install the following. Since your are here: Create Surfshark wireguard connection on OpenWrt easily
We'll assume you've already hit the Git

opkg update
opkg install luci-proto-wireguard luci-app-wireguard qrencode curl jq
/etc/init.d/rpcd restart

optional: and after you get yazdan's configs mastered....This is a placeholder url that you may find handy that is easily overlooked.. winking at Paul :wink:

opkg vpn-policy-routing
/etc/init.d/rpcd restart

VPR

Log into your router: CHECK your "WG_IF "interface" doublechecking the copy/paste wiz/bang you did from the clean install of "Client". Look at your keys.
Now use your terminal to ssh into your router. I use WinSCP because Windows grants the cheat to visualize this and eventually make directories, files, text edits; without wondering what vi or nano keyboard command are for text editing. ¯(ツ)/¯ winking @ Paul again for weeks now ¯(ツ)/¯

Try looking in /root.. Once you find the keys from vanilla's install
step 2:
It's time to decide where you're; going to run your awesome RuralRoots Cron job from and... AND, edit that location into the "gen_wg_config.sh" file. Yup you heard me right Paul...Awesome! Speaking of Awesome don't neglect to get the code snippet he's posted. This code makes life fun!

My example is shown in the pics.. and crontab job below.. I buried yazdan's files in /etc/config/wireguard/
Notice line 26 of the current Git sh.

I've edited the gen_wg_config.sh file and left the config.json with only my user/pass.. that darnblamfrigglefracking lost cause "config_folder": "." thingy can stay "." OK! BECAUSE we are going to tell json to go to hello world with line 26 of the gen_wg_config.sh file. Why? because the Professor asked a good question. If you run this from Putty anywhere, Crontab defaults to /root, or six folders deep in WinSCP's Console: config.json errors are a bygone problem.

And make it happen your style. This means moving your files to a folder of your making and align it to placeholders in gen_wg_config.sh line 26, and Crontab.

BTW.. I've camped on this page for about 6 weeks now reading up/down/sideway/over/beyond, so apologies since I've given ya'll nicknames to your avatars. Professor aka directnupe you've been pleasantly persistent asking the hard questions. By that I means humble yet succinct. Paul aka RuralRoots. Bless you for making us think and learn and strive. I hope yazdan lives to plug your verbose mods.

If you're a smart feller, edit the crontab below to align with the directory you placed yazdan's edited files.. If you're a *art smeller and copied my example.. it's simply copy/paste from here.

cat << "EOF" >> /etc/crontabs/root
# Periodically reinstate Key duration
#######################################################
05 00 * * * /etc/config/wireguard/gen_wg_config.sh -f -g >/etc/config/wireguard/wg-f.log 2>&1 # force registration and print to log midnight+5min
10 00 * * * /etc/config/wireguard/gen_wg_config.sh -g >/etc/config/wireguard/wg-g.log 2>&1 # after force and print to log.  
######################################################
05 12 * * * /etc/config/wireguard/gen_wg_config.sh -f -g >/etc/config/wireguard/wg-f.log 2>&1 # force registration and print to log noon+5min
10 12 * * * /etc/config/wireguard/gen_wg_config.sh -g >/etc/config/wireguard/wg-g.log 2>&1 # after force and print to log.
#######################################################
EOF
uci set system.@system[0].cronloglevel="5"
uci commit system
/etc/init.d/cron restart

Good Luck All
I trust one pic is enough newbie's of any age: Born Limited.

The actual server configs seldom change. I haven’t regenerated the 5 I employ round-robin here since day one. I think you’ll find the contents of the json response as you alluded to in your reference to some neat filtering . . . is the primary reason for the regular updates.

Nor do I. Considering it only listens to a single ip (/32) I just considered it part of the api’s authentication mechanism. Have you tried removing Peer 1 ?

DNS leaks? If you haven’t changed your upstream resolver . . . ?

Hey Patrickm. I'm intrigued by the work of your script. Some things I really like and one maybe two things I don't understand.

Like the echo you use to show potential errors. Since I run your script to a log >>/etc/config/wireguard/wg-g.log 2>&1 I can see the work accomplished. I like that it can run with a -g argument. Spent the good portion of last night testing this by deleting all files just to watch it work. This brings me to my quandary/question/confusion.

Was the writing of this scripts intent not to populate private keys for every server downloaded and why does it not write the client configs to the conf folder?

Thanks

Hey RuralRoot.
Question to the Round Robin; is that a unique Wireguard VPN Interface per config file?
Also since you have linked stangri or actually Melmac site, do you employ this addon as well?
Thanks for your insights.

If you can call it that. Just a simple uci script to change Peer2 endpoint to preferred server and restart when I need to.

I do. Moving to PBR (same site) as update to VPN-PBR.

If you’re curious, this might help seeing what the script(s) are seeing when they retrieve info from SS in json format.

cat <wg-generated-file>.json | jq . for all, or
cat <wg-generated-file>.json | jq .[1] for a single entry

1 Like

Thank you Sir. I don't have the kernel to run PBR. However, I did notice you were actively (very) engaged with helping @stangri and others on the forum.

I also noticed a screenshot: being proactive waiting on your gracious reply:
VPN Policy-Based Routing + Web UI -- Discussion - #1157 by RuralRoots that's similar to my setting.

I'll follow up on the commands soon; digging into (MINGW64:/c/Users/wbc) now. I'll post any follow ups on the aforementioned forum.

Thank you Paul
Have a good timezone! :grin:

I just noticed the part about the "simple" uci script.. OK so I'll get back to that very soon.

I'm going to need a primer on this.. I just logged into my router and pasted that into putty and opps! I get the -ash can't open ...
Not really sure what to do and what I expected to see. When the shell barks back like that, I feel kinda dumb. Was that your plan? lol

In your run directory cat surf_servers.json | jq . for example

So... from /etc/config/wireguard Or
/etc/config/wireguard/conf where the Server/Client files download?

Also do I use the file name of the conf-file as "pl-waw.prod.json"

EDIT: My bad!
My eyes are shot from tinkering with @patrickm script. I deleted so much from my run directory that I didn't see what was right in front of me.

His mangled/sniffed/ script dropped a lot of curl and used more jq and the output of the surf_servers.json file is replaced with surfshark_servers.json in the exact same format as your cat command. Much easier to read.. but what to I gain from examining this json file?
Brain Dump! Feel free to share a cool link because I'll read it.
Thanks again for stretching my limits.
Bill

Run directory = /etc/config/wireguard/ and any sub-dir’s with .json extensions

Got it ;>)

1 Like

You're better than Youtube..
BTW, how's the view from your location? LOL :nauseated_face:

I can think of many ways to use load, co-ordinates, country/region et al to groom my preferred servers file.

Going out on the limb I frequent so often:
Could I assume that grooming the surfshark_servers.json/ surf_servers.json file to the list of server/peers I want, getting me a baby step closer, to then utilizing this in a elusively beautiful "simple uci script" for round-robin?

Thinking this as applied learning for a purpose of meeting a goal.

Depending how you set up your default route (all traffic via ‘wan’ or OpenVpn tunnel or WG or ???) VPN-PBR just lets you direct specific devices to be routed to other than your default route. Ergo, it doesn’t interact with VPN-PBR other than presenting an additional service gateway.

uci by itself will produce a cheat sheet for reference.

uci show network will show you /etc/config/network in UCI format. You want to concern yourself with the Peer 2 section for your WG interface. Two entries need to be revised server PubKey and your corresponding new endpoint host.

Script Pseudo code:

uci set PubKey
uci set Preferred Server endpoint
uci commit
/etc/init.d/network restart ; /etc/init.d/firewall restart
1 Like

uci show network.@[10]

shows one of my four peer2 wireguard endpoints. Now I just have to learn how to reorder the list. :upside_down_face: hehehehehehhehehhe :thinking: don't tell me!!

Thanks Paul!
I'll study the uci usage further. I currently have a working script, however, I purpose to understand the basics. I had manually entered into Luci, 3 additional peer2. Last entered endpoint becomes wireguard connection upon uci commit ; /etc/init.d/network restart ; /etc/init.d/firewall restart.

I did that early yesterday and have 4 scripts to initialize the "preferred peer2" but it's adds an additional redundant entry into /etc/config/network.

So with your guidance above I have some reading and honing to accomplish, as the pic below is........ blah ok....... your help has given me some more tools to explore.

I'm sure there exist eaiser methods, I for one could just drop a pre made "network" file into /etc/config/network and restart. But it was a fun challenge and I learned something. When the other options pop up; I'll learn more! Enjoy your journey. @RuralRoots I have the suggestion saved to learn along with jq curl cat Thank you.

#!/bin/sh
echo "Running at $(date)"
uci reorder network.@[13]=12
uci commit network
/etc/init.d/network restart
logger -t yourIFname ":$(date)   connection established"

## Undo examples:
## uci reorder network.@[13]=12
## uci reorder network.@[12]=13

## uci reorder network.@[13]=11
## uci reorder network.@[11]=13

## uci reorder network.@[13]=10
## uci reorder network.@[10]=13

## uci reorder network.@[13]=9
## uci reorder network.@[9]=13

####################################################################################
# MULTIPLE PEER(2) NETWORKS CAN BE ADDED TO LUCI AND SWAPPED BY .sh
# These networks are known by the notations below. Goal is to find peer(2).
# Plug in a number, or examine your "network" file ~ vi , nano, gui ~ 
# Count the unique "config" entries to find your first and last peer(2) entry
#
# (uci show network.@[])  	#example will show first top entry /etc/config/network
# (uci show network.@[0]) 	#example will also show first top entry /etc/config/network
# (uci show network.@[1]) 	#example will show second entry /etc/config/network
# (uci show network.@[2])	#example will show third entry /etc/config/netork
# ....
# (uci show network.@[13]	#example ~~ 13th entry /etc/config/network 
# last peer=wg0 current tunnel us-nyc!

#########################      Visual    ##############################

#root@Dachshund:~# uci show network.@[]
#network.loopback=interface
#network.loopback.ifname='lo'
#network.loopback.proto='static'
#network.loopback.ipaddr='127.0.0.1'
#network.loopback.netmask='255.0.0.0'
#root@Dachshund:~# uci show network.@[0]
#network.loopback=interface
#network.loopback.ifname='lo'
#network.loopback.proto='static'
#network.loopback.ipaddr='127.0.0.1'
#network.loopback.netmask='255.0.0.0'
#root@Dachshund:~# uci show network.@[1]
#network.globals=globals
#network.globals.ula_prefix='0:0:0:0::/0'
#root@Dachshund:~# uci show network.@[13]
#network.cfg0e6912=wireguard_SSWG
#network.cfg0e6912.public_key='rhuoCmHdyYrh0zW3J0YXZK4aN3It7DD26TXlACuWnwU='
#network.cfg0e6912.peersistent_keepalive='25'
#network.cfg0e6912.endpoint_port='51820'
#network.cfg0e6912.allowed_ips='0.0.0.0/0' '::/0'
#network.cfg0e6912.route_allowed_ips='1'
#network.cfg0e6912.endpoint_host='us-nyc.prod.surfshark.com'
#network.cfg0e6912.description='nyc-prod'
#
# Per OpenWrt - CFGID's are assigned to WireGuard Peers in order a~z.
# Shown below as cfg0(a)6912, cfg0(b)6912, etcetera
# Static entries insofar as peers do not move in order, unless commanded to. This sh's goal.
# The command: (uci reorder network.'cfg0a6912'=) will move that peer  <NOTE:AVOID> 
# to the very top of your /etc/config/network file and the CFGID's will change!
# The command: (uci reorder network.@[9]=) will move that peer <NOTE:AVOID>
# to the very top of your /etc/config/network file and the CFGID's will change!
# These CFGID can be found by either using a web browser's inspect tool
# upon the peer in the setup section of the Peer Tab in Luci, or
# invoking a save and then inspecting the "unsaved changes" section,
# or uci reorder network.@[#] where # represents number (see above [1]) of config line entry
# in your 'network' file, and then using (uci changes) to view the cfg0xxxxxx
# or using (uci show network.'cfgxxxxxx') if you happen to know xxxxxx
# Last entry will become path>wg0 tunnel. In this ex. cfg0e6912 is path.
# This example demonstrate five peers added via uci or Luci.
#
# cfg0a6912					#example cfg0a6912 is fr-bod
# cfg0b6912					#example cfg0a6912 is jp-tok
# cfg0c6912					#example cfg0a6912 is it-rom
# cfg0d6912					#example cfg0a6912 is pl-waw
# cfg0e6912					#example cfg0a6912 is us-nyc
#
# ***Issuing a reorder command to move from us-nyc onto pl-waw***
# Since us-nyc is the 13th config line [13] and currently cfg0e6912
# Since pl-waw is the 12th config line [12] and currently cfg0d6912
# uci the following... 
#
#root@Dachshund:~# uci reorder network.@[13]=12
#root@Dachshund:~# uci changes
#network.cfg0e6912='12'
#uci: Entry not found
#uci: Entry not found
#uci: Entry not found
#uci: Entry not found
#uci: Entry not found
#root@Dachshund:~# uci export network
#package network
#
#config interface 'loopback'
#        option ifname 'lo'
#        option proto 'static'
#        option ipaddr '127.0.0.1'
#        option netmask '255.0.0.0'
#
#config globals 'globals'
#        option ula_prefix '0:0:0:0::/0'
#
####  TRUNCATED  ####
#
#config wireguard_SSWG
#        option public_key 'rhuoCmHdyYrh0zW3J0YXZK4aN3It7DD26TXlACuWnwU='
#        option peersistent_keepalive '25'
#        option endpoint_port '51820'
#        list allowed_ips '0.0.0.0/0'
#        list allowed_ips '::/0'
#        option route_allowed_ips '1'
#        option endpoint_host 'us-nyc.prod.surfshark.com'
#        option description 'nyc-prod'
#
#config wireguard_SSWG
#        option public_key 'vBa3HK7QXietG64rHRLm085VMS2cAX2paeAaphB/SEU='
#        option persistent_keepalive '25'
#        option endpoint_port '51820'
#        list allowed_ips '0.0.0.0/0'
#        list allowed_ips '::/0'
#        option route_allowed_ips '1'
#        option endpoint_host 'pl-waw.prod.surfshark.com'
#        option description 'waw-prod'
#
#root@Dachshund:~# uci commit ; /etc/init.d/network restart
#
# Now pl-waw takes the CFGID of cfg0e6912 and position of 13th and is VPN tun. 
# Now us-nyc takes the CFGID of cfg0d6912 and position of 12th.
# Changes will be reflected in the Peer Tab of Setup and the WireGuard Status page.
###################################################################################
1 Like

Yessir! You did ask though. :rofl:

I wondered how you’d tackle the indexing when I read that. Well Done!!

No better honor than receiving my "Welcome Badge" from the Sensei of this forum. :man_bowing:

I dug deep into the router /www/luci-static/resources/protocol/wireguard.js

See illustration:

To find some clues..........out on the limb I so frequently visit........

`deleteConfiguration:function(){uci.sections('network','wireguard_%s'.format(this.sid),function(s){uci.remove('network',s['.name']);});`

The thought process is that since we have an "Add Peer" button and the "Delete" button; if I could manipulate these commands from deleteConfiguration and uci.remove to say reorderConfiguration and uci.reorder and if it work then, move onto adding an addition line, and button. But it failed.
I threw several blind punches, at the line: rebooted the router.. the good news is I didn't brick luci. So any ideas Paul? Do you mingle with some top notch js peeps?

On somewhat of a sidetrack I found this odd: All these *.json dated files several week old. Which would match the time I started from scratch. Oddly no surfshark_servers.json files AKA from running @patrickm script.

/www/luci-static/resources/tools/selected_servers.json
/www/luci-static/resources/icons/selected_servers.json
/www/luci-static/resources/selected_servers.json
/www/luci-static/resources/icons/token.json
/www/luci-static/resources/token.json
/www/luci-static/resources/tools/surf_servers.json
/www/luci-static/resources/icons/surf_servers.json
/www/luci-static/resources/surf_servers.json
/www/luci-static/resources/tools/wg.json
/www/luci-static/resources/icons/wg.json
/www/luci-static/resources/wg.json
/www/luci-static/resources/view/status/include/selected_servers.json
/www/luci-static/resources/view/status/include/wg.json
/www/luci-static/resources/view/status/include/surf_servers.json
/www/luci-static/resources/view/status/include/token.json
get_servers() {
    echo "Retrieving servers list..."
    tmpfile=$(mktemp /tmp/surfshark-wg-servers.XXXXXX)
     .
     .
     .

rm $tmpfile
    return $rc
}

He retrieves the former surfshark_servers.json file instead to a temp file every run so a physical file never exists.

Not my forte, maybe this might help. https://github.com/openwrt/luci#development

Thanks for the homework link.

I meddled around with his script and actually produced a copy and somehow manage to get the "handicapped" conf files place in my run /etc/config/wireguard/conf folder.

BUT..

find / -iname wg.json

So it's not odd to have these sticks scatter in the wind?

Summary