Create Surfshark wireguard connection on OpenWrt easily

Hi everyone,

I wrote a simple script that helps me create Surfshark's wireguard connection on my OpenWRT.
I'm sharing it with you in a hope that it hopefully will help someone else.
Please see

It needs curl and jq because it calls Surfshark API in order to get server's information and submit generated public key to Surfshark.

Right now it generates normal wireguard config file and the next step is to generate/emit set of uci commands to actually add it OpenWRT.

I will be happy to get any feedback from it

8 Likes

Hi @yazdan ,

once I have the .json files generated, how is the interface configured, with what values?

Thanks.

Hi @Gcholvi
After you run the script you should be able to see a folder named conf is created.

In that folder all classic Wireguard connection configs are generated.
Then if you cat one of these config files you see

[Interface]
PrivateKey=someprivatekey=
Address=10.14.0.2/8
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=6dZGkg0iAMgQuOCGknAgBAqDEeJeBQ4Of5eblO4aNC8=
AllowedIPs=0.0.0.0/0
Endpoint=ae-dub.prod.surfshark.com:51820
PersistentKeepalive=25

use these information to create an interface using this guide

to have some sort of reference my folder structure is like this

.
├── LICENSE
├── README.md
├── conf
│   ├── ae-dub.prod.surfshark.com.conf
│   ├── al-tia.prod.surfshark.com.conf
│   ├── ar-bua.prod.surfshark.com.conf
│   ├── at-vie.prod.surfshark.com.conf
│   ├── au-adl.prod.surfshark.com.conf
│   ├── au-bne.prod.surfshark.com.conf
│   ├── au-mel.prod.surfshark.com.conf
│   ├── au-per.prod.surfshark.com.conf
│   ├── au-syd.prod.surfshark.com.conf
│   ├── az-bak.prod.surfshark.com.conf
│   ├── ba-sjj.prod.surfshark.com.conf
│   ├── be-anr.prod.surfshark.com.conf
│   ├── be-bru.prod.surfshark.com.conf
│   ├── bg-sof.prod.surfshark.com.conf
│   ├── br-sao.prod.surfshark.com.conf
│   ├── ca-mon.prod.surfshark.com.conf
│   ├── ca-tor.prod.surfshark.com.conf
│   ├── ca-van.prod.surfshark.com.conf
│   ├── ch-zur.prod.surfshark.com.conf
│   ├── cl-san.prod.surfshark.com.conf
│   ├── co-bog.prod.surfshark.com.conf
│   ├── cr-sjn.prod.surfshark.com.conf
│   ├── cy-nic.prod.surfshark.com.conf
│   ├── cz-prg.prod.surfshark.com.conf
│   ├── de-ber.prod.surfshark.com.conf
│   ├── de-fra.prod.surfshark.com.conf
│   ├── dk-cph.prod.surfshark.com.conf
│   ├── dz-alg.prod.surfshark.com.conf
│   ├── ee-tll.prod.surfshark.com.conf
│   ├── es-bcn.prod.surfshark.com.conf
│   ├── es-mad.prod.surfshark.com.conf
│   ├── es-vlc.prod.surfshark.com.conf
│   ├── fi-hel.prod.surfshark.com.conf
│   ├── fr-bod.prod.surfshark.com.conf
│   ├── fr-mrs.prod.surfshark.com.conf
│   ├── fr-par.prod.surfshark.com.conf
│   ├── ge-tbs.prod.surfshark.com.conf
│   ├── gr-ath.prod.surfshark.com.conf
│   ├── hk-hkg.prod.surfshark.com.conf
│   ├── hr-zag.prod.surfshark.com.conf
│   ├── hu-bud.prod.surfshark.com.conf
│   ├── id-jak.prod.surfshark.com.conf
│   ├── ie-dub.prod.surfshark.com.conf
│   ├── il-tlv.prod.surfshark.com.conf
│   ├── in-chn.prod.surfshark.com.conf
│   ├── in-idr.prod.surfshark.com.conf
│   ├── in-mum.prod.surfshark.com.conf
│   ├── is-rkv.prod.surfshark.com.conf
│   ├── it-mil.prod.surfshark.com.conf
│   ├── it-rom.prod.surfshark.com.conf
│   ├── jp-tok.prod.surfshark.com.conf
│   ├── kr-seo.prod.surfshark.com.conf
│   ├── kz-ura.prod.surfshark.com.conf
│   ├── lu-ste.prod.surfshark.com.conf
│   ├── lv-rig.prod.surfshark.com.conf
│   ├── md-chi.prod.surfshark.com.conf
│   ├── mk-skp.prod.surfshark.com.conf
│   ├── mx-mex.prod.surfshark.com.conf
│   ├── my-kul.prod.surfshark.com.conf
│   ├── ng-lag.prod.surfshark.com.conf
│   ├── nl-ams.prod.surfshark.com.conf
│   ├── no-osl.prod.surfshark.com.conf
│   ├── nz-akl.prod.surfshark.com.conf
│   ├── pa-pac.prod.surfshark.com.conf
│   ├── pe-lim.prod.surfshark.com.conf
│   ├── ph-mnl.prod.surfshark.com.conf
│   ├── pl-gdn.prod.surfshark.com.conf
│   ├── pl-waw.prod.surfshark.com.conf
│   ├── pt-lis.prod.surfshark.com.conf
│   ├── pt-opo.prod.surfshark.com.conf
│   ├── ro-buc.prod.surfshark.com.conf
│   ├── rs-beg.prod.surfshark.com.conf
│   ├── ru-mos.prod.surfshark.com.conf
│   ├── se-sto.prod.surfshark.com.conf
│   ├── sg-sng.prod.surfshark.com.conf
│   ├── si-lju.prod.surfshark.com.conf
│   ├── sk-bts.prod.surfshark.com.conf
│   ├── th-bkk.prod.surfshark.com.conf
│   ├── tr-ist.prod.surfshark.com.conf
│   ├── tw-tai.prod.surfshark.com.conf
│   ├── ua-iev.prod.surfshark.com.conf
│   ├── uk-gla.prod.surfshark.com.conf
│   ├── uk-lon.prod.surfshark.com.conf
│   ├── uk-man.prod.surfshark.com.conf
│   ├── us-ash.prod.surfshark.com.conf
│   ├── us-atl.prod.surfshark.com.conf
│   ├── us-bdn.prod.surfshark.com.conf
│   ├── us-bos.prod.surfshark.com.conf
│   ├── us-buf.prod.surfshark.com.conf
│   ├── us-chi.prod.surfshark.com.conf
│   ├── us-clt.prod.surfshark.com.conf
│   ├── us-dal.prod.surfshark.com.conf
│   ├── us-den.prod.surfshark.com.conf
│   ├── us-dtw.prod.surfshark.com.conf
│   ├── us-hou.prod.surfshark.com.conf
│   ├── us-kan.prod.surfshark.com.conf
│   ├── us-las.prod.surfshark.com.conf
│   ├── us-lax.prod.surfshark.com.conf
│   ├── us-ltm.prod.surfshark.com.conf
│   ├── us-mia.prod.surfshark.com.conf
│   ├── us-nyc.prod.surfshark.com.conf
│   ├── us-orl.prod.surfshark.com.conf
│   ├── us-phx.prod.surfshark.com.conf
│   ├── us-sea.prod.surfshark.com.conf
│   ├── us-sfo.prod.surfshark.com.conf
│   ├── us-sjc.prod.surfshark.com.conf
│   ├── us-slc.prod.surfshark.com.conf
│   ├── us-stl.prod.surfshark.com.conf
│   ├── us-tpa.prod.surfshark.com.conf
│   ├── ve-car.prod.surfshark.com.conf
│   └── za-jnb.prod.surfshark.com.conf
├── config.json
├── config.json.sample
├── gen_wg_config.sh
├── selected_servers.json
├── surf_servers.json
├── token.json
└── wg.json

