Create Surfshark wireguard connection on OpenWrt easily

I keep encountering this last issue. Seems that I don't know how to create /mnt/shared directory.
When creating my usb exroot - I put /dev/sda1
Mount point = / ( root ) - should it be mount point = overlay instead ?
I Googled /mnt/shared - and I got cifs - windows - samba - basically information about file sharing. My setup is not that elaborate or sophisticated.
Is there an installation directory that I can use which is less complex to use for the cron job ?
Maybe something like -

mkdir -p /mnt/opt/wgapi

I successfully run AdguardHome on / from this directory on my current setup

Anyway - no matter the outcome of this attempt to get this working; I wish to thank you to the Nth degree for sticking with me - through all my fumbling, stumbling and ignorance. I am not ashamed that there are many things that I simply don't know. I try to the best of my ability to find the answers on my own ( in part - not to become a perpetual giant PITA ) ; however, there are times where I still remain in the dark - and have to reach out in order to led into the light.
Thanks RuralRoots - hopefully - this will be it on this topic.

PS - If you do suggest an alternate installation folder / directory - if you would include an illustration of the correct corresponding cron job I would appreciate it -

Yes, I was curious about that when you were talking overlay.

I’m not up on, but I’ll get back to you to work it out.

The cron was just a way to set and forget and the log was just to check key update because there wasn’t any visibility.

You can still run this once a day to update. /mnt/shared/wgapi/ -f -g
Wait a few minutes and run /mnt/shared/wgapi/ -g

find / -iname Should return path.

Thanks I will run that command and report back shortly. I am truly amazed by your knowledge and expertise. Thank you so very much for pointing me in the right directions - and most of all for your patience. I am a retired HS English Teacher - and this was not always among my best qualities. So, I especially appreciate and respect the courtesy and kindness you have shown throughout my struggles here. Hopefully, others will benefit from - the " alls well that ends well " culmination of our interchanges.

Here's my current version of the script:
Still fine tuning but it works well for public key registration, renewal and retrieving SurfShark server configs (which seems to be updated every 30 mins or so). Next step is generating/updating OpenWRT configuration, still not sure if there's any benefit in having multiple peers. Maybe config.json should be extended with a 'preferred server' so only one is selected? Also you could do some neat filtering based on current load and other properties in the surfshark json response but i really need to brush up on my jq skills for that...


For those in the dark as to how to configure SurfShark WireGuard Configuration Files
Thanks to all the folks here who keep perfecting this project.

IMPORTANT UPDATE April 17, 2022 - Easter Day
For The Most Simple and Direct Evolution of All
The Collective Hard Work Done Here -
In other words TRULY Easy SurfShark WireGuard

Go Here People For SurfShark WireGurard ~ SSWG


Overview of nano's shortcuts

From the dummy file below: Go to the the very bottom of this file and add the following :
The keys and addresses used here are fictional and used only for illustrative purposes.

Set the server's network configuration by editing /etc/config/network to include following parts.

In the default install folder ( /wg/ ) after running script ( ) - you will find SurfShark Wireguard configuration files in the default installation folder /wg/ in the conf directory. In this example I am using - you can read the file - by running # cat - while in the conf directory. All configuration files are in /wg/conf directory - my file used here is


1) Set the wireguard server's network configuration by editing 
to include following parts.




2 - Open the file: nano /etc/config/network  - and go to the very bottom of the file
Here is how you configure the SurfShark WireGuard Interface and Two Peers
The Information is found in the example directly above.

config interface 'wg0'
        option proto 'wireguard'
        option private_key 'foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q='
        list addresses ''
        option mtu '1350'
        option dns ''

config wireguard_wg0
        option public_key '/llFOsnvj7GcXasKrojhZl6nRnnn4D8sRuDUKEdiZzM='
        option route_allowed_ips '1'
        list allowed_ips ''
        option persistent_keepalive '25'
        option description 'WG_1'
        option endpoint_host ''
        option endpoint_port '51820'

config wireguard_wg0
        option public_key 'cxti1XR6uW483xAioP3d1ZaoGSy+obY6WaE4fW1A6Nk='
        list allowed_ips ''
        option persistent_keepalive '25'
        option description 'WG_2'
        option route_allowed_ips '1'
        option endpoint_host ''
        option endpoint_port '51820'

Save and Exit 

3) Configure the OpenWRT firewall for your Surfshark WIRGUARD Client:

Special Thanks to trendy ( from the OpenWRT Forum ) for helping me with this elegant solution

The most simple, effective and efficient method to set up your firewall
for Surfshark WIREGUARD this is to add the 'wg0' network 
to the wan zone in the /etc/config/firewall configuration file

Edit /etc/config/firewall file and add the 'wg0' network as follows:

Open the file: nano /etc/config/firewall 

config zone
        option name 'wan'
        list network 'wan'
        list network 'wan6'
        list network 'wg0'  ## This is the line you need to add - and you are done
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'

Save and Exit 

Then issue from command line Step 4 below:

4 ) Apply changes

/etc/init.d/network reload
ifdown wg0
ifup wg0
/etc/init.d/firewall restart


# wg show  ## in order to check connection and data transfer rates

Dear patrickm,
Thanks for the script - should a cron job be set up with this script. BTW - your script registered / renewed keys just fine. Ran into a bit of an issue as it did not generate / retrieve SurfShark server configs.
I ran both of the commands below : and -f

Neither command produced the SurfShark server configs, but both registered the public key - and generated both wg.json and the token.json. Just reporting back

Any information about possible necessity of cron job - and information as to how to properly use your script will be greatly appreciated.


1 Like

What is the reason for adding a peer for I didn't do that and it seems to work fine for me but i've seen this in RuralRoots script as well. No idea if it has any purpose?

How do you guys take care of not leaking DNS requests? I think I need to setup a split DNS, so eligible clients on my LAN resolve remote hosts over VPN without losing access to local DNS.

Without any arguments my version of the script just registers or renews the public key. It's valid for 7 days, i've not yet confirmed the connection actually breaks if you don't renew in time. If it does you should run it in a cronjob at least once per week I guess. But my goal is to update openwrt wireguard config in place, run it maybe every ~6 hours to check for config changes, run it automatically when connection goes down etc.

For now to generate conf for all servers (which takes a while and you likely just need one), in my version of the script, run it with -g parameter.

Updated Script


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" >> 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


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 "" 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 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 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 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/ -f -g >/etc/config/wireguard/wg-f.log 2>&1 # force registration and print to log midnight+5min
10 00 * * * /etc/config/wireguard/ -g >/etc/config/wireguard/wg-g.log 2>&1 # after force and print to log.  
05 12 * * * /etc/config/wireguard/ -f -g >/etc/config/wireguard/wg-f.log 2>&1 # force registration and print to log noon+5min
10 12 * * * /etc/config/wireguard/ -g >/etc/config/wireguard/wg-g.log 2>&1 # after force and print to log.
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?


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 ""

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.

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.