1 directory, 123 files

Hi @yazdan ,


I've been all afternoon and I can't connect to Surfshark.
See attached image.
To what is due?

It seems that your public key is not registered with surfshark servers

Can you run my scripts again and send me the output?
It will not change your configs and just retry the key registration if it is needed

Hi,

The script works perfectly. In my router the speed with Openvpn 35M with Wiregurd 120M.
@yazdan thanks for the help

3 Likes

Happy to hear that

I think I evaluated Surfshark a year or so ago. If I remember right, I didn't go with them because they do not provide the WG configs to users so they can set it up themselves. Hence the need for this script, is that correct? Nice to see this is an option.

Right now they still don't officially provide WG configs.

I saw in github that there are some repositories in other languages that say they generate wireguard configs, and what I've done is just converting them to shell scripts so we can run/use it on OpenWRT.

2 Likes

Hi @yazdan and @Gcholvi

I tried your script and I’m having the same problem where my public key is not registered with the Surfshark servers. Do you mind sharing what you did to make it work? Thanks in advance for your help and for making this script! Cheers!

1 Like

Hella @yazdan,

I find myself in a similar situation here as well - Peer One handshake, Peer Two never sees a handshake.

I added some echo commands to the script to allow me to track function returns and variables, and added -v switch to the curl calls to track what might be failing here.

Everything runs fine until the script hits the

VALIDATE PUBKEY Function - output below

< HTTP/1.1 404 Not Found	<------------

                         .
                         .    
                      S N I P 
                         .
                         .

The script populates the .conf files absolutely correctly. Correct public/private keys, IP's,MTU, and required peer values. It works as advertised.

EDIT: My apologies to @yazdan. I mistakenly misconstrued the logic between the wg_check_pubkey and wg_reg_pubkey functions.

1 Like

@RuralRoots It's recommended that you delete all files in the directory except for config.json and wg_gen_config.sh

Also, the script will populate the .conf files (and include private keys) even if the username and password are incorrect in config.json. I tried running the script with username: user and password: pass in the config.json and the script completed successfully along with a private key and a directory of .conf files. Of course, these .conf files will not successfully establish a connection in the Wireguard client.

For me, the failure is occurring at /v1/account/users/public-keys/validate but the API response is different.

wg_check_pubkey
url=https://api.surfshark.com/v1/account/users/public-keys/validate

....

Connection #0 to host api.surfshark.com left intact
curl_res='{"code":400,"message":"Bad Request"}'

...
No need to register pubkey

Perhaps Surfshark changed something with this API method recently?

1 Like

Hi guys, this sounds really super interesting. Is there any chance this will make it into part of the openwrt software list, so i can install it like openvpn? wireguard is so much faster than openvpn...
i would be very grateful as i am always happy if sth with openwrt starts working, but with this scripts here, i feel overwhelmed.

1 Like

wg.json contains MY valid Private/Public keys generated from the standard wg genkey function - no need to regenerate another key pair.

True, but irrelevant. If SS username/password authentication fails it creates an empty authentication token.json file OR a properly signed and correctly populated token.json file if authentication passes. A proper token.json file must be valid for success. The recent commit adding set -e and unset delimiting the login function appears to address this.

Same place I noted. If the function validate fails ie (HTTP/1.1 404 Not Found/code":400,"message":"Bad Request"), your wgpub key will never be registered with SS. wg_reg_key () function just essentially verifies your token key hasn't expired.

Provided:
Your SS username/password is configured correctly and authenticated you will get your token.json file.
You have your valid wg genkey - you can use the script to generate a new pair, or keep your existing key pair
the script works as advertised. No changes to the SS API.

My problem came back to ISP issues and my attempts to trace through the script logic.

1 Like

If you have a SS account it will work with Wireguard on OpenWrt. You will need to install: opkg update ; opkg install wireguard-tools ; opkg install kmod-wireguard ; luci-app-wireguard ; luci-proto-wireguard ; jq ; curl as a prerequisite.

No worries, the thread title is accurate. Go the the first post by @yazdan and click on the github link. Click on the green "Code" button and select "Download ZIP" and extract gen_wg_config.sh and config.json.sample. Read the read.me as well.

1 Like

Hi I'm in trip and I tried the script my self and it is not also working for me. I think Surfshark has changed something in its API. I need to investigate more after I got back to home

Hi @RuralRoots

That is interesting I think Surfshark change changed some of their API. I'll try to findout what is changed and will let you know.

PS: I'm on a work trip and will be able to do it after I got back

Public and Private keys are generated locally and we just register public key, so they are somehow local and are not related to Surfshark's usename and password

It was my first try and the error handling is not there. I updated the repo and just add set -e so it will fail if something goes wrong. It still needs improvement regarding error handling

I thinks that is the case

It is just a prototype and if I have time I'll try to make a package with a separate Luci package for it

So if i get that correctly, it does not work at the moment? (5.12.2021